@almadar/core 2.7.0 → 2.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/builders.d.ts +2 -2
- package/dist/builders.js.map +1 -1
- package/dist/{compose-behaviors-Be7k7Esx.d.ts → compose-behaviors-j53THIou.d.ts} +1 -1
- package/dist/domain-language/index.d.ts +1 -1
- package/dist/domain-language/index.js.map +1 -1
- package/dist/index.d.ts +4 -4
- package/dist/index.js +177 -14
- package/dist/index.js.map +1 -1
- package/dist/{schema-Cm63mgSP.d.ts → schema-BNBpNxGb.d.ts} +112 -2
- package/dist/state-machine/index.d.ts +56 -1
- package/dist/state-machine/index.js +149 -1
- package/dist/state-machine/index.js.map +1 -1
- package/dist/types/index.d.ts +2 -2
- package/dist/types/index.js +26 -11
- package/dist/types/index.js.map +1 -1
- package/package.json +1 -1
package/dist/builders.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { T as TraitEventContract, E as EntityField, a as EntityPersistence, O as OrbitalDefinition, b as OrbitalSchema, c as Trait, d as Entity, P as Page } from './schema-
|
|
2
|
-
export { C as ComposeBehaviorsInput, a as ComposeBehaviorsResult, E as EventWiringEntry, L as LayoutStrategy, b as applyEventWiring, c as composeBehaviors, d as detectLayoutStrategy } from './compose-behaviors-
|
|
1
|
+
import { T as TraitEventContract, E as EntityField, a as EntityPersistence, O as OrbitalDefinition, b as OrbitalSchema, c as Trait, d as Entity, P as Page } from './schema-BNBpNxGb.js';
|
|
2
|
+
export { C as ComposeBehaviorsInput, a as ComposeBehaviorsResult, E as EventWiringEntry, L as LayoutStrategy, b as applyEventWiring, c as composeBehaviors, d as detectLayoutStrategy } from './compose-behaviors-j53THIou.js';
|
|
3
3
|
import 'zod';
|
|
4
4
|
import '@almadar/patterns';
|
|
5
5
|
|
package/dist/builders.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/builders/layout-strategy.ts","../src/types/effect.ts","../src/types/expression.ts","../src/types/state-machine.ts","../src/types/trait.ts","../src/builders/event-wiring.ts","../src/builders/compose-behaviors.ts","../src/builders.ts"],"names":["z"],"mappings":"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","file":"builders.js","sourcesContent":["/**\n * Layout Strategy Detection\n *\n * Auto-detects the best layout strategy for a composed application\n * based on the number of orbitals and their event wiring topology.\n *\n * @packageDocumentation\n */\n\nimport type { OrbitalDefinition } from '../types/orbital.js';\nimport type { EventWiringEntry } from './event-wiring.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Layout strategy for the composed application.\n *\n * - 'single': One orbital, one page\n * - 'tabs': 2-4 orbitals with no sequential chain\n * - 'sidebar': 5+ orbitals (navigation-heavy)\n * - 'dashboard': Single page with all orbitals visible\n * - 'wizard-flow': Sequential event chain detected (A -> B -> C)\n */\nexport type LayoutStrategy =\n | 'sidebar'\n | 'tabs'\n | 'dashboard'\n | 'wizard-flow'\n | 'single';\n\n// ============================================================================\n// Chain Detection\n// ============================================================================\n\n/**\n * Detect whether the event wiring forms a sequential chain.\n *\n * A sequential chain exists when orbital A's `from` feeds into B's `to`,\n * and B's `from` feeds into C's `to`, forming A -> B -> C.\n *\n * We build a directed graph from wiring entries and look for a chain\n * that covers 3+ nodes (the minimum for a meaningful wizard flow).\n */\nfunction hasSequentialChain(wiring: EventWiringEntry[]): boolean {\n if (wiring.length < 2) {\n return false;\n }\n\n // Build adjacency: from -> Set<to>\n const adjacency = new Map<string, Set<string>>();\n const allTargets = new Set<string>();\n\n for (const entry of wiring) {\n let targets = adjacency.get(entry.from);\n if (!targets) {\n targets = new Set<string>();\n adjacency.set(entry.from, targets);\n }\n targets.add(entry.to);\n allTargets.add(entry.to);\n }\n\n // Find roots (nodes that are sources but never targets)\n const roots: string[] = [];\n for (const from of adjacency.keys()) {\n if (!allTargets.has(from)) {\n roots.push(from);\n }\n }\n\n // If no clear root, try all sources\n const starts = roots.length > 0 ? roots : [...adjacency.keys()];\n\n // Walk from each start and measure chain length\n for (const start of starts) {\n let current = start;\n let length = 1;\n const visited = new Set<string>([current]);\n\n while (true) {\n const nexts = adjacency.get(current);\n if (!nexts || nexts.size === 0) break;\n\n // Follow the first unvisited successor (linear chain)\n let advanced = false;\n for (const next of nexts) {\n if (!visited.has(next)) {\n visited.add(next);\n current = next;\n length++;\n advanced = true;\n break;\n }\n }\n\n if (!advanced) break;\n }\n\n // A chain of 3+ nodes qualifies as wizard-flow\n if (length >= 3) {\n return true;\n }\n }\n\n return false;\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Detect the best layout strategy based on orbital count and event wiring.\n *\n * Heuristic:\n * 1. Sequential event chain detected -> 'wizard-flow'\n * 2. 1 orbital -> 'single'\n * 3. 2-4 orbitals -> 'tabs'\n * 4. 5+ orbitals -> 'sidebar'\n */\nexport function detectLayoutStrategy(\n orbitals: OrbitalDefinition[],\n eventWiring?: EventWiringEntry[],\n): LayoutStrategy {\n // Check for sequential chain first (takes priority)\n if (eventWiring && eventWiring.length > 0 && hasSequentialChain(eventWiring)) {\n return 'wizard-flow';\n }\n\n const count = orbitals.length;\n\n if (count <= 1) {\n return 'single';\n }\n\n if (count <= 4) {\n return 'tabs';\n }\n\n return 'sidebar';\n}\n","/**\n * Effect Types (Self-Contained)\n *\n * Defines effect types for trait transitions and ticks.\n * Effects are S-expressions (arrays) that describe actions to perform.\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\nimport { type SExpr, type Expression } from './expression.js';\n\n// ============================================================================\n// UI Slots\n// ============================================================================\n\n/**\n * Known UI slots where content can be rendered\n */\nexport const UI_SLOTS = [\n // App slots\n 'main',\n 'sidebar',\n 'modal',\n 'drawer',\n 'overlay',\n 'center',\n 'toast',\n 'floating',\n 'system', // For invisible system components (InputListener, CollisionDetector)\n 'content',\n 'screen',\n // Game HUD slots\n 'hud',\n 'hud-top',\n 'hud-bottom',\n 'hud.health',\n 'hud.score',\n 'hud.inventory',\n 'hud.stamina',\n // Game overlay slots\n 'overlay.inventory',\n 'overlay.dialogue',\n 'overlay.menu',\n 'overlay.pause',\n] as const;\n\nexport type UISlot = (typeof UI_SLOTS)[number];\n\nexport const UISlotSchema = z.enum(UI_SLOTS);\n\n// ============================================================================\n// Pattern Config (for render-ui effects)\n// ============================================================================\n\n// Import pattern types for local use and re-export for consumers\nimport type {\n PatternType,\n PatternConfig,\n PatternProps,\n PatternPropsMap,\n AnyPatternConfig,\n} from '@almadar/patterns';\n\n/**\n * Type-safe pattern configuration for render-ui effects.\n *\n * Re-exported from @almadar/patterns. Generated from patterns-registry.json.\n *\n * @example\n * // Type-safe with specific pattern type\n * const config: PatternConfig<'entity-table'> = {\n * patternType: 'entity-table',\n * columns: ['name', 'email'], // ✅ Required prop\n * entity: 'User',\n * };\n *\n * // Error: Property 'columns' is missing (required prop)\n * const bad: PatternConfig<'entity-table'> = { patternType: 'entity-table' };\n *\n * // Error: 'fake-pattern' is not assignable to PatternType\n * const invalid: PatternConfig = { patternType: 'fake-pattern' };\n */\nexport type {\n PatternType,\n PatternConfig,\n PatternProps,\n PatternPropsMap,\n AnyPatternConfig,\n};\n\n/**\n * Configuration for render-ui effect.\n * Used in runtime to specify which slot and pattern to render.\n */\nexport interface RenderUIConfig {\n /** Target UI slot */\n slot: UISlot;\n /** Pattern configuration (null clears the slot) */\n pattern: AnyPatternConfig | null;\n /** Target element (trait name or entity ID) */\n target?: string;\n /** Additional props for the pattern */\n props?: Record<string, unknown>;\n /** Optional priority for slot ordering */\n priority?: number;\n}\n\n// ============================================================================\n// Service Config (for call-service effects)\n// ============================================================================\n\n/**\n * Configuration extracted from call-service effects\n */\nexport interface CallServiceConfig {\n service: string;\n action: string;\n endpoint?: string;\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n params?: Record<string, unknown>;\n onSuccess?: string;\n onError?: string;\n}\n\n// ============================================================================\n// Typed Effect Tuples\n// ============================================================================\n\n/**\n * Render UI effect - displays a pattern in a UI slot.\n * @example ['render-ui', 'main', { patternType: 'entity-table', columns: ['name'] }]\n */\nexport type RenderUIEffect =\n | ['render-ui', UISlot, AnyPatternConfig]\n | ['render-ui', UISlot, AnyPatternConfig, Record<string, unknown>]\n | ['render-ui', UISlot, null];\n\n/**\n * Navigate effect - navigates to a path.\n * @example ['navigate', '/tasks'] or ['navigate', '/tasks/:id', { id: '123' }]\n */\nexport type NavigateEffect = ['navigate', string] | ['navigate', string, Record<string, string>];\n\n/**\n * Emit effect - emits an event, optionally with payload.\n * @example ['emit', 'SAVE'] or ['emit', 'PLAYER_DIED', { playerId: '@entity.id' }]\n * @example ['emit', 'FILTER_CHANGED', '@entity.filters']\n */\nexport type EmitEffect = ['emit', string] | ['emit', string, Record<string, unknown> | string];\n\n/**\n * Set effect - sets a binding to a value.\n * @example ['set', '@entity.health', 100]\n */\nexport type SetEffect = ['set', string, unknown];\n\n/**\n * Persist effect - creates, updates, deletes, or clears entities.\n * @example ['persist', 'create', 'Task', { title: '@payload.title' }]\n * @example ['persist', 'update', '@entity.entityType', '@payload.data']\n */\nexport type PersistEffect =\n | ['persist', 'create', string, Record<string, unknown> | string]\n | ['persist', 'update', string, Record<string, unknown> | string]\n | ['persist', 'delete', string]\n | ['persist', 'delete', string, Record<string, unknown> | string]\n | ['persist', 'clear', string]\n | ['persist', 'clear', string, Record<string, unknown> | string];\n\n/**\n * Call service effect - invokes an external service.\n * @example ['call-service', 'WeatherAPI', { service: 'weather', action: 'get', onSuccess: 'OK' }]\n */\nexport type CallServiceEffect = ['call-service', string, CallServiceConfig];\n\n/**\n * Spawn effect - creates a new entity instance (games).\n * @example ['spawn', 'Bullet', { x: '@entity.x', y: '@entity.y' }]\n */\nexport type SpawnEffect = ['spawn', string] | ['spawn', string, Record<string, unknown>];\n\n/**\n * Despawn effect - removes an entity instance (games).\n * @example ['despawn', '@entity.id']\n */\nexport type DespawnEffect = ['despawn', string];\n\n/**\n * Do effect - executes multiple effects in sequence.\n * Uses SExpr to allow deeply nested conditionals.\n * @example ['do', ['set', '@entity.x', 0], ['set', '@entity.y', 0]]\n */\nexport type DoEffect = ['do', ...SExpr[]];\n\n/**\n * Notify effect - sends a notification.\n * @example ['notify', 'in_app', 'Task created successfully']\n * @example ['notify', 'in_app', ['str/concat', 'Item: ', '@entity.name']]\n */\nexport type NotifyEffect =\n | ['notify', string, string | SExpr]\n | ['notify', string, string | SExpr, string];\n\n/**\n * Fetch effect - retrieves entity data (server-side).\n * @example ['fetch', 'User'] or ['fetch', 'User', { id: '@payload.userId' }]\n */\nexport type FetchEffect = ['fetch', string] | ['fetch', string, Record<string, unknown>];\n\n/**\n * If effect - conditional effect execution.\n * Uses SExpr to allow deeply nested conditionals.\n * @example ['if', ['>', '@entity.health', 0], ['emit', 'ALIVE'], ['emit', 'DEAD']]\n */\nexport type IfEffect = ['if', Expression, SExpr] | ['if', Expression, SExpr, SExpr];\n\n/**\n * When effect - conditional effect similar to if but without else.\n * Uses SExpr to allow deeply nested conditionals.\n * @example ['when', ['>', '@entity.health', 0], ['emit', 'ALIVE']]\n */\nexport type WhenEffect = ['when', Expression, SExpr];\n\n/**\n * Let effect - creates local bindings for effects.\n * Uses SExpr to allow deeply nested conditionals.\n * @example ['let', ['temp', ['get', '@payload.value']], ['set', '@entity.value', 'temp']]\n */\nexport type LetEffect = ['let', [string, unknown][], ...SExpr[]];\n\n/**\n * Log effect - logs a message for debugging.\n * @example ['log', 'User created:', '@entity.name']\n */\nexport type LogEffect = ['log', ...unknown[]];\n\n/**\n * Wait effect - delays execution.\n * @example ['wait', 1000] - wait 1 second\n */\nexport type WaitEffect = ['wait', number];\n\n// ============================================================================\n// ML Effects (from almadar-std/modules/nn, tensor, train)\n// ============================================================================\n\n/**\n * Forward effect - runs a neural network forward pass (Python backend).\n * @example ['forward', 'primary', { architecture: [...], input: '@payload.input', 'on-complete': 'PREDICTION_READY' }]\n */\nexport type ForwardEffect = ['forward', string, Record<string, unknown>];\n\n/**\n * Train effect - runs a training loop (Python backend).\n * @example ['train', { architecture: [...], dataset: '@entity.data', config: { epochs: 10 }, 'on-complete': 'TRAINING_DONE' }]\n */\nexport type TrainEffect = ['train', Record<string, unknown>];\n\n/**\n * Evaluate effect - runs model evaluation (Python backend).\n * @example ['evaluate', { architecture: [...], dataset: '@entity.testData', metrics: ['accuracy'], 'on-complete': 'EVAL_DONE' }]\n */\nexport type EvaluateEffect = ['evaluate', Record<string, unknown>];\n\n/**\n * Checkpoint save effect - saves model weights.\n * @example ['checkpoint/save', '/path/to/model.pt', '@entity.weights']\n */\nexport type CheckpointSaveEffect = ['checkpoint/save', string, unknown];\n\n/**\n * Checkpoint load effect - loads model weights.\n * @example ['checkpoint/load', '/path/to/model.pt']\n */\nexport type CheckpointLoadEffect = ['checkpoint/load', string];\n\n// ============================================================================\n// Async Effects (from almadar-std/modules/async)\n// ============================================================================\n\n/**\n * Async delay effect - wait then execute effects.\n * @example ['async/delay', 2000, ['emit', 'TIMEOUT']]\n */\nexport type AsyncDelayEffect = ['async/delay', number | string, ...Effect[]];\n\n/**\n * Async debounce effect - debounce then execute effect.\n * @example ['async/debounce', 300, ['emit', 'SEARCH_COMPLETE']]\n * @example ['async/debounce', '@entity.debounceMs', ['emit', 'SEARCH_COMPLETE']]\n */\nexport type AsyncDebounceEffect = ['async/debounce', number | string, SExpr];\n\n/**\n * Async throttle effect - throttle then execute effect.\n * @example ['async/throttle', 100, ['emit', 'SCROLL_HANDLED']]\n * @example ['async/throttle', '@entity.throttleMs', ['emit', 'SCROLL_HANDLED']]\n */\nexport type AsyncThrottleEffect = ['async/throttle', number | string, SExpr];\n\n/**\n * Async interval effect - execute effect at intervals.\n * @example ['async/interval', 1000, ['emit', 'TICK']]\n * @example ['async/interval', '@entity.intervalMs', ['emit', 'POLL_TICK']]\n */\nexport type AsyncIntervalEffect = ['async/interval', number | string, SExpr];\n\n/**\n * Async race effect - first effect to complete wins.\n * @example ['async/race', ['call', 'api1'], ['call', 'api2']]\n */\nexport type AsyncRaceEffect = ['async/race', ...Effect[]];\n\n/**\n * Async all effect - wait for all effects to complete.\n * @example ['async/all', ['call', 'api1'], ['call', 'api2']]\n */\nexport type AsyncAllEffect = ['async/all', ...Effect[]];\n\n/**\n * Async sequence effect - execute effects in sequence.\n * @example ['async/sequence', ['call', 'validate'], ['call', 'save']]\n */\nexport type AsyncSequenceEffect = ['async/sequence', ...Effect[]];\n\n/**\n * Union of all typed effects.\n * Provides compile-time validation for common effect types.\n */\nexport type TypedEffect =\n | RenderUIEffect\n | NavigateEffect\n | EmitEffect\n | SetEffect\n | PersistEffect\n | CallServiceEffect\n | SpawnEffect\n | DespawnEffect\n | DoEffect\n | NotifyEffect\n | FetchEffect\n | IfEffect\n | WhenEffect\n | LetEffect\n | LogEffect\n | WaitEffect\n | AsyncDelayEffect\n | AsyncDebounceEffect\n | AsyncThrottleEffect\n | AsyncIntervalEffect\n | AsyncRaceEffect\n | AsyncAllEffect\n | AsyncSequenceEffect\n | ForwardEffect\n | TrainEffect\n | EvaluateEffect\n | CheckpointSaveEffect\n | CheckpointLoadEffect;\n\n// ============================================================================\n// Effect Type (Strictly Typed)\n// ============================================================================\n\n/**\n * Effect type - typed S-expression format.\n *\n * Effects are strongly typed tuples that enforce:\n * - Valid effect operators (render-ui, emit, set, persist, navigate, call-service)\n * - Valid UISlots for render-ui\n * - Valid PatternTypes and props for render-ui\n * - Correct argument types for each effect\n *\n * Available typed effects:\n * - RenderUIEffect: ['render-ui', UISlot, PatternConfig]\n * - NavigateEffect: ['navigate', path] or ['navigate', path, params]\n * - EmitEffect: ['emit', eventName] or ['emit', eventName, payload]\n * - SetEffect: ['set', binding, value]\n * - PersistEffect: ['persist', operation, entity, data?]\n * - CallServiceEffect: ['call-service', serviceName, config]\n *\n * @example\n * [\"set\", \"@entity.health\", 100]\n * [\"emit\", \"PLAYER_DIED\", { \"playerId\": \"@entity.id\" }]\n * [\"render-ui\", \"main\", { \"patternType\": \"entity-table\", \"columns\": [\"name\"] }]\n * [\"call-service\", \"WeatherAPI\", { \"action\": \"getWeather\", \"onSuccess\": \"OK\" }]\n * [\"navigate\", \"/tasks\"]\n * [\"persist\", \"create\", \"Task\", { \"title\": \"@payload.title\" }]\n */\nexport type Effect = TypedEffect;\n\n/**\n * Schema for Effect - validates S-expression format\n */\nexport const EffectSchema = z.array(z.unknown()).min(1).refine(\n (arr) => typeof arr[0] === 'string',\n { message: 'Effect must be an S-expression with a string operator as first element' }\n);\n\nexport type EffectInput = z.input<typeof EffectSchema>;\n\n/**\n * Type guard to check if a value is a valid Effect (S-expression).\n * \n * Validates that a value conforms to the Effect structure. Effects are\n * represented as arrays where the first element is a string (effect type)\n * and subsequent elements are parameters. Used for runtime validation\n * of effect structures.\n * \n * @param {unknown} value - Value to check\n * @returns {boolean} True if value is a valid Effect, false otherwise\n * \n * @example\n * isEffect(['set', '@entity.health', 100]); // returns true\n * isEffect('not-an-effect'); // returns false\n * isEffect([]); // returns false\n */\nexport function isEffect(value: unknown): value is Effect {\n return Array.isArray(value) && value.length > 0 && typeof value[0] === 'string';\n}\n\n/**\n * Alias for isEffect (for clarity when working with S-expressions)\n */\nexport const isSExprEffect = isEffect;\n\n// ============================================================================\n// Effect Builder Helpers\n// ============================================================================\n\n/**\n * Creates a set effect for state updates.\n * \n * Generates an effect that sets a binding to a value. Used in state\n * machine transitions to update entity fields, UI state, or other\n * mutable data.\n * \n * @param {string} binding - Target binding (e.g., '@entity.health')\n * @param {SExpr} value - Value to set (can be literal or expression)\n * @returns {Effect} Set effect array\n * \n * @example\n * set('@entity.health', 100); // returns [\"set\", \"@entity.health\", 100]\n * set('@state.loading', false); // returns [\"set\", \"@state.loading\", false]\n */\nexport function set(binding: string, value: SExpr): Effect {\n return ['set', binding, value];\n}\n\n/**\n * Creates an emit effect for event dispatching.\n * \n * Generates an effect that emits an event with optional payload.\n * Used in state machine transitions to trigger events that can be\n * handled by other traits, services, or external systems.\n * \n * @param {string} event - Event name to emit\n * @param {Record<string, unknown>} [payload] - Optional event payload\n * @returns {Effect} Emit effect array\n * \n * @example\n * emit('PLAYER_DIED', { playerId: '@entity.id' }); // returns [\"emit\", \"PLAYER_DIED\", { playerId: \"@entity.id\" }]\n * emit('GAME_STARTED'); // returns [\"emit\", \"GAME_STARTED\"]\n */\nexport function emit(event: string, payload?: Record<string, unknown>): Effect {\n return payload ? ['emit', event, payload] : ['emit', event];\n}\n\n/**\n * Creates a navigation effect for page routing.\n * \n * Generates an effect that navigates to a specified path with optional\n * parameters. Used in state machine transitions to change pages or\n * update URL parameters.\n * \n * @param {string} path - Target path (e.g., '/tasks')\n * @param {Record<string, string>} [params] - Optional URL parameters\n * @returns {NavigateEffect} Navigation effect array\n * \n * @example\n * navigate('/tasks'); // returns [\"navigate\", \"/tasks\"]\n * navigate('/user', { id: '123' }); // returns [\"navigate\", \"/user\", { id: \"123\" }]\n */\nexport function navigate(path: string): NavigateEffect;\nexport function navigate(path: string, params: Record<string, string>): NavigateEffect;\nexport function navigate(path: string, params?: Record<string, string>): NavigateEffect {\n return params ? ['navigate', path, params] : ['navigate', path];\n}\n\n/**\n * Create a render-ui effect\n * @example [\"render-ui\", \"main\", { \"patternType\": \"entity-table\", \"columns\": [\"name\"] }]\n */\nexport function renderUI(\n target: UISlot,\n pattern: AnyPatternConfig\n): RenderUIEffect;\nexport function renderUI(\n target: UISlot,\n pattern: AnyPatternConfig,\n props: Record<string, unknown>\n): RenderUIEffect;\nexport function renderUI(\n target: UISlot,\n pattern: AnyPatternConfig,\n props?: Record<string, unknown>\n): RenderUIEffect {\n return props\n ? ['render-ui', target, pattern, props]\n : ['render-ui', target, pattern];\n}\n\n/**\n * Create a persist effect\n * @example [\"persist\", \"create\", \"Task\", { \"title\": \"@payload.title\" }]\n */\nexport function persist(\n action: 'create' | 'update',\n entity: string,\n data: Record<string, unknown>\n): PersistEffect;\nexport function persist(\n action: 'delete' | 'clear',\n entity: string,\n data?: Record<string, unknown>\n): PersistEffect;\nexport function persist(\n action: 'create' | 'update' | 'delete' | 'clear',\n entity: string,\n data?: Record<string, unknown>\n): PersistEffect {\n if (action === 'create' || action === 'update') {\n return ['persist', action, entity, data!] as PersistEffect;\n }\n return data\n ? ['persist', action, entity, data] as PersistEffect\n : ['persist', action, entity] as PersistEffect;\n}\n\n/**\n * Create a call-service effect\n * @example [\"call-service\", \"stripe\", { \"service\": \"stripe\", \"action\": \"charge\", \"onSuccess\": \"OK\", \"onError\": \"ERR\" }]\n */\nexport function callService(\n serviceName: string,\n config: CallServiceConfig\n): CallServiceEffect {\n return ['call-service', serviceName, config];\n}\n\n/**\n * Create a spawn effect (games)\n * @example [\"spawn\", \"Bullet\", { \"x\": \"@entity.x\", \"y\": \"@entity.y\" }]\n */\nexport function spawn(entity: string): SpawnEffect;\nexport function spawn(entity: string, initialState: Record<string, unknown>): SpawnEffect;\nexport function spawn(entity: string, initialState?: Record<string, unknown>): SpawnEffect {\n return initialState ? ['spawn', entity, initialState] : ['spawn', entity];\n}\n\n/**\n * Create a despawn effect (games)\n * @example [\"despawn\", \"@entity.id\"]\n */\nexport function despawn(entityId: string): DespawnEffect {\n return ['despawn', entityId];\n}\n\n/**\n * Create a do effect (multiple effects)\n * @example [\"do\", [\"set\", \"@entity.x\", 0], [\"set\", \"@entity.y\", 0]]\n */\nexport function doEffects(...effects: SExpr[]): DoEffect {\n return ['do', ...effects];\n}\n\n/**\n * Create a notify effect\n * @example [\"notify\", \"in_app\", \"Task created successfully\"]\n */\nexport function notify(\n channel: 'email' | 'push' | 'sms' | 'in_app',\n message: string\n): NotifyEffect;\nexport function notify(\n channel: 'email' | 'push' | 'sms' | 'in_app',\n message: string,\n recipient: string\n): NotifyEffect;\nexport function notify(\n channel: 'email' | 'push' | 'sms' | 'in_app',\n message: string,\n recipient?: string\n): NotifyEffect {\n return recipient\n ? ['notify', channel, message, recipient]\n : ['notify', channel, message];\n}\n\n/**\n * Fetch options for entity data retrieval\n */\nexport interface FetchOptions {\n /** Fetch a single entity by ID */\n id?: string;\n /** Filter expression (S-expression) */\n filter?: SExpr;\n /** Maximum number of entities to return */\n limit?: number;\n /** Number of entities to skip */\n offset?: number;\n /** Allow additional properties for flexibility */\n [key: string]: unknown;\n}\n\n/**\n * Create a fetch effect (server-side data retrieval)\n * @example [\"fetch\", \"User\"] - fetch all users\n * @example [\"fetch\", \"User\", { \"id\": \"@payload.userId\" }] - fetch by ID\n * @example [\"fetch\", \"User\", { \"filter\": [\"=\", \"@entity.status\", \"active\"], \"limit\": 10 }]\n */\nexport function fetch(entity: string): FetchEffect;\nexport function fetch(entity: string, options: FetchOptions): FetchEffect;\nexport function fetch(entity: string, options?: FetchOptions): FetchEffect {\n return options ? ['fetch', entity, options as Record<string, unknown>] : ['fetch', entity];\n}\n\n","/**\n * S-Expression Types\n *\n * Defines the S-Expression type system for guards, effects, and computed values.\n * S-expressions are JSON arrays where the first element is an operator string.\n *\n * @example\n * // Guard: health > 0\n * [\">\", \"@entity.health\", 0]\n *\n * // Effect: set x to x + vx\n * [\"set\", \"@entity.x\", [\"+\", \"@entity.x\", \"@entity.vx\"]]\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\n\n// ============================================================================\n// S-Expression Type\n// ============================================================================\n\n/**\n * S-Expression type - recursive structure representing expressions.\n *\n * An S-expression is either:\n * - A literal value (string, number, boolean, null)\n * - An object literal (for payload data, props, etc.)\n * - A binding reference (string starting with @)\n * - A call expression (array with operator as first element)\n */\nexport type SExprAtom = string | number | boolean | null | Record<string, unknown>;\nexport type SExpr = SExprAtom | SExpr[];\n\n/**\n * Expression type - S-expressions only.\n * Used for guards, computed values, and effect expressions.\n *\n * NOTE: Legacy string format is no longer supported.\n * All expressions must be S-expression arrays.\n */\nexport type Expression = SExpr;\n\n// ============================================================================\n// S-Expression Schema (Zod)\n// ============================================================================\n\n/**\n * Schema for atomic S-expression values (non-array)\n * Includes objects for payload data, props, etc.\n */\nexport const SExprAtomSchema: z.ZodType<SExprAtom> = z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.null(),\n z.record(z.unknown()), // Objects for payload data\n]);\n\n/**\n * Recursive schema for S-expressions.\n * Validates that arrays have at least one element and first element is a string (operator).\n */\nexport const SExprSchema: z.ZodType<SExpr> = z.lazy(() =>\n z.union([\n SExprAtomSchema,\n z\n .array(z.lazy(() => SExprSchema))\n .min(1)\n .refine(\n (arr) => typeof arr[0] === 'string',\n { message: 'S-expression array must have a string operator as first element' }\n ),\n ])\n);\n\n/**\n * Schema for Expression type - S-expressions only.\n * S-expressions are arrays with operator as first element.\n *\n * NOTE: Legacy string format is no longer supported.\n */\nexport const ExpressionSchema: z.ZodType<Expression> = SExprSchema;\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Type guard for S-expression detection.\n * 100% reliable - structural check, no regex or keyword matching.\n *\n * @param value - Value to check\n * @returns true if value is an S-expression (array with string operator)\n */\nexport function isSExpr(value: unknown): value is SExpr[] {\n return (\n Array.isArray(value) &&\n value.length > 0 &&\n typeof value[0] === 'string'\n );\n}\n\n/**\n * Type guard for S-expression atoms (non-array values).\n * \n * Validates that a value is an S-expression atom (literal value).\n * Includes null, strings, numbers, booleans, and objects. Used to\n * distinguish atomic values from S-expression calls (arrays).\n * \n * @param {unknown} value - Value to check\n * @returns {boolean} True if value is an S-expression atom, false otherwise\n * \n * @example\n * isSExprAtom('hello'); // returns true\n * isSExprAtom(42); // returns true\n * isSExprAtom(null); // returns true\n * isSExprAtom({ key: 'value' }); // returns true\n * isSExprAtom(['+', 1, 2]); // returns false\n */\nexport function isSExprAtom(value: unknown): value is SExprAtom {\n if (value === null) return true;\n if (Array.isArray(value)) return false;\n const type = typeof value;\n return type === 'string' || type === 'number' || type === 'boolean' || type === 'object';\n}\n\n/**\n * Checks if a value is a binding reference.\n * \n * Validates that a string is a binding reference (starts with @).\n * Bindings reference runtime values like @entity.health, @payload.amount, @now.\n * Used for identifying bindings in S-expressions and validation.\n * \n * @param {unknown} value - Value to check\n * @returns {boolean} True if value is a binding reference, false otherwise\n * \n * @example\n * isBinding('@entity.health'); // returns true\n * isBinding('@payload.amount'); // returns true\n * isBinding('not-a-binding'); // returns false\n * isBinding(123); // returns false\n */\nexport function isBinding(value: unknown): value is string {\n return typeof value === 'string' && value.startsWith('@');\n}\n\n/**\n * Checks if a value is a valid S-expression call (array with operator).\n * \n * Alias for isSExpr() - validates S-expression call structure.\n * Used to distinguish between S-expression calls and atom values.\n * \n * @param {unknown} value - Value to check\n * @returns {boolean} True if value is a valid S-expression call, false otherwise\n * \n * @example\n * isSExprCall(['+', 1, 2]); // returns true\n * isSExprCall(['set', '@entity.health', 100]); // returns true\n * isSExprCall('not-a-call'); // returns false\n */\nexport function isSExprCall(value: unknown): value is SExpr[] {\n return isSExpr(value);\n}\n\n// ============================================================================\n// Binding Parsing\n// ============================================================================\n\n/**\n * Parsed binding reference\n */\nexport interface ParsedBinding {\n /** Type of binding: core (@entity, @payload, @state, @now) or entity (@EntityName) */\n type: 'core' | 'entity';\n /** The root binding name (entity, payload, state, now, or EntityName) */\n root: string;\n /** Path segments after the root (e.g., ['health'] for @entity.health) */\n path: string[];\n /** Full original binding string */\n original: string;\n}\n\n/**\n * Core bindings that are always available.\n * Phase 4.5 adds: config, computed, trait (for behavior support)\n */\nexport const CORE_BINDINGS = ['entity', 'payload', 'state', 'now', 'config', 'computed', 'trait'] as const;\nexport type CoreBinding = (typeof CORE_BINDINGS)[number];\n\n/**\n * Parses a binding reference into its components.\n * \n * Deconstructs a binding string (e.g., '@entity.health') into its constituent\n * parts: type, root, path, and original string. Does NOT use regex - uses\n * structured string operations for reliability and maintainability.\n * \n * @param {string} binding - Binding string starting with @\n * @returns {ParsedBinding | null} Parsed binding object or null if invalid\n * \n * @example\n * parseBinding('@entity.health'); // returns { type: 'core', root: 'entity', path: ['health'], original: '@entity.health' }\n * parseBinding('@User.name'); // returns { type: 'entity', root: 'User', path: ['name'], original: '@User.name' }\n * parseBinding('not-a-binding'); // returns null\n */\nexport function parseBinding(binding: string): ParsedBinding | null {\n if (!binding.startsWith('@')) {\n return null;\n }\n\n // Remove @ prefix\n const withoutPrefix = binding.slice(1);\n\n // Split by dots\n const parts = withoutPrefix.split('.');\n\n if (parts.length === 0 || parts[0] === '') {\n return null;\n }\n\n const root = parts[0];\n const path = parts.slice(1);\n\n // Determine if core binding or entity reference\n const isCore = (CORE_BINDINGS as readonly string[]).includes(root);\n\n return {\n type: isCore ? 'core' : 'entity',\n root,\n path,\n original: binding,\n };\n}\n\n/**\n * Validate a binding reference format.\n *\n * @param binding - Binding string to validate\n * @returns true if valid binding format\n */\nexport function isValidBinding(binding: string): boolean {\n const parsed = parseBinding(binding);\n if (!parsed) return false;\n\n // Core bindings: @entity, @payload, @state, @now (optionally with path)\n // @state and @now don't have paths\n if (parsed.type === 'core') {\n if (parsed.root === 'state' || parsed.root === 'now') {\n return parsed.path.length === 0;\n }\n // @entity and @payload can have paths\n return true;\n }\n\n // Entity bindings: @EntityName.field - must have at least one path segment\n return parsed.path.length > 0;\n}\n\n// ============================================================================\n// S-Expression Utilities\n// ============================================================================\n\n/**\n * Get the operator from an S-expression call.\n *\n * @param expr - S-expression array\n * @returns The operator string or null if not a valid call\n */\nexport function getOperator(expr: SExpr): string | null {\n if (!isSExpr(expr)) return null;\n return expr[0] as string;\n}\n\n/**\n * Get the arguments from an S-expression call.\n *\n * @param expr - S-expression array\n * @returns Array of arguments (empty if not a valid call)\n */\nexport function getArgs(expr: SExpr): SExpr[] {\n if (!isSExpr(expr)) return [];\n return expr.slice(1);\n}\n\n/**\n * Create an S-expression call.\n *\n * @param operator - The operator string\n * @param args - Arguments to the operator\n * @returns S-expression array\n */\nexport function sexpr(operator: string, ...args: SExpr[]): SExpr[] {\n return [operator, ...args];\n}\n\n/**\n * Walk an S-expression tree and apply a visitor function to each node.\n *\n * @param expr - S-expression to walk\n * @param visitor - Function to call on each node\n */\nexport function walkSExpr(\n expr: SExpr,\n visitor: (node: SExpr, parent: SExpr[] | null, index: number) => void,\n parent: SExpr[] | null = null,\n index: number = 0\n): void {\n visitor(expr, parent, index);\n\n if (isSExpr(expr)) {\n for (let i = 0; i < expr.length; i++) {\n walkSExpr(expr[i], visitor, expr, i);\n }\n }\n}\n\n/**\n * Collect all bindings referenced in an S-expression.\n *\n * @param expr - S-expression to analyze\n * @returns Array of binding strings found\n */\nexport function collectBindings(expr: SExpr): string[] {\n const bindings: string[] = [];\n\n walkSExpr(expr, (node) => {\n if (isBinding(node)) {\n bindings.push(node);\n }\n });\n\n return bindings;\n}\n\n// ============================================================================\n// Type Exports\n// ============================================================================\n\nexport type SExprInput = z.input<typeof SExprSchema>;\nexport type ExpressionInput = z.input<typeof ExpressionSchema>;\n","/**\n * State Machine Types (Self-Contained)\n *\n * Defines state machine types for traits.\n * Copied from schema/state-machine.ts to make orbitals/ self-contained.\n *\n * @packageDocumentation\n */\n\nimport { z } from \"zod\";\nimport type { Effect } from \"./effect.js\";\nimport { EffectSchema } from \"./effect.js\";\nimport type { Expression } from \"./expression.js\";\nimport { ExpressionSchema } from \"./expression.js\";\n\n// ============================================================================\n// State\n// ============================================================================\n\n/**\n * Represents a state in the state machine\n */\nexport interface State {\n /** State name (unique identifier) */\n name: string;\n /** Whether this is the initial state */\n isInitial?: boolean;\n /** Whether this is a terminal state (no outgoing transitions expected) */\n isTerminal?: boolean;\n /** Whether this is a final state (legacy alias for isTerminal) */\n isFinal?: boolean;\n /** Human-readable description */\n description?: string;\n /** Effect names to run on entry */\n onEntry?: string[];\n /** Effect names to run on exit */\n onExit?: string[];\n}\n\nexport const StateSchema = z.object({\n name: z.string().min(1, \"State name is required\"),\n isInitial: z.boolean().optional(),\n isTerminal: z.boolean().optional(),\n isFinal: z.boolean().optional(),\n description: z.string().optional(),\n onEntry: z.array(z.string()).optional(),\n onExit: z.array(z.string()).optional(),\n});\n\n// ============================================================================\n// Event\n// ============================================================================\n\n/**\n * Payload field definition for events\n */\nexport interface PayloadField {\n name: string;\n type: \"string\" | \"number\" | \"boolean\" | \"object\" | \"array\";\n required?: boolean;\n}\n\nexport const PayloadFieldSchema = z.object({\n name: z.string().min(1),\n type: z.enum([\"string\", \"number\", \"boolean\", \"object\", \"array\"]),\n required: z.boolean().optional(),\n});\n\n/**\n * Represents an event that can trigger transitions\n */\nexport interface Event {\n /** Event key (UPPER_SNAKE_CASE) */\n key: string;\n /** Human-readable name */\n name: string;\n /** Description */\n description?: string;\n /** Expected payload structure */\n payloadSchema?: PayloadField[];\n /** Domain vs System classification (optional, for analysis) */\n classification?: \"domain\" | \"system\";\n /** Semantic role of this event (optional, for analysis) */\n semanticRole?: string;\n}\n\nexport const EventSchema = z.object({\n key: z.string().min(1, \"Event key is required\"),\n name: z.string().min(1, \"Event name is required\"),\n description: z.string().optional(),\n payloadSchema: z.array(PayloadFieldSchema).optional(),\n classification: z.enum([\"domain\", \"system\"]).optional(),\n semanticRole: z.string().optional(),\n});\n\n// ============================================================================\n// Guard\n// ============================================================================\n\n/**\n * Represents a named guard condition.\n * Expression must be an S-expression.\n *\n * @example\n * {\n * name: \"hasHealth\",\n * expression: [\">\", \"@entity.health\", 0],\n * description: \"Check if entity has health remaining\"\n * }\n */\nexport interface Guard {\n name: string;\n /** Guard expression - S-expression array only */\n expression: Expression;\n description?: string;\n}\n\nexport const GuardSchema = z.object({\n name: z.string().min(1, \"Guard name is required\"),\n expression: ExpressionSchema,\n description: z.string().optional(),\n});\n\n// ============================================================================\n// Transition (Effect imported separately to avoid circular deps)\n// ============================================================================\n\n/**\n * Represents a transition between states.\n * Guards and effects must be S-expressions.\n *\n * @example\n * {\n * from: \"idle\",\n * to: \"running\",\n * event: \"START\",\n * guard: [\">\", \"@entity.fuel\", 0],\n * effects: [\n * [\"set\", \"@entity.status\", \"running\"],\n * [\"emit\", \"ENGINE_STARTED\"]\n * ]\n * }\n */\nexport interface Transition {\n /** Source state name */\n from: string;\n /** Target state name */\n to: string;\n /** Event key that triggers this transition */\n event: string;\n /** Guard expression - S-expression array */\n guard?: Expression | null;\n /** Effects to execute - S-expression arrays */\n effects?: Effect[];\n /** Description */\n description?: string | null;\n}\n\nexport const TransitionSchema = z.object({\n from: z.string().min(1, \"Transition source state is required\"),\n to: z.string().min(1, \"Transition target state is required\"),\n event: z.string().min(1, \"Transition event is required\"),\n guard: ExpressionSchema.nullish(),\n effects: z.array(EffectSchema).optional(),\n description: z.string().nullish(),\n});\n\n// ============================================================================\n// State Machine\n// ============================================================================\n\n/**\n * Complete state machine definition\n */\nexport interface StateMachine {\n /** All states in the machine */\n states: State[];\n /** All events that can be triggered */\n events: Event[];\n /** All transitions between states */\n transitions: Transition[];\n /** Named guard definitions */\n guards?: Guard[];\n}\n\nexport const StateMachineSchema = z.object({\n states: z.array(StateSchema).min(1, \"At least one state is required\"),\n events: z.array(EventSchema),\n transitions: z.array(TransitionSchema),\n guards: z.array(GuardSchema).optional(),\n});\n\n// ============================================================================\n// Type exports\n// ============================================================================\n\nexport type StateInput = z.input<typeof StateSchema>;\nexport type EventInput = z.input<typeof EventSchema>;\nexport type GuardInput = z.input<typeof GuardSchema>;\nexport type TransitionInput = z.input<typeof TransitionSchema>;\nexport type StateMachineInput = z.input<typeof StateMachineSchema>;\n\n// ============================================================================\n// Event Utilities\n// ============================================================================\n\n/**\n * Check if an event is a circuit event (not internal/system event).\n * Circuit events are user-defined events that participate in the closed circuit pattern.\n * Internal/system events start with underscore (e.g., _INIT, _TICK, _TIMER).\n *\n * @param {string} event - Event name to check\n * @returns {boolean} true if event is a circuit event (doesn't start with underscore)\n *\n * @example\n * isCircuitEvent('CREATE') // true\n * isCircuitEvent('SAVE') // true\n * isCircuitEvent('_INIT') // false (internal)\n * isCircuitEvent('_TICK') // false (internal)\n */\nexport function isCircuitEvent(event: string): boolean {\n return !event.startsWith('_');\n}\n","/**\n * Trait Types (Self-Contained)\n *\n * Defines trait types for behavioral patterns.\n * Self-contained - imports only from local orbital types.\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\nimport type { StateMachine } from './state-machine.js';\nimport { StateMachineSchema } from './state-machine.js';\nimport type { Effect } from './effect.js';\nimport { EffectSchema } from './effect.js';\nimport type { Expression } from './expression.js';\nimport { ExpressionSchema } from './expression.js';\n\n// ============================================================================\n// Trait Categories\n// ============================================================================\n\n/**\n * Categories for organizing traits\n */\nexport type TraitCategory =\n | 'lifecycle'\n | 'temporal'\n | 'validation'\n | 'notification'\n | 'integration'\n | 'interaction'\n | 'game-core'\n | 'game-character'\n | 'game-ai'\n | 'game-combat'\n | 'game-items'\n | 'game-cards'\n | 'game-board'\n | 'game-puzzle';\n\nexport const TraitCategorySchema = z.enum([\n 'lifecycle',\n 'temporal',\n 'validation',\n 'notification',\n 'integration',\n 'interaction',\n 'game-core',\n 'game-character',\n 'game-ai',\n 'game-combat',\n 'game-items',\n 'game-cards',\n 'game-board',\n 'game-puzzle',\n]);\n\n// ============================================================================\n// Trait Entity Field (simplified)\n// ============================================================================\n\n/**\n * Field types for trait data entities\n */\nexport type TraitFieldType = 'string' | 'number' | 'boolean' | 'date' | 'array' | 'object' | 'timestamp' | 'datetime' | 'enum';\n\n/**\n * Simplified field for trait data entities\n */\nexport interface TraitEntityField {\n name: string;\n type: TraitFieldType;\n required?: boolean;\n default?: unknown;\n values?: string[];\n}\n\nexport const TraitEntityFieldSchema = z.object({\n name: z.string().min(1),\n type: z.enum([\n 'string',\n 'number',\n 'boolean',\n 'date',\n 'array',\n 'object',\n 'timestamp',\n 'datetime',\n 'enum',\n ]),\n required: z.boolean().optional(),\n default: z.unknown().optional(),\n values: z.array(z.string()).optional(),\n});\n\n// ============================================================================\n// Trait Data Entity\n// ============================================================================\n\n/**\n * Simplified data entity for traits\n */\nexport interface TraitDataEntity {\n name: string;\n collection?: string;\n fields: TraitEntityField[];\n timestamps?: boolean;\n description?: string;\n runtime?: boolean;\n singleton?: boolean;\n pages?: string[];\n}\n\nexport const TraitDataEntitySchema = z.object({\n name: z.string().min(1),\n collection: z.string().optional(),\n fields: z.array(TraitEntityFieldSchema).min(1),\n timestamps: z.boolean().optional(),\n description: z.string().optional(),\n runtime: z.boolean().optional(),\n singleton: z.boolean().optional(),\n pages: z.array(z.string()).optional(),\n});\n\n// ============================================================================\n// Trait Tick\n// ============================================================================\n\n/**\n * Tick rule for traits.\n * Guards can be legacy strings or S-expressions.\n * Effects can be typed Effect objects or S-expressions.\n */\nexport interface TraitTick {\n name: string;\n description?: string;\n priority?: number;\n interval: string | number;\n appliesTo?: string[];\n pages?: string[];\n /** Guard expression - string (legacy) or S-expression array */\n guard?: Expression;\n /** Effects to execute (S-expressions) */\n effects: Effect[];\n /**\n * Events this tick emits.\n * Must reference events defined in trait's emits array.\n * Used for validation and documentation.\n */\n emits?: string[];\n}\n\nexport const TraitTickSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n priority: z.number().optional(),\n interval: z.union([z.literal('frame'), z.number().positive()]),\n appliesTo: z.array(z.string()).optional(),\n pages: z.array(z.string()).optional(),\n guard: ExpressionSchema.optional(),\n effects: z.array(EffectSchema).min(1),\n emits: z.array(z.string()).optional(),\n});\n\n// ============================================================================\n// Event Scope\n// ============================================================================\n\n/**\n * Event scope determines visibility:\n * - 'internal': Trait-to-trait within same orbital (default)\n * - 'external': Exposed for cross-orbital communication\n */\nexport type EventScope = 'internal' | 'external';\n\nexport const EventScopeSchema = z.enum(['internal', 'external']);\n\n// ============================================================================\n// Event Payload Field\n// ============================================================================\n\n/**\n * Payload field definition for events.\n * Defines the structure of data carried by events.\n */\nexport interface EventPayloadField {\n /** Field name */\n name: string;\n /** Field type */\n type: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'entity';\n /** Whether field is required in payload */\n required?: boolean;\n /** Human-readable description */\n description?: string;\n /** For 'entity' type: the entity type name */\n entityType?: string;\n}\n\nexport const EventPayloadFieldSchema = z.object({\n name: z.string().min(1),\n type: z.enum(['string', 'number', 'boolean', 'object', 'array', 'entity']),\n required: z.boolean().optional(),\n description: z.string().optional(),\n entityType: z.string().optional(),\n});\n\n// ============================================================================\n// Trait Event Contract\n// ============================================================================\n\n/**\n * Event contract for events a trait emits.\n * Declares the event name, scope, and payload schema.\n */\nexport interface TraitEventContract {\n /** Event name (UPPER_SNAKE_CASE) */\n event: string;\n /** Human-readable description */\n description?: string;\n /** Payload schema - what data this event carries */\n payload?: EventPayloadField[];\n /**\n * Event scope:\n * - 'internal': Trait-to-trait within same orbital (default)\n * - 'external': Exposed for cross-orbital communication\n */\n scope?: EventScope;\n}\n\nexport const TraitEventContractSchema = z.object({\n event: z.string().min(1).regex(\n /^[A-Z][A-Z0-9_]*$/,\n 'Event name must be UPPER_SNAKE_CASE'\n ),\n description: z.string().optional(),\n payload: z.array(EventPayloadFieldSchema).optional(),\n scope: EventScopeSchema.optional(),\n});\n\n// ============================================================================\n// Trait Event Listener\n// ============================================================================\n\n/**\n * Event listener for trait communication.\n * Guards can be legacy strings or S-expressions.\n * Enhanced with scope and payloadMapping for cross-orbital communication.\n */\nexport interface TraitEventListener {\n /** Event key to listen for (may be namespaced: TraitName.EVENT_NAME) */\n event: string;\n /** State machine event to trigger */\n triggers: string;\n /** Guard expression - string (legacy) or S-expression array */\n guard?: Expression;\n /**\n * Listener scope:\n * - 'internal': Listen to events within same orbital (default)\n * - 'external': Listen to events from other orbitals\n */\n scope?: EventScope;\n /** Map event payload fields to transition payload */\n payloadMapping?: Record<string, string>;\n}\n\nexport const TraitEventListenerSchema = z.object({\n event: z.string().min(1),\n triggers: z.string().min(1),\n guard: ExpressionSchema.optional(),\n scope: EventScopeSchema.optional(),\n payloadMapping: z.record(z.string()).optional(),\n});\n\n// ============================================================================\n// Required Field\n// ============================================================================\n\n/**\n * Field required by a trait from its linkedEntity\n */\nexport interface RequiredField {\n name: string;\n type: 'string' | 'number' | 'boolean' | 'date' | 'array' | 'object' | 'timestamp' | 'datetime' | 'enum';\n description?: string;\n}\n\nexport const RequiredFieldSchema = z.object({\n name: z.string().min(1),\n type: z.enum(['string', 'number', 'boolean', 'date', 'array', 'object', 'timestamp', 'datetime', 'enum']),\n description: z.string().optional(),\n});\n\n// ============================================================================\n// Trait Reference\n// ============================================================================\n\n/**\n * Reference to a trait from an entity or page\n */\nexport interface TraitReference {\n ref: string;\n linkedEntity?: string;\n config?: Record<string, Record<string, unknown>>;\n appliesTo?: string[];\n}\n\nexport const TraitReferenceSchema = z.object({\n ref: z.string().min(1),\n linkedEntity: z.string().optional(),\n config: z.record(z.record(z.unknown())).optional(),\n appliesTo: z.array(z.string()).optional(),\n});\n\n/**\n * Simplified trait reference - supports string, reference object, or inline Trait definition\n * - string: \"TraitName\" - reference to a trait by name\n * - { ref: \"TraitName\" }: reference object with optional config\n * - { name: \"TraitName\", stateMachine: {...} }: inline trait definition\n */\nexport type TraitRef = string | { ref: string; config?: Record<string, unknown>; linkedEntity?: string } | Trait;\n\n// TraitRefSchema is defined after TraitSchema (see below) to avoid forward reference\n\n// ============================================================================\n// Trait UI Binding\n// ============================================================================\n\nexport type PresentationType = 'modal' | 'drawer' | 'popover' | 'inline' | 'confirm-dialog';\n\nexport interface TraitUIBinding {\n [stateName: string]: {\n presentation: PresentationType;\n content: Record<string, unknown> | Record<string, unknown>[];\n props?: {\n size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';\n position?: 'left' | 'right' | 'top' | 'bottom' | 'center';\n title?: string;\n closable?: boolean;\n width?: string;\n showProgress?: boolean;\n step?: number;\n totalSteps?: number;\n };\n };\n}\n\n// ============================================================================\n// Trait Definition\n// ============================================================================\n\n/**\n * A Trait is a reusable behavioral module with state machine.\n *\n * Traits declare their event contracts via `emits` and `listens`:\n * - `emits`: Events this trait can emit (with scope and payload schema)\n * - `listens`: Events this trait listens for (with optional payloadMapping)\n */\nexport interface Trait {\n name: string;\n description?: string;\n description_visual_prompt?: string;\n category?: TraitCategory;\n /**\n * The entity this trait is linked to.\n * Required for inline trait definitions within an orbital.\n */\n linkedEntity?: string;\n requiredFields?: RequiredField[];\n dataEntities?: TraitDataEntity[];\n stateMachine?: StateMachine;\n initialEffects?: Effect[];\n ticks?: TraitTick[];\n /**\n * Events this trait emits.\n * Each event can be scoped as internal or external.\n * External events are namespaced at orbital level (TraitName.EVENT_NAME).\n */\n emits?: TraitEventContract[];\n /**\n * Events this trait listens for.\n * External listeners reference namespaced events (TraitName.EVENT_NAME).\n */\n listens?: TraitEventListener[];\n ui?: TraitUIBinding;\n}\n\nexport const TraitSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n description_visual_prompt: z.string().optional(),\n category: TraitCategorySchema.optional(),\n linkedEntity: z.string().optional(),\n requiredFields: z.array(RequiredFieldSchema).optional(),\n dataEntities: z.array(TraitDataEntitySchema).optional(),\n stateMachine: StateMachineSchema.optional(),\n initialEffects: z.array(EffectSchema).optional(),\n ticks: z.array(TraitTickSchema).optional(),\n emits: z.array(TraitEventContractSchema).optional(),\n listens: z.array(TraitEventListenerSchema).optional(),\n ui: z.record(z.unknown()).optional(),\n});\n\n// TraitRefSchema defined here after TraitSchema to avoid forward reference\nexport const TraitRefSchema = z.union([\n z.string().min(1),\n z.object({\n ref: z.string().min(1),\n config: z.record(z.unknown()).optional(),\n linkedEntity: z.string().optional(),\n }),\n TraitSchema, // Allow inline trait definitions\n]);\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Check if a trait ref is an inline Trait definition\n */\n/**\n * Checks if a trait reference is an inline trait definition.\n * \n * Type guard to determine if a TraitRef is an inline trait object\n * (with 'name' property) rather than a string reference or object reference.\n * \n * @param {TraitRef} traitRef - Trait reference to check\n * @returns {boolean} True if traitRef is an inline trait, false otherwise\n * \n * @example\n * isInlineTrait({ name: 'MyTrait' }); // returns true (inline)\n * isInlineTrait('MyTrait'); // returns false (string reference)\n * isInlineTrait({ ref: 'MyTrait' }); // returns false (object reference)\n */\nexport function isInlineTrait(traitRef: TraitRef): traitRef is Trait {\n return typeof traitRef === 'object' && 'name' in traitRef && !('ref' in traitRef);\n}\n\n/**\n * Extracts the trait name from a trait reference.\n * \n * Handles all trait reference formats (string, inline object, object reference)\n * and returns the canonical trait name.\n * \n * @param {TraitRef} traitRef - Trait reference to extract name from\n * @returns {string} Trait name\n * \n * @example\n * getTraitName('MyTrait'); // returns 'MyTrait'\n * getTraitName({ name: 'MyTrait' }); // returns 'MyTrait'\n * getTraitName({ ref: 'MyTrait' }); // returns 'MyTrait'\n */\nexport function getTraitName(traitRef: TraitRef): string {\n if (typeof traitRef === 'string') {\n return traitRef;\n }\n if (isInlineTrait(traitRef)) {\n return traitRef.name;\n }\n return traitRef.ref;\n}\n\n/**\n * Extracts the configuration from a trait reference.\n * \n * Returns the configuration object for trait references that support it\n * (object references with 'config' property). Returns undefined for\n * string references and inline traits.\n * \n * @param {TraitRef} traitRef - Trait reference to extract config from\n * @returns {Record<string, unknown> | undefined} Trait configuration or undefined\n * \n * @example\n * getTraitConfig('MyTrait'); // returns undefined\n * getTraitConfig({ name: 'MyTrait' }); // returns undefined\n * getTraitConfig({ ref: 'MyTrait', config: { option: 'value' } }); // returns config object\n */\nexport function getTraitConfig(traitRef: TraitRef): Record<string, unknown> | undefined {\n if (typeof traitRef === 'string') {\n return undefined;\n }\n if (isInlineTrait(traitRef)) {\n return undefined; // Inline traits don't have config\n }\n return traitRef.config;\n}\n\n/**\n * Normalizes a trait reference to object form.\n * \n * Converts any trait reference format (string, inline, object) to a\n * standardized object format with 'ref' and optional 'config' properties.\n * \n * @param {TraitRef} traitRef - Trait reference to normalize\n * @returns {{ ref: string; config?: Record<string, unknown> }} Normalized trait reference\n * \n * @example\n * normalizeTraitRef('MyTrait'); // returns { ref: 'MyTrait' }\n * normalizeTraitRef({ name: 'MyTrait' }); // returns { ref: 'MyTrait' }\n * normalizeTraitRef({ ref: 'MyTrait', config: {...} }); // returns original\n */\nexport function normalizeTraitRef(traitRef: TraitRef): { ref: string; config?: Record<string, unknown> } {\n if (typeof traitRef === 'string') {\n return { ref: traitRef };\n }\n if (isInlineTrait(traitRef)) {\n return { ref: traitRef.name };\n }\n return traitRef;\n}\n\n// ============================================================================\n// Type exports\n// ============================================================================\n\nexport type TraitInput = z.input<typeof TraitSchema>;\nexport type TraitReferenceInput = z.input<typeof TraitReferenceSchema>;\n\n// Backward compatibility aliases\nexport type OrbitalTraitRef = TraitRef;\nexport const OrbitalTraitRefSchema = TraitRefSchema;\n","/**\n * Event Wiring\n *\n * Applies cross-orbital event wiring to orbital definitions.\n * Adds emits/listens declarations to traits so they can communicate\n * across orbital boundaries.\n *\n * @packageDocumentation\n */\n\nimport type { OrbitalDefinition } from '../types/orbital.js';\nimport type { Trait, TraitEventContract, TraitEventListener } from '../types/trait.js';\nimport { isInlineTrait } from '../types/trait.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * A single event wiring entry connecting two traits across orbitals.\n */\nexport interface EventWiringEntry {\n /** Source trait name or orbital name */\n from: string;\n /** Event name (UPPER_SNAKE_CASE) */\n event: string;\n /** Target trait name or orbital name */\n to: string;\n /** Event to trigger on the listener side */\n triggers: string;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Find a trait by name across all orbitals.\n * Only inline traits can be mutated; string/ref traits are skipped.\n * Returns the inline Trait object if found, or null.\n */\nfunction findInlineTrait(\n orbitals: OrbitalDefinition[],\n name: string,\n): Trait | null {\n for (const orbital of orbitals) {\n for (const traitRef of orbital.traits) {\n if (isInlineTrait(traitRef) && traitRef.name === name) {\n return traitRef;\n }\n }\n }\n return null;\n}\n\n/**\n * Check if an emit already exists in the list.\n * @internal\n */\nfunction hasEmit(emits: TraitEventContract[], event: string): boolean {\n return emits.some((e) => e.event === event);\n}\n\n/**\n * Check if a listen already exists in the list.\n * @internal\n */\nfunction hasListen(\n listens: TraitEventListener[],\n event: string,\n triggers: string,\n): boolean {\n return listens.some((l) => l.event === event && l.triggers === triggers);\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Apply event wiring to orbital definitions.\n *\n * For each wiring entry:\n * 1. Find the source trait and add an external emit (if not already present)\n * 2. Find the target trait and add an external listen (if not already present)\n *\n * Returns a new array of orbitals with wiring applied (deep-cloned).\n */\nexport function applyEventWiring(\n orbitals: OrbitalDefinition[],\n wiring: EventWiringEntry[],\n): OrbitalDefinition[] {\n // Deep clone to avoid mutating input\n const cloned: OrbitalDefinition[] = JSON.parse(\n JSON.stringify(orbitals),\n ) as OrbitalDefinition[];\n\n for (const entry of wiring) {\n // Wire the source: add emit\n const sourceTrait = findInlineTrait(cloned, entry.from);\n if (sourceTrait) {\n if (!sourceTrait.emits) {\n sourceTrait.emits = [];\n }\n if (!hasEmit(sourceTrait.emits, entry.event)) {\n sourceTrait.emits.push({\n event: entry.event,\n scope: 'external',\n });\n }\n }\n\n // Wire the target: add listen\n const targetTrait = findInlineTrait(cloned, entry.to);\n if (targetTrait) {\n if (!targetTrait.listens) {\n targetTrait.listens = [];\n }\n if (!hasListen(targetTrait.listens, entry.event, entry.triggers)) {\n targetTrait.listens.push({\n event: entry.event,\n triggers: entry.triggers,\n scope: 'external',\n });\n }\n }\n }\n\n return cloned;\n}\n","/**\n * Compose Behaviors\n *\n * Main entry point for composing multiple orbital definitions into\n * a single OrbitalSchema application. Handles event wiring, layout\n * strategy detection, and page generation.\n *\n * @packageDocumentation\n */\n\nimport type { OrbitalDefinition } from '../types/orbital.js';\nimport type { OrbitalSchema } from '../types/schema.js';\nimport type { Page } from '../types/page.js';\nimport type { EventWiringEntry } from './event-wiring.js';\nimport { applyEventWiring } from './event-wiring.js';\nimport type { LayoutStrategy } from './layout-strategy.js';\nimport { detectLayoutStrategy } from './layout-strategy.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Input for composing behaviors into an application.\n */\nexport interface ComposeBehaviorsInput {\n /** Application name */\n appName: string;\n /** Orbital definitions to compose */\n orbitals: OrbitalDefinition[];\n /** Layout strategy override, or 'auto' to detect */\n layoutStrategy?: LayoutStrategy | 'auto';\n /** Cross-orbital event wiring */\n eventWiring?: EventWiringEntry[];\n /** Optional entity name mappings (original -> renamed) */\n entityMappings?: Record<string, string>;\n}\n\n/**\n * Result of composing behaviors.\n */\nexport interface ComposeBehaviorsResult {\n /** The composed OrbitalSchema */\n schema: OrbitalSchema;\n /** Layout metadata */\n layout: { strategy: LayoutStrategy; pageCount: number };\n /** Wiring metadata */\n wiring: { connections: number };\n}\n\n// ============================================================================\n// Page Generation\n// ============================================================================\n\nfunction toKebabCase(name: string): string {\n return name\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n}\n\n/**\n * Generate pages for each orbital based on the layout strategy.\n *\n * For strategies that produce one page per orbital (sidebar, tabs, wizard-flow),\n * each orbital gets a page at `/<kebab-name>` with `isInitial` on the first.\n *\n * For 'dashboard', all orbitals share a single page.\n * For 'single', the lone orbital gets a single root page.\n */\nfunction generatePages(\n orbitals: OrbitalDefinition[],\n strategy: LayoutStrategy,\n): Page[] {\n switch (strategy) {\n case 'single': {\n const orbital = orbitals[0];\n const name = orbital?.name ?? 'Main';\n return [\n {\n name: `${name}Page`,\n path: '/',\n isInitial: true,\n primaryEntity: getEntityName(orbital),\n },\n ];\n }\n\n case 'dashboard': {\n return [\n {\n name: 'DashboardPage',\n path: '/',\n viewType: 'dashboard',\n isInitial: true,\n },\n ];\n }\n\n case 'sidebar':\n case 'tabs':\n case 'wizard-flow': {\n return orbitals.map((orbital, index) => ({\n name: `${orbital.name}Page`,\n path: index === 0 ? '/' : `/${toKebabCase(orbital.name)}`,\n isInitial: index === 0,\n primaryEntity: getEntityName(orbital),\n }));\n }\n }\n}\n\n/**\n * Extract entity name from an orbital definition.\n * Handles both inline entities and string references.\n */\nfunction getEntityName(orbital: OrbitalDefinition | undefined): string | undefined {\n if (!orbital) return undefined;\n const entity = orbital.entity;\n if (typeof entity === 'string') {\n // Reference like \"Alias.entity\" - extract the alias as entity name\n return entity.replace('.entity', '');\n }\n return entity.name;\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Compose multiple orbital definitions into a single application schema.\n *\n * Steps:\n * 1. Apply event wiring (adds emits/listens to traits)\n * 2. Detect or use provided layout strategy\n * 3. Generate pages based on the strategy\n * 4. Build the final OrbitalSchema\n */\nexport function composeBehaviors(\n input: ComposeBehaviorsInput,\n): ComposeBehaviorsResult {\n const {\n appName,\n orbitals: rawOrbitals,\n layoutStrategy: strategyInput,\n eventWiring,\n } = input;\n\n // Step 1: Apply event wiring\n const wiredOrbitals =\n eventWiring && eventWiring.length > 0\n ? applyEventWiring(rawOrbitals, eventWiring)\n : rawOrbitals;\n\n // Step 2: Determine layout strategy\n const strategy: LayoutStrategy =\n !strategyInput || strategyInput === 'auto'\n ? detectLayoutStrategy(wiredOrbitals, eventWiring)\n : strategyInput;\n\n // Step 3: Generate pages\n const pages = generatePages(wiredOrbitals, strategy);\n\n // Step 4: Assign generated pages to orbitals (merge, don't replace existing)\n const orbitalsWithPages = wiredOrbitals.map((orbital, index) => {\n // If the orbital already has pages, keep them\n if (orbital.pages && orbital.pages.length > 0) {\n return orbital;\n }\n\n // Assign the generated page for this orbital\n const page = strategy === 'dashboard' || strategy === 'single'\n ? pages[0]\n : pages[index];\n\n return {\n ...orbital,\n pages: page ? [page] : [],\n };\n });\n\n // Step 5: Build the schema\n const schema: OrbitalSchema = {\n name: appName,\n version: '1.0.0',\n orbitals: orbitalsWithPages,\n };\n\n return {\n schema,\n layout: {\n strategy,\n pageCount: pages.length,\n },\n wiring: {\n connections: eventWiring?.length ?? 0,\n },\n };\n}\n","/**\n * Orbital Builders\n *\n * Pure functions for constructing and composing Orbitals.\n * No new types. Everything uses existing core types:\n * Entity, Trait, Page, OrbitalDefinition, OrbitalSchema.\n *\n * Three categories:\n * 1. Builders: construct Entity, Page from common params\n * 2. Utilities: ensureIdField, resolveDefaults\n * 3. Composition: connect, compose, pipe\n *\n * @packageDocumentation\n */\n\nimport type { Entity, EntityPersistence } from './types/entity.js';\nimport type { EntityField } from './types/field.js';\nimport type { Page } from './types/page.js';\nimport type { OrbitalDefinition } from './types/orbital.js';\nimport type { OrbitalSchema } from './types/schema.js';\nimport type { TraitEventContract, TraitEventListener, Trait } from './types/trait.js';\n\n// Re-export compose-behaviors module\nexport { type LayoutStrategy, detectLayoutStrategy } from './builders/layout-strategy.js';\nexport { type EventWiringEntry, applyEventWiring } from './builders/event-wiring.js';\nexport {\n type ComposeBehaviorsInput,\n type ComposeBehaviorsResult,\n composeBehaviors,\n} from './builders/compose-behaviors.js';\n\n// ============================================================================\n// Utilities\n// ============================================================================\n\n/**\n * Ensure the fields array has an `id` field. Prepends one if missing.\n */\nexport function ensureIdField(fields: EntityField[]): EntityField[] {\n if (fields.some(f => f.name === 'id')) return fields;\n return [{ name: 'id', type: 'string', required: true }, ...fields];\n}\n\n/**\n * Simple pluralization: append 's'.\n */\nexport function plural(name: string): string {\n return name + 's';\n}\n\n// ============================================================================\n// Entity Builder\n// ============================================================================\n\nexport interface MakeEntityOpts {\n name: string;\n fields: EntityField[];\n persistence?: EntityPersistence;\n collection?: string;\n /** Pre-authored seed data instances */\n instances?: Record<string, unknown>[];\n}\n\n/**\n * Build an Entity from options. Auto-adds id field, auto-derives collection.\n */\nexport function makeEntity(opts: MakeEntityOpts): Entity {\n const fields = ensureIdField(opts.fields);\n const persistence = opts.persistence ?? 'runtime';\n return {\n name: opts.name,\n persistence,\n ...(persistence === 'persistent'\n ? { collection: opts.collection ?? plural(opts.name).toLowerCase() }\n : {}),\n fields,\n ...(opts.instances && opts.instances.length > 0 ? { instances: opts.instances } : {}),\n };\n}\n\n// ============================================================================\n// Page Builder\n// ============================================================================\n\nexport interface MakePageOpts {\n name: string;\n path: string;\n traitName: string;\n isInitial?: boolean;\n}\n\n/**\n * Build a Page that binds to a single trait.\n */\nexport function makePage(opts: MakePageOpts): Page {\n return {\n name: opts.name,\n path: opts.path,\n ...(opts.isInitial ? { isInitial: true } : {}),\n traits: [{ ref: opts.traitName }],\n };\n}\n\n// ============================================================================\n// Orbital Builder\n// ============================================================================\n\n/**\n * Build an OrbitalDefinition from its three components.\n */\nexport function makeOrbital(\n name: string,\n entity: Entity,\n traits: Trait[],\n pages: Page[],\n): OrbitalDefinition {\n return { name, entity, traits, pages } as OrbitalDefinition;\n}\n\n// ============================================================================\n// Intra-Orbital Composition\n// ============================================================================\n\n/**\n * Merge multiple OrbitalDefinitions into one.\n * Collects all traits from all sources into a single orbital with a shared entity.\n * Pure: clones all traits, no mutation.\n */\nexport function mergeOrbitals(\n name: string,\n entity: Entity,\n sources: OrbitalDefinition[],\n pages: Page[],\n): OrbitalDefinition {\n const allTraits = sources.flatMap(s =>\n (s.traits as Trait[]).map(t => structuredClone(t)),\n );\n return { name, entity, traits: allTraits, pages } as OrbitalDefinition;\n}\n\n/**\n * Wire an intra-orbital event between two traits.\n * Adds emits to the source trait, listens to the target trait.\n * Pure: returns cloned traits, no mutation.\n */\nexport function wire(\n source: Trait,\n target: Trait,\n event: TraitEventContract,\n triggers: string,\n): [Trait, Trait] {\n const s = structuredClone(source);\n const t = structuredClone(target);\n\n s.emits = [...(s.emits ?? []), { ...event, scope: event.scope ?? ('internal' as const) }];\n t.listens = [...(t.listens ?? []), {\n event: event.event,\n triggers,\n scope: 'internal' as const,\n }];\n\n return [s, t];\n}\n\n/**\n * Extract the first trait from an OrbitalDefinition.\n */\nexport function extractTrait(orbital: OrbitalDefinition): Trait {\n return structuredClone((orbital.traits as Trait[])[0]);\n}\n\n// ============================================================================\n// Composition: connect\n// ============================================================================\n\n/**\n * Wire a cross-orbital event between two orbitals.\n * Adds emits to a's first trait, listens to b's first trait.\n * Pure: returns new orbitals, no mutation.\n */\nexport function connect(\n a: OrbitalDefinition,\n b: OrbitalDefinition,\n event: TraitEventContract,\n triggers?: string,\n): [OrbitalDefinition, OrbitalDefinition] {\n const aClone = structuredClone(a);\n const bClone = structuredClone(b);\n\n // Add emit to first trait of a\n const aTrait = (aClone.traits as Trait[])[0];\n if (aTrait) {\n const emitContract: TraitEventContract = {\n ...event,\n scope: event.scope ?? 'external',\n };\n aTrait.emits = [...(aTrait.emits ?? []), emitContract];\n }\n\n // Add listen to first trait of b\n const bTrait = (bClone.traits as Trait[])[0];\n if (bTrait) {\n const listener: TraitEventListener = {\n event: event.event,\n triggers: triggers ?? 'INIT',\n scope: 'external',\n };\n bTrait.listens = [...(bTrait.listens ?? []), listener];\n }\n\n return [aClone, bClone];\n}\n\n// ============================================================================\n// Composition: compose\n// ============================================================================\n\nexport interface ComposeConnection {\n from: string;\n to: string;\n event: TraitEventContract;\n triggers?: string;\n}\n\nexport interface ComposePage {\n name: string;\n path: string;\n traits: string[];\n isInitial?: boolean;\n}\n\n/**\n * Compose multiple orbitals into a single OrbitalSchema (application).\n * Applies connections (cross-orbital event wiring) and page assignments.\n */\nexport function compose(\n orbitals: OrbitalDefinition[],\n pages: ComposePage[],\n connections: ComposeConnection[],\n appName?: string,\n): OrbitalSchema {\n const cloned = structuredClone(orbitals);\n\n // Apply connections\n for (const conn of connections) {\n const emitter = cloned.find(o => {\n const traits = o.traits as Trait[];\n return traits.some(t => t.name === conn.from);\n });\n const listener = cloned.find(o => {\n const traits = o.traits as Trait[];\n return traits.some(t => t.name === conn.to);\n });\n\n if (emitter && listener) {\n const eTrait = (emitter.traits as Trait[]).find(t => t.name === conn.from);\n const lTrait = (listener.traits as Trait[]).find(t => t.name === conn.to);\n\n if (eTrait) {\n const emitContract: TraitEventContract = { ...conn.event, scope: conn.event.scope ?? 'external' };\n eTrait.emits = [...(eTrait.emits ?? []), emitContract];\n }\n if (lTrait) {\n const listenContract: TraitEventListener = {\n event: conn.event.event,\n triggers: conn.triggers ?? 'INIT',\n scope: 'external',\n };\n lTrait.listens = [...(lTrait.listens ?? []), listenContract];\n }\n }\n }\n\n // Assign pages to orbitals\n for (const orbital of cloned) {\n const traitNames = (orbital.traits as Trait[]).map(t => t.name);\n const matchingPages = pages.filter(p =>\n p.traits.some(t => traitNames.includes(t)),\n );\n orbital.pages = matchingPages.map(p => ({\n name: p.name,\n path: p.path,\n ...(p.isInitial ? { isInitial: true } : {}),\n traits: p.traits\n .filter(t => traitNames.includes(t))\n .map(ref => ({ ref })),\n }));\n }\n\n return {\n name: appName ?? 'Application',\n version: '1.0.0',\n orbitals: cloned,\n };\n}\n\n// ============================================================================\n// Composition: pipe\n// ============================================================================\n\n/**\n * Chain orbitals in sequence with automatic event wiring.\n * Sugar over connect + compose: wires events[0] from orbital[0] to orbital[1], etc.\n */\nexport function pipe(\n orbitals: OrbitalDefinition[],\n events: TraitEventContract[],\n appName?: string,\n): OrbitalSchema {\n if (events.length !== orbitals.length - 1) {\n throw new Error(`pipe requires exactly ${orbitals.length - 1} events for ${orbitals.length} orbitals`);\n }\n\n const cloned = structuredClone(orbitals);\n\n // Wire adjacent pairs\n for (let i = 0; i < events.length; i++) {\n const aTrait = (cloned[i].traits as Trait[])[0];\n const bTrait = (cloned[i + 1].traits as Trait[])[0];\n\n if (aTrait) {\n const emitContract: TraitEventContract = { ...events[i], scope: events[i].scope ?? 'external' };\n aTrait.emits = [...(aTrait.emits ?? []), emitContract];\n }\n if (bTrait) {\n const listener: TraitEventListener = {\n event: events[i].event,\n triggers: 'INIT',\n scope: 'external',\n };\n bTrait.listens = [...(bTrait.listens ?? []), listener];\n }\n }\n\n // Auto-generate pages: one per orbital, first is initial\n const pages: Page[] = cloned.map((o, i) => {\n const entityName = typeof o.entity === 'string' ? o.entity : o.entity.name;\n const traitNames = (o.traits as Trait[]).map(t => t.name);\n return {\n name: `${entityName}Page`,\n path: `/${plural(entityName).toLowerCase()}`,\n ...(i === 0 ? { isInitial: true } : {}),\n traits: traitNames.map(ref => ({ ref })),\n };\n });\n\n // Assign pages back to orbitals\n for (let i = 0; i < cloned.length; i++) {\n cloned[i].pages = [pages[i]];\n }\n\n return {\n name: appName ?? 'Application',\n version: '1.0.0',\n orbitals: cloned,\n };\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../src/builders/layout-strategy.ts","../src/types/effect.ts","../src/types/expression.ts","../src/types/state-machine.ts","../src/types/trait.ts","../src/builders/event-wiring.ts","../src/builders/compose-behaviors.ts","../src/builders.ts"],"names":["z"],"mappings":"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","file":"builders.js","sourcesContent":["/**\n * Layout Strategy Detection\n *\n * Auto-detects the best layout strategy for a composed application\n * based on the number of orbitals and their event wiring topology.\n *\n * @packageDocumentation\n */\n\nimport type { OrbitalDefinition } from '../types/orbital.js';\nimport type { EventWiringEntry } from './event-wiring.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Layout strategy for the composed application.\n *\n * - 'single': One orbital, one page\n * - 'tabs': 2-4 orbitals with no sequential chain\n * - 'sidebar': 5+ orbitals (navigation-heavy)\n * - 'dashboard': Single page with all orbitals visible\n * - 'wizard-flow': Sequential event chain detected (A -> B -> C)\n */\nexport type LayoutStrategy =\n | 'sidebar'\n | 'tabs'\n | 'dashboard'\n | 'wizard-flow'\n | 'single';\n\n// ============================================================================\n// Chain Detection\n// ============================================================================\n\n/**\n * Detect whether the event wiring forms a sequential chain.\n *\n * A sequential chain exists when orbital A's `from` feeds into B's `to`,\n * and B's `from` feeds into C's `to`, forming A -> B -> C.\n *\n * We build a directed graph from wiring entries and look for a chain\n * that covers 3+ nodes (the minimum for a meaningful wizard flow).\n */\nfunction hasSequentialChain(wiring: EventWiringEntry[]): boolean {\n if (wiring.length < 2) {\n return false;\n }\n\n // Build adjacency: from -> Set<to>\n const adjacency = new Map<string, Set<string>>();\n const allTargets = new Set<string>();\n\n for (const entry of wiring) {\n let targets = adjacency.get(entry.from);\n if (!targets) {\n targets = new Set<string>();\n adjacency.set(entry.from, targets);\n }\n targets.add(entry.to);\n allTargets.add(entry.to);\n }\n\n // Find roots (nodes that are sources but never targets)\n const roots: string[] = [];\n for (const from of adjacency.keys()) {\n if (!allTargets.has(from)) {\n roots.push(from);\n }\n }\n\n // If no clear root, try all sources\n const starts = roots.length > 0 ? roots : [...adjacency.keys()];\n\n // Walk from each start and measure chain length\n for (const start of starts) {\n let current = start;\n let length = 1;\n const visited = new Set<string>([current]);\n\n while (true) {\n const nexts = adjacency.get(current);\n if (!nexts || nexts.size === 0) break;\n\n // Follow the first unvisited successor (linear chain)\n let advanced = false;\n for (const next of nexts) {\n if (!visited.has(next)) {\n visited.add(next);\n current = next;\n length++;\n advanced = true;\n break;\n }\n }\n\n if (!advanced) break;\n }\n\n // A chain of 3+ nodes qualifies as wizard-flow\n if (length >= 3) {\n return true;\n }\n }\n\n return false;\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Detect the best layout strategy based on orbital count and event wiring.\n *\n * Heuristic:\n * 1. Sequential event chain detected -> 'wizard-flow'\n * 2. 1 orbital -> 'single'\n * 3. 2-4 orbitals -> 'tabs'\n * 4. 5+ orbitals -> 'sidebar'\n */\nexport function detectLayoutStrategy(\n orbitals: OrbitalDefinition[],\n eventWiring?: EventWiringEntry[],\n): LayoutStrategy {\n // Check for sequential chain first (takes priority)\n if (eventWiring && eventWiring.length > 0 && hasSequentialChain(eventWiring)) {\n return 'wizard-flow';\n }\n\n const count = orbitals.length;\n\n if (count <= 1) {\n return 'single';\n }\n\n if (count <= 4) {\n return 'tabs';\n }\n\n return 'sidebar';\n}\n","/**\n * Effect Types (Self-Contained)\n *\n * Defines effect types for trait transitions and ticks.\n * Effects are S-expressions (arrays) that describe actions to perform.\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\nimport { type SExpr, type Expression } from './expression.js';\n\n// ============================================================================\n// UI Slots\n// ============================================================================\n\n/**\n * Known UI slots where content can be rendered\n */\nexport const UI_SLOTS = [\n // App slots\n 'main',\n 'sidebar',\n 'modal',\n 'drawer',\n 'overlay',\n 'center',\n 'toast',\n 'floating',\n 'system', // For invisible system components (InputListener, CollisionDetector)\n 'content',\n 'screen',\n // Game HUD slots\n 'hud',\n 'hud-top',\n 'hud-bottom',\n 'hud.health',\n 'hud.score',\n 'hud.inventory',\n 'hud.stamina',\n // Game overlay slots\n 'overlay.inventory',\n 'overlay.dialogue',\n 'overlay.menu',\n 'overlay.pause',\n] as const;\n\nexport type UISlot = (typeof UI_SLOTS)[number];\n\nexport const UISlotSchema = z.enum(UI_SLOTS);\n\n// ============================================================================\n// Pattern Config (for render-ui effects)\n// ============================================================================\n\n// Import pattern types for local use and re-export for consumers\nimport type {\n PatternType,\n PatternConfig,\n PatternProps,\n PatternPropsMap,\n AnyPatternConfig,\n} from '@almadar/patterns';\n\n/**\n * Type-safe pattern configuration for render-ui effects.\n *\n * Re-exported from @almadar/patterns. Generated from patterns-registry.json.\n *\n * @example\n * // Type-safe with specific pattern type\n * const config: PatternConfig<'entity-table'> = {\n * patternType: 'entity-table',\n * columns: ['name', 'email'], // ✅ Required prop\n * entity: 'User',\n * };\n *\n * // Error: Property 'columns' is missing (required prop)\n * const bad: PatternConfig<'entity-table'> = { patternType: 'entity-table' };\n *\n * // Error: 'fake-pattern' is not assignable to PatternType\n * const invalid: PatternConfig = { patternType: 'fake-pattern' };\n */\nexport type {\n PatternType,\n PatternConfig,\n PatternProps,\n PatternPropsMap,\n AnyPatternConfig,\n};\n\n/**\n * Configuration for render-ui effect.\n * Used in runtime to specify which slot and pattern to render.\n */\nexport interface RenderUIConfig {\n /** Target UI slot */\n slot: UISlot;\n /** Pattern configuration (null clears the slot) */\n pattern: AnyPatternConfig | null;\n /** Target element (trait name or entity ID) */\n target?: string;\n /** Additional props for the pattern */\n props?: Record<string, unknown>;\n /** Optional priority for slot ordering */\n priority?: number;\n}\n\n// ============================================================================\n// Service Config (for call-service effects)\n// ============================================================================\n\n/**\n * Configuration extracted from call-service effects\n */\nexport interface CallServiceConfig {\n service: string;\n action: string;\n endpoint?: string;\n method?: 'GET' | 'POST' | 'PUT' | 'PATCH' | 'DELETE';\n params?: Record<string, unknown>;\n onSuccess?: string;\n onError?: string;\n}\n\n// ============================================================================\n// Typed Effect Tuples\n// ============================================================================\n\n/**\n * Render UI effect - displays a pattern in a UI slot.\n * @example ['render-ui', 'main', { patternType: 'entity-table', columns: ['name'] }]\n */\nexport type RenderUIEffect =\n | ['render-ui', UISlot, AnyPatternConfig]\n | ['render-ui', UISlot, AnyPatternConfig, Record<string, unknown>]\n | ['render-ui', UISlot, null];\n\n/**\n * Navigate effect - navigates to a path.\n * @example ['navigate', '/tasks'] or ['navigate', '/tasks/:id', { id: '123' }]\n */\nexport type NavigateEffect = ['navigate', string] | ['navigate', string, Record<string, string>];\n\n/**\n * Emit effect - emits an event, optionally with payload.\n * @example ['emit', 'SAVE'] or ['emit', 'PLAYER_DIED', { playerId: '@entity.id' }]\n * @example ['emit', 'FILTER_CHANGED', '@entity.filters']\n */\nexport type EmitEffect = ['emit', string] | ['emit', string, Record<string, unknown> | string];\n\n/**\n * Set effect - sets a binding to a value.\n * @example ['set', '@entity.health', 100]\n */\nexport type SetEffect = ['set', string, unknown];\n\n/**\n * Persist effect - creates, updates, deletes, or clears entities.\n * @example ['persist', 'create', 'Task', { title: '@payload.title' }]\n * @example ['persist', 'update', '@entity.entityType', '@payload.data']\n */\nexport type PersistEffect =\n | ['persist', 'create', string, Record<string, unknown> | string]\n | ['persist', 'update', string, Record<string, unknown> | string]\n | ['persist', 'delete', string]\n | ['persist', 'delete', string, Record<string, unknown> | string]\n | ['persist', 'clear', string]\n | ['persist', 'clear', string, Record<string, unknown> | string];\n\n/**\n * Call service effect - invokes an external service.\n * @example ['call-service', 'WeatherAPI', { service: 'weather', action: 'get', onSuccess: 'OK' }]\n */\nexport type CallServiceEffect = ['call-service', string, CallServiceConfig];\n\n/**\n * Spawn effect - creates a new entity instance (games).\n * @example ['spawn', 'Bullet', { x: '@entity.x', y: '@entity.y' }]\n */\nexport type SpawnEffect = ['spawn', string] | ['spawn', string, Record<string, unknown>];\n\n/**\n * Despawn effect - removes an entity instance (games).\n * @example ['despawn', '@entity.id']\n */\nexport type DespawnEffect = ['despawn', string];\n\n/**\n * Do effect - executes multiple effects in sequence.\n * Uses SExpr to allow deeply nested conditionals.\n * @example ['do', ['set', '@entity.x', 0], ['set', '@entity.y', 0]]\n */\nexport type DoEffect = ['do', ...SExpr[]];\n\n/**\n * Notify effect - sends a notification.\n * @example ['notify', 'in_app', 'Task created successfully']\n * @example ['notify', 'in_app', ['str/concat', 'Item: ', '@entity.name']]\n */\nexport type NotifyEffect =\n | ['notify', string, string | SExpr]\n | ['notify', string, string | SExpr, string];\n\n/**\n * Fetch effect - retrieves entity data (server-side).\n * @example ['fetch', 'User'] or ['fetch', 'User', { id: '@payload.userId' }]\n */\nexport type FetchEffect = ['fetch', string] | ['fetch', string, Record<string, unknown>];\n\n/**\n * If effect - conditional effect execution.\n * Uses SExpr to allow deeply nested conditionals.\n * @example ['if', ['>', '@entity.health', 0], ['emit', 'ALIVE'], ['emit', 'DEAD']]\n */\nexport type IfEffect = ['if', Expression, SExpr] | ['if', Expression, SExpr, SExpr];\n\n/**\n * When effect - conditional effect similar to if but without else.\n * Uses SExpr to allow deeply nested conditionals.\n * @example ['when', ['>', '@entity.health', 0], ['emit', 'ALIVE']]\n */\nexport type WhenEffect = ['when', Expression, SExpr];\n\n/**\n * Let effect - creates local bindings for effects.\n * Uses SExpr to allow deeply nested conditionals.\n * @example ['let', ['temp', ['get', '@payload.value']], ['set', '@entity.value', 'temp']]\n */\nexport type LetEffect = ['let', [string, unknown][], ...SExpr[]];\n\n/**\n * Log effect - logs a message for debugging.\n * @example ['log', 'User created:', '@entity.name']\n */\nexport type LogEffect = ['log', ...unknown[]];\n\n/**\n * Wait effect - delays execution.\n * @example ['wait', 1000] - wait 1 second\n */\nexport type WaitEffect = ['wait', number];\n\n// ============================================================================\n// Resource Effects (reactive entity subscriptions and atomic operations)\n// ============================================================================\n\n/**\n * Ref effect - creates a reactive entity subscription.\n * Returns a reactive reference that auto-updates when the entity changes.\n * @example ['ref', '@entity.health'] - reactive subscription to health\n * @example ['ref', 'User', { id: '@payload.userId' }] - reactive ref to specific user\n */\nexport type RefEffect =\n | ['ref', string]\n | ['ref', string, Record<string, unknown>];\n\n/**\n * Deref effect - snapshot read of an entity value.\n * Returns the current value without subscribing to changes.\n * @example ['deref', '@entity.health'] - read current health value\n * @example ['deref', 'User', { id: '@payload.userId' }] - read specific user snapshot\n */\nexport type DerefEffect =\n | ['deref', string]\n | ['deref', string, Record<string, unknown>];\n\n/**\n * Swap! effect - atomic compare-and-swap on an entity field.\n * Only updates if the current value matches the expected value.\n * @example ['swap!', '@entity.health', ['fn', ['old'], ['-', 'old', '@payload.damage']]]\n * @example ['swap!', '@entity.counter', ['+', '@entity.counter', 1]]\n */\nexport type SwapEffect = ['swap!', string, SExpr];\n\n/**\n * Watch effect - registers a callback for entity changes.\n * Emits an event whenever the watched binding changes.\n * @example ['watch', '@entity.health', 'HEALTH_CHANGED']\n * @example ['watch', '@entity.status', 'STATUS_UPDATED', { debounce: 100 }]\n */\nexport type WatchEffect =\n | ['watch', string, string]\n | ['watch', string, string, Record<string, unknown>];\n\n/**\n * Atomic effect - groups multiple effects into an atomic transaction.\n * All effects either succeed together or are rolled back.\n * @example ['atomic', ['set', '@entity.x', 10], ['set', '@entity.y', 20]]\n * @example ['atomic', ['persist', 'update', 'User', { balance: 100 }], ['emit', 'BALANCE_UPDATED']]\n */\nexport type AtomicEffect = ['atomic', ...SExpr[]];\n\n// ============================================================================\n// ML Effects (from almadar-std/modules/nn, tensor, train)\n// ============================================================================\n\n/**\n * Forward effect - runs a neural network forward pass (Python backend).\n * @example ['forward', 'primary', { architecture: [...], input: '@payload.input', 'on-complete': 'PREDICTION_READY' }]\n */\nexport type ForwardEffect = ['forward', string, Record<string, unknown>];\n\n/**\n * Train effect - runs a training loop (Python backend).\n * @example ['train', { architecture: [...], dataset: '@entity.data', config: { epochs: 10 }, 'on-complete': 'TRAINING_DONE' }]\n */\nexport type TrainEffect = ['train', Record<string, unknown>];\n\n/**\n * Evaluate effect - runs model evaluation (Python backend).\n * @example ['evaluate', { architecture: [...], dataset: '@entity.testData', metrics: ['accuracy'], 'on-complete': 'EVAL_DONE' }]\n */\nexport type EvaluateEffect = ['evaluate', Record<string, unknown>];\n\n/**\n * Checkpoint save effect - saves model weights.\n * @example ['checkpoint/save', '/path/to/model.pt', '@entity.weights']\n */\nexport type CheckpointSaveEffect = ['checkpoint/save', string, unknown];\n\n/**\n * Checkpoint load effect - loads model weights.\n * @example ['checkpoint/load', '/path/to/model.pt']\n */\nexport type CheckpointLoadEffect = ['checkpoint/load', string];\n\n// ============================================================================\n// Async Effects (from almadar-std/modules/async)\n// ============================================================================\n\n/**\n * Async delay effect - wait then execute effects.\n * @example ['async/delay', 2000, ['emit', 'TIMEOUT']]\n */\nexport type AsyncDelayEffect = ['async/delay', number | string, ...Effect[]];\n\n/**\n * Async debounce effect - debounce then execute effect.\n * @example ['async/debounce', 300, ['emit', 'SEARCH_COMPLETE']]\n * @example ['async/debounce', '@entity.debounceMs', ['emit', 'SEARCH_COMPLETE']]\n */\nexport type AsyncDebounceEffect = ['async/debounce', number | string, SExpr];\n\n/**\n * Async throttle effect - throttle then execute effect.\n * @example ['async/throttle', 100, ['emit', 'SCROLL_HANDLED']]\n * @example ['async/throttle', '@entity.throttleMs', ['emit', 'SCROLL_HANDLED']]\n */\nexport type AsyncThrottleEffect = ['async/throttle', number | string, SExpr];\n\n/**\n * Async interval effect - execute effect at intervals.\n * @example ['async/interval', 1000, ['emit', 'TICK']]\n * @example ['async/interval', '@entity.intervalMs', ['emit', 'POLL_TICK']]\n */\nexport type AsyncIntervalEffect = ['async/interval', number | string, SExpr];\n\n/**\n * Async race effect - first effect to complete wins.\n * @example ['async/race', ['call', 'api1'], ['call', 'api2']]\n */\nexport type AsyncRaceEffect = ['async/race', ...Effect[]];\n\n/**\n * Async all effect - wait for all effects to complete.\n * @example ['async/all', ['call', 'api1'], ['call', 'api2']]\n */\nexport type AsyncAllEffect = ['async/all', ...Effect[]];\n\n/**\n * Async sequence effect - execute effects in sequence.\n * @example ['async/sequence', ['call', 'validate'], ['call', 'save']]\n */\nexport type AsyncSequenceEffect = ['async/sequence', ...Effect[]];\n\n/**\n * Union of all typed effects.\n * Provides compile-time validation for common effect types.\n */\nexport type TypedEffect =\n | RenderUIEffect\n | NavigateEffect\n | EmitEffect\n | SetEffect\n | PersistEffect\n | CallServiceEffect\n | SpawnEffect\n | DespawnEffect\n | DoEffect\n | NotifyEffect\n | FetchEffect\n | IfEffect\n | WhenEffect\n | LetEffect\n | LogEffect\n | WaitEffect\n | RefEffect\n | DerefEffect\n | SwapEffect\n | WatchEffect\n | AtomicEffect\n | AsyncDelayEffect\n | AsyncDebounceEffect\n | AsyncThrottleEffect\n | AsyncIntervalEffect\n | AsyncRaceEffect\n | AsyncAllEffect\n | AsyncSequenceEffect\n | ForwardEffect\n | TrainEffect\n | EvaluateEffect\n | CheckpointSaveEffect\n | CheckpointLoadEffect;\n\n// ============================================================================\n// Effect Type (Strictly Typed)\n// ============================================================================\n\n/**\n * Effect type - typed S-expression format.\n *\n * Effects are strongly typed tuples that enforce:\n * - Valid effect operators (render-ui, emit, set, persist, navigate, call-service)\n * - Valid UISlots for render-ui\n * - Valid PatternTypes and props for render-ui\n * - Correct argument types for each effect\n *\n * Available typed effects:\n * - RenderUIEffect: ['render-ui', UISlot, PatternConfig]\n * - NavigateEffect: ['navigate', path] or ['navigate', path, params]\n * - EmitEffect: ['emit', eventName] or ['emit', eventName, payload]\n * - SetEffect: ['set', binding, value]\n * - PersistEffect: ['persist', operation, entity, data?]\n * - CallServiceEffect: ['call-service', serviceName, config]\n *\n * @example\n * [\"set\", \"@entity.health\", 100]\n * [\"emit\", \"PLAYER_DIED\", { \"playerId\": \"@entity.id\" }]\n * [\"render-ui\", \"main\", { \"patternType\": \"entity-table\", \"columns\": [\"name\"] }]\n * [\"call-service\", \"WeatherAPI\", { \"action\": \"getWeather\", \"onSuccess\": \"OK\" }]\n * [\"navigate\", \"/tasks\"]\n * [\"persist\", \"create\", \"Task\", { \"title\": \"@payload.title\" }]\n */\nexport type Effect = TypedEffect;\n\n/**\n * Schema for Effect - validates S-expression format\n */\nexport const EffectSchema = z.array(z.unknown()).min(1).refine(\n (arr) => typeof arr[0] === 'string',\n { message: 'Effect must be an S-expression with a string operator as first element' }\n);\n\nexport type EffectInput = z.input<typeof EffectSchema>;\n\n/**\n * Type guard to check if a value is a valid Effect (S-expression).\n * \n * Validates that a value conforms to the Effect structure. Effects are\n * represented as arrays where the first element is a string (effect type)\n * and subsequent elements are parameters. Used for runtime validation\n * of effect structures.\n * \n * @param {unknown} value - Value to check\n * @returns {boolean} True if value is a valid Effect, false otherwise\n * \n * @example\n * isEffect(['set', '@entity.health', 100]); // returns true\n * isEffect('not-an-effect'); // returns false\n * isEffect([]); // returns false\n */\nexport function isEffect(value: unknown): value is Effect {\n return Array.isArray(value) && value.length > 0 && typeof value[0] === 'string';\n}\n\n/**\n * Alias for isEffect (for clarity when working with S-expressions)\n */\nexport const isSExprEffect = isEffect;\n\n// ============================================================================\n// Effect Builder Helpers\n// ============================================================================\n\n/**\n * Creates a set effect for state updates.\n * \n * Generates an effect that sets a binding to a value. Used in state\n * machine transitions to update entity fields, UI state, or other\n * mutable data.\n * \n * @param {string} binding - Target binding (e.g., '@entity.health')\n * @param {SExpr} value - Value to set (can be literal or expression)\n * @returns {Effect} Set effect array\n * \n * @example\n * set('@entity.health', 100); // returns [\"set\", \"@entity.health\", 100]\n * set('@state.loading', false); // returns [\"set\", \"@state.loading\", false]\n */\nexport function set(binding: string, value: SExpr): Effect {\n return ['set', binding, value];\n}\n\n/**\n * Creates an emit effect for event dispatching.\n * \n * Generates an effect that emits an event with optional payload.\n * Used in state machine transitions to trigger events that can be\n * handled by other traits, services, or external systems.\n * \n * @param {string} event - Event name to emit\n * @param {Record<string, unknown>} [payload] - Optional event payload\n * @returns {Effect} Emit effect array\n * \n * @example\n * emit('PLAYER_DIED', { playerId: '@entity.id' }); // returns [\"emit\", \"PLAYER_DIED\", { playerId: \"@entity.id\" }]\n * emit('GAME_STARTED'); // returns [\"emit\", \"GAME_STARTED\"]\n */\nexport function emit(event: string, payload?: Record<string, unknown>): Effect {\n return payload ? ['emit', event, payload] : ['emit', event];\n}\n\n/**\n * Creates a navigation effect for page routing.\n * \n * Generates an effect that navigates to a specified path with optional\n * parameters. Used in state machine transitions to change pages or\n * update URL parameters.\n * \n * @param {string} path - Target path (e.g., '/tasks')\n * @param {Record<string, string>} [params] - Optional URL parameters\n * @returns {NavigateEffect} Navigation effect array\n * \n * @example\n * navigate('/tasks'); // returns [\"navigate\", \"/tasks\"]\n * navigate('/user', { id: '123' }); // returns [\"navigate\", \"/user\", { id: \"123\" }]\n */\nexport function navigate(path: string): NavigateEffect;\nexport function navigate(path: string, params: Record<string, string>): NavigateEffect;\nexport function navigate(path: string, params?: Record<string, string>): NavigateEffect {\n return params ? ['navigate', path, params] : ['navigate', path];\n}\n\n/**\n * Create a render-ui effect\n * @example [\"render-ui\", \"main\", { \"patternType\": \"entity-table\", \"columns\": [\"name\"] }]\n */\nexport function renderUI(\n target: UISlot,\n pattern: AnyPatternConfig\n): RenderUIEffect;\nexport function renderUI(\n target: UISlot,\n pattern: AnyPatternConfig,\n props: Record<string, unknown>\n): RenderUIEffect;\nexport function renderUI(\n target: UISlot,\n pattern: AnyPatternConfig,\n props?: Record<string, unknown>\n): RenderUIEffect {\n return props\n ? ['render-ui', target, pattern, props]\n : ['render-ui', target, pattern];\n}\n\n/**\n * Create a persist effect\n * @example [\"persist\", \"create\", \"Task\", { \"title\": \"@payload.title\" }]\n */\nexport function persist(\n action: 'create' | 'update',\n entity: string,\n data: Record<string, unknown>\n): PersistEffect;\nexport function persist(\n action: 'delete' | 'clear',\n entity: string,\n data?: Record<string, unknown>\n): PersistEffect;\nexport function persist(\n action: 'create' | 'update' | 'delete' | 'clear',\n entity: string,\n data?: Record<string, unknown>\n): PersistEffect {\n if (action === 'create' || action === 'update') {\n return ['persist', action, entity, data!] as PersistEffect;\n }\n return data\n ? ['persist', action, entity, data] as PersistEffect\n : ['persist', action, entity] as PersistEffect;\n}\n\n/**\n * Create a call-service effect\n * @example [\"call-service\", \"stripe\", { \"service\": \"stripe\", \"action\": \"charge\", \"onSuccess\": \"OK\", \"onError\": \"ERR\" }]\n */\nexport function callService(\n serviceName: string,\n config: CallServiceConfig\n): CallServiceEffect {\n return ['call-service', serviceName, config];\n}\n\n/**\n * Create a spawn effect (games)\n * @example [\"spawn\", \"Bullet\", { \"x\": \"@entity.x\", \"y\": \"@entity.y\" }]\n */\nexport function spawn(entity: string): SpawnEffect;\nexport function spawn(entity: string, initialState: Record<string, unknown>): SpawnEffect;\nexport function spawn(entity: string, initialState?: Record<string, unknown>): SpawnEffect {\n return initialState ? ['spawn', entity, initialState] : ['spawn', entity];\n}\n\n/**\n * Create a despawn effect (games)\n * @example [\"despawn\", \"@entity.id\"]\n */\nexport function despawn(entityId: string): DespawnEffect {\n return ['despawn', entityId];\n}\n\n/**\n * Create a do effect (multiple effects)\n * @example [\"do\", [\"set\", \"@entity.x\", 0], [\"set\", \"@entity.y\", 0]]\n */\nexport function doEffects(...effects: SExpr[]): DoEffect {\n return ['do', ...effects];\n}\n\n/**\n * Create a notify effect\n * @example [\"notify\", \"in_app\", \"Task created successfully\"]\n */\nexport function notify(\n channel: 'email' | 'push' | 'sms' | 'in_app',\n message: string\n): NotifyEffect;\nexport function notify(\n channel: 'email' | 'push' | 'sms' | 'in_app',\n message: string,\n recipient: string\n): NotifyEffect;\nexport function notify(\n channel: 'email' | 'push' | 'sms' | 'in_app',\n message: string,\n recipient?: string\n): NotifyEffect {\n return recipient\n ? ['notify', channel, message, recipient]\n : ['notify', channel, message];\n}\n\n/**\n * Fetch options for entity data retrieval\n */\nexport interface FetchOptions {\n /** Fetch a single entity by ID */\n id?: string;\n /** Filter expression (S-expression) */\n filter?: SExpr;\n /** Maximum number of entities to return */\n limit?: number;\n /** Number of entities to skip */\n offset?: number;\n /** Allow additional properties for flexibility */\n [key: string]: unknown;\n}\n\n/**\n * Create a fetch effect (server-side data retrieval)\n * @example [\"fetch\", \"User\"] - fetch all users\n * @example [\"fetch\", \"User\", { \"id\": \"@payload.userId\" }] - fetch by ID\n * @example [\"fetch\", \"User\", { \"filter\": [\"=\", \"@entity.status\", \"active\"], \"limit\": 10 }]\n */\nexport function fetch(entity: string): FetchEffect;\nexport function fetch(entity: string, options: FetchOptions): FetchEffect;\nexport function fetch(entity: string, options?: FetchOptions): FetchEffect {\n return options ? ['fetch', entity, options as Record<string, unknown>] : ['fetch', entity];\n}\n\n// ============================================================================\n// Resource Effect Builder Helpers\n// ============================================================================\n\n/**\n * Create a ref effect (reactive entity subscription).\n *\n * @param {string} binding - Binding or entity name to subscribe to\n * @param {Record<string, unknown>} [selector] - Optional selector for specific entity\n * @returns {RefEffect} Ref effect array\n *\n * @example\n * ref('@entity.health'); // returns [\"ref\", \"@entity.health\"]\n * ref('User', { id: '@payload.userId' }); // returns [\"ref\", \"User\", { id: \"@payload.userId\" }]\n */\nexport function ref(binding: string): RefEffect;\nexport function ref(binding: string, selector: Record<string, unknown>): RefEffect;\nexport function ref(binding: string, selector?: Record<string, unknown>): RefEffect {\n return selector ? ['ref', binding, selector] : ['ref', binding];\n}\n\n/**\n * Create a deref effect (snapshot read).\n *\n * @param {string} binding - Binding or entity name to read\n * @param {Record<string, unknown>} [selector] - Optional selector for specific entity\n * @returns {DerefEffect} Deref effect array\n *\n * @example\n * deref('@entity.health'); // returns [\"deref\", \"@entity.health\"]\n * deref('User', { id: '@payload.userId' }); // returns [\"deref\", \"User\", { id: \"@payload.userId\" }]\n */\nexport function deref(binding: string): DerefEffect;\nexport function deref(binding: string, selector: Record<string, unknown>): DerefEffect;\nexport function deref(binding: string, selector?: Record<string, unknown>): DerefEffect {\n return selector ? ['deref', binding, selector] : ['deref', binding];\n}\n\n/**\n * Create a swap! effect (atomic compare-and-swap).\n *\n * @param {string} binding - Binding to atomically update\n * @param {SExpr} transform - Transformation expression applied to the current value\n * @returns {SwapEffect} Swap effect array\n *\n * @example\n * swap('@entity.counter', ['+', '@entity.counter', 1]);\n * // returns [\"swap!\", \"@entity.counter\", [\"+\", \"@entity.counter\", 1]]\n */\nexport function swap(binding: string, transform: SExpr): SwapEffect {\n return ['swap!', binding, transform];\n}\n\n/**\n * Options for watch effect\n */\nexport interface WatchOptions {\n /** Debounce duration in milliseconds */\n debounce?: number;\n /** Allow additional properties */\n [key: string]: unknown;\n}\n\n/**\n * Create a watch effect (entity change callback).\n *\n * @param {string} binding - Binding to watch for changes\n * @param {string} event - Event name to emit on change\n * @param {WatchOptions} [options] - Optional watch configuration\n * @returns {WatchEffect} Watch effect array\n *\n * @example\n * watch('@entity.health', 'HEALTH_CHANGED');\n * // returns [\"watch\", \"@entity.health\", \"HEALTH_CHANGED\"]\n *\n * watch('@entity.status', 'STATUS_UPDATED', { debounce: 100 });\n * // returns [\"watch\", \"@entity.status\", \"STATUS_UPDATED\", { debounce: 100 }]\n */\nexport function watch(binding: string, event: string): WatchEffect;\nexport function watch(binding: string, event: string, options: WatchOptions): WatchEffect;\nexport function watch(binding: string, event: string, options?: WatchOptions): WatchEffect {\n return options\n ? ['watch', binding, event, options as Record<string, unknown>]\n : ['watch', binding, event];\n}\n\n/**\n * Create an atomic effect (transaction group).\n *\n * @param {...SExpr[]} effects - Effects to execute atomically\n * @returns {AtomicEffect} Atomic effect array\n *\n * @example\n * atomic(['set', '@entity.x', 10], ['set', '@entity.y', 20]);\n * // returns [\"atomic\", [\"set\", \"@entity.x\", 10], [\"set\", \"@entity.y\", 20]]\n */\nexport function atomic(...effects: SExpr[]): AtomicEffect {\n return ['atomic', ...effects];\n}\n\n","/**\n * S-Expression Types\n *\n * Defines the S-Expression type system for guards, effects, and computed values.\n * S-expressions are JSON arrays where the first element is an operator string.\n *\n * @example\n * // Guard: health > 0\n * [\">\", \"@entity.health\", 0]\n *\n * // Effect: set x to x + vx\n * [\"set\", \"@entity.x\", [\"+\", \"@entity.x\", \"@entity.vx\"]]\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\n\n// ============================================================================\n// S-Expression Type\n// ============================================================================\n\n/**\n * S-Expression type - recursive structure representing expressions.\n *\n * An S-expression is either:\n * - A literal value (string, number, boolean, null)\n * - An object literal (for payload data, props, etc.)\n * - A binding reference (string starting with @)\n * - A call expression (array with operator as first element)\n */\nexport type SExprAtom = string | number | boolean | null | Record<string, unknown>;\nexport type SExpr = SExprAtom | SExpr[];\n\n/**\n * Expression type - S-expressions only.\n * Used for guards, computed values, and effect expressions.\n *\n * NOTE: Legacy string format is no longer supported.\n * All expressions must be S-expression arrays.\n */\nexport type Expression = SExpr;\n\n// ============================================================================\n// S-Expression Schema (Zod)\n// ============================================================================\n\n/**\n * Schema for atomic S-expression values (non-array)\n * Includes objects for payload data, props, etc.\n */\nexport const SExprAtomSchema: z.ZodType<SExprAtom> = z.union([\n z.string(),\n z.number(),\n z.boolean(),\n z.null(),\n z.record(z.unknown()), // Objects for payload data\n]);\n\n/**\n * Recursive schema for S-expressions.\n * Validates that arrays have at least one element and first element is a string (operator).\n */\nexport const SExprSchema: z.ZodType<SExpr> = z.lazy(() =>\n z.union([\n SExprAtomSchema,\n z\n .array(z.lazy(() => SExprSchema))\n .min(1)\n .refine(\n (arr) => typeof arr[0] === 'string',\n { message: 'S-expression array must have a string operator as first element' }\n ),\n ])\n);\n\n/**\n * Schema for Expression type - S-expressions only.\n * S-expressions are arrays with operator as first element.\n *\n * NOTE: Legacy string format is no longer supported.\n */\nexport const ExpressionSchema: z.ZodType<Expression> = SExprSchema;\n\n// ============================================================================\n// Type Guards\n// ============================================================================\n\n/**\n * Type guard for S-expression detection.\n * 100% reliable - structural check, no regex or keyword matching.\n *\n * @param value - Value to check\n * @returns true if value is an S-expression (array with string operator)\n */\nexport function isSExpr(value: unknown): value is SExpr[] {\n return (\n Array.isArray(value) &&\n value.length > 0 &&\n typeof value[0] === 'string'\n );\n}\n\n/**\n * Type guard for S-expression atoms (non-array values).\n * \n * Validates that a value is an S-expression atom (literal value).\n * Includes null, strings, numbers, booleans, and objects. Used to\n * distinguish atomic values from S-expression calls (arrays).\n * \n * @param {unknown} value - Value to check\n * @returns {boolean} True if value is an S-expression atom, false otherwise\n * \n * @example\n * isSExprAtom('hello'); // returns true\n * isSExprAtom(42); // returns true\n * isSExprAtom(null); // returns true\n * isSExprAtom({ key: 'value' }); // returns true\n * isSExprAtom(['+', 1, 2]); // returns false\n */\nexport function isSExprAtom(value: unknown): value is SExprAtom {\n if (value === null) return true;\n if (Array.isArray(value)) return false;\n const type = typeof value;\n return type === 'string' || type === 'number' || type === 'boolean' || type === 'object';\n}\n\n/**\n * Checks if a value is a binding reference.\n * \n * Validates that a string is a binding reference (starts with @).\n * Bindings reference runtime values like @entity.health, @payload.amount, @now.\n * Used for identifying bindings in S-expressions and validation.\n * \n * @param {unknown} value - Value to check\n * @returns {boolean} True if value is a binding reference, false otherwise\n * \n * @example\n * isBinding('@entity.health'); // returns true\n * isBinding('@payload.amount'); // returns true\n * isBinding('not-a-binding'); // returns false\n * isBinding(123); // returns false\n */\nexport function isBinding(value: unknown): value is string {\n return typeof value === 'string' && value.startsWith('@');\n}\n\n/**\n * Checks if a value is a valid S-expression call (array with operator).\n * \n * Alias for isSExpr() - validates S-expression call structure.\n * Used to distinguish between S-expression calls and atom values.\n * \n * @param {unknown} value - Value to check\n * @returns {boolean} True if value is a valid S-expression call, false otherwise\n * \n * @example\n * isSExprCall(['+', 1, 2]); // returns true\n * isSExprCall(['set', '@entity.health', 100]); // returns true\n * isSExprCall('not-a-call'); // returns false\n */\nexport function isSExprCall(value: unknown): value is SExpr[] {\n return isSExpr(value);\n}\n\n// ============================================================================\n// Binding Parsing\n// ============================================================================\n\n/**\n * Parsed binding reference\n */\nexport interface ParsedBinding {\n /** Type of binding: core (@entity, @payload, @state, @now) or entity (@EntityName) */\n type: 'core' | 'entity';\n /** The root binding name (entity, payload, state, now, or EntityName) */\n root: string;\n /** Path segments after the root (e.g., ['health'] for @entity.health) */\n path: string[];\n /** Full original binding string */\n original: string;\n}\n\n/**\n * Core bindings that are always available.\n * Phase 4.5 adds: config, computed, trait (for behavior support)\n */\nexport const CORE_BINDINGS = ['entity', 'payload', 'state', 'now', 'config', 'computed', 'trait'] as const;\nexport type CoreBinding = (typeof CORE_BINDINGS)[number];\n\n/**\n * Parses a binding reference into its components.\n * \n * Deconstructs a binding string (e.g., '@entity.health') into its constituent\n * parts: type, root, path, and original string. Does NOT use regex - uses\n * structured string operations for reliability and maintainability.\n * \n * @param {string} binding - Binding string starting with @\n * @returns {ParsedBinding | null} Parsed binding object or null if invalid\n * \n * @example\n * parseBinding('@entity.health'); // returns { type: 'core', root: 'entity', path: ['health'], original: '@entity.health' }\n * parseBinding('@User.name'); // returns { type: 'entity', root: 'User', path: ['name'], original: '@User.name' }\n * parseBinding('not-a-binding'); // returns null\n */\nexport function parseBinding(binding: string): ParsedBinding | null {\n if (!binding.startsWith('@')) {\n return null;\n }\n\n // Remove @ prefix\n const withoutPrefix = binding.slice(1);\n\n // Split by dots\n const parts = withoutPrefix.split('.');\n\n if (parts.length === 0 || parts[0] === '') {\n return null;\n }\n\n const root = parts[0];\n const path = parts.slice(1);\n\n // Determine if core binding or entity reference\n const isCore = (CORE_BINDINGS as readonly string[]).includes(root);\n\n return {\n type: isCore ? 'core' : 'entity',\n root,\n path,\n original: binding,\n };\n}\n\n/**\n * Validate a binding reference format.\n *\n * @param binding - Binding string to validate\n * @returns true if valid binding format\n */\nexport function isValidBinding(binding: string): boolean {\n const parsed = parseBinding(binding);\n if (!parsed) return false;\n\n // Core bindings: @entity, @payload, @state, @now (optionally with path)\n // @state and @now don't have paths\n if (parsed.type === 'core') {\n if (parsed.root === 'state' || parsed.root === 'now') {\n return parsed.path.length === 0;\n }\n // @entity and @payload can have paths\n return true;\n }\n\n // Entity bindings: @EntityName.field - must have at least one path segment\n return parsed.path.length > 0;\n}\n\n// ============================================================================\n// S-Expression Utilities\n// ============================================================================\n\n/**\n * Get the operator from an S-expression call.\n *\n * @param expr - S-expression array\n * @returns The operator string or null if not a valid call\n */\nexport function getOperator(expr: SExpr): string | null {\n if (!isSExpr(expr)) return null;\n return expr[0] as string;\n}\n\n/**\n * Get the arguments from an S-expression call.\n *\n * @param expr - S-expression array\n * @returns Array of arguments (empty if not a valid call)\n */\nexport function getArgs(expr: SExpr): SExpr[] {\n if (!isSExpr(expr)) return [];\n return expr.slice(1);\n}\n\n/**\n * Create an S-expression call.\n *\n * @param operator - The operator string\n * @param args - Arguments to the operator\n * @returns S-expression array\n */\nexport function sexpr(operator: string, ...args: SExpr[]): SExpr[] {\n return [operator, ...args];\n}\n\n/**\n * Walk an S-expression tree and apply a visitor function to each node.\n *\n * @param expr - S-expression to walk\n * @param visitor - Function to call on each node\n */\nexport function walkSExpr(\n expr: SExpr,\n visitor: (node: SExpr, parent: SExpr[] | null, index: number) => void,\n parent: SExpr[] | null = null,\n index: number = 0\n): void {\n visitor(expr, parent, index);\n\n if (isSExpr(expr)) {\n for (let i = 0; i < expr.length; i++) {\n walkSExpr(expr[i], visitor, expr, i);\n }\n }\n}\n\n/**\n * Collect all bindings referenced in an S-expression.\n *\n * @param expr - S-expression to analyze\n * @returns Array of binding strings found\n */\nexport function collectBindings(expr: SExpr): string[] {\n const bindings: string[] = [];\n\n walkSExpr(expr, (node) => {\n if (isBinding(node)) {\n bindings.push(node);\n }\n });\n\n return bindings;\n}\n\n// ============================================================================\n// Type Exports\n// ============================================================================\n\nexport type SExprInput = z.input<typeof SExprSchema>;\nexport type ExpressionInput = z.input<typeof ExpressionSchema>;\n","/**\n * State Machine Types (Self-Contained)\n *\n * Defines state machine types for traits.\n * Copied from schema/state-machine.ts to make orbitals/ self-contained.\n *\n * @packageDocumentation\n */\n\nimport { z } from \"zod\";\nimport type { Effect } from \"./effect.js\";\nimport { EffectSchema } from \"./effect.js\";\nimport type { Expression } from \"./expression.js\";\nimport { ExpressionSchema } from \"./expression.js\";\n\n// ============================================================================\n// State\n// ============================================================================\n\n/**\n * Represents a state in the state machine\n */\nexport interface State {\n /** State name (unique identifier) */\n name: string;\n /** Whether this is the initial state */\n isInitial?: boolean;\n /** Whether this is a terminal state (no outgoing transitions expected) */\n isTerminal?: boolean;\n /** Whether this is a final state (legacy alias for isTerminal) */\n isFinal?: boolean;\n /** Human-readable description */\n description?: string;\n /** Effect names to run on entry */\n onEntry?: string[];\n /** Effect names to run on exit */\n onExit?: string[];\n}\n\nexport const StateSchema = z.object({\n name: z.string().min(1, \"State name is required\"),\n isInitial: z.boolean().optional(),\n isTerminal: z.boolean().optional(),\n isFinal: z.boolean().optional(),\n description: z.string().optional(),\n onEntry: z.array(z.string()).optional(),\n onExit: z.array(z.string()).optional(),\n});\n\n// ============================================================================\n// Event\n// ============================================================================\n\n/**\n * Payload field definition for events\n */\nexport interface PayloadField {\n name: string;\n type: \"string\" | \"number\" | \"boolean\" | \"object\" | \"array\";\n required?: boolean;\n}\n\nexport const PayloadFieldSchema = z.object({\n name: z.string().min(1),\n type: z.enum([\"string\", \"number\", \"boolean\", \"object\", \"array\"]),\n required: z.boolean().optional(),\n});\n\n/**\n * Represents an event that can trigger transitions\n */\nexport interface Event {\n /** Event key (UPPER_SNAKE_CASE) */\n key: string;\n /** Human-readable name */\n name: string;\n /** Description */\n description?: string;\n /** Expected payload structure */\n payloadSchema?: PayloadField[];\n /** Domain vs System classification (optional, for analysis) */\n classification?: \"domain\" | \"system\";\n /** Semantic role of this event (optional, for analysis) */\n semanticRole?: string;\n}\n\nexport const EventSchema = z.object({\n key: z.string().min(1, \"Event key is required\"),\n name: z.string().min(1, \"Event name is required\"),\n description: z.string().optional(),\n payloadSchema: z.array(PayloadFieldSchema).optional(),\n classification: z.enum([\"domain\", \"system\"]).optional(),\n semanticRole: z.string().optional(),\n});\n\n// ============================================================================\n// Guard\n// ============================================================================\n\n/**\n * Represents a named guard condition.\n * Expression must be an S-expression.\n *\n * @example\n * {\n * name: \"hasHealth\",\n * expression: [\">\", \"@entity.health\", 0],\n * description: \"Check if entity has health remaining\"\n * }\n */\nexport interface Guard {\n name: string;\n /** Guard expression - S-expression array only */\n expression: Expression;\n description?: string;\n}\n\nexport const GuardSchema = z.object({\n name: z.string().min(1, \"Guard name is required\"),\n expression: ExpressionSchema,\n description: z.string().optional(),\n});\n\n// ============================================================================\n// Transition (Effect imported separately to avoid circular deps)\n// ============================================================================\n\n/**\n * Represents a transition between states.\n * Guards and effects must be S-expressions.\n *\n * @example\n * {\n * from: \"idle\",\n * to: \"running\",\n * event: \"START\",\n * guard: [\">\", \"@entity.fuel\", 0],\n * effects: [\n * [\"set\", \"@entity.status\", \"running\"],\n * [\"emit\", \"ENGINE_STARTED\"]\n * ]\n * }\n */\nexport interface Transition {\n /** Source state name */\n from: string;\n /** Target state name */\n to: string;\n /** Event key that triggers this transition */\n event: string;\n /** Guard expression - S-expression array */\n guard?: Expression | null;\n /** Effects to execute - S-expression arrays */\n effects?: Effect[];\n /** Description */\n description?: string | null;\n}\n\nexport const TransitionSchema = z.object({\n from: z.string().min(1, \"Transition source state is required\"),\n to: z.string().min(1, \"Transition target state is required\"),\n event: z.string().min(1, \"Transition event is required\"),\n guard: ExpressionSchema.nullish(),\n effects: z.array(EffectSchema).optional(),\n description: z.string().nullish(),\n});\n\n// ============================================================================\n// State Machine\n// ============================================================================\n\n/**\n * Complete state machine definition\n */\nexport interface StateMachine {\n /** All states in the machine */\n states: State[];\n /** All events that can be triggered */\n events: Event[];\n /** All transitions between states */\n transitions: Transition[];\n /** Named guard definitions */\n guards?: Guard[];\n}\n\nexport const StateMachineSchema = z.object({\n states: z.array(StateSchema).min(1, \"At least one state is required\"),\n events: z.array(EventSchema),\n transitions: z.array(TransitionSchema),\n guards: z.array(GuardSchema).optional(),\n});\n\n// ============================================================================\n// Type exports\n// ============================================================================\n\nexport type StateInput = z.input<typeof StateSchema>;\nexport type EventInput = z.input<typeof EventSchema>;\nexport type GuardInput = z.input<typeof GuardSchema>;\nexport type TransitionInput = z.input<typeof TransitionSchema>;\nexport type StateMachineInput = z.input<typeof StateMachineSchema>;\n\n// ============================================================================\n// Event Utilities\n// ============================================================================\n\n/**\n * Check if an event is a circuit event (not internal/system event).\n * Circuit events are user-defined events that participate in the closed circuit pattern.\n * Internal/system events start with underscore (e.g., _INIT, _TICK, _TIMER).\n *\n * @param {string} event - Event name to check\n * @returns {boolean} true if event is a circuit event (doesn't start with underscore)\n *\n * @example\n * isCircuitEvent('CREATE') // true\n * isCircuitEvent('SAVE') // true\n * isCircuitEvent('_INIT') // false (internal)\n * isCircuitEvent('_TICK') // false (internal)\n */\nexport function isCircuitEvent(event: string): boolean {\n return !event.startsWith('_');\n}\n","/**\n * Trait Types (Self-Contained)\n *\n * Defines trait types for behavioral patterns.\n * Self-contained - imports only from local orbital types.\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\nimport type { StateMachine } from './state-machine.js';\nimport { StateMachineSchema } from './state-machine.js';\nimport type { Effect } from './effect.js';\nimport { EffectSchema } from './effect.js';\nimport type { Expression } from './expression.js';\nimport { ExpressionSchema } from './expression.js';\n\n// ============================================================================\n// Trait Categories\n// ============================================================================\n\n/**\n * Categories for organizing traits\n */\nexport type TraitCategory =\n | 'lifecycle'\n | 'temporal'\n | 'validation'\n | 'notification'\n | 'integration'\n | 'interaction'\n | 'game-core'\n | 'game-character'\n | 'game-ai'\n | 'game-combat'\n | 'game-items'\n | 'game-cards'\n | 'game-board'\n | 'game-puzzle';\n\nexport const TraitCategorySchema = z.enum([\n 'lifecycle',\n 'temporal',\n 'validation',\n 'notification',\n 'integration',\n 'interaction',\n 'game-core',\n 'game-character',\n 'game-ai',\n 'game-combat',\n 'game-items',\n 'game-cards',\n 'game-board',\n 'game-puzzle',\n]);\n\n// ============================================================================\n// Trait Entity Field (simplified)\n// ============================================================================\n\n/**\n * Field types for trait data entities\n */\nexport type TraitFieldType = 'string' | 'number' | 'boolean' | 'date' | 'array' | 'object' | 'timestamp' | 'datetime' | 'enum';\n\n/**\n * Simplified field for trait data entities\n */\nexport interface TraitEntityField {\n name: string;\n type: TraitFieldType;\n required?: boolean;\n default?: unknown;\n values?: string[];\n}\n\nexport const TraitEntityFieldSchema = z.object({\n name: z.string().min(1),\n type: z.enum([\n 'string',\n 'number',\n 'boolean',\n 'date',\n 'array',\n 'object',\n 'timestamp',\n 'datetime',\n 'enum',\n ]),\n required: z.boolean().optional(),\n default: z.unknown().optional(),\n values: z.array(z.string()).optional(),\n});\n\n// ============================================================================\n// Trait Data Entity\n// ============================================================================\n\n/**\n * Simplified data entity for traits\n */\nexport interface TraitDataEntity {\n name: string;\n collection?: string;\n fields: TraitEntityField[];\n timestamps?: boolean;\n description?: string;\n runtime?: boolean;\n singleton?: boolean;\n pages?: string[];\n}\n\nexport const TraitDataEntitySchema = z.object({\n name: z.string().min(1),\n collection: z.string().optional(),\n fields: z.array(TraitEntityFieldSchema).min(1),\n timestamps: z.boolean().optional(),\n description: z.string().optional(),\n runtime: z.boolean().optional(),\n singleton: z.boolean().optional(),\n pages: z.array(z.string()).optional(),\n});\n\n// ============================================================================\n// Trait Tick\n// ============================================================================\n\n/**\n * Tick rule for traits.\n * Guards can be legacy strings or S-expressions.\n * Effects can be typed Effect objects or S-expressions.\n */\nexport interface TraitTick {\n name: string;\n description?: string;\n priority?: number;\n interval: string | number;\n appliesTo?: string[];\n pages?: string[];\n /** Guard expression - string (legacy) or S-expression array */\n guard?: Expression;\n /** Effects to execute (S-expressions) */\n effects: Effect[];\n /**\n * Events this tick emits.\n * Must reference events defined in trait's emits array.\n * Used for validation and documentation.\n */\n emits?: string[];\n}\n\nexport const TraitTickSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n priority: z.number().optional(),\n interval: z.union([z.literal('frame'), z.number().positive()]),\n appliesTo: z.array(z.string()).optional(),\n pages: z.array(z.string()).optional(),\n guard: ExpressionSchema.optional(),\n effects: z.array(EffectSchema).min(1),\n emits: z.array(z.string()).optional(),\n});\n\n// ============================================================================\n// Event Scope\n// ============================================================================\n\n/**\n * Event scope determines visibility:\n * - 'internal': Trait-to-trait within same orbital (default)\n * - 'external': Exposed for cross-orbital communication\n */\nexport type EventScope = 'internal' | 'external';\n\nexport const EventScopeSchema = z.enum(['internal', 'external']);\n\n// ============================================================================\n// Event Payload Field\n// ============================================================================\n\n/**\n * Payload field definition for events.\n * Defines the structure of data carried by events.\n */\nexport interface EventPayloadField {\n /** Field name */\n name: string;\n /** Field type */\n type: 'string' | 'number' | 'boolean' | 'object' | 'array' | 'entity';\n /** Whether field is required in payload */\n required?: boolean;\n /** Human-readable description */\n description?: string;\n /** For 'entity' type: the entity type name */\n entityType?: string;\n}\n\nexport const EventPayloadFieldSchema = z.object({\n name: z.string().min(1),\n type: z.enum(['string', 'number', 'boolean', 'object', 'array', 'entity']),\n required: z.boolean().optional(),\n description: z.string().optional(),\n entityType: z.string().optional(),\n});\n\n// ============================================================================\n// Trait Event Contract\n// ============================================================================\n\n/**\n * Event contract for events a trait emits.\n * Declares the event name, scope, and payload schema.\n */\nexport interface TraitEventContract {\n /** Event name (UPPER_SNAKE_CASE) */\n event: string;\n /** Human-readable description */\n description?: string;\n /** Payload schema - what data this event carries */\n payload?: EventPayloadField[];\n /**\n * Event scope:\n * - 'internal': Trait-to-trait within same orbital (default)\n * - 'external': Exposed for cross-orbital communication\n */\n scope?: EventScope;\n}\n\nexport const TraitEventContractSchema = z.object({\n event: z.string().min(1).regex(\n /^[A-Z][A-Z0-9_]*$/,\n 'Event name must be UPPER_SNAKE_CASE'\n ),\n description: z.string().optional(),\n payload: z.array(EventPayloadFieldSchema).optional(),\n scope: EventScopeSchema.optional(),\n});\n\n// ============================================================================\n// Trait Event Listener\n// ============================================================================\n\n/**\n * Event listener for trait communication.\n * Guards can be legacy strings or S-expressions.\n * Enhanced with scope and payloadMapping for cross-orbital communication.\n */\nexport interface TraitEventListener {\n /** Event key to listen for (may be namespaced: TraitName.EVENT_NAME) */\n event: string;\n /** State machine event to trigger */\n triggers: string;\n /** Guard expression - string (legacy) or S-expression array */\n guard?: Expression;\n /**\n * Listener scope:\n * - 'internal': Listen to events within same orbital (default)\n * - 'external': Listen to events from other orbitals\n */\n scope?: EventScope;\n /** Map event payload fields to transition payload */\n payloadMapping?: Record<string, string>;\n}\n\nexport const TraitEventListenerSchema = z.object({\n event: z.string().min(1),\n triggers: z.string().min(1),\n guard: ExpressionSchema.optional(),\n scope: EventScopeSchema.optional(),\n payloadMapping: z.record(z.string()).optional(),\n});\n\n// ============================================================================\n// Required Field\n// ============================================================================\n\n/**\n * Field required by a trait from its linkedEntity\n */\nexport interface RequiredField {\n name: string;\n type: 'string' | 'number' | 'boolean' | 'date' | 'array' | 'object' | 'timestamp' | 'datetime' | 'enum';\n description?: string;\n}\n\nexport const RequiredFieldSchema = z.object({\n name: z.string().min(1),\n type: z.enum(['string', 'number', 'boolean', 'date', 'array', 'object', 'timestamp', 'datetime', 'enum']),\n description: z.string().optional(),\n});\n\n// ============================================================================\n// Trait Reference\n// ============================================================================\n\n/**\n * Reference to a trait from an entity or page\n */\nexport interface TraitReference {\n ref: string;\n linkedEntity?: string;\n config?: Record<string, Record<string, unknown>>;\n appliesTo?: string[];\n}\n\nexport const TraitReferenceSchema = z.object({\n ref: z.string().min(1),\n linkedEntity: z.string().optional(),\n config: z.record(z.record(z.unknown())).optional(),\n appliesTo: z.array(z.string()).optional(),\n});\n\n/**\n * Simplified trait reference - supports string, reference object, or inline Trait definition\n * - string: \"TraitName\" - reference to a trait by name\n * - { ref: \"TraitName\" }: reference object with optional config\n * - { name: \"TraitName\", stateMachine: {...} }: inline trait definition\n */\nexport type TraitRef = string | { ref: string; config?: Record<string, unknown>; linkedEntity?: string } | Trait;\n\n// TraitRefSchema is defined after TraitSchema (see below) to avoid forward reference\n\n// ============================================================================\n// Trait UI Binding\n// ============================================================================\n\nexport type PresentationType = 'modal' | 'drawer' | 'popover' | 'inline' | 'confirm-dialog';\n\nexport interface TraitUIBinding {\n [stateName: string]: {\n presentation: PresentationType;\n content: Record<string, unknown> | Record<string, unknown>[];\n props?: {\n size?: 'sm' | 'md' | 'lg' | 'xl' | 'full';\n position?: 'left' | 'right' | 'top' | 'bottom' | 'center';\n title?: string;\n closable?: boolean;\n width?: string;\n showProgress?: boolean;\n step?: number;\n totalSteps?: number;\n };\n };\n}\n\n// ============================================================================\n// Trait Definition\n// ============================================================================\n\n/**\n * A Trait is a reusable behavioral module with state machine.\n *\n * Traits declare their event contracts via `emits` and `listens`:\n * - `emits`: Events this trait can emit (with scope and payload schema)\n * - `listens`: Events this trait listens for (with optional payloadMapping)\n */\nexport interface Trait {\n name: string;\n description?: string;\n description_visual_prompt?: string;\n category?: TraitCategory;\n /**\n * The entity this trait is linked to.\n * Required for inline trait definitions within an orbital.\n */\n linkedEntity?: string;\n requiredFields?: RequiredField[];\n dataEntities?: TraitDataEntity[];\n stateMachine?: StateMachine;\n initialEffects?: Effect[];\n ticks?: TraitTick[];\n /**\n * Events this trait emits.\n * Each event can be scoped as internal or external.\n * External events are namespaced at orbital level (TraitName.EVENT_NAME).\n */\n emits?: TraitEventContract[];\n /**\n * Events this trait listens for.\n * External listeners reference namespaced events (TraitName.EVENT_NAME).\n */\n listens?: TraitEventListener[];\n ui?: TraitUIBinding;\n}\n\nexport const TraitSchema = z.object({\n name: z.string().min(1),\n description: z.string().optional(),\n description_visual_prompt: z.string().optional(),\n category: TraitCategorySchema.optional(),\n linkedEntity: z.string().optional(),\n requiredFields: z.array(RequiredFieldSchema).optional(),\n dataEntities: z.array(TraitDataEntitySchema).optional(),\n stateMachine: StateMachineSchema.optional(),\n initialEffects: z.array(EffectSchema).optional(),\n ticks: z.array(TraitTickSchema).optional(),\n emits: z.array(TraitEventContractSchema).optional(),\n listens: z.array(TraitEventListenerSchema).optional(),\n ui: z.record(z.unknown()).optional(),\n});\n\n// TraitRefSchema defined here after TraitSchema to avoid forward reference\nexport const TraitRefSchema = z.union([\n z.string().min(1),\n z.object({\n ref: z.string().min(1),\n config: z.record(z.unknown()).optional(),\n linkedEntity: z.string().optional(),\n }),\n TraitSchema, // Allow inline trait definitions\n]);\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Check if a trait ref is an inline Trait definition\n */\n/**\n * Checks if a trait reference is an inline trait definition.\n * \n * Type guard to determine if a TraitRef is an inline trait object\n * (with 'name' property) rather than a string reference or object reference.\n * \n * @param {TraitRef} traitRef - Trait reference to check\n * @returns {boolean} True if traitRef is an inline trait, false otherwise\n * \n * @example\n * isInlineTrait({ name: 'MyTrait' }); // returns true (inline)\n * isInlineTrait('MyTrait'); // returns false (string reference)\n * isInlineTrait({ ref: 'MyTrait' }); // returns false (object reference)\n */\nexport function isInlineTrait(traitRef: TraitRef): traitRef is Trait {\n return typeof traitRef === 'object' && 'name' in traitRef && !('ref' in traitRef);\n}\n\n/**\n * Extracts the trait name from a trait reference.\n * \n * Handles all trait reference formats (string, inline object, object reference)\n * and returns the canonical trait name.\n * \n * @param {TraitRef} traitRef - Trait reference to extract name from\n * @returns {string} Trait name\n * \n * @example\n * getTraitName('MyTrait'); // returns 'MyTrait'\n * getTraitName({ name: 'MyTrait' }); // returns 'MyTrait'\n * getTraitName({ ref: 'MyTrait' }); // returns 'MyTrait'\n */\nexport function getTraitName(traitRef: TraitRef): string {\n if (typeof traitRef === 'string') {\n return traitRef;\n }\n if (isInlineTrait(traitRef)) {\n return traitRef.name;\n }\n return traitRef.ref;\n}\n\n/**\n * Extracts the configuration from a trait reference.\n * \n * Returns the configuration object for trait references that support it\n * (object references with 'config' property). Returns undefined for\n * string references and inline traits.\n * \n * @param {TraitRef} traitRef - Trait reference to extract config from\n * @returns {Record<string, unknown> | undefined} Trait configuration or undefined\n * \n * @example\n * getTraitConfig('MyTrait'); // returns undefined\n * getTraitConfig({ name: 'MyTrait' }); // returns undefined\n * getTraitConfig({ ref: 'MyTrait', config: { option: 'value' } }); // returns config object\n */\nexport function getTraitConfig(traitRef: TraitRef): Record<string, unknown> | undefined {\n if (typeof traitRef === 'string') {\n return undefined;\n }\n if (isInlineTrait(traitRef)) {\n return undefined; // Inline traits don't have config\n }\n return traitRef.config;\n}\n\n/**\n * Normalizes a trait reference to object form.\n * \n * Converts any trait reference format (string, inline, object) to a\n * standardized object format with 'ref' and optional 'config' properties.\n * \n * @param {TraitRef} traitRef - Trait reference to normalize\n * @returns {{ ref: string; config?: Record<string, unknown> }} Normalized trait reference\n * \n * @example\n * normalizeTraitRef('MyTrait'); // returns { ref: 'MyTrait' }\n * normalizeTraitRef({ name: 'MyTrait' }); // returns { ref: 'MyTrait' }\n * normalizeTraitRef({ ref: 'MyTrait', config: {...} }); // returns original\n */\nexport function normalizeTraitRef(traitRef: TraitRef): { ref: string; config?: Record<string, unknown> } {\n if (typeof traitRef === 'string') {\n return { ref: traitRef };\n }\n if (isInlineTrait(traitRef)) {\n return { ref: traitRef.name };\n }\n return traitRef;\n}\n\n// ============================================================================\n// Type exports\n// ============================================================================\n\nexport type TraitInput = z.input<typeof TraitSchema>;\nexport type TraitReferenceInput = z.input<typeof TraitReferenceSchema>;\n\n// Backward compatibility aliases\nexport type OrbitalTraitRef = TraitRef;\nexport const OrbitalTraitRefSchema = TraitRefSchema;\n","/**\n * Event Wiring\n *\n * Applies cross-orbital event wiring to orbital definitions.\n * Adds emits/listens declarations to traits so they can communicate\n * across orbital boundaries.\n *\n * @packageDocumentation\n */\n\nimport type { OrbitalDefinition } from '../types/orbital.js';\nimport type { Trait, TraitEventContract, TraitEventListener } from '../types/trait.js';\nimport { isInlineTrait } from '../types/trait.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * A single event wiring entry connecting two traits across orbitals.\n */\nexport interface EventWiringEntry {\n /** Source trait name or orbital name */\n from: string;\n /** Event name (UPPER_SNAKE_CASE) */\n event: string;\n /** Target trait name or orbital name */\n to: string;\n /** Event to trigger on the listener side */\n triggers: string;\n}\n\n// ============================================================================\n// Helpers\n// ============================================================================\n\n/**\n * Find a trait by name across all orbitals.\n * Only inline traits can be mutated; string/ref traits are skipped.\n * Returns the inline Trait object if found, or null.\n */\nfunction findInlineTrait(\n orbitals: OrbitalDefinition[],\n name: string,\n): Trait | null {\n for (const orbital of orbitals) {\n for (const traitRef of orbital.traits) {\n if (isInlineTrait(traitRef) && traitRef.name === name) {\n return traitRef;\n }\n }\n }\n return null;\n}\n\n/**\n * Check if an emit already exists in the list.\n * @internal\n */\nfunction hasEmit(emits: TraitEventContract[], event: string): boolean {\n return emits.some((e) => e.event === event);\n}\n\n/**\n * Check if a listen already exists in the list.\n * @internal\n */\nfunction hasListen(\n listens: TraitEventListener[],\n event: string,\n triggers: string,\n): boolean {\n return listens.some((l) => l.event === event && l.triggers === triggers);\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Apply event wiring to orbital definitions.\n *\n * For each wiring entry:\n * 1. Find the source trait and add an external emit (if not already present)\n * 2. Find the target trait and add an external listen (if not already present)\n *\n * Returns a new array of orbitals with wiring applied (deep-cloned).\n */\nexport function applyEventWiring(\n orbitals: OrbitalDefinition[],\n wiring: EventWiringEntry[],\n): OrbitalDefinition[] {\n // Deep clone to avoid mutating input\n const cloned: OrbitalDefinition[] = JSON.parse(\n JSON.stringify(orbitals),\n ) as OrbitalDefinition[];\n\n for (const entry of wiring) {\n // Wire the source: add emit\n const sourceTrait = findInlineTrait(cloned, entry.from);\n if (sourceTrait) {\n if (!sourceTrait.emits) {\n sourceTrait.emits = [];\n }\n if (!hasEmit(sourceTrait.emits, entry.event)) {\n sourceTrait.emits.push({\n event: entry.event,\n scope: 'external',\n });\n }\n }\n\n // Wire the target: add listen\n const targetTrait = findInlineTrait(cloned, entry.to);\n if (targetTrait) {\n if (!targetTrait.listens) {\n targetTrait.listens = [];\n }\n if (!hasListen(targetTrait.listens, entry.event, entry.triggers)) {\n targetTrait.listens.push({\n event: entry.event,\n triggers: entry.triggers,\n scope: 'external',\n });\n }\n }\n }\n\n return cloned;\n}\n","/**\n * Compose Behaviors\n *\n * Main entry point for composing multiple orbital definitions into\n * a single OrbitalSchema application. Handles event wiring, layout\n * strategy detection, and page generation.\n *\n * @packageDocumentation\n */\n\nimport type { OrbitalDefinition } from '../types/orbital.js';\nimport type { OrbitalSchema } from '../types/schema.js';\nimport type { Page } from '../types/page.js';\nimport type { EventWiringEntry } from './event-wiring.js';\nimport { applyEventWiring } from './event-wiring.js';\nimport type { LayoutStrategy } from './layout-strategy.js';\nimport { detectLayoutStrategy } from './layout-strategy.js';\n\n// ============================================================================\n// Types\n// ============================================================================\n\n/**\n * Input for composing behaviors into an application.\n */\nexport interface ComposeBehaviorsInput {\n /** Application name */\n appName: string;\n /** Orbital definitions to compose */\n orbitals: OrbitalDefinition[];\n /** Layout strategy override, or 'auto' to detect */\n layoutStrategy?: LayoutStrategy | 'auto';\n /** Cross-orbital event wiring */\n eventWiring?: EventWiringEntry[];\n /** Optional entity name mappings (original -> renamed) */\n entityMappings?: Record<string, string>;\n}\n\n/**\n * Result of composing behaviors.\n */\nexport interface ComposeBehaviorsResult {\n /** The composed OrbitalSchema */\n schema: OrbitalSchema;\n /** Layout metadata */\n layout: { strategy: LayoutStrategy; pageCount: number };\n /** Wiring metadata */\n wiring: { connections: number };\n}\n\n// ============================================================================\n// Page Generation\n// ============================================================================\n\nfunction toKebabCase(name: string): string {\n return name\n .replace(/([a-z])([A-Z])/g, '$1-$2')\n .replace(/[\\s_]+/g, '-')\n .toLowerCase();\n}\n\n/**\n * Generate pages for each orbital based on the layout strategy.\n *\n * For strategies that produce one page per orbital (sidebar, tabs, wizard-flow),\n * each orbital gets a page at `/<kebab-name>` with `isInitial` on the first.\n *\n * For 'dashboard', all orbitals share a single page.\n * For 'single', the lone orbital gets a single root page.\n */\nfunction generatePages(\n orbitals: OrbitalDefinition[],\n strategy: LayoutStrategy,\n): Page[] {\n switch (strategy) {\n case 'single': {\n const orbital = orbitals[0];\n const name = orbital?.name ?? 'Main';\n return [\n {\n name: `${name}Page`,\n path: '/',\n isInitial: true,\n primaryEntity: getEntityName(orbital),\n },\n ];\n }\n\n case 'dashboard': {\n return [\n {\n name: 'DashboardPage',\n path: '/',\n viewType: 'dashboard',\n isInitial: true,\n },\n ];\n }\n\n case 'sidebar':\n case 'tabs':\n case 'wizard-flow': {\n return orbitals.map((orbital, index) => ({\n name: `${orbital.name}Page`,\n path: index === 0 ? '/' : `/${toKebabCase(orbital.name)}`,\n isInitial: index === 0,\n primaryEntity: getEntityName(orbital),\n }));\n }\n }\n}\n\n/**\n * Extract entity name from an orbital definition.\n * Handles both inline entities and string references.\n */\nfunction getEntityName(orbital: OrbitalDefinition | undefined): string | undefined {\n if (!orbital) return undefined;\n const entity = orbital.entity;\n if (typeof entity === 'string') {\n // Reference like \"Alias.entity\" - extract the alias as entity name\n return entity.replace('.entity', '');\n }\n return entity.name;\n}\n\n// ============================================================================\n// Public API\n// ============================================================================\n\n/**\n * Compose multiple orbital definitions into a single application schema.\n *\n * Steps:\n * 1. Apply event wiring (adds emits/listens to traits)\n * 2. Detect or use provided layout strategy\n * 3. Generate pages based on the strategy\n * 4. Build the final OrbitalSchema\n */\nexport function composeBehaviors(\n input: ComposeBehaviorsInput,\n): ComposeBehaviorsResult {\n const {\n appName,\n orbitals: rawOrbitals,\n layoutStrategy: strategyInput,\n eventWiring,\n } = input;\n\n // Step 1: Apply event wiring\n const wiredOrbitals =\n eventWiring && eventWiring.length > 0\n ? applyEventWiring(rawOrbitals, eventWiring)\n : rawOrbitals;\n\n // Step 2: Determine layout strategy\n const strategy: LayoutStrategy =\n !strategyInput || strategyInput === 'auto'\n ? detectLayoutStrategy(wiredOrbitals, eventWiring)\n : strategyInput;\n\n // Step 3: Generate pages\n const pages = generatePages(wiredOrbitals, strategy);\n\n // Step 4: Assign generated pages to orbitals (merge, don't replace existing)\n const orbitalsWithPages = wiredOrbitals.map((orbital, index) => {\n // If the orbital already has pages, keep them\n if (orbital.pages && orbital.pages.length > 0) {\n return orbital;\n }\n\n // Assign the generated page for this orbital\n const page = strategy === 'dashboard' || strategy === 'single'\n ? pages[0]\n : pages[index];\n\n return {\n ...orbital,\n pages: page ? [page] : [],\n };\n });\n\n // Step 5: Build the schema\n const schema: OrbitalSchema = {\n name: appName,\n version: '1.0.0',\n orbitals: orbitalsWithPages,\n };\n\n return {\n schema,\n layout: {\n strategy,\n pageCount: pages.length,\n },\n wiring: {\n connections: eventWiring?.length ?? 0,\n },\n };\n}\n","/**\n * Orbital Builders\n *\n * Pure functions for constructing and composing Orbitals.\n * No new types. Everything uses existing core types:\n * Entity, Trait, Page, OrbitalDefinition, OrbitalSchema.\n *\n * Three categories:\n * 1. Builders: construct Entity, Page from common params\n * 2. Utilities: ensureIdField, resolveDefaults\n * 3. Composition: connect, compose, pipe\n *\n * @packageDocumentation\n */\n\nimport type { Entity, EntityPersistence } from './types/entity.js';\nimport type { EntityField } from './types/field.js';\nimport type { Page } from './types/page.js';\nimport type { OrbitalDefinition } from './types/orbital.js';\nimport type { OrbitalSchema } from './types/schema.js';\nimport type { TraitEventContract, TraitEventListener, Trait } from './types/trait.js';\n\n// Re-export compose-behaviors module\nexport { type LayoutStrategy, detectLayoutStrategy } from './builders/layout-strategy.js';\nexport { type EventWiringEntry, applyEventWiring } from './builders/event-wiring.js';\nexport {\n type ComposeBehaviorsInput,\n type ComposeBehaviorsResult,\n composeBehaviors,\n} from './builders/compose-behaviors.js';\n\n// ============================================================================\n// Utilities\n// ============================================================================\n\n/**\n * Ensure the fields array has an `id` field. Prepends one if missing.\n */\nexport function ensureIdField(fields: EntityField[]): EntityField[] {\n if (fields.some(f => f.name === 'id')) return fields;\n return [{ name: 'id', type: 'string', required: true }, ...fields];\n}\n\n/**\n * Simple pluralization: append 's'.\n */\nexport function plural(name: string): string {\n return name + 's';\n}\n\n// ============================================================================\n// Entity Builder\n// ============================================================================\n\nexport interface MakeEntityOpts {\n name: string;\n fields: EntityField[];\n persistence?: EntityPersistence;\n collection?: string;\n /** Pre-authored seed data instances */\n instances?: Record<string, unknown>[];\n}\n\n/**\n * Build an Entity from options. Auto-adds id field, auto-derives collection.\n */\nexport function makeEntity(opts: MakeEntityOpts): Entity {\n const fields = ensureIdField(opts.fields);\n const persistence = opts.persistence ?? 'runtime';\n return {\n name: opts.name,\n persistence,\n ...(persistence === 'persistent'\n ? { collection: opts.collection ?? plural(opts.name).toLowerCase() }\n : {}),\n fields,\n ...(opts.instances && opts.instances.length > 0 ? { instances: opts.instances } : {}),\n };\n}\n\n// ============================================================================\n// Page Builder\n// ============================================================================\n\nexport interface MakePageOpts {\n name: string;\n path: string;\n traitName: string;\n isInitial?: boolean;\n}\n\n/**\n * Build a Page that binds to a single trait.\n */\nexport function makePage(opts: MakePageOpts): Page {\n return {\n name: opts.name,\n path: opts.path,\n ...(opts.isInitial ? { isInitial: true } : {}),\n traits: [{ ref: opts.traitName }],\n };\n}\n\n// ============================================================================\n// Orbital Builder\n// ============================================================================\n\n/**\n * Build an OrbitalDefinition from its three components.\n */\nexport function makeOrbital(\n name: string,\n entity: Entity,\n traits: Trait[],\n pages: Page[],\n): OrbitalDefinition {\n return { name, entity, traits, pages } as OrbitalDefinition;\n}\n\n// ============================================================================\n// Intra-Orbital Composition\n// ============================================================================\n\n/**\n * Merge multiple OrbitalDefinitions into one.\n * Collects all traits from all sources into a single orbital with a shared entity.\n * Pure: clones all traits, no mutation.\n */\nexport function mergeOrbitals(\n name: string,\n entity: Entity,\n sources: OrbitalDefinition[],\n pages: Page[],\n): OrbitalDefinition {\n const allTraits = sources.flatMap(s =>\n (s.traits as Trait[]).map(t => structuredClone(t)),\n );\n return { name, entity, traits: allTraits, pages } as OrbitalDefinition;\n}\n\n/**\n * Wire an intra-orbital event between two traits.\n * Adds emits to the source trait, listens to the target trait.\n * Pure: returns cloned traits, no mutation.\n */\nexport function wire(\n source: Trait,\n target: Trait,\n event: TraitEventContract,\n triggers: string,\n): [Trait, Trait] {\n const s = structuredClone(source);\n const t = structuredClone(target);\n\n s.emits = [...(s.emits ?? []), { ...event, scope: event.scope ?? ('internal' as const) }];\n t.listens = [...(t.listens ?? []), {\n event: event.event,\n triggers,\n scope: 'internal' as const,\n }];\n\n return [s, t];\n}\n\n/**\n * Extract the first trait from an OrbitalDefinition.\n */\nexport function extractTrait(orbital: OrbitalDefinition): Trait {\n return structuredClone((orbital.traits as Trait[])[0]);\n}\n\n// ============================================================================\n// Composition: connect\n// ============================================================================\n\n/**\n * Wire a cross-orbital event between two orbitals.\n * Adds emits to a's first trait, listens to b's first trait.\n * Pure: returns new orbitals, no mutation.\n */\nexport function connect(\n a: OrbitalDefinition,\n b: OrbitalDefinition,\n event: TraitEventContract,\n triggers?: string,\n): [OrbitalDefinition, OrbitalDefinition] {\n const aClone = structuredClone(a);\n const bClone = structuredClone(b);\n\n // Add emit to first trait of a\n const aTrait = (aClone.traits as Trait[])[0];\n if (aTrait) {\n const emitContract: TraitEventContract = {\n ...event,\n scope: event.scope ?? 'external',\n };\n aTrait.emits = [...(aTrait.emits ?? []), emitContract];\n }\n\n // Add listen to first trait of b\n const bTrait = (bClone.traits as Trait[])[0];\n if (bTrait) {\n const listener: TraitEventListener = {\n event: event.event,\n triggers: triggers ?? 'INIT',\n scope: 'external',\n };\n bTrait.listens = [...(bTrait.listens ?? []), listener];\n }\n\n return [aClone, bClone];\n}\n\n// ============================================================================\n// Composition: compose\n// ============================================================================\n\nexport interface ComposeConnection {\n from: string;\n to: string;\n event: TraitEventContract;\n triggers?: string;\n}\n\nexport interface ComposePage {\n name: string;\n path: string;\n traits: string[];\n isInitial?: boolean;\n}\n\n/**\n * Compose multiple orbitals into a single OrbitalSchema (application).\n * Applies connections (cross-orbital event wiring) and page assignments.\n */\nexport function compose(\n orbitals: OrbitalDefinition[],\n pages: ComposePage[],\n connections: ComposeConnection[],\n appName?: string,\n): OrbitalSchema {\n const cloned = structuredClone(orbitals);\n\n // Apply connections\n for (const conn of connections) {\n const emitter = cloned.find(o => {\n const traits = o.traits as Trait[];\n return traits.some(t => t.name === conn.from);\n });\n const listener = cloned.find(o => {\n const traits = o.traits as Trait[];\n return traits.some(t => t.name === conn.to);\n });\n\n if (emitter && listener) {\n const eTrait = (emitter.traits as Trait[]).find(t => t.name === conn.from);\n const lTrait = (listener.traits as Trait[]).find(t => t.name === conn.to);\n\n if (eTrait) {\n const emitContract: TraitEventContract = { ...conn.event, scope: conn.event.scope ?? 'external' };\n eTrait.emits = [...(eTrait.emits ?? []), emitContract];\n }\n if (lTrait) {\n const listenContract: TraitEventListener = {\n event: conn.event.event,\n triggers: conn.triggers ?? 'INIT',\n scope: 'external',\n };\n lTrait.listens = [...(lTrait.listens ?? []), listenContract];\n }\n }\n }\n\n // Assign pages to orbitals\n for (const orbital of cloned) {\n const traitNames = (orbital.traits as Trait[]).map(t => t.name);\n const matchingPages = pages.filter(p =>\n p.traits.some(t => traitNames.includes(t)),\n );\n orbital.pages = matchingPages.map(p => ({\n name: p.name,\n path: p.path,\n ...(p.isInitial ? { isInitial: true } : {}),\n traits: p.traits\n .filter(t => traitNames.includes(t))\n .map(ref => ({ ref })),\n }));\n }\n\n return {\n name: appName ?? 'Application',\n version: '1.0.0',\n orbitals: cloned,\n };\n}\n\n// ============================================================================\n// Composition: pipe\n// ============================================================================\n\n/**\n * Chain orbitals in sequence with automatic event wiring.\n * Sugar over connect + compose: wires events[0] from orbital[0] to orbital[1], etc.\n */\nexport function pipe(\n orbitals: OrbitalDefinition[],\n events: TraitEventContract[],\n appName?: string,\n): OrbitalSchema {\n if (events.length !== orbitals.length - 1) {\n throw new Error(`pipe requires exactly ${orbitals.length - 1} events for ${orbitals.length} orbitals`);\n }\n\n const cloned = structuredClone(orbitals);\n\n // Wire adjacent pairs\n for (let i = 0; i < events.length; i++) {\n const aTrait = (cloned[i].traits as Trait[])[0];\n const bTrait = (cloned[i + 1].traits as Trait[])[0];\n\n if (aTrait) {\n const emitContract: TraitEventContract = { ...events[i], scope: events[i].scope ?? 'external' };\n aTrait.emits = [...(aTrait.emits ?? []), emitContract];\n }\n if (bTrait) {\n const listener: TraitEventListener = {\n event: events[i].event,\n triggers: 'INIT',\n scope: 'external',\n };\n bTrait.listens = [...(bTrait.listens ?? []), listener];\n }\n }\n\n // Auto-generate pages: one per orbital, first is initial\n const pages: Page[] = cloned.map((o, i) => {\n const entityName = typeof o.entity === 'string' ? o.entity : o.entity.name;\n const traitNames = (o.traits as Trait[]).map(t => t.name);\n return {\n name: `${entityName}Page`,\n path: `/${plural(entityName).toLowerCase()}`,\n ...(i === 0 ? { isInitial: true } : {}),\n traits: traitNames.map(ref => ({ ref })),\n };\n });\n\n // Assign pages back to orbitals\n for (let i = 0; i < cloned.length; i++) {\n cloned[i].pages = [pages[i]];\n }\n\n return {\n name: appName ?? 'Application',\n version: '1.0.0',\n orbitals: cloned,\n };\n}\n"]}
|