# Schemas This document specifies how data types are described and used. ## Status Draft — based on codebase investigation and design discussion. --- ## Current State ### Overview Schemas describe the shape and type of data in cells. The system uses JSON Schema as the description language, with extensions for cell-specific behavior. ### JSON Schema as Type Language Standard JSON Schema properties are used: - `type`: "string", "number", "boolean", "object", "array", "null" - `properties`: object property schemas - `items`: array element schema - `default`: default value - `required`: required properties ### Special Schema Properties #### `asCell` Marks a property as a cell reference rather than inline data: ```json { "type": "object", "properties": { "linkedItem": { "asCell": true, "type": "object" } } } ``` #### `asStream` Marks a property as a stream endpoint: ```json { "type": "object", "properties": { "onClick": { "asStream": true } } } ``` This causes: - Storage of `{ $stream: true }` marker - Different runtime behavior (send vs set) - Different change detection (every send triggers) #### `default` Provides default values: ```json { "type": "object", "properties": { "count": { "type": "number", "default": 0 } } } ``` ### Schema-Driven Behavior Schemas influence runtime behavior: - **Validation and transformation**: Schema-aware traversal resolves references and shapes data. Non-conforming values are rejected: required properties that don't match return `undefined` at the top level (and `null` for array elements where null is allowed). Optional properties that don't match are simply absent. The result is always either a valid value or `undefined`. - **Cell creation**: `asCell` properties become cell references - **Stream detection**: `asStream` properties get event semantics ### Schema Resolution Schemas can be: - Explicitly provided when creating cells - Inherited from source cells - Inferred from values (limited) --- ## Proposed Directions ### Removing `asStream` The `asStream` flag encodes type information in a schema property rather than in the data itself. This creates: - Two parallel type systems (schema types + stream/cell bifurcation) - Method duplication (get/set vs send) - Runtime brand checking (isStream) #### Alternative: Timestamps in Schema Instead of `asStream`, events could be data that includes timestamps: ```json { "type": "object", "properties": { "x": { "type": "number" }, "y": { "type": "number" }, "timestamp": { "type": "number" } } } ``` The "event-ness" emerges from the data shape: - Values with different timestamps are different values - Change detection works normally - No special flags or bifurcated runtime behavior #### What This Eliminates - `asStream` flag - `isStream()` / `isCell()` checks - Separate Stream type - Duplicated methods (send vs set) #### What This Requires - Convention for timestamp fields - Event producers include timestamps - Or: system adds timestamps if schema indicates it --- ## Open Questions - Should `asStream` be removed in favor of timestamp-based events? - How are schema migrations handled? - What is the validation behavior on schema mismatch? - How do schemas interact with the type system in pattern code? - Should schemas be versioned? --- **Previous:** [Reactivity](./6-reactivity.md) | **Next:** [Traversal and Schema Query](./8-traversal.md)