@almadar/core 10.51.0 → 10.52.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/mock/index.js +17 -1
- package/dist/mock/index.js.map +1 -1
- package/package.json +1 -1
package/dist/mock/index.js
CHANGED
|
@@ -188,13 +188,29 @@ function ownerFieldsFromSchema(schema) {
|
|
|
188
188
|
const identity = identityEntityName(schema);
|
|
189
189
|
if (identity === void 0) return [];
|
|
190
190
|
const out = [];
|
|
191
|
-
|
|
191
|
+
const defs = inlineEntities(schema);
|
|
192
|
+
const declaredByCollection = /* @__PURE__ */ new Map();
|
|
193
|
+
for (const def of defs) {
|
|
192
194
|
for (const field of def.fields ?? []) {
|
|
193
195
|
if (field.name && field.type === "relation" && field.relation.entity === identity) {
|
|
194
196
|
out.push(`${def.name}.${field.name}`);
|
|
197
|
+
if (def.collection) {
|
|
198
|
+
const cols = declaredByCollection.get(def.collection) ?? [];
|
|
199
|
+
if (!cols.includes(field.name)) cols.push(field.name);
|
|
200
|
+
declaredByCollection.set(def.collection, cols);
|
|
201
|
+
}
|
|
195
202
|
}
|
|
196
203
|
}
|
|
197
204
|
}
|
|
205
|
+
for (const def of defs) {
|
|
206
|
+
const cols = def.collection ? declaredByCollection.get(def.collection) : void 0;
|
|
207
|
+
if (!cols) continue;
|
|
208
|
+
for (const col of cols) {
|
|
209
|
+
const key = `${def.name}.${col}`;
|
|
210
|
+
if (out.includes(key)) continue;
|
|
211
|
+
if ((def.fields ?? []).some((f) => f.name === col)) out.push(key);
|
|
212
|
+
}
|
|
213
|
+
}
|
|
198
214
|
return out;
|
|
199
215
|
}
|
|
200
216
|
|
package/dist/mock/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/mock/random.ts","../../src/mock/identityOwners.ts","../../src/access/entityAccess.ts","../../src/types/identity.ts","../../src/types/json.ts","../../src/types/field.ts","../../src/types/asset.ts","../../src/types/expression.ts","../../src/types/entity.ts","../../src/mock/sampleValue.ts"],"names":["slug","inlineEntities","z"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Lightweight seeded pseudo-random generator for mock data.\n *\n * Replaces @faker-js/faker in browser-facing code so the client bundle does\n * not pay the ~3.7 MB faker cost. The API surface is intentionally narrow:\n * only the helpers actually used by MockPersistenceAdapter.\n */\n\nlet seedState = 42;\n\n/** Re-seed the generator. Same signature as `faker.seed()`. */\nexport function seedRandom(value: number | undefined): void {\n seedState = (value ?? 42) >>> 0;\n}\n\n/** Linear congruential generator returning a float in [0, 1). */\nfunction nextFloat(): number {\n seedState = (seedState * 1664525 + 1013904223) >>> 0;\n return seedState / 4294967296;\n}\n\n/** Integer in [min, max]. */\nexport function randomInt({ min, max }: { min: number; max: number }): number {\n return Math.floor(nextFloat() * (max - min + 1)) + min;\n}\n\n/** Float in [min, max] with fixed fraction digits. */\nexport function randomFloat({\n min,\n max,\n fractionDigits = 2,\n}: {\n min: number;\n max: number;\n fractionDigits?: number;\n}): number {\n const value = nextFloat() * (max - min) + min;\n const factor = 10 ** fractionDigits;\n return Math.round(value * factor) / factor;\n}\n\n/** True/false with 50% probability. */\nexport function randomBoolean(): boolean {\n return nextFloat() < 0.5;\n}\n\n/** Pick one element from an array. */\nexport function randomArrayElement<T>(array: ReadonlyArray<T>): T {\n return array[randomInt({ min: 0, max: array.length - 1 })]!;\n}\n\n/** Return a shallow-shuffled copy of the array (Fisher-Yates). */\nexport function shuffleArray<T>(array: ReadonlyArray<T>): T[] {\n const copy = array.slice();\n for (let i = copy.length - 1; i > 0; i--) {\n const j = randomInt({ min: 0, max: i });\n const tmp = copy[i];\n copy[i] = copy[j]!;\n copy[j] = tmp!;\n }\n return copy;\n}\n\n/** ISO-8601 date string roughly `years` in the past. */\nexport function randomPastDate({ years = 1 }: { years?: number } = {}): Date {\n const now = Date.now();\n const maxAge = years * 365 * 24 * 60 * 60 * 1000;\n const age = Math.floor(nextFloat() * maxAge);\n return new Date(now - age);\n}\n\n/** ISO-8601 date string within the last `days`. */\nexport function randomRecentDate({ days = 30 }: { days?: number } = {}): Date {\n const now = Date.now();\n const maxAge = days * 24 * 60 * 60 * 1000;\n const age = Math.floor(nextFloat() * maxAge);\n return new Date(now - age);\n}\n\n/** ISO-8601 date string straddling now: `[-days, +days]`. One PRNG draw,\n * same call shape as `randomRecentDate`, so seeded field order is unchanged —\n * only the window shifts from past-only to centered-on-now. Past-only starved\n * any calendar/upcoming view, since every seeded `startsAt` was already over. */\nexport function randomStraddlingDate({ days = 15 }: { days?: number } = {}): Date {\n const now = Date.now();\n const span = days * 24 * 60 * 60 * 1000;\n const offset = Math.floor(nextFloat() * span * 2) - span;\n return new Date(now + offset);\n}\n\n/** Any date in the last ~100 years. */\nexport function randomAnytimeDate(): Date {\n const now = Date.now();\n const maxAge = 100 * 365 * 24 * 60 * 60 * 1000;\n const age = Math.floor(nextFloat() * maxAge);\n return new Date(now - age);\n}\n\nconst LOREM_WORDS = [\n 'lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipiscing', 'elit',\n 'sed', 'do', 'eiusmod', 'tempor', 'incididunt', 'ut', 'labore', 'et', 'dolore',\n 'magna', 'aliqua', 'enim', 'ad', 'minim', 'veniam', 'quis', 'nostrud',\n 'exercitation', 'ullamco', 'laboris', 'nisi', 'aliquip', 'ex', 'ea', 'commodo',\n 'consequat', 'duis', 'aute', 'irure', 'in', 'reprehenderit', 'voluptate',\n 'velit', 'esse', 'cillum', 'fugiat', 'nulla', 'pariatur', 'excepteur', 'sint',\n 'occaecat', 'cupidatat', 'non', 'proident', 'sunt', 'culpa', 'qui', 'officia',\n 'deserunt', 'mollit', 'anim', 'id', 'est', 'laborum',\n];\n\n/** A few random words. */\nexport function randomWords(count: number): string {\n const words: string[] = [];\n for (let i = 0; i < count; i++) {\n words.push(randomArrayElement(LOREM_WORDS));\n }\n return words.join(' ');\n}\n\n/** A short sentence. */\nexport function randomSentence(): string {\n const words = randomWords(randomInt({ min: 4, max: 8 }));\n return words.charAt(0).toUpperCase() + words.slice(1) + '.';\n}\n\n/** UUID v4-like string (random, not strictly compliant). */\nexport function randomUuid(): string {\n const hex = () => randomInt({ min: 0, max: 15 }).toString(16);\n return `${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}-${hex()}${hex()}${hex()}${hex()}-4${hex()}${hex()}${hex()}-${hex()}${hex()}${hex()}${hex()}-${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}`;\n}\n\n/** Random hex color (#rrggbb). */\nexport function randomColor(): string {\n const channel = () => randomInt({ min: 0, max: 255 }).toString(16).padStart(2, '0');\n return `#${channel()}${channel()}${channel()}`;\n}\n\nconst PASSWORD_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*';\n\n/** Random password of the given length. */\nexport function randomPassword(length = 12): string {\n let password = '';\n for (let i = 0; i < length; i++) {\n password += randomArrayElement(PASSWORD_CHARS.split(''));\n }\n return password;\n}\n\n/** Random email address. */\nexport function randomEmail(): string {\n const user = randomWords(1).toLowerCase().replace(/\\s+/g, '.');\n const domain = randomWords(1).toLowerCase().replace(/\\s+/g, '');\n return `${user}@${domain}.com`;\n}\n\n/** Random URL. */\nexport function randomUrl(): string {\n const slug = randomWords(2).toLowerCase().replace(/\\s+/g, '-');\n return `https://example.com/${slug}`;\n}\n\n/** Random phone number. */\nexport function randomPhone(): string {\n const area = randomInt({ min: 200, max: 999 });\n const prefix = randomInt({ min: 200, max: 999 });\n const line = randomInt({ min: 0, max: 9999 }).toString().padStart(4, '0');\n return `+1 (${area}) ${prefix}-${line}`;\n}\n","/**\n * Owner columns derived from a program's `[identity]` entity.\n *\n * The JS mirror of `orbital-core/src/runtime/seed.rs`\n * (`identity_entity_name` / `owner_fields_from_schema`). Both paths must agree:\n * a column is an owner column because the source *declared* it as a relation to\n * the `[identity]` entity (`patientId : Person`), never because its name looks\n * like one — a name-matching guess would silently scope the wrong column.\n *\n * @packageDocumentation\n */\n\nimport type { OrbitalEntity } from '../types/entity.js';\nimport type { EntityRef } from '../types/orbital.js';\nimport type { OrbitalSchema } from '../types/schema.js';\n\n/** Inline entity definitions of an orbital: the primary plus any auxiliaries. */\nfunction inlineEntities(schema: OrbitalSchema): OrbitalEntity[] {\n const out: OrbitalEntity[] = [];\n for (const orbital of schema.orbitals ?? []) {\n const refs: EntityRef[] = [orbital.entity, ...(orbital.auxiliaryEntities ?? [])];\n for (const ref of refs) {\n if (typeof ref === 'object' && ref !== null && 'fields' in ref) {\n out.push(ref as OrbitalEntity);\n }\n }\n }\n return out;\n}\n\n/**\n * The name of the schema's `[identity]` entity, if it declares one.\n *\n * At most one per composed program (`ORB_S_IDENTITY_NOT_UNIQUE`); same-name\n * duplicates across orbitals are rejected upstream by `validate_entity_uniqueness`,\n * so the first match is the only match.\n */\nexport function identityEntityName(schema: OrbitalSchema): string | undefined {\n return inlineEntities(schema).find((def) => def.identity === true)?.name;\n}\n\n/**\n * Owner columns as `Entity.field` pairs — every relation field pointing at the\n * `[identity]` entity. Empty when the program declares no identity, which keeps\n * every unmigrated app behaving exactly as before.\n */\nexport function ownerFieldsFromSchema(schema: OrbitalSchema): string[] {\n const identity = identityEntityName(schema);\n if (identity === undefined) return [];\n\n const out: string[] = [];\n for (const def of inlineEntities(schema)) {\n for (const field of def.fields ?? []) {\n // Cardinality-one only: an owner column holds ONE viewer id. A\n // `[Person]` array is a participant list, not ownership.\n if (field.name && field.type === 'relation' && field.relation.entity === identity) {\n out.push(`${def.name}.${field.name}`);\n }\n }\n }\n return out;\n}\n","/**\n * Entity access policies — the declared `@read`/`@create`/`@update`/`@delete`\n * directives, keyed by entity name.\n *\n * The JS mirror of `orbital-core/src/runtime/entity_access.rs`'s\n * `EntityAccessPolicies`/`EntityAccessTable`. Both paths must agree: a\n * directive is a per-row predicate (`@entity` = the candidate row, or for\n * `@create` the incoming data; `@user` = the viewer), enforced once for\n * every trait that touches the entity — the un-bypassable twin of a\n * call-site `filter:`, which sibling traits can skip simply by not\n * declaring one.\n *\n * @packageDocumentation\n */\n\nimport type { OrbitalEntity } from '../types/entity.js';\nimport type { EntityRef } from '../types/orbital.js';\nimport type { OrbitalSchema } from '../types/schema.js';\nimport type { SExpr } from '../types/expression.js';\n\n/** Inline entity definitions of an orbital: the primary plus any auxiliaries. */\nfunction inlineEntities(schema: OrbitalSchema): OrbitalEntity[] {\n const out: OrbitalEntity[] = [];\n for (const orbital of schema.orbitals ?? []) {\n const refs: EntityRef[] = [orbital.entity, ...(orbital.auxiliaryEntities ?? [])];\n for (const ref of refs) {\n if (typeof ref === 'object' && ref !== null && 'fields' in ref) {\n out.push(ref as OrbitalEntity);\n }\n }\n }\n return out;\n}\n\n/** An entity's four declared directives. Any may be absent — an absent\n * directive means \"no restriction\" for that operation, exactly like an\n * absent fetch `filter:`. */\nexport interface EntityAccessPolicies {\n read?: SExpr;\n create?: SExpr;\n update?: SExpr;\n delete?: SExpr;\n}\n\n/** Whether the author declared any of the four directives on this entity. */\nfunction isDeclared(p: EntityAccessPolicies): boolean {\n return (\n p.read !== undefined ||\n p.create !== undefined ||\n p.update !== undefined ||\n p.delete !== undefined\n );\n}\n\n/**\n * Every entity's access policies, keyed by entity name.\n *\n * A policy governs the **collection**, not the declaration. A `persistent:`\n * collection is one table, and two entity declarations over one table cannot\n * honestly carry different visibility rules. Keying by entity name alone let an\n * organism declare `@read` on its own entity and still ship an ALLOW-ALL list\n * wherever a page rendered through a std-atom trait that fetched the ATOM's\n * entity on the same collection — measured on `std-customer-success`, where\n * `/health-scores` returned 6 rows for every persona while the organism's own\n * `/cs-accounts` correctly returned 3 vs 6. 36 of 54 app organisms share a\n * collection this way (`R-SHADOW-ENTITY-SHARES-COLLECTION-DIRECTIVES-DONT-APPLY`).\n *\n * So an entity that declares nothing adopts the policy declared on its\n * collection. This can only ever ADD a restriction: an entity with its own\n * directives keeps exactly those, and an entity whose collection carries no\n * declared policy is untouched. Conflicting declarations on one collection are\n * rejected at validate time by `ORB_S_COLLECTION_POLICY_CONFLICT`.\n *\n * Mirrors `resolve_collection_inheritance` in\n * `orbital-rust/crates/orbital-core/src/runtime/entity_access.rs`.\n */\nexport function entityAccessTable(schema: OrbitalSchema): Map<string, EntityAccessPolicies> {\n const table = new Map<string, EntityAccessPolicies>();\n const collectionOf = new Map<string, string>();\n\n for (const def of inlineEntities(schema)) {\n table.set(def.name, {\n read: def.read_policy,\n create: def.create_policy,\n update: def.update_policy,\n delete: def.delete_policy,\n });\n if (def.collection) collectionOf.set(def.name, def.collection);\n }\n\n const byCollection = new Map<string, EntityAccessPolicies>();\n for (const [name, policies] of table) {\n const collection = collectionOf.get(name);\n if (collection && isDeclared(policies) && !byCollection.has(collection)) {\n byCollection.set(collection, policies);\n }\n }\n\n for (const [name, policies] of table) {\n if (isDeclared(policies)) continue;\n const collection = collectionOf.get(name);\n const inherited = collection ? byCollection.get(collection) : undefined;\n if (inherited) table.set(name, { ...inherited });\n }\n\n return table;\n}\n\n/** One entity's access policies, or `undefined` when it declares none. */\nexport function entityAccessPolicies(\n schema: OrbitalSchema,\n entityName: string,\n): EntityAccessPolicies | undefined {\n return entityAccessTable(schema).get(entityName);\n}\n","/**\n * Identity model (Almadar Rabit V4, Phase 1 — types only).\n *\n * Branded, prefix-tagged node ids + a workspace-scoped name ledger. Ids are\n * the durable edge keys of the identity-keyed schema graph; the ledger is the\n * sole name↔id map (names are display labels, one row per rename). This module\n * is pure: no I/O, no side effects. Minting is the only impurity (clock +\n * crypto randomness for the ULID suffix).\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\n\n// ============================================================================\n// Branded id types\n// ============================================================================\n\ntype Branded<K extends string> = string & { readonly __idBrand: K };\n\nexport type OrbitalId = Branded<'OrbitalId'>;\nexport type EntityId = Branded<'EntityId'>;\nexport type TraitId = Branded<'TraitId'>;\nexport type EventId = Branded<'EventId'>;\nexport type PageId = Branded<'PageId'>;\nexport type ServiceId = Branded<'ServiceId'>;\nexport type ThemeId = Branded<'ThemeId'>;\nexport type PaletteEntryId = Branded<'PaletteEntryId'>;\n\n/** Node kind ↔ id-prefix table. The single source of truth for every prefix. */\nconst ID_PREFIXES = {\n orbital: 'orb_',\n entity: 'ent_',\n trait: 'trt_',\n event: 'evt_',\n page: 'pag_',\n service: 'svc_',\n theme: 'thm_',\n palette: 'pal_',\n} as const;\n\nexport type IdKind = keyof typeof ID_PREFIXES;\n\n/** Compile-time map from kind to its branded id type. */\nexport interface IdForKind {\n orbital: OrbitalId;\n entity: EntityId;\n trait: TraitId;\n event: EventId;\n page: PageId;\n service: ServiceId;\n theme: ThemeId;\n palette: PaletteEntryId;\n}\n\n/**\n * The one controlled brand assertion in this module. A prefix-checked string\n * is asserted into its branded form here and nowhere else.\n */\nfunction brand<Id extends string>(value: string): Id {\n return value as Id;\n}\n\n// ============================================================================\n// Kind guards + constructors (one shared factory, eight kinds)\n// ============================================================================\n\ninterface IdKindApi<Id extends string> {\n readonly prefix: string;\n is(value: string): value is Id;\n as(value: string): Id;\n}\n\nfunction makeIdKind<Id extends string>(kind: IdKind): IdKindApi<Id> {\n const prefix = ID_PREFIXES[kind];\n const is = (value: string): value is Id =>\n value.startsWith(prefix) && value.length > prefix.length;\n const as = (value: string): Id => {\n if (!is(value)) {\n throw new Error(\n `Expected ${kind} id (prefix \"${prefix}\"), got: ${JSON.stringify(value)}`,\n );\n }\n return brand<Id>(value);\n };\n return { prefix, is, as };\n}\n\nconst orbitalKind = makeIdKind<OrbitalId>('orbital');\nconst entityKind = makeIdKind<EntityId>('entity');\nconst traitKind = makeIdKind<TraitId>('trait');\nconst eventKind = makeIdKind<EventId>('event');\nconst pageKind = makeIdKind<PageId>('page');\nconst serviceKind = makeIdKind<ServiceId>('service');\nconst themeKind = makeIdKind<ThemeId>('theme');\nconst paletteKind = makeIdKind<PaletteEntryId>('palette');\n\nexport const isOrbitalId = orbitalKind.is;\nexport const asOrbitalId = orbitalKind.as;\nexport const isEntityId = entityKind.is;\nexport const asEntityId = entityKind.as;\nexport const isTraitId = traitKind.is;\nexport const asTraitId = traitKind.as;\nexport const isEventId = eventKind.is;\nexport const asEventId = eventKind.as;\nexport const isPageId = pageKind.is;\nexport const asPageId = pageKind.as;\nexport const isServiceId = serviceKind.is;\nexport const asServiceId = serviceKind.as;\nexport const isThemeId = themeKind.is;\nexport const asThemeId = themeKind.as;\nexport const isPaletteEntryId = paletteKind.is;\nexport const asPaletteEntryId = paletteKind.as;\n\n/**\n * The id-prefix for a node kind (`'entity' → 'ent_'`). The JS mirror of the\n * Rust `IdKind::prefix`. Single source of truth is {@link ID_PREFIXES}.\n */\nexport function idPrefix(kind: IdKind): string {\n return ID_PREFIXES[kind];\n}\n\n/**\n * The node kind an id's prefix denotes, or `null` for an unrecognized /\n * bare-prefix string. The JS mirror of the Rust `id_kind_of`. Prefixes are\n * mutually non-overlapping, so match order is irrelevant.\n */\nexport function idKindOf(id: string): IdKind | null {\n for (const kind of Object.keys(ID_PREFIXES) as IdKind[]) {\n const prefix = ID_PREFIXES[kind];\n if (id.startsWith(prefix) && id.length > prefix.length) return kind;\n }\n return null;\n}\n\n// ============================================================================\n// Minting — prefix + ULID\n// ============================================================================\n\nconst CROCKFORD = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';\nconst TIME_LEN = 10;\nconst RANDOM_LEN = 16;\n\nfunction randomBytes(len: number): Uint8Array {\n const g = globalThis as { crypto?: { getRandomValues?: (a: Uint8Array) => Uint8Array } };\n if (g.crypto?.getRandomValues) {\n return g.crypto.getRandomValues(new Uint8Array(len));\n }\n throw new Error('mintId: no crypto.getRandomValues available in this runtime');\n}\n\nfunction encodeTime(now: number): string {\n let value = now;\n let out = '';\n for (let i = 0; i < TIME_LEN; i++) {\n const mod = value % 32;\n out = CROCKFORD[mod] + out;\n value = (value - mod) / 32;\n }\n return out;\n}\n\nfunction encodeRandom(): string {\n const bytes = randomBytes(RANDOM_LEN);\n let out = '';\n for (let i = 0; i < RANDOM_LEN; i++) {\n out += CROCKFORD[bytes[i] & 31];\n }\n return out;\n}\n\n/** A 26-char Crockford-base32 ULID: 48-bit ms timestamp + 80 bits of randomness. */\nfunction ulid(): string {\n return encodeTime(Date.now()) + encodeRandom();\n}\n\n/** Mint a fresh, opaque, kind-tagged id: `<prefix><ULID>`. */\nexport function mintId<K extends IdKind>(kind: K): IdForKind[K] {\n return brand<IdForKind[K]>(ID_PREFIXES[kind] + ulid());\n}\n\n// ============================================================================\n// Identity ledger\n// ============================================================================\n\n/** Ledger row kind. `palette` entries are manifest ids, not name-ledger rows. */\nexport type LedgerKind =\n | 'orbital'\n | 'entity'\n | 'trait'\n | 'event'\n | 'page'\n | 'service'\n | 'theme';\n\n/**\n * One ledger row: the workspace's name history for a single node id.\n *\n * For kind `'event'` the row is minted per-(trait, declared event) per the\n * Phase-0 freeze — the owning trait is recorded in `parent`; a call-site event\n * rename is a one-row edit on this same id (the baked-vs-current key namespaces\n * collapse into `bakedName` vs `curName`).\n */\nexport interface LedgerEntry {\n id: string;\n kind: LedgerKind;\n bakedName: string;\n curName: string;\n renames: ReadonlyArray<{ from: string; to: string; at: string }>;\n owner: 'std' | 'io' | 'workspace';\n /** Owning trait for kind `'event'` (per-trait event-id namespace). */\n parent?: TraitId;\n}\n\nexport interface IdentityLedger {\n schemaVersion: 1;\n entries: Record<string, LedgerEntry>;\n}\n\n/** Resolve a name to its id via exact `curName` match within `kind`, else null. */\nexport function ledgerResolveName(\n ledger: IdentityLedger,\n kind: LedgerKind,\n name: string,\n): string | null {\n for (const [id, entry] of Object.entries(ledger.entries)) {\n if (entry.kind === kind && entry.curName === name) return id;\n }\n return null;\n}\n\n/** Immutable rename: returns a new ledger with the id's `curName` + `renames` updated. */\nexport function ledgerRename(\n ledger: IdentityLedger,\n id: string,\n to: string,\n at: string,\n): IdentityLedger {\n const entry = ledger.entries[id];\n if (entry === undefined) return ledger;\n const updated: LedgerEntry = {\n ...entry,\n curName: to,\n renames: [...entry.renames, { from: entry.curName, to, at }],\n };\n return { ...ledger, entries: { ...ledger.entries, [id]: updated } };\n}\n\n/** Current display name for an id, or null when the id is not in the ledger. */\nexport function ledgerCurName(ledger: IdentityLedger, id: string): string | null {\n return ledger.entries[id]?.curName ?? null;\n}\n\n// ============================================================================\n// Zod schemas — the `.orb` load-time activation surface (Rabit V4, Phase 4)\n// ============================================================================\n\n/**\n * Prefix-checked, kind-tagged id schemas. Each narrows a validated string to\n * its branded id type via the module's own kind guard, so a schema that reads\n * `TraitIdSchema.optional()` yields `TraitId | undefined` with no cast. The\n * guard is the single source of prefix truth (`ID_PREFIXES`); the schema is a\n * thin zod wrapper over it.\n */\nexport const OrbitalIdSchema = z\n .string()\n .refine(isOrbitalId, { message: `Expected an orbital id (prefix \"${ID_PREFIXES.orbital}\")` });\nexport const EntityIdSchema = z\n .string()\n .refine(isEntityId, { message: `Expected an entity id (prefix \"${ID_PREFIXES.entity}\")` });\nexport const TraitIdSchema = z\n .string()\n .refine(isTraitId, { message: `Expected a trait id (prefix \"${ID_PREFIXES.trait}\")` });\nexport const EventIdSchema = z\n .string()\n .refine(isEventId, { message: `Expected an event id (prefix \"${ID_PREFIXES.event}\")` });\nexport const PageIdSchema = z\n .string()\n .refine(isPageId, { message: `Expected a page id (prefix \"${ID_PREFIXES.page}\")` });\nexport const ServiceIdSchema = z\n .string()\n .refine(isServiceId, { message: `Expected a service id (prefix \"${ID_PREFIXES.service}\")` });\nexport const ThemeIdSchema = z\n .string()\n .refine(isThemeId, { message: `Expected a theme id (prefix \"${ID_PREFIXES.theme}\")` });\nexport const PaletteEntryIdSchema = z\n .string()\n .refine(isPaletteEntryId, { message: `Expected a palette-entry id (prefix \"${ID_PREFIXES.palette}\")` });\n\nexport const LedgerKindSchema = z.enum([\n 'orbital',\n 'entity',\n 'trait',\n 'event',\n 'page',\n 'service',\n 'theme',\n]);\n\nexport const LedgerEntrySchema = z.object({\n id: z.string(),\n kind: LedgerKindSchema,\n bakedName: z.string(),\n curName: z.string(),\n renames: z.array(\n z.object({ from: z.string(), to: z.string(), at: z.string() }),\n ),\n owner: z.enum(['std', 'io', 'workspace']),\n parent: TraitIdSchema.optional(),\n});\n\nexport const IdentityLedgerSchema = z.object({\n schemaVersion: z.literal(1),\n entries: z.record(LedgerEntrySchema),\n});\n","/**\n * JSON primitives — the universal \"data crossed a boundary\" type.\n *\n * Every value that arrives over the wire from an LLM (tool-call args),\n * from disk (workspace files), or from an HTTP body before\n * domain-specific validation is a `JsonValue`. Narrow with a typed\n * predicate (`is`-guard) at the boundary; don't widen back to `unknown`.\n *\n * `JsonObject` and `ToolArgs` are aliases for the common\n * `Record<string, JsonValue>` shape. `ToolArgs` is the name the\n * agent surface uses for LLM-emitted tool-call arguments; `JsonObject`\n * is the general-purpose alias. They are the same type — the alias\n * exists so call sites read at the right semantic level.\n *\n * Why not `Record<string, unknown>`? Two reasons. (1) `unknown` widens\n * back to anything, which defeats the purpose of typing the boundary.\n * (2) The `@almadar/eslint-plugin/no-record-string-unknown` rule blocks\n * the wider form — `JsonValue`-based records are the typed answer.\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\n\n/**\n * Recursive JSON value union — every shape JSON can carry.\n */\nexport type JsonValue =\n | string\n | number\n | boolean\n | null\n | JsonValue[]\n | { [key: string]: JsonValue };\n\n/**\n * JSON object — keyed string→JsonValue. The wire form of arbitrary\n * structured data. Replaces `Record<string, unknown>` at typed\n * boundaries (LLM emits, file reads, HTTP bodies).\n */\nexport type JsonObject = { [key: string]: JsonValue };\n\n/** Zod schema for JsonValue — the one boundary validator for parsed-JSON slots. */\nexport const JsonValueSchema: z.ZodType<JsonValue> = z.lazy(() =>\n z.union([z.string(), z.number(), z.boolean(), z.null(), z.array(JsonValueSchema), z.record(JsonValueSchema)]),\n);\n\n/**\n * LLM tool-call arguments — same shape as `JsonObject`, named for the\n * agent-surface call site. Each tool's `execute(args: ToolArgs)`\n * receives this and narrows via an `is`-guard predicate before any\n * field access.\n */\nexport type ToolArgs = JsonObject;\n\n/**\n * Universal type-guard input — every runtime value shape a predicate can\n * be handed, enumerated instead of `unknown` (the repo bans `unknown`\n * even at guard boundaries). Primitives cover every `typeof` result;\n * `object` covers arrays, records, class instances, and functions.\n */\nexport type RuntimeValue =\n | string\n | number\n | bigint\n | boolean\n | symbol\n | Date\n | null\n | undefined\n | object;\n\n/**\n * Type guard: is the given value a JSON primitive (non-array,\n * non-object)? Used by walkers that decide whether to recurse.\n */\nexport function isJsonPrimitive(\n value: JsonValue,\n): value is string | number | boolean | null {\n return (\n value === null\n || typeof value === 'string'\n || typeof value === 'number'\n || typeof value === 'boolean'\n );\n}\n\n/**\n * Type guard: is the given value a JSON object (non-array, non-null)?\n */\nexport function isJsonObject(value: JsonValue): value is JsonObject {\n return (\n value !== null\n && typeof value === 'object'\n && !Array.isArray(value)\n );\n}\n\n/**\n * Type guard: is the given value a JSON array?\n */\nexport function isJsonArray(value: JsonValue): value is JsonValue[] {\n return Array.isArray(value);\n}\n","/**\n * Field Types for Orbital Units\n *\n * Extracted from schema/data-entities.ts for the orbitals module.\n * These types define the field structure within orbital entities.\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\nimport type { EntityId } from './identity.js';\nimport { EntityIdSchema } from './identity.js';\nimport type { JsonValue, RuntimeValue } from './json.js';\nimport { JsonValueSchema } from './json.js';\n\n// ============================================================================\n// Field Types\n// ============================================================================\n\n/**\n * Supported field types for entity fields.\n *\n * @example\n * { name: 'status', type: 'enum', values: ['draft', 'published'] }\n * { name: 'authorId', type: 'relation', relation: { entity: 'User', cardinality: 'one' } }\n */\nexport type FieldType =\n | 'string'\n | 'number'\n | 'boolean'\n | 'date'\n | 'timestamp'\n | 'datetime'\n // Semantic string domains. `.lolo` already types `date`/`datetime` rather\n // than annotating them, so these belong in the type system for the same\n // reason: a field's domain is a declared fact, not a decoration. They\n // replaced the optional `format` property, which had zero producers.\n | 'email'\n | 'url'\n | 'phone'\n | 'uuid'\n | 'image'\n | 'array'\n | 'object'\n | 'enum'\n | 'relation'\n | 'trait'\n | 'slot'\n | 'pattern';\n\n/** Every `FieldType`, as a runtime array. Downstream imports this instead of\n * re-listing the union — five copies had already drifted apart. */\nexport const FIELD_TYPES = [\n 'string',\n 'number',\n 'boolean',\n 'date',\n 'timestamp',\n 'datetime',\n 'email',\n 'url',\n 'phone',\n 'uuid',\n 'image',\n 'array',\n 'object',\n 'enum',\n 'relation',\n 'trait',\n 'slot',\n 'pattern',\n] as const satisfies readonly FieldType[];\n\n/** The semantic string domains — constrained strings, validatable by value. */\nexport const SEMANTIC_STRING_TYPES = ['email', 'url', 'phone', 'uuid', 'image'] as const;\n\nexport type SemanticStringType = (typeof SEMANTIC_STRING_TYPES)[number];\n\n/** Is this a semantic string domain (as opposed to a bare `string`)? */\nexport function isSemanticStringType(type: FieldType): type is SemanticStringType {\n return (SEMANTIC_STRING_TYPES as readonly string[]).includes(type);\n}\n\nexport const FieldTypeSchema = z.enum(FIELD_TYPES);\n\n// ============================================================================\n// Relation Configuration\n// ============================================================================\n\n/**\n * Cardinality for relation fields.\n * Matches Rust compiler's Cardinality enum.\n */\nexport type RelationCardinality = \n | 'one' \n | 'many' \n | 'one-to-many' \n | 'many-to-one' \n | 'many-to-many';\n\nexport const RelationCardinalitySchema = z.enum([\n 'one',\n 'many',\n 'one-to-many',\n 'many-to-one',\n 'many-to-many',\n]);\n\n/**\n * Configuration for relation fields (foreign keys).\n * Matches Rust compiler's RelationDefinition format.\n */\nexport type RelationConfig = {\n /** Target entity name (e.g., 'User', 'Task') - matches Rust's `entity` field */\n entity: string;\n /** V4 dual-carry id sibling of `entity` — optional until the Phase-7 flip. */\n entityId?: EntityId;\n /** Field on target entity (defaults to 'id') */\n field?: string;\n /** \n * Cardinality: one, many, one-to-many, many-to-one, many-to-many\n * Matches Rust compiler's cardinality format\n */\n cardinality?: RelationCardinality;\n /** Delete behavior */\n onDelete?: 'cascade' | 'nullify' | 'restrict';\n /** \n * Foreign key field name (for legacy compatibility).\n * @deprecated Use field instead\n */\n foreignKey?: string;\n /**\n * Target entity name (for legacy compatibility).\n * @deprecated Use entity instead\n */\n target?: string;\n /**\n * Cardinality type alias (for legacy compatibility).\n * @deprecated Use cardinality instead\n */\n type?: RelationCardinality;\n};\n\nexport const RelationConfigSchema = z.object({\n entity: z.string().min(1, 'Target entity is required'),\n entityId: EntityIdSchema.optional(),\n field: z.string().optional(),\n cardinality: RelationCardinalitySchema.optional(),\n onDelete: z.enum(['cascade', 'nullify', 'restrict']).optional(),\n // Legacy compatibility fields\n foreignKey: z.string().optional(),\n target: z.string().optional(),\n type: RelationCardinalitySchema.optional(),\n}).transform((data) => {\n // Normalize legacy format to standard format\n const normalized: RelationConfig = {\n entity: data.entity || data.target || '',\n entityId: data.entityId,\n cardinality: data.cardinality || data.type,\n field: data.field,\n onDelete: data.onDelete,\n };\n return normalized;\n});\n\nexport type RelationConfigInput = z.input<typeof RelationConfigSchema>;\n\n// ============================================================================\n// Field Format\n// ============================================================================\n\n/**\n * Value rules for the semantic string domains — one owner, so the seeders, the\n * validators and the verifiers cannot drift apart on what counts as valid.\n *\n * These replaced the old optional `format` property, which had zero producers\n * anywhere in the repo and no Rust counterpart at all: `format` was unreachable\n * from `.lolo`, so every consumer fell back to guessing from field names.\n */\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@.]+\\.[^\\s@]+$/;\nconst URL_RE = /^https?:\\/\\/[^\\s]+$/;\nconst PHONE_RE = /^[+]?[\\d\\s().-]{7,}$/;\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nexport function isEmailValue(value: string): boolean {\n return EMAIL_RE.test(value);\n}\n\nexport function isUrlValue(value: string): boolean {\n return URL_RE.test(value);\n}\n\nexport function isPhoneValue(value: string): boolean {\n return PHONE_RE.test(value);\n}\n\nexport function isUuidValue(value: string): boolean {\n return UUID_RE.test(value);\n}\n\n/** Does `value` satisfy the declared semantic domain? `image` is a URL. */\nexport function isSemanticStringValue(type: SemanticStringType, value: string): boolean {\n switch (type) {\n case 'email':\n return isEmailValue(value);\n case 'url':\n case 'image':\n return isUrlValue(value);\n case 'phone':\n return isPhoneValue(value);\n case 'uuid':\n return isUuidValue(value);\n }\n}\n\n// ============================================================================\n// Entity Field — discriminated union by `type`\n// ============================================================================\n\n/**\n * Field-type tags that don't carry a type-dependent payload. The base\n * `EntityField` shape applies as-is.\n */\ntype ScalarFieldType =\n | 'string'\n | 'number'\n | 'boolean'\n | 'date'\n | 'timestamp'\n | 'datetime'\n | 'email'\n | 'url'\n | 'phone'\n | 'uuid'\n | 'image'\n | 'trait'\n | 'slot'\n | 'pattern';\n\n/** Fields shared across every variant. */\ntype EntityFieldBase = {\n /**\n * Field name (camelCase). Optional for nested item/property descriptors\n * where the name is implied by the parent (`items`, `properties[k]`).\n * Mirrors Rust's `FieldDefinition.name: Option<String>`.\n */\n name?: string;\n /** Whether the field is required */\n required?: boolean;\n /** Default value — parsed from `.orb`, always JSON-shaped. */\n default?: JsonValue;\n /** Minimum value (for number) or length (for string) */\n min?: number;\n /** Maximum value or length */\n max?: number;\n /** Object property schemas keyed by property name (for object type).\n * Mirrors Rust's `FieldDefinition.properties: Option<HashMap<String,\n * FieldDefinition>>`. Populated by the lolo lowerer when a field /\n * config slot's type expression resolves to a struct shape\n * (`TypeExpr::Object`), including named-type aliases like `[MetricSpec]`. */\n properties?: Record<string, EntityField>;\n /** Runtime-managed widget state (authored `@intrinsic` in `.lolo`). Exempt\n * from the explicit-binding rule and never a domain-data bind target. */\n intrinsic?: boolean;\n /** Human/semantic description (authored `@description \"...\"` in `.lolo`).\n * Authoring/build-time metadata — factory-signature catalog, embeddings,\n * curation field-matching; the runtime ignores it. */\n description?: string;\n /** User-vocabulary synonyms (authored `@synonyms \"...\"` in `.lolo`).\n * Free text feeding catalog search / curation field-matching. */\n synonyms?: string;\n};\n\n/**\n * Scalar / structural fields — no type-dependent payload required.\n * `values?` is permitted as an OPTIONAL UI/validation hint (e.g. lolo's\n * `'a' | 'b' | 'c'` string-union sugar lowers to `type: 'string', values:\n * [...]`). Only `EnumEntityField` MANDATES values.\n */\nexport type ScalarEntityField = EntityFieldBase & {\n type: ScalarFieldType;\n /** Optional vocabulary hint for scalar fields (e.g. string unions\n * authored as `'a'|'b'|'c'` in lolo). Not required at this variant. */\n values?: string[];\n};\n\n/** `type: 'enum'` REQUIRES the closed vocabulary in `values`. */\nexport type EnumEntityField = EntityFieldBase & {\n type: 'enum';\n /** Closed string vocabulary the field accepts. */\n values: string[];\n};\n\n/** `type: 'relation'` REQUIRES the relation target binding. */\nexport type RelationEntityField = EntityFieldBase & {\n type: 'relation';\n /** Relation target binding (entity + cardinality). */\n relation: RelationConfig;\n};\n\n/** `type: 'array'` — element schema in `items` strongly preferred but\n * optional for legacy compatibility with codegen-emitted scalar-array\n * fields (e.g. `{type: 'array', default: []}`). The lolo lowerer + Rust\n * validator catch typed-element-required cases downstream. */\nexport type ArrayEntityField = EntityFieldBase & {\n type: 'array';\n /** Element schema for the array. */\n items?: EntityField;\n};\n\n/**\n * `type: 'object'` — a fixed-key struct (fields in `properties`) OR a\n * dynamic-key map (`Map K V` in `.lolo`; the uniform value schema lives in\n * `items`, mirroring an array's element schema). A distinct variant so `items`\n * is statically allowed only on object/array fields, never on scalars.\n */\nexport type ObjectEntityField = EntityFieldBase & {\n type: 'object';\n /** Uniform value schema for a dynamic-key map (`Map K V`). */\n items?: EntityField;\n};\n\n/**\n * Entity field definition — discriminated union by `type`. Each variant\n * statically enforces its dependent payload (`values` for enum,\n * `relation` for relation, `items` for array) so TS / Zod / JSON Schema\n * consumers all agree on the dependency, not just the Rust validator.\n *\n * @example\n * { name: 'status', type: 'enum', values: ['draft', 'published'] }\n * { name: 'authorId', type: 'relation', relation: { entity: 'User', cardinality: 'one' } }\n * { name: 'tags', type: 'array', items: { type: 'string' } }\n */\nexport type EntityField =\n | ScalarEntityField\n | EnumEntityField\n | RelationEntityField\n | ArrayEntityField\n | ObjectEntityField;\n\n/**\n * Alias map for legacy/loose field-type spellings. Preprocessed into the\n * canonical `FieldType` enum before zod validates. Without this, agent-produced\n * schemas using `text`/`int`/`float`/`ts` were rejected at parse time — this\n * normalizes them so the rest of the pipeline sees only canonical types.\n */\nconst FIELD_TYPE_ALIASES: Record<string, FieldType> = {\n text: 'string',\n int: 'number',\n float: 'number',\n ts: 'timestamp',\n};\n\n/**\n * Zod schema for `EntityField`. Preprocess normalizes:\n * - legacy `type` aliases (text → string, int → number, etc.)\n * - legacy `enum: string[]` alias → `values: string[]`\n *\n * Branches on `type` so TS narrows the parsed output to the matching\n * discriminated-union variant.\n */\n// The third type param stays `unknown`: zod v3 bakes `unknown` into\n// `z.preprocess`'s input type, and the recursion needs the explicit annotation.\nexport const EntityFieldSchema: z.ZodType<EntityField, z.ZodTypeDef, unknown> = z.lazy(() => {\n const baseFieldShape = {\n name: z.string().min(1, 'Field name is required').optional(),\n required: z.boolean().optional(),\n default: JsonValueSchema.optional(),\n min: z.number().optional(),\n max: z.number().optional(),\n properties: z.record(EntityFieldSchema).optional(),\n intrinsic: z.boolean().optional(),\n description: z.string().optional(),\n synonyms: z.string().optional(),\n };\n\n /** Build a scalar variant schema. `values?` is permitted as a hint;\n * only the enum variant mandates a non-empty values array. */\n function scalarVariant<T extends ScalarFieldType>(t: T) {\n return z.object({\n ...baseFieldShape,\n type: z.literal(t),\n values: z.array(z.string()).optional(),\n });\n }\n\n return z.preprocess(\n (input) => {\n if (\n input === null ||\n typeof input !== 'object' ||\n !('type' in input) ||\n typeof (input as { type?: RuntimeValue }).type !== 'string'\n ) {\n return input;\n }\n const obj = input as { type: string; enum?: RuntimeValue; values?: RuntimeValue };\n const next: { type: string; enum?: RuntimeValue; values?: RuntimeValue } = { ...obj };\n const aliased = FIELD_TYPE_ALIASES[obj.type];\n if (aliased !== undefined) next.type = aliased;\n // Fold legacy `enum: string[]` into `values: string[]`.\n if (next.enum !== undefined && next.values === undefined) {\n next.values = next.enum;\n }\n delete next.enum;\n return next;\n },\n z.discriminatedUnion('type', [\n scalarVariant('string'),\n scalarVariant('number'),\n scalarVariant('boolean'),\n scalarVariant('date'),\n scalarVariant('timestamp'),\n scalarVariant('datetime'),\n scalarVariant('email'),\n scalarVariant('url'),\n scalarVariant('phone'),\n scalarVariant('uuid'),\n scalarVariant('image'),\n scalarVariant('trait'),\n scalarVariant('slot'),\n scalarVariant('pattern'),\n // Enum variant — REQUIRES non-empty values.\n z.object({\n ...baseFieldShape,\n type: z.literal('enum'),\n values: z.array(z.string()).min(1, 'Enum field requires a non-empty `values` array'),\n }),\n // Relation variant — REQUIRES relation config.\n z.object({\n ...baseFieldShape,\n type: z.literal('relation'),\n relation: RelationConfigSchema,\n }),\n // Array variant — items optional to match relaxed TS shape.\n z.object({\n ...baseFieldShape,\n type: z.literal('array'),\n items: EntityFieldSchema.optional(),\n }),\n // Object variant — fixed-key struct (`properties`) or dynamic-key\n // map (`Map K V`, uniform value schema in `items`).\n z.object({\n ...baseFieldShape,\n type: z.literal('object'),\n items: EntityFieldSchema.optional(),\n values: z.array(z.string()).optional(),\n }),\n ]),\n );\n});\n\nexport type EntityFieldInput = z.input<typeof EntityFieldSchema>;\n\n// ============================================================================\n// Type Aliases (for cleaner imports)\n// ============================================================================\n\n/** Alias for EntityField - preferred name */\nexport type Field = EntityField;\n\n/** Alias for EntityFieldSchema - preferred name */\nexport const FieldSchema = EntityFieldSchema;\n","/**\n * Asset Types for Semantic Asset References\n *\n * Defines types for abstracting asset paths into semantic references.\n * Assets are resolved from SemanticAssetRef to actual paths at compile time.\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\n\n// ============================================================================\n// Entity Roles\n// ============================================================================\n\n/**\n * Entity roles in game contexts\n */\nexport const ENTITY_ROLES = [\n 'player',\n 'enemy',\n 'npc',\n 'item',\n 'tile',\n 'projectile',\n 'effect',\n 'ui',\n 'decoration',\n 'vehicle',\n] as const;\n\nexport type EntityRole = (typeof ENTITY_ROLES)[number];\n\nexport const EntityRoleSchema = z.enum(ENTITY_ROLES);\n\n// ============================================================================\n// Visual Styles\n// ============================================================================\n\n/**\n * Visual art styles for games\n */\nexport const VISUAL_STYLES = ['pixel', 'vector', 'hd', '1-bit', 'isometric'] as const;\n\nexport type VisualStyle = (typeof VISUAL_STYLES)[number];\n\nexport const VisualStyleSchema = z.enum(VISUAL_STYLES);\n\n// ============================================================================\n// Asset Dimension + Aspect (render metadata carried with the asset / the need)\n// ============================================================================\n\n/**\n * Whether the asset is a 2D sprite/image or a 3D model. Set by the consuming\n * canvas: the same entity role is a 2D sprite-sheet on a tile board and a 3D\n * rigged model on a 3D board.\n */\nexport const ASSET_DIMENSIONS = ['2d', '3d'] as const;\n\nexport type AssetDimension = (typeof ASSET_DIMENSIONS)[number];\n\nexport const AssetDimensionSchema = z.enum(ASSET_DIMENSIONS);\n\n/**\n * Rendering aspect ratio of an asset: square (tiles/sprites/portraits/icons),\n * 16:9 (scene backdrops), 5:7 (cards), 8:1 (effect frame strips).\n */\nexport const ASSET_ASPECTS = ['1:1', '16:9', '5:7', '8:1'] as const;\n\nexport type AssetAspect = (typeof ASSET_ASPECTS)[number];\n\nexport const AssetAspectSchema = z.enum(ASSET_ASPECTS);\n\n// ============================================================================\n// Animation Name + Sheet Direction\n// ============================================================================\n\n/**\n * Animation names matching a sprite sheet's row layout. Canonical home for\n * this vocabulary — `@almadar/ui`'s `spriteAnimationTypes.ts` re-exports it\n * rather than redeclaring, so board `.lolo` config and the render library\n * agree on one enum.\n */\nexport const ANIMATION_NAMES = ['idle', 'walk', 'attack', 'hit', 'death'] as const;\n\nexport type AnimationName = (typeof ANIMATION_NAMES)[number];\n\nexport const AnimationNameSchema = z.enum(ANIMATION_NAMES);\n\n/**\n * Sheet file directions (physical PNG files a sprite sheet ships as).\n * Legacy hand-drawn packs ship only se/sw and mirror-flip for ne/nw (a cheat\n * that shows the face while walking away); 3D-baked sheets ship all four real\n * directions — the renderer prefers a real sheet and keeps the flip only as\n * the legacy fallback.\n */\nexport const SPRITE_DIRECTIONS = ['se', 'sw', 'ne', 'nw'] as const;\n\nexport type SpriteDirection = (typeof SPRITE_DIRECTIONS)[number];\n\nexport const SpriteDirectionSchema = z.enum(SPRITE_DIRECTIONS);\n\n/**\n * Camera projections a baked sprite sheet can ship. `iso` is directional\n * (se/sw physical sheets, ne/nw by mirror); `front`/`top`/`perspective` are\n * single fixed-camera sheets (the mesh reference-sheet camera vocabulary).\n */\nexport const SHEET_PROJECTIONS = ['iso', 'front', 'back', 'top', 'perspective'] as const;\n\nexport type SheetProjection = (typeof SHEET_PROJECTIONS)[number];\n\nexport const SheetProjectionSchema = z.enum(SHEET_PROJECTIONS);\n\n// ============================================================================\n// Animation Definition\n// ============================================================================\n\n/**\n * Definition for a single named animation within a sprite sheet: which row\n * it occupies, how many frames it has, and its playback rate. This is the\n * shape actually consumed by `@almadar/ui`'s sprite-sheet renderer\n * (`spriteAnimation.ts`'s `frameRect`/`getCurrentFrameFromDef`) — moved here\n * verbatim rather than reconciled with a differently-shaped guess, since\n * `@almadar/ui`'s version is the one with real production consumers.\n */\nexport interface AnimationDef {\n /** Row index in the sprite sheet (0-based; each animation occupies one row). */\n row: number;\n /** Number of frames in this animation. */\n frames: number;\n /** Frames per second. */\n frameRate: number;\n /** Whether the animation loops. */\n loop: boolean;\n}\n\nexport const AnimationDefSchema = z.object({\n row: z.number().int().nonnegative(),\n frames: z.number().int().positive(),\n frameRate: z.number().positive(),\n loop: z.boolean(),\n});\n\n// ============================================================================\n// Sprite Sheet Atlas\n// ============================================================================\n\n/**\n * Parsed sprite-sheet atlas JSON — the contract a `spriteSheet`-role `Asset.url`\n * resolves to when fetched (see `Asset.url` usage in `@almadar/ui`'s\n * `useUnitSpriteAtlas`). A unit's `sprite?: Asset` stays the static single-pose\n * image; `spriteSheet?: Asset` is a SEPARATE reference whose URL points at a\n * `SpriteSheetAtlas`-shaped JSON manifest (e.g. `.../guardian-sprite-sheet.json`),\n * not a PNG. Frame-cutting geometry lives here, not inlined onto `Asset` — an\n * `Asset` traveling through `render-ui` every tick stays small.\n */\nexport interface SpriteSheetAtlas {\n /** Unit archetype key. */\n unit?: string;\n /** Visual type key. */\n type?: string;\n /** Width of a single frame in pixels. */\n frameWidth: number;\n /** Height of a single frame in pixels. */\n frameHeight: number;\n /** Number of columns (frames per row). */\n columns: number;\n /** Number of rows (animations). */\n rows: number;\n /** Directions present as physical PNG files. */\n directions: SpriteDirection[];\n /** Relative PNG sheet paths per direction. */\n sheets: Partial<Record<SpriteDirection, string>>;\n /** Animation row layout keyed by animation name. */\n animations: Partial<Record<AnimationName, AnimationDef>>;\n /**\n * Per-projection sheet PNGs (additive; absent on legacy atlases). `iso`\n * mirrors `sheets` (directional se/sw); the fixed cameras carry one sheet\n * each. `sheets` remains the iso back-compat alias — writers emit both.\n */\n projections?: {\n iso?: Partial<Record<SpriteDirection, string>>;\n front?: string;\n back?: string;\n top?: string;\n perspective?: string;\n };\n}\n\nexport const SpriteSheetAtlasSchema = z.object({\n unit: z.string().optional(),\n type: z.string().optional(),\n frameWidth: z.number().positive(),\n frameHeight: z.number().positive(),\n columns: z.number().int().positive(),\n rows: z.number().int().positive(),\n directions: z.array(SpriteDirectionSchema),\n sheets: z.record(SpriteDirectionSchema, z.string()),\n animations: z.record(AnimationNameSchema, AnimationDefSchema),\n projections: z\n .object({\n iso: z.record(SpriteDirectionSchema, z.string()).optional(),\n front: z.string().optional(),\n back: z.string().optional(),\n top: z.string().optional(),\n perspective: z.string().optional(),\n })\n .optional(),\n});\n\n// ============================================================================\n// Texture Atlas — named-subrect packed sheet (the industry standard)\n// ============================================================================\n\n/**\n * One named sub-rectangle inside a packed sheet. Mirrors the ShoeBox /\n * TexturePacker `<SubTexture>` element every Kenney `Spritesheet/*.xml` ships\n * (`x`/`y`/`width`/`height` = the rect in the sheet PNG; `frameX`/`frameY`/\n * `frameWidth`/`frameHeight` = the trim/pad offsets for sprites packed with\n * transparent edges removed — optional, present only on trimmed atlases).\n */\nexport interface SubTexture {\n x: number;\n y: number;\n width: number;\n height: number;\n frameX?: number;\n frameY?: number;\n frameWidth?: number;\n frameHeight?: number;\n}\n\nexport const SubTextureSchema = z.object({\n x: z.number().nonnegative(),\n y: z.number().nonnegative(),\n width: z.number().positive(),\n height: z.number().positive(),\n frameX: z.number().optional(),\n frameY: z.number().optional(),\n frameWidth: z.number().positive().optional(),\n frameHeight: z.number().positive().optional(),\n});\n\n/**\n * A packed sheet + its named sub-rectangles — the canonical parse target for a\n * Kenney `Spritesheet/*.xml` atlas. A STATIC tile/prop/UI Asset references one\n * of these: `{ url: <sheet.png>, atlas: <this.json>, sprite: \"grass.png\" }` →\n * the renderer fetches the sheet + atlas ONCE and blits the named sub-rect,\n * instead of loading N individual PNGs. (Animated actors use `SpriteSheetAtlas`\n * instead; a uniform-grid tile page uses `Tilesheet`.)\n */\nexport interface TextureAtlas {\n /** Relative path to the sheet PNG the sub-rects index into (the atlas's own `imagePath`). */\n imagePath: string;\n /** Sub-rectangles keyed by their atlas name (e.g. `\"grass.png\"`). */\n subTextures: Record<string, SubTexture>;\n}\n\nexport const TextureAtlasSchema = z.object({\n imagePath: z.string(),\n subTextures: z.record(z.string(), SubTextureSchema),\n});\n\n// ============================================================================\n// Tilesheet — uniform-grid packed page (cut by index)\n// ============================================================================\n\n/**\n * A uniform-grid tile page — the shape a Kenney `Tilesheet/` sheet takes (e.g.\n * Pirate Pack: \"each tile is 64×64, no margin\"). Tiles are cut by `(col,row)`\n * index rather than by named rect. `names` is present only when a sibling\n * `.xml`/`.txt` supplies an index→name list; otherwise a tile is addressed by\n * its `\"col,row\"` (or flat index) via `Asset.sprite`.\n */\nexport interface Tilesheet {\n /** Relative path to the tile sheet PNG. */\n imagePath: string;\n /** Width of one tile cell in pixels. */\n tileWidth: number;\n /** Height of one tile cell in pixels. */\n tileHeight: number;\n /** Number of columns in the grid. */\n columns: number;\n /** Number of rows in the grid. */\n rows: number;\n /** Outer margin before the first tile, in pixels (default 0). */\n margin?: number;\n /** Gap between adjacent tiles, in pixels (default 0). */\n spacing?: number;\n /** Optional index→name labels when a descriptor supplies them. */\n names?: string[];\n}\n\nexport const TilesheetSchema = z.object({\n imagePath: z.string(),\n tileWidth: z.number().positive(),\n tileHeight: z.number().positive(),\n columns: z.number().int().positive(),\n rows: z.number().int().positive(),\n margin: z.number().nonnegative().optional(),\n spacing: z.number().nonnegative().optional(),\n names: z.array(z.string()).optional(),\n});\n\n// ============================================================================\n// Semantic Asset Reference\n// ============================================================================\n\n/**\n * Semantic reference to an asset (not a hardcoded path).\n * Resolved to actual paths at compile time via asset maps.\n */\nexport type SemanticAssetRef = {\n /**\n * Entity role — a free string. Core no longer constrains the vocabulary to\n * `EntityRole` (that enum stays an exported shared reference for the asset\n * tool + renderer); genre boards may use their own roles (`boss`, `tower`, …).\n */\n role: string;\n /** Sub-category within role (hero, slime, coin, etc.) */\n category: string;\n /** Required animations for this entity */\n animations?: string[];\n /** Visual style preference */\n style?: VisualStyle;\n /** Variant identifier (for multiple versions) */\n variant?: string;\n /** 2D sprite vs 3D model — the rendering dimension the consuming canvas needs. */\n dimension?: AssetDimension;\n /** Rendering aspect ratio (square sprite/portrait/tile, 16:9 backdrop, 5:7 card, 8:1 fx-strip). */\n aspect?: AssetAspect;\n};\n\nexport const SemanticAssetRefSchema = z.object({\n role: z.string().min(1),\n category: z.string().min(1),\n animations: z.array(z.string()).optional(),\n style: VisualStyleSchema.optional(),\n variant: z.string().optional(),\n dimension: AssetDimensionSchema.optional(),\n aspect: AssetAspectSchema.optional(),\n});\n\n// ============================================================================\n// Asset — the UNIFIED asset type\n// ============================================================================\n\n/**\n * The single asset type: a `SemanticAssetRef` (role/dimension/animations/aspect/style)\n * WITH its resolved URL folded in. Used everywhere an asset is referenced — a lolo\n * board `assetManifest` (`Map string Asset`), every `@almadar/ui` game prop, the\n * asset-workflow's resolved/pool assets, and the inspector picker. Replaces the bare\n * `AssetUrl`-string asset field so the render metadata travels WITH the asset (no\n * pixel-dimension or filename heuristics needed to know sheet-vs-frame / 2d-vs-3d).\n */\nexport interface Asset extends SemanticAssetRef {\n /** The resolved asset URL. When `atlas`/`sprite` are set this is the SHEET png; otherwise a standalone image. */\n url: AssetUrl;\n /**\n * Optional atlas JSON (a `TextureAtlas` or `Tilesheet`) that slices `url`.\n * When present with `sprite`, the renderer fetches sheet + atlas once and\n * blits one sub-rect instead of loading a standalone PNG. Absent → `url` is\n * a plain whole-image asset (the existing, non-atlas path).\n */\n atlas?: AssetUrl;\n /**\n * The sub-texture selector within `atlas`: a `SubTexture` name for a\n * `TextureAtlas` (e.g. `\"grass.png\"`), or a `\"col,row\"`/flat index for a\n * `Tilesheet`. Only meaningful alongside `atlas`.\n */\n sprite?: string;\n /** Optional display name (inspector picker). */\n name?: string;\n /** Optional thumbnail URL (inspector picker grid). */\n thumbnailUrl?: string;\n}\n\nexport const AssetSchema = SemanticAssetRefSchema.extend({\n url: z.string(),\n atlas: z.string().optional(),\n sprite: z.string().optional(),\n name: z.string().optional(),\n thumbnailUrl: z.string().optional(),\n});\n\n// ============================================================================\n// Asset Catalog\n// ============================================================================\n\n/**\n * Single browsable asset in the inspector picker catalog.\n * Backs the asset/icon pickers — a flat list the inspector renders for\n * the user to choose from when a config field's type is `'asset'`.\n */\nexport interface AssetCatalogEntry {\n /** Resolvable URL to the asset. */\n url: string;\n /** Display name for the asset. */\n name: string;\n /** Grouping category within the catalog. */\n category: string;\n /** Asset kind the picker dispatches on. */\n kind: 'image' | 'spritesheet' | 'audio' | 'scene' | 'portrait' | 'model' | 'other';\n /** Optional thumbnail URL for grid previews. */\n thumbnailUrl?: string;\n /** 2D sprite vs 3D model — the asset's actual rendering dimension. */\n dimension?: AssetDimension;\n /** The asset's actual rendering aspect ratio. */\n aspect?: AssetAspect;\n}\n\nexport const AssetCatalogEntrySchema = z.object({\n url: z.string(),\n name: z.string(),\n category: z.string(),\n kind: z.enum(['image', 'spritesheet', 'audio', 'scene', 'portrait', 'model', 'other']),\n thumbnailUrl: z.string().optional(),\n dimension: AssetDimensionSchema.optional(),\n aspect: AssetAspectSchema.optional(),\n});\n\n/**\n * Flat list of browsable assets surfaced by the inspector pickers.\n */\nexport type AssetCatalog = AssetCatalogEntry[];\n\nexport const AssetCatalogSchema = z.array(AssetCatalogEntrySchema);\n\n/**\n * Asset-reference URL marker. A plain alias over `string` — the value is a\n * resolvable asset URL — but the named type lets the pattern-sync tool\n * (`tools/almadar-pattern-sync/parser.ts`) detect a component prop as an asset\n * field (tagged `asset`) the same way `EventKey`/`LucideIcon` are detected by\n * type identity. Components annotate image/url props as `AssetUrl` (`src`,\n * `backgroundImage`, `avatar`, …); the generator emits a `string` config knob\n * declared as the `asset` config type, which the property inspector dispatches\n * an AssetPicker on. Not branded — asset urls originate from user data, so cast\n * friction would buy nothing; the value is the marker the tool finds.\n */\nexport type AssetUrl = string;\n\n// ============================================================================\n// ScenePos — neutral scene coordinate\n// ============================================================================\n\n/**\n * A neutral position in scene space: 2D (`x`,`y`) or optionally 3D (`x`,`y`,`z`).\n * The single coordinate type shared by every drawable descriptor and camera pose\n * across the 2D and 3D canvas hosts, so a scene composes from the same `{x,y,z?}`\n * regardless of projection or painter. Logical, not pixel — the host's projector\n * maps a `ScenePos` to screen space.\n */\nexport interface ScenePos {\n x: number;\n y: number;\n z?: number;\n}\n\nexport const ScenePosSchema = z.object({\n x: z.number(),\n y: z.number(),\n z: z.number().optional(),\n});\n\n// ============================================================================\n// Camera — neutral camera pose shared by the 2D and 3D canvas hosts\n// ============================================================================\n\n/**\n * Camera behaviors, unifying the former per-host vocab (2D `camera` string +\n * 3D `cameraMode`). `isometric`/`top-down`/`front` are fixed framings (`front` =\n * the straight-on flat elevation — side-scroller / reference-sheet view);\n * `follow`/`chase` track a target; `perspective` is the 3D dramatic framing.\n */\nexport const CAMERA_MODES = ['isometric', 'perspective', 'top-down', 'front', 'follow', 'chase'] as const;\n\nexport type CameraMode = (typeof CAMERA_MODES)[number];\n\nexport const CameraModeSchema = z.enum(CAMERA_MODES);\n\n/**\n * A neutral camera pose shared by the 2D and 3D canvas hosts, so `type: canvas`\n * carries one camera object regardless of painter. `pos`/`target` are `ScenePos`\n * (logical scene space, not pixels); `zoom` scales the view (the former `scale`);\n * `fov` is the 3D field of view; `mode` selects the framing/tracking behavior.\n * Every field is optional — an omitted camera means the host's default framing.\n */\nexport interface Camera {\n pos?: ScenePos;\n target?: ScenePos;\n zoom?: number;\n fov?: number;\n mode?: CameraMode;\n /** Orbit the mode's framing position around the vertical axis through the target, in radians (3D hosts only). */\n azimuth?: number;\n}\n\nexport const CameraSchema = z.object({\n pos: ScenePosSchema.optional(),\n target: ScenePosSchema.optional(),\n zoom: z.number().optional(),\n fov: z.number().optional(),\n mode: CameraModeSchema.optional(),\n azimuth: z.number().optional(),\n});\n\n// ============================================================================\n// Type Exports\n// ============================================================================\n\nexport type SemanticAssetRefInput = z.input<typeof SemanticAssetRefSchema>;\nexport type AnimationDefInput = z.input<typeof AnimationDefSchema>;\nexport type AssetCatalogEntryInput = z.input<typeof AssetCatalogEntrySchema>;\nexport type SpriteSheetAtlasInput = z.input<typeof SpriteSheetAtlasSchema>;\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Creates a semantic asset key from role and category.\n * \n * Generates a unique asset identifier by combining role and category\n * with a colon separator. Used for asset management and lookup.\n * \n * @param {EntityRole} role - Entity role (e.g., 'player', 'enemy')\n * @param {string} category - Asset category (e.g., 'sprite', 'animation')\n * @returns {string} Asset key in format 'role:category'\n * \n * @example\n * createAssetKey('player', 'sprite'); // returns 'player:sprite'\n * createAssetKey('enemy', 'animation'); // returns 'enemy:animation'\n */\nexport function createAssetKey(role: EntityRole, category: string): string {\n return `${role}:${category}`;\n}\n\n/**\n * Parses an asset key into role and category components.\n * \n * Deconstructs an asset key string (format 'role:category') into its\n * constituent parts. Returns null if the key format is invalid.\n * \n * @param {string} key - Asset key in format 'role:category'\n * @returns {{ role: string; category: string } | null} Parsed components or null\n * \n * @example\n * parseAssetKey('player:sprite'); // returns { role: 'player', category: 'sprite' }\n * parseAssetKey('enemy:animation'); // returns { role: 'enemy', category: 'animation' }\n * parseAssetKey('invalid'); // returns null\n */\nexport function parseAssetKey(key: string): { role: string; category: string } | null {\n const parts = key.split(':');\n if (parts.length !== 2) return null;\n return { role: parts[0], category: parts[1] };\n}\n\n/**\n * Gets common animations for an entity role.\n * \n * Returns an array of default animation names appropriate for the\n * specified entity role. Used for asset configuration and validation.\n * \n * @param {EntityRole} role - Entity role\n * @returns {string[]} Array of default animation names\n * \n * @example\n * getDefaultAnimationsForRole('player'); // returns ['idle', 'run', 'jump', 'fall', 'attack', 'hurt', 'die']\n * getDefaultAnimationsForRole('enemy'); // returns ['idle', 'walk', 'attack', 'hurt', 'die']\n */\nexport function getDefaultAnimationsForRole(role: EntityRole): string[] {\n switch (role) {\n case 'player':\n return ['idle', 'run', 'jump', 'fall', 'attack', 'hurt', 'die'];\n case 'enemy':\n return ['idle', 'walk', 'attack', 'hurt', 'die'];\n case 'npc':\n return ['idle', 'walk', 'talk'];\n case 'item':\n return ['idle', 'collected'];\n case 'tile':\n return ['static'];\n case 'projectile':\n return ['fly', 'hit', 'expire'];\n case 'effect':\n return ['play'];\n case 'ui':\n return ['normal', 'hover', 'pressed', 'disabled'];\n case 'decoration':\n return ['idle'];\n case 'vehicle':\n return ['idle', 'move', 'brake'];\n default:\n return ['idle'];\n }\n}\n\n/**\n * Validates that an asset reference has required animations.\n * \n * Checks if an asset reference contains all required animations.\n * Returns an error message if validation fails, or null if valid.\n * \n * @param {SemanticAssetRef} assetRef - Asset reference to validate\n * @param {string[]} requiredAnimations - Required animation names\n * @returns {string | null} Error message or null if valid\n * \n * @example\n * validateAssetAnimations(assetRef, ['idle', 'run']); // returns null if valid\n * validateAssetAnimations(assetRef, ['missing-animation']); // returns error message\n */\nexport function validateAssetAnimations(\n assetRef: SemanticAssetRef,\n requiredAnimations: string[]\n): { valid: boolean; missing: string[] } {\n const provided = assetRef.animations || [];\n const missing = requiredAnimations.filter((anim) => !provided.includes(anim));\n return { valid: missing.length === 0, missing };\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';\nimport type { RuntimeValue } from './json.js';\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 */\n/** Object literal branch of an S-expression atom (payload data, props, etc.). */\nexport interface SExprObject {\n [key: string]: SExpr;\n}\nexport type SExprAtom = string | number | boolean | null | SExprObject;\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 * Recursive schema for s-expr-shaped DATA in literal positions (object\n * values, effect arguments). Unlike `SExprSchema`, arrays may be empty or\n * non-operator-headed — literal data lists (`children: []`, `tiles: [...]`)\n * are valid here; only call positions get the operator-head refine.\n */\nexport const SExprDataSchema: z.ZodType<SExpr> = z.lazy(() =>\n z.union([SExprAtomSchema, z.array(SExprDataSchema)]),\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(SExprDataSchema), // 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: RuntimeValue): 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 {RuntimeValue} 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: RuntimeValue): 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 {RuntimeValue} 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: RuntimeValue): 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 {RuntimeValue} 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: RuntimeValue): 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 * `user` is the authenticated user / agent context (see binding.ts) and is\n * read-only in guards/effects/ticks — atoms reference `@user.id` and\n * `@user.role` for ownership / role-based gating.\n * `callsitePayload` is the call-site-captured event payload emitted by the\n * compiler's inline-trait hoisting; the runtime BindingResolver resolves it\n * at the composing effect.\n */\nexport const CORE_BINDINGS = ['entity', 'payload', 'state', 'now', 'config', 'computed', 'trait', 'user', 'callsitePayload'] 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// ============================================================================\n// Runtime Evaluation Types\n// ============================================================================\n\n/** Evaluation context for guards and s-expressions. Recursive. */\nexport interface EvalContext {\n [key: string]: string | number | boolean | Date | null | string[] | EvalContext | undefined;\n}\n\n/**\n * A single value carried by an event payload field. The top-level payload\n * is always an object; the VALUES in that object can be primitives, nested\n * objects, or arrays of the same. Arrays are allowed so real-world emits\n * like `{ files: [{ name, size, type }, ...] }` or `{ selected: string[] }`\n * are typed natively instead of forcing consumers to wrap at every call.\n *\n * `Date` is included so `EntityRow` (whose values are `FieldValue`, which\n * includes `Date`) is assignable to a payload field without a cast —\n * emitted entity rows flow through the bus without boundary widening.\n */\nexport type EventPayloadValue =\n | string\n | number\n | boolean\n | Date\n | null\n | undefined\n | EventPayload\n | readonly EventPayloadValue[];\n\n/**\n * Typed event payload. Object-shaped so it's assignable to the bus's\n * `EventPayload` parameter without casts.\n */\nexport interface EventPayload {\n [key: string]: EventPayloadValue;\n}\n\n/**\n * Runtime guard for `EventPayloadValue` — narrows interpreter-produced\n * `unknown` values at typed substrate boundaries (e.g. `TraceContext.emit`).\n */\nexport function isEventPayloadValue(value: RuntimeValue): value is EventPayloadValue {\n if (value === null || value === undefined) return true;\n const kind = typeof value;\n if (kind === 'string' || kind === 'number' || kind === 'boolean') return true;\n if (value instanceof Date) return true;\n if (Array.isArray(value)) return value.every((item: RuntimeValue) => isEventPayloadValue(item));\n if (kind === 'object' && value !== null && typeof value === 'object') {\n return Object.values(value).every((item: RuntimeValue) => isEventPayloadValue(item));\n }\n return false;\n}\n\n/**\n * Allowed leaf value for `LogMeta`. Mirrors `EventPayloadValue` shape so\n * the same row/list data flows through logs without manual flattening,\n * with `Error` added since structured logs carry exception detail.\n */\nexport type LogMetaValue =\n | string\n | number\n | boolean\n | Date\n | null\n | undefined\n | Error\n | LogMeta\n | readonly LogMetaValue[];\n\n/** Structured log/event metadata. Recursive to support nested log data. */\nexport interface LogMeta {\n [key: string]: LogMetaValue;\n}\n","/**\n * Entity Types for Orbital Units\n *\n * Defines the OrbitalEntity type - the nucleus of an Orbital Unit.\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\nimport type { EntityId } from './identity.js';\nimport { EntityFieldSchema, type EntityField } from './field.js';\nimport { SemanticAssetRefSchema, type SemanticAssetRef } from './asset.js';\nimport { JsonValueSchema, type RuntimeValue } from './json.js';\nimport { SExprSchema, type SExpr } from './expression.js';\n\n// ============================================================================\n// Entity Persistence\n// ============================================================================\n\n/**\n * Entity persistence types.\n *\n * - persistent: Stored in database (has collection)\n * - runtime: Exists only at runtime (not persisted)\n */\nexport type EntityPersistence = 'persistent' | 'runtime';\n\nexport const EntityPersistenceSchema = z.enum([\n 'persistent',\n 'runtime',\n]);\n\n// ============================================================================\n// Orbital Entity\n// ============================================================================\n\n/**\n * OrbitalEntity - the nucleus of an Orbital Unit.\n *\n * This is a simplified entity definition optimized for orbital composition.\n * Collection names are derived automatically from persistence type if not provided.\n */\nexport type OrbitalEntity = {\n /** V4 dual-carry id sibling of `name` — optional until the Phase-7 flip. */\n id?: EntityId;\n\n /** Entity name (PascalCase, e.g., \"Task\", \"User\") */\n name: string;\n\n /** Entity persistence type (defaults to 'persistent' if not specified) */\n persistence?: EntityPersistence;\n\n /** Whether this entity's state is shared across all bound traits (vs per-trait copy). Orthogonal to persistence. */\n shared?: boolean;\n\n /**\n * Whether this entity types the ambient `@user` viewer. Orthogonal to both\n * `persistence` and `shared`: `[persistent: people, identity]` is an\n * app-owned user directory, `[runtime, identity]` the provider-supplied\n * current viewer. At most one per composed program.\n */\n identity?: boolean;\n\n /**\n * `@read` — a per-row predicate (`@entity` = candidate row, `@user` =\n * viewer) ANDed with any call-site `filter:`. The un-bypassable twin of\n * `filter:`, enforced once for every trait that fetches this entity.\n */\n read_policy?: SExpr;\n\n /** `@create` — `@entity` binds the incoming data about to become a row. */\n create_policy?: SExpr;\n\n /** `@update` — `@entity` binds the existing row before mutation. */\n update_policy?: SExpr;\n\n /** `@delete` — same binding shape as `@update`. */\n delete_policy?: SExpr;\n\n /**\n * `@<op> none \"<reason>\"` — a directive's omission, DECLARED.\n *\n * Runtime behaviour is identical to leaving the directive out (an absent\n * policy is allow-all). It records that the author concluded no per-row\n * predicate can express the rule — usually because visibility depends on a\n * DIFFERENT entity, which a per-row predicate cannot join across. Without\n * it a lint must flag considered and forgotten omissions alike, and a lint\n * that flags correct code is one people learn to ignore.\n */\n access_waivers?: {\n read?: string;\n create?: string;\n update?: string;\n delete?: string;\n };\n\n /** Collection name (auto-derived if not provided for persistent entities) */\n collection?: string;\n\n /** Entity fields */\n fields: EntityField[];\n\n /** Pre-authored instances (seed data or static reference data) */\n instances?: EntityRow[];\n\n /** Auto-add createdAt/updatedAt timestamps */\n timestamps?: boolean;\n\n /** Soft delete support */\n softDelete?: boolean;\n\n /** Human-readable description */\n description?: string;\n\n /** Visual prompt for AI generation */\n visual_prompt?: string;\n\n /** Semantic asset reference for visual representation (games) */\n assetRef?: SemanticAssetRef;\n};\n\nexport const OrbitalEntitySchema = z.object({\n name: z.string().min(1, 'Entity name is required'),\n persistence: EntityPersistenceSchema.default('persistent'),\n shared: z.boolean().optional(),\n // Must stay in step with the Rust serde field (`EntityDefinition.identity`,\n // orbital-core/src/schema/types.rs). `z.object()` STRIPS unknown keys rather\n // than rejecting them, so a Rust-only field works on the compiled path and\n // silently vanishes on the interpreter path.\n identity: z.boolean().optional(),\n // Same \"must stay in step with Rust serde\" hazard as `identity` above —\n // these four mirror `EntityDefinition.{read,create,update,delete}_policy`.\n // Rust has no `rename_all` on this struct, so the wire key IS snake_case\n // (unlike this file's other camelCase fields, which are Rust-side-absent\n // and so never hit this cross-language constraint — see `visual_prompt`\n // just below for the existing precedent).\n read_policy: SExprSchema.optional(),\n create_policy: SExprSchema.optional(),\n update_policy: SExprSchema.optional(),\n delete_policy: SExprSchema.optional(),\n // Snake_case for the same cross-language reason as the four policies above.\n access_waivers: z\n .object({\n read: z.string().optional(),\n create: z.string().optional(),\n update: z.string().optional(),\n delete: z.string().optional(),\n })\n .optional(),\n collection: z.string().optional(),\n fields: z.array(EntityFieldSchema).min(1, 'At least one field is required'),\n instances: z.array(z.record(JsonValueSchema)).optional(),\n timestamps: z.boolean().optional(),\n softDelete: z.boolean().optional(),\n description: z.string().optional(),\n visual_prompt: z.string().optional(),\n assetRef: SemanticAssetRefSchema.optional(),\n});\n\nexport type OrbitalEntityInput = z.input<typeof OrbitalEntitySchema>;\n\n// ============================================================================\n// Type Aliases (for cleaner imports)\n// ============================================================================\n\n/** Alias for OrbitalEntity - preferred name */\nexport type Entity = OrbitalEntity;\n\n/** Alias for OrbitalEntitySchema - preferred name */\nexport const EntitySchema = OrbitalEntitySchema;\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Derives the collection name for a persistent entity.\n * \n * Generates the database collection name by converting the entity name\n * to lowercase and adding an 's' suffix (simple pluralization).\n * Returns undefined for non-persistent (runtime) entities.\n * \n * @param {OrbitalEntity} entity - Entity to derive collection name for\n * @returns {string | undefined} Collection name or undefined for non-persistent entities\n * \n * @example\n * deriveCollection({ name: 'User', persistence: 'persistent' }); // returns 'users'\n * deriveCollection({ name: 'Task', persistence: 'runtime' }); // returns undefined\n */\nexport function deriveCollection(entity: OrbitalEntity): string | undefined {\n if (entity.persistence !== 'persistent') {\n return undefined;\n }\n // Lowercase + 's' suffix (simple pluralization)\n return entity.name.toLowerCase() + 's';\n}\n\n/**\n * Checks if an entity is runtime-only (not persisted).\n * \n * Type guard to determine if an entity exists only at runtime\n * and is not stored in the database.\n * \n * @param {OrbitalEntity} entity - Entity to check\n * @returns {boolean} True if entity is runtime-only, false otherwise\n * \n * @example\n * isRuntimeEntity({ persistence: 'runtime' }); // returns true\n * isRuntimeEntity({ persistence: 'persistent' }); // returns false\n */\nexport function isRuntimeEntity(entity: OrbitalEntity): boolean {\n return entity.persistence === 'runtime';\n}\n\n/**\n * Checks whether an entity's persistence mode allows `persistence` /\n * `collection` overrides at the factory call site.\n *\n * Only `persistent` entities (explicit or default) support these overrides.\n * Runtime entities are fixed; callers must not expose `persistence` or\n * `collection` params for them.\n *\n * @param persistence - The entity persistence mode (undefined = default persistent)\n * @returns True when overrides are allowed, false otherwise\n *\n * @example\n * persistenceModeAllowsOverrides('persistent'); // returns true\n * persistenceModeAllowsOverrides('runtime'); // returns false\n * persistenceModeAllowsOverrides(undefined); // returns true (default persistent)\n */\nexport function persistenceModeAllowsOverrides(\n persistence: EntityPersistence | undefined,\n): boolean {\n return persistence === 'persistent' || persistence === undefined;\n}\n\n// ============================================================================\n// Entity Instance Data (Runtime)\n// ============================================================================\n\n/**\n * A single field value at runtime.\n * Union of all possible types from FieldType: string, number, boolean, date, array, nested.\n * The nested-record branch's index signature tolerates `undefined` so that\n * TypeScript optional properties (`x?: string`, carrying `string | undefined`)\n * on EntityRow extenders typecheck without ceremony. At JSON serialization\n * time `undefined` is equivalent to \"key absent\" and never appears on the\n * wire; the inclusion here is a pure type-surface accommodation.\n */\nexport type FieldValue = string | number | boolean | Date | null | string[] | FieldValue[] | { [key: string]: FieldValue | undefined };\n\n/**\n * Runtime guard for `FieldValue` — narrows interpreter-produced `unknown`\n * values at typed substrate boundaries (e.g. `IntegrationContext.http` body).\n */\nexport function isFieldValue(value: RuntimeValue): value is FieldValue {\n if (value === null) return true;\n const kind = typeof value;\n if (kind === 'string' || kind === 'number' || kind === 'boolean') return true;\n if (value instanceof Date) return true;\n if (Array.isArray(value)) return value.every((item: RuntimeValue) => isFieldValue(item));\n if (kind === 'object' && value !== null && typeof value === 'object') {\n return Object.values(value).every((item: RuntimeValue) => item === undefined || isFieldValue(item));\n }\n return false;\n}\n\n/**\n * One instance of an entity with actual field values.\n * The shape is determined by the Entity definition at schema time.\n *\n * @example\n * // Entity defines: Patient { fullName: string, age: number, active: boolean }\n * // EntityRow is: { id: \"p1\", fullName: \"Sarah\", age: 34, active: true }\n */\nexport type EntityRow = { id?: string } & Record<string, FieldValue | undefined>;\n\n/**\n * A field-TYPED `EntityRow` — the SINGLE entity type, refined with a concrete\n * field SHAPE `S`. Non-optional members of `S` are REQUIRED, each with its real\n * type; the result stays `& EntityRow`, so the index signature is intact and\n * every other field is still field-open — any domain entity that provides those\n * fields satisfies it.\n *\n * One declaration, two jobs: (1) TypeScript enforces the bound entity has the\n * fields WITH their types (a behavior binding a thinner/mistyped entity fails to\n * typecheck); and (2) pattern-sync reads the same type and writes the entity\n * prop's field shape (`properties` + `requiredFields`) onto the registry, so\n * lolo-ui emits a COMPLETE `entity { … }` (every field, typed + demo-seeded) and\n * the `ORB_X_ENTITY_PROP_CONTRACT` validator rejects an incompatible bind at\n * `orbital validate`. (A raw `EntityRow & { rating: number }` intersection is\n * equivalent for one-off shapes.)\n *\n * @example\n * // HeroOrganism renders entity.title / entity.subtitle:\n * entity?: EntityWith<{ title: string; subtitle?: string }>;\n * // entity.title → string (required)\n * // entity.subtitle → string | undefined (optional)\n * // entity.other → FieldValue | undefined (still field-open)\n */\n// `S extends object` (not `Record<string, FieldValue>`) so a plain `interface`\n// row shape satisfies it — interfaces lack the implicit index signature `Record`\n// requires. FieldValue-compatibility is still enforced structurally: `& EntityRow`\n// intersects every field with the `FieldValue | undefined` index signature, so a\n// non-FieldValue field (e.g. a React `LucideIcon`) collapses to `never` at use.\nexport type EntityWith<S extends object> = EntityRow & S;\n\n/**\n * Collection of entity instances keyed by entity name.\n * Used by OrbPreview mockData, OrbitalServerRuntime state, data grids, etc.\n *\n * @example\n * const data: EntityData = {\n * Patient: [{ id: \"1\", fullName: \"Sarah\", age: 34 }],\n * QueueEntry: [{ id: \"1\", patientName: \"Sarah\", waitMinutes: 12 }],\n * };\n */\nexport type EntityData = Record<string, EntityRow[]>;\n","/**\n * The one owner of mock-seed value synthesis.\n *\n * Five synthesizers used to hold four different policies on a field's declared\n * `default`, so the same entity seeded differently depending on which path\n * rendered it. This module is the single policy; callers supply only entropy.\n *\n * @packageDocumentation\n */\n\nimport type {\n ArrayEntityField,\n EntityField,\n ObjectEntityField,\n RelationEntityField,\n} from '../types/field.js';\nimport type { EntityPersistence, EntityRow, FieldValue } from '../types/entity.js';\nimport { isFieldValue } from '../types/entity.js';\nimport {\n randomBoolean,\n randomEmail,\n randomInt,\n randomPhone,\n randomStraddlingDate,\n randomUrl,\n randomUuid,\n randomWords,\n} from './random.js';\n\n/**\n * Entropy source. `'seeded'` draws from the shared LCG — stateful and\n * order-dependent, so a value depends on how many draws earlier rows consumed.\n * `'index'` is a pure function of `(field, index)`, which is the only strategy\n * Rust can reproduce and therefore the one parity is asserted on.\n */\nexport type SampleStrategy = 'seeded' | 'index';\n\n/** Recursion cap for self-referential `items` / `properties` walks. */\nconst MAX_NESTED_DEPTH = 3;\n\n/** Keys never synthesized — the caller's row loop owns them. */\nconst RESERVED_FIELD_NAMES: ReadonlySet<string> = new Set(['id', 'createdAt', 'updatedAt']);\n\nexport interface SampleEntity {\n readonly name: string;\n readonly persistence?: EntityPersistence;\n readonly fields: readonly EntityField[];\n}\n\nexport interface SampleContext {\n readonly entityName: string;\n /** 1-based row ordinal. Row 1 always yields `values[0]`. */\n readonly index: number;\n readonly strategy: SampleStrategy;\n /** Declared persistence of the OWNING entity; undefined means persistent. */\n readonly persistence?: EntityPersistence;\n readonly depth?: number;\n}\n\n/**\n * Image-bearing field names that still resolve to a real photo.\n *\n * A stopgap, kept verbatim from the two copies it replaces: no entity field in\n * the corpus can express an image type yet, and 470 string fields are named\n * this way, so deleting it would render broken `<img>` corpus-wide. Retire it\n * once a real `image` type exists — not before.\n */\nexport const IMAGE_FIELD_NAMES: ReadonlySet<string> = new Set([\n 'image', 'imageurl', 'image_url',\n 'photo', 'photourl', 'photo_url',\n 'avatar', 'avatarurl', 'avatar_url',\n 'thumbnail', 'thumbnailurl', 'thumbnail_url',\n 'picture', 'pictureurl',\n 'cover', 'coverurl',\n 'banner', 'bannerurl',\n]);\n\n/** Deterministic stock-photo URL; the same entity+field renders the same image. */\nexport function sampleImageUrl(\n entityName: string,\n fieldName: string,\n ctx: SampleContext,\n width = 400,\n height = 400,\n): string {\n const salt = ctx.strategy === 'seeded' ? randomInt({ min: 0, max: 1000 }) : ctx.index;\n const seed = `${entityName}-${fieldName}-${salt}`;\n return `https://picsum.photos/seed/${encodeURIComponent(seed)}/${width}/${height}`;\n}\n\n/** `targetType` / `target_type` -> `Target Type`, for readable sample text. */\nfunction titleCase(name: string): string {\n const spaced = name\n .split('')\n .flatMap((c) => (c === '_' || c === '-' ? [' '] : c === c.toUpperCase() && c !== c.toLowerCase() ? [' ', c] : [c]))\n .join('');\n return spaced\n .split(/\\s+/)\n .filter((w) => w.length > 0)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ');\n}\n\n/** Lowercase, punctuation-free fragment safe to embed in an email or URL. */\nfunction slug(name: string): string {\n return name.replace(/[^a-zA-Z0-9]/g, '').toLowerCase() || 'value';\n}\n\n/** A deterministic, validator-satisfying UUID for the pure-index strategy. */\nfunction indexUuid(index: number): string {\n return `00000000-0000-4000-8000-${index.toString(16).padStart(12, '0').slice(-12)}`;\n}\n\n/** The closed vocabulary a field declares, if any. */\nfunction declaredValues(field: EntityField): readonly string[] | undefined {\n const values = 'values' in field ? field.values : undefined;\n return values && values.length > 0 ? values : undefined;\n}\n\n/**\n * Is `field.default` a value the synthesizer must return verbatim?\n *\n * Exported so codegen and tests share the one predicate rather than restating it.\n */\nexport function isDeclaredDefaultHonored(field: EntityField): boolean {\n const value = field.default;\n if (value === undefined || value === null) return false;\n if (typeof value === 'number' || typeof value === 'boolean') return true;\n if (Array.isArray(value)) return true;\n if (typeof value === 'object') return true;\n if (typeof value !== 'string') return false;\n\n const values = declaredValues(field);\n // Gate 3: '' is a placeholder unless the field's own vocabulary declares it.\n if (value === '') return values !== undefined && values.includes('');\n // A default on a closed vocabulary of a collection is a new-record default,\n // not a claim about existing rows — so the row cycle wins over it.\n return values === undefined;\n}\n\n/** Rows to synthesize. A `[runtime]` entity is a per-orbital singleton. */\nexport function sampleRowCount(entity: SampleEntity, requested: number): number {\n return entity.persistence === 'runtime' ? 1 : requested;\n}\n\nfunction sampleText(field: EntityField, ctx: SampleContext): string {\n const fieldName = field.name ?? 'field';\n if (IMAGE_FIELD_NAMES.has(fieldName.toLowerCase())) {\n return sampleImageUrl(ctx.entityName, fieldName, ctx);\n }\n return ctx.strategy === 'seeded'\n ? randomWords(2)\n : `${titleCase(fieldName)} ${ctx.index}`;\n}\n\nfunction sampleDate(ctx: SampleContext, dateOnly: boolean): string {\n if (ctx.strategy === 'index') {\n const month = String((ctx.index % 12) + 1).padStart(2, '0');\n return dateOnly ? `2026-${month}-15` : `2026-${month}-15T00:00:00.000Z`;\n }\n const iso = randomStraddlingDate({ days: 15 }).toISOString();\n return dateOnly ? iso.split('T')[0]! : iso;\n}\n\nfunction sampleRelation(field: RelationEntityField): FieldValue {\n // Placeholder; the caller's post-pass links real sibling ids.\n return field.relation?.cardinality === 'one' ? '' : [];\n}\n\nfunction sampleArray(field: ArrayEntityField, ctx: SampleContext): FieldValue {\n const depth = ctx.depth ?? 0;\n if (!field.items || depth >= MAX_NESTED_DEPTH) return [];\n const count = ctx.strategy === 'seeded' ? randomInt({ min: 3, max: 5 }) : 3;\n const elementName = field.name ?? 'item';\n const out: FieldValue[] = [];\n for (let i = 0; i < count; i++) {\n const element: EntityField = { ...field.items, name: `${elementName}[${i}]` };\n out.push(\n sampleFieldValue(element, {\n ...ctx,\n index: ctx.index * 10 + i,\n depth: depth + 1,\n }) ?? null,\n );\n }\n return out;\n}\n\nfunction sampleObject(field: ObjectEntityField, ctx: SampleContext): FieldValue {\n const depth = ctx.depth ?? 0;\n if (!field.properties || depth >= MAX_NESTED_DEPTH) return null;\n const out: Record<string, FieldValue> = {};\n for (const [propName, propField] of Object.entries(field.properties)) {\n const child: EntityField = { ...propField, name: propName };\n out[propName] = sampleFieldValue(child, { ...ctx, depth: depth + 1 }) ?? null;\n }\n return out;\n}\n\n/**\n * One sample value for one field. `undefined` means OMIT the key.\n *\n * Order matters — see the three gates in the plan. Gates 1 and 2 read declared\n * schema properties (`persistence`, `intrinsic`), never field names.\n */\nexport function sampleFieldValue(field: EntityField, ctx: SampleContext): FieldValue | undefined {\n const honoredDefault =\n field.default !== undefined && isFieldValue(field.default) ? field.default : undefined;\n\n // Gate 2: the owning trait computes this, so the data layer must not write it.\n if (field.intrinsic === true) return honoredDefault;\n\n // Gate 1: a runtime singleton's seeded row must equal its declared-defaults\n // projection, or persistence disagrees with the default layer in the @entity\n // merge and boots the machine into the wrong state.\n const isRuntime = ctx.persistence === 'runtime';\n if (isRuntime && honoredDefault !== undefined) return honoredDefault;\n\n if (!isRuntime && isDeclaredDefaultHonored(field) && honoredDefault !== undefined) {\n return honoredDefault;\n }\n\n const values = declaredValues(field);\n if (values) {\n // Row 1 yields values[0], which is the declared default for 85% of fields.\n const ordinal = isRuntime ? 1 : ctx.index;\n return values[(ordinal - 1) % values.length]!;\n }\n\n switch (field.type) {\n case 'string':\n return sampleText(field, ctx);\n // Semantic domains synthesize a value that SATISFIES their own validator —\n // the property that keeps the seeder and the validator from drifting.\n case 'email':\n return ctx.strategy === 'seeded'\n ? randomEmail()\n : `${slug(field.name ?? 'user')}${ctx.index}@example.com`;\n case 'url':\n return ctx.strategy === 'seeded'\n ? randomUrl()\n : `https://example.com/${slug(field.name ?? 'link')}/${ctx.index}`;\n case 'phone':\n return ctx.strategy === 'seeded'\n ? randomPhone()\n : `+1-555-${String(1000 + (ctx.index % 9000)).padStart(4, '0')}`;\n case 'uuid':\n return ctx.strategy === 'seeded' ? randomUuid() : indexUuid(ctx.index);\n case 'image':\n return sampleImageUrl(ctx.entityName, field.name ?? 'image', ctx);\n case 'number': {\n // A declared range constrains the value; an UNdeclared one must not, or\n // the index ladder silently flattens once it passes an invented ceiling.\n if (ctx.strategy === 'seeded') {\n return randomInt({ min: field.min ?? 0, max: field.max ?? 100 });\n }\n const stepped = (field.min ?? 0) + ctx.index * 10;\n return field.max !== undefined && stepped > field.max ? field.max : stepped;\n }\n case 'boolean':\n return ctx.strategy === 'seeded' ? randomBoolean() : ctx.index % 2 === 0;\n case 'date':\n return sampleDate(ctx, true);\n case 'timestamp':\n case 'datetime':\n return sampleDate(ctx, false);\n case 'enum':\n // Reached only when the enum declares no values — a malformed field.\n return null;\n case 'relation':\n return sampleRelation(field);\n case 'array':\n return sampleArray(field, ctx);\n case 'object':\n return sampleObject(field, ctx);\n case 'trait':\n case 'slot':\n case 'pattern':\n return undefined;\n default:\n return sampleText(field, ctx);\n }\n}\n\n/** One row. Reserved keys are left to the caller. */\nexport function sampleRow(\n entity: SampleEntity,\n ctx: Omit<SampleContext, 'entityName' | 'depth'>,\n): EntityRow {\n const row: EntityRow = {};\n for (const field of entity.fields) {\n const name = field.name;\n if (!name || RESERVED_FIELD_NAMES.has(name)) continue;\n const value = sampleFieldValue(field, {\n ...ctx,\n entityName: entity.name,\n persistence: ctx.persistence ?? entity.persistence,\n });\n if (value !== undefined) row[name] = value;\n }\n return row;\n}\n\n/** `count` rows, 1-based, honoring the runtime-singleton gate. */\nexport function sampleRows(\n entity: SampleEntity,\n count: number,\n strategy: SampleStrategy,\n): EntityRow[] {\n const rowCount = sampleRowCount(entity, count);\n const rows: EntityRow[] = [];\n for (let i = 1; i <= rowCount; i++) {\n rows.push(sampleRow(entity, { index: i, strategy, persistence: entity.persistence }));\n }\n return rows;\n}\n"]}
|
|
1
|
+
{"version":3,"sources":["../../src/mock/random.ts","../../src/mock/identityOwners.ts","../../src/access/entityAccess.ts","../../src/types/identity.ts","../../src/types/json.ts","../../src/types/field.ts","../../src/types/asset.ts","../../src/types/expression.ts","../../src/types/entity.ts","../../src/mock/sampleValue.ts"],"names":["slug","inlineEntities","z"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * Lightweight seeded pseudo-random generator for mock data.\n *\n * Replaces @faker-js/faker in browser-facing code so the client bundle does\n * not pay the ~3.7 MB faker cost. The API surface is intentionally narrow:\n * only the helpers actually used by MockPersistenceAdapter.\n */\n\nlet seedState = 42;\n\n/** Re-seed the generator. Same signature as `faker.seed()`. */\nexport function seedRandom(value: number | undefined): void {\n seedState = (value ?? 42) >>> 0;\n}\n\n/** Linear congruential generator returning a float in [0, 1). */\nfunction nextFloat(): number {\n seedState = (seedState * 1664525 + 1013904223) >>> 0;\n return seedState / 4294967296;\n}\n\n/** Integer in [min, max]. */\nexport function randomInt({ min, max }: { min: number; max: number }): number {\n return Math.floor(nextFloat() * (max - min + 1)) + min;\n}\n\n/** Float in [min, max] with fixed fraction digits. */\nexport function randomFloat({\n min,\n max,\n fractionDigits = 2,\n}: {\n min: number;\n max: number;\n fractionDigits?: number;\n}): number {\n const value = nextFloat() * (max - min) + min;\n const factor = 10 ** fractionDigits;\n return Math.round(value * factor) / factor;\n}\n\n/** True/false with 50% probability. */\nexport function randomBoolean(): boolean {\n return nextFloat() < 0.5;\n}\n\n/** Pick one element from an array. */\nexport function randomArrayElement<T>(array: ReadonlyArray<T>): T {\n return array[randomInt({ min: 0, max: array.length - 1 })]!;\n}\n\n/** Return a shallow-shuffled copy of the array (Fisher-Yates). */\nexport function shuffleArray<T>(array: ReadonlyArray<T>): T[] {\n const copy = array.slice();\n for (let i = copy.length - 1; i > 0; i--) {\n const j = randomInt({ min: 0, max: i });\n const tmp = copy[i];\n copy[i] = copy[j]!;\n copy[j] = tmp!;\n }\n return copy;\n}\n\n/** ISO-8601 date string roughly `years` in the past. */\nexport function randomPastDate({ years = 1 }: { years?: number } = {}): Date {\n const now = Date.now();\n const maxAge = years * 365 * 24 * 60 * 60 * 1000;\n const age = Math.floor(nextFloat() * maxAge);\n return new Date(now - age);\n}\n\n/** ISO-8601 date string within the last `days`. */\nexport function randomRecentDate({ days = 30 }: { days?: number } = {}): Date {\n const now = Date.now();\n const maxAge = days * 24 * 60 * 60 * 1000;\n const age = Math.floor(nextFloat() * maxAge);\n return new Date(now - age);\n}\n\n/** ISO-8601 date string straddling now: `[-days, +days]`. One PRNG draw,\n * same call shape as `randomRecentDate`, so seeded field order is unchanged —\n * only the window shifts from past-only to centered-on-now. Past-only starved\n * any calendar/upcoming view, since every seeded `startsAt` was already over. */\nexport function randomStraddlingDate({ days = 15 }: { days?: number } = {}): Date {\n const now = Date.now();\n const span = days * 24 * 60 * 60 * 1000;\n const offset = Math.floor(nextFloat() * span * 2) - span;\n return new Date(now + offset);\n}\n\n/** Any date in the last ~100 years. */\nexport function randomAnytimeDate(): Date {\n const now = Date.now();\n const maxAge = 100 * 365 * 24 * 60 * 60 * 1000;\n const age = Math.floor(nextFloat() * maxAge);\n return new Date(now - age);\n}\n\nconst LOREM_WORDS = [\n 'lorem', 'ipsum', 'dolor', 'sit', 'amet', 'consectetur', 'adipiscing', 'elit',\n 'sed', 'do', 'eiusmod', 'tempor', 'incididunt', 'ut', 'labore', 'et', 'dolore',\n 'magna', 'aliqua', 'enim', 'ad', 'minim', 'veniam', 'quis', 'nostrud',\n 'exercitation', 'ullamco', 'laboris', 'nisi', 'aliquip', 'ex', 'ea', 'commodo',\n 'consequat', 'duis', 'aute', 'irure', 'in', 'reprehenderit', 'voluptate',\n 'velit', 'esse', 'cillum', 'fugiat', 'nulla', 'pariatur', 'excepteur', 'sint',\n 'occaecat', 'cupidatat', 'non', 'proident', 'sunt', 'culpa', 'qui', 'officia',\n 'deserunt', 'mollit', 'anim', 'id', 'est', 'laborum',\n];\n\n/** A few random words. */\nexport function randomWords(count: number): string {\n const words: string[] = [];\n for (let i = 0; i < count; i++) {\n words.push(randomArrayElement(LOREM_WORDS));\n }\n return words.join(' ');\n}\n\n/** A short sentence. */\nexport function randomSentence(): string {\n const words = randomWords(randomInt({ min: 4, max: 8 }));\n return words.charAt(0).toUpperCase() + words.slice(1) + '.';\n}\n\n/** UUID v4-like string (random, not strictly compliant). */\nexport function randomUuid(): string {\n const hex = () => randomInt({ min: 0, max: 15 }).toString(16);\n return `${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}-${hex()}${hex()}${hex()}${hex()}-4${hex()}${hex()}${hex()}-${hex()}${hex()}${hex()}${hex()}-${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}${hex()}`;\n}\n\n/** Random hex color (#rrggbb). */\nexport function randomColor(): string {\n const channel = () => randomInt({ min: 0, max: 255 }).toString(16).padStart(2, '0');\n return `#${channel()}${channel()}${channel()}`;\n}\n\nconst PASSWORD_CHARS = 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789!@#$%^&*';\n\n/** Random password of the given length. */\nexport function randomPassword(length = 12): string {\n let password = '';\n for (let i = 0; i < length; i++) {\n password += randomArrayElement(PASSWORD_CHARS.split(''));\n }\n return password;\n}\n\n/** Random email address. */\nexport function randomEmail(): string {\n const user = randomWords(1).toLowerCase().replace(/\\s+/g, '.');\n const domain = randomWords(1).toLowerCase().replace(/\\s+/g, '');\n return `${user}@${domain}.com`;\n}\n\n/** Random URL. */\nexport function randomUrl(): string {\n const slug = randomWords(2).toLowerCase().replace(/\\s+/g, '-');\n return `https://example.com/${slug}`;\n}\n\n/** Random phone number. */\nexport function randomPhone(): string {\n const area = randomInt({ min: 200, max: 999 });\n const prefix = randomInt({ min: 200, max: 999 });\n const line = randomInt({ min: 0, max: 9999 }).toString().padStart(4, '0');\n return `+1 (${area}) ${prefix}-${line}`;\n}\n","/**\n * Owner columns derived from a program's `[identity]` entity.\n *\n * The JS mirror of `orbital-core/src/runtime/seed.rs`\n * (`identity_entity_name` / `owner_fields_from_schema`). Both paths must agree:\n * a column is an owner column because the source *declared* it as a relation to\n * the `[identity]` entity (`patientId : Person`), never because its name looks\n * like one — a name-matching guess would silently scope the wrong column.\n *\n * @packageDocumentation\n */\n\nimport type { OrbitalEntity } from '../types/entity.js';\nimport type { EntityRef } from '../types/orbital.js';\nimport type { OrbitalSchema } from '../types/schema.js';\n\n/** Inline entity definitions of an orbital: the primary plus any auxiliaries. */\nfunction inlineEntities(schema: OrbitalSchema): OrbitalEntity[] {\n const out: OrbitalEntity[] = [];\n for (const orbital of schema.orbitals ?? []) {\n const refs: EntityRef[] = [orbital.entity, ...(orbital.auxiliaryEntities ?? [])];\n for (const ref of refs) {\n if (typeof ref === 'object' && ref !== null && 'fields' in ref) {\n out.push(ref as OrbitalEntity);\n }\n }\n }\n return out;\n}\n\n/**\n * The name of the schema's `[identity]` entity, if it declares one.\n *\n * At most one per composed program (`ORB_S_IDENTITY_NOT_UNIQUE`); same-name\n * duplicates across orbitals are rejected upstream by `validate_entity_uniqueness`,\n * so the first match is the only match.\n */\nexport function identityEntityName(schema: OrbitalSchema): string | undefined {\n return inlineEntities(schema).find((def) => def.identity === true)?.name;\n}\n\n/**\n * Owner columns as `Entity.field` pairs — every relation field pointing at the\n * `[identity]` entity. Empty when the program declares no identity, which keeps\n * every unmigrated app behaving exactly as before.\n */\nexport function ownerFieldsFromSchema(schema: OrbitalSchema): string[] {\n const identity = identityEntityName(schema);\n if (identity === undefined) return [];\n\n const out: string[] = [];\n const defs = inlineEntities(schema);\n const declaredByCollection = new Map<string, string[]>();\n for (const def of defs) {\n for (const field of def.fields ?? []) {\n // Cardinality-one only: an owner column holds ONE viewer id. A\n // `[Person]` array is a participant list, not ownership.\n if (field.name && field.type === 'relation' && field.relation.entity === identity) {\n out.push(`${def.name}.${field.name}`);\n if (def.collection) {\n const cols = declaredByCollection.get(def.collection) ?? [];\n if (!cols.includes(field.name)) cols.push(field.name);\n declaredByCollection.set(def.collection, cols);\n }\n }\n }\n }\n\n // Collection mirror of `entityAccessTable`'s policy inheritance: an entity\n // sharing a collection with a declaring sibling is scoped by that sibling's\n // @read policy, so its same-named column IS the owner column the policy\n // compares — an imported atom's entity structurally cannot declare the\n // relation itself (it does not know the app's identity entity). Still\n // declaration-grounded, never name-guessing across collections.\n for (const def of defs) {\n const cols = def.collection ? declaredByCollection.get(def.collection) : undefined;\n if (!cols) continue;\n for (const col of cols) {\n const key = `${def.name}.${col}`;\n if (out.includes(key)) continue;\n if ((def.fields ?? []).some((f) => f.name === col)) out.push(key);\n }\n }\n return out;\n}\n","/**\n * Entity access policies — the declared `@read`/`@create`/`@update`/`@delete`\n * directives, keyed by entity name.\n *\n * The JS mirror of `orbital-core/src/runtime/entity_access.rs`'s\n * `EntityAccessPolicies`/`EntityAccessTable`. Both paths must agree: a\n * directive is a per-row predicate (`@entity` = the candidate row, or for\n * `@create` the incoming data; `@user` = the viewer), enforced once for\n * every trait that touches the entity — the un-bypassable twin of a\n * call-site `filter:`, which sibling traits can skip simply by not\n * declaring one.\n *\n * @packageDocumentation\n */\n\nimport type { OrbitalEntity } from '../types/entity.js';\nimport type { EntityRef } from '../types/orbital.js';\nimport type { OrbitalSchema } from '../types/schema.js';\nimport type { SExpr } from '../types/expression.js';\n\n/** Inline entity definitions of an orbital: the primary plus any auxiliaries. */\nfunction inlineEntities(schema: OrbitalSchema): OrbitalEntity[] {\n const out: OrbitalEntity[] = [];\n for (const orbital of schema.orbitals ?? []) {\n const refs: EntityRef[] = [orbital.entity, ...(orbital.auxiliaryEntities ?? [])];\n for (const ref of refs) {\n if (typeof ref === 'object' && ref !== null && 'fields' in ref) {\n out.push(ref as OrbitalEntity);\n }\n }\n }\n return out;\n}\n\n/** An entity's four declared directives. Any may be absent — an absent\n * directive means \"no restriction\" for that operation, exactly like an\n * absent fetch `filter:`. */\nexport interface EntityAccessPolicies {\n read?: SExpr;\n create?: SExpr;\n update?: SExpr;\n delete?: SExpr;\n}\n\n/** Whether the author declared any of the four directives on this entity. */\nfunction isDeclared(p: EntityAccessPolicies): boolean {\n return (\n p.read !== undefined ||\n p.create !== undefined ||\n p.update !== undefined ||\n p.delete !== undefined\n );\n}\n\n/**\n * Every entity's access policies, keyed by entity name.\n *\n * A policy governs the **collection**, not the declaration. A `persistent:`\n * collection is one table, and two entity declarations over one table cannot\n * honestly carry different visibility rules. Keying by entity name alone let an\n * organism declare `@read` on its own entity and still ship an ALLOW-ALL list\n * wherever a page rendered through a std-atom trait that fetched the ATOM's\n * entity on the same collection — measured on `std-customer-success`, where\n * `/health-scores` returned 6 rows for every persona while the organism's own\n * `/cs-accounts` correctly returned 3 vs 6. 36 of 54 app organisms share a\n * collection this way (`R-SHADOW-ENTITY-SHARES-COLLECTION-DIRECTIVES-DONT-APPLY`).\n *\n * So an entity that declares nothing adopts the policy declared on its\n * collection. This can only ever ADD a restriction: an entity with its own\n * directives keeps exactly those, and an entity whose collection carries no\n * declared policy is untouched. Conflicting declarations on one collection are\n * rejected at validate time by `ORB_S_COLLECTION_POLICY_CONFLICT`.\n *\n * Mirrors `resolve_collection_inheritance` in\n * `orbital-rust/crates/orbital-core/src/runtime/entity_access.rs`.\n */\nexport function entityAccessTable(schema: OrbitalSchema): Map<string, EntityAccessPolicies> {\n const table = new Map<string, EntityAccessPolicies>();\n const collectionOf = new Map<string, string>();\n\n for (const def of inlineEntities(schema)) {\n table.set(def.name, {\n read: def.read_policy,\n create: def.create_policy,\n update: def.update_policy,\n delete: def.delete_policy,\n });\n if (def.collection) collectionOf.set(def.name, def.collection);\n }\n\n const byCollection = new Map<string, EntityAccessPolicies>();\n for (const [name, policies] of table) {\n const collection = collectionOf.get(name);\n if (collection && isDeclared(policies) && !byCollection.has(collection)) {\n byCollection.set(collection, policies);\n }\n }\n\n for (const [name, policies] of table) {\n if (isDeclared(policies)) continue;\n const collection = collectionOf.get(name);\n const inherited = collection ? byCollection.get(collection) : undefined;\n if (inherited) table.set(name, { ...inherited });\n }\n\n return table;\n}\n\n/** One entity's access policies, or `undefined` when it declares none. */\nexport function entityAccessPolicies(\n schema: OrbitalSchema,\n entityName: string,\n): EntityAccessPolicies | undefined {\n return entityAccessTable(schema).get(entityName);\n}\n","/**\n * Identity model (Almadar Rabit V4, Phase 1 — types only).\n *\n * Branded, prefix-tagged node ids + a workspace-scoped name ledger. Ids are\n * the durable edge keys of the identity-keyed schema graph; the ledger is the\n * sole name↔id map (names are display labels, one row per rename). This module\n * is pure: no I/O, no side effects. Minting is the only impurity (clock +\n * crypto randomness for the ULID suffix).\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\n\n// ============================================================================\n// Branded id types\n// ============================================================================\n\ntype Branded<K extends string> = string & { readonly __idBrand: K };\n\nexport type OrbitalId = Branded<'OrbitalId'>;\nexport type EntityId = Branded<'EntityId'>;\nexport type TraitId = Branded<'TraitId'>;\nexport type EventId = Branded<'EventId'>;\nexport type PageId = Branded<'PageId'>;\nexport type ServiceId = Branded<'ServiceId'>;\nexport type ThemeId = Branded<'ThemeId'>;\nexport type PaletteEntryId = Branded<'PaletteEntryId'>;\n\n/** Node kind ↔ id-prefix table. The single source of truth for every prefix. */\nconst ID_PREFIXES = {\n orbital: 'orb_',\n entity: 'ent_',\n trait: 'trt_',\n event: 'evt_',\n page: 'pag_',\n service: 'svc_',\n theme: 'thm_',\n palette: 'pal_',\n} as const;\n\nexport type IdKind = keyof typeof ID_PREFIXES;\n\n/** Compile-time map from kind to its branded id type. */\nexport interface IdForKind {\n orbital: OrbitalId;\n entity: EntityId;\n trait: TraitId;\n event: EventId;\n page: PageId;\n service: ServiceId;\n theme: ThemeId;\n palette: PaletteEntryId;\n}\n\n/**\n * The one controlled brand assertion in this module. A prefix-checked string\n * is asserted into its branded form here and nowhere else.\n */\nfunction brand<Id extends string>(value: string): Id {\n return value as Id;\n}\n\n// ============================================================================\n// Kind guards + constructors (one shared factory, eight kinds)\n// ============================================================================\n\ninterface IdKindApi<Id extends string> {\n readonly prefix: string;\n is(value: string): value is Id;\n as(value: string): Id;\n}\n\nfunction makeIdKind<Id extends string>(kind: IdKind): IdKindApi<Id> {\n const prefix = ID_PREFIXES[kind];\n const is = (value: string): value is Id =>\n value.startsWith(prefix) && value.length > prefix.length;\n const as = (value: string): Id => {\n if (!is(value)) {\n throw new Error(\n `Expected ${kind} id (prefix \"${prefix}\"), got: ${JSON.stringify(value)}`,\n );\n }\n return brand<Id>(value);\n };\n return { prefix, is, as };\n}\n\nconst orbitalKind = makeIdKind<OrbitalId>('orbital');\nconst entityKind = makeIdKind<EntityId>('entity');\nconst traitKind = makeIdKind<TraitId>('trait');\nconst eventKind = makeIdKind<EventId>('event');\nconst pageKind = makeIdKind<PageId>('page');\nconst serviceKind = makeIdKind<ServiceId>('service');\nconst themeKind = makeIdKind<ThemeId>('theme');\nconst paletteKind = makeIdKind<PaletteEntryId>('palette');\n\nexport const isOrbitalId = orbitalKind.is;\nexport const asOrbitalId = orbitalKind.as;\nexport const isEntityId = entityKind.is;\nexport const asEntityId = entityKind.as;\nexport const isTraitId = traitKind.is;\nexport const asTraitId = traitKind.as;\nexport const isEventId = eventKind.is;\nexport const asEventId = eventKind.as;\nexport const isPageId = pageKind.is;\nexport const asPageId = pageKind.as;\nexport const isServiceId = serviceKind.is;\nexport const asServiceId = serviceKind.as;\nexport const isThemeId = themeKind.is;\nexport const asThemeId = themeKind.as;\nexport const isPaletteEntryId = paletteKind.is;\nexport const asPaletteEntryId = paletteKind.as;\n\n/**\n * The id-prefix for a node kind (`'entity' → 'ent_'`). The JS mirror of the\n * Rust `IdKind::prefix`. Single source of truth is {@link ID_PREFIXES}.\n */\nexport function idPrefix(kind: IdKind): string {\n return ID_PREFIXES[kind];\n}\n\n/**\n * The node kind an id's prefix denotes, or `null` for an unrecognized /\n * bare-prefix string. The JS mirror of the Rust `id_kind_of`. Prefixes are\n * mutually non-overlapping, so match order is irrelevant.\n */\nexport function idKindOf(id: string): IdKind | null {\n for (const kind of Object.keys(ID_PREFIXES) as IdKind[]) {\n const prefix = ID_PREFIXES[kind];\n if (id.startsWith(prefix) && id.length > prefix.length) return kind;\n }\n return null;\n}\n\n// ============================================================================\n// Minting — prefix + ULID\n// ============================================================================\n\nconst CROCKFORD = '0123456789ABCDEFGHJKMNPQRSTVWXYZ';\nconst TIME_LEN = 10;\nconst RANDOM_LEN = 16;\n\nfunction randomBytes(len: number): Uint8Array {\n const g = globalThis as { crypto?: { getRandomValues?: (a: Uint8Array) => Uint8Array } };\n if (g.crypto?.getRandomValues) {\n return g.crypto.getRandomValues(new Uint8Array(len));\n }\n throw new Error('mintId: no crypto.getRandomValues available in this runtime');\n}\n\nfunction encodeTime(now: number): string {\n let value = now;\n let out = '';\n for (let i = 0; i < TIME_LEN; i++) {\n const mod = value % 32;\n out = CROCKFORD[mod] + out;\n value = (value - mod) / 32;\n }\n return out;\n}\n\nfunction encodeRandom(): string {\n const bytes = randomBytes(RANDOM_LEN);\n let out = '';\n for (let i = 0; i < RANDOM_LEN; i++) {\n out += CROCKFORD[bytes[i] & 31];\n }\n return out;\n}\n\n/** A 26-char Crockford-base32 ULID: 48-bit ms timestamp + 80 bits of randomness. */\nfunction ulid(): string {\n return encodeTime(Date.now()) + encodeRandom();\n}\n\n/** Mint a fresh, opaque, kind-tagged id: `<prefix><ULID>`. */\nexport function mintId<K extends IdKind>(kind: K): IdForKind[K] {\n return brand<IdForKind[K]>(ID_PREFIXES[kind] + ulid());\n}\n\n// ============================================================================\n// Identity ledger\n// ============================================================================\n\n/** Ledger row kind. `palette` entries are manifest ids, not name-ledger rows. */\nexport type LedgerKind =\n | 'orbital'\n | 'entity'\n | 'trait'\n | 'event'\n | 'page'\n | 'service'\n | 'theme';\n\n/**\n * One ledger row: the workspace's name history for a single node id.\n *\n * For kind `'event'` the row is minted per-(trait, declared event) per the\n * Phase-0 freeze — the owning trait is recorded in `parent`; a call-site event\n * rename is a one-row edit on this same id (the baked-vs-current key namespaces\n * collapse into `bakedName` vs `curName`).\n */\nexport interface LedgerEntry {\n id: string;\n kind: LedgerKind;\n bakedName: string;\n curName: string;\n renames: ReadonlyArray<{ from: string; to: string; at: string }>;\n owner: 'std' | 'io' | 'workspace';\n /** Owning trait for kind `'event'` (per-trait event-id namespace). */\n parent?: TraitId;\n}\n\nexport interface IdentityLedger {\n schemaVersion: 1;\n entries: Record<string, LedgerEntry>;\n}\n\n/** Resolve a name to its id via exact `curName` match within `kind`, else null. */\nexport function ledgerResolveName(\n ledger: IdentityLedger,\n kind: LedgerKind,\n name: string,\n): string | null {\n for (const [id, entry] of Object.entries(ledger.entries)) {\n if (entry.kind === kind && entry.curName === name) return id;\n }\n return null;\n}\n\n/** Immutable rename: returns a new ledger with the id's `curName` + `renames` updated. */\nexport function ledgerRename(\n ledger: IdentityLedger,\n id: string,\n to: string,\n at: string,\n): IdentityLedger {\n const entry = ledger.entries[id];\n if (entry === undefined) return ledger;\n const updated: LedgerEntry = {\n ...entry,\n curName: to,\n renames: [...entry.renames, { from: entry.curName, to, at }],\n };\n return { ...ledger, entries: { ...ledger.entries, [id]: updated } };\n}\n\n/** Current display name for an id, or null when the id is not in the ledger. */\nexport function ledgerCurName(ledger: IdentityLedger, id: string): string | null {\n return ledger.entries[id]?.curName ?? null;\n}\n\n// ============================================================================\n// Zod schemas — the `.orb` load-time activation surface (Rabit V4, Phase 4)\n// ============================================================================\n\n/**\n * Prefix-checked, kind-tagged id schemas. Each narrows a validated string to\n * its branded id type via the module's own kind guard, so a schema that reads\n * `TraitIdSchema.optional()` yields `TraitId | undefined` with no cast. The\n * guard is the single source of prefix truth (`ID_PREFIXES`); the schema is a\n * thin zod wrapper over it.\n */\nexport const OrbitalIdSchema = z\n .string()\n .refine(isOrbitalId, { message: `Expected an orbital id (prefix \"${ID_PREFIXES.orbital}\")` });\nexport const EntityIdSchema = z\n .string()\n .refine(isEntityId, { message: `Expected an entity id (prefix \"${ID_PREFIXES.entity}\")` });\nexport const TraitIdSchema = z\n .string()\n .refine(isTraitId, { message: `Expected a trait id (prefix \"${ID_PREFIXES.trait}\")` });\nexport const EventIdSchema = z\n .string()\n .refine(isEventId, { message: `Expected an event id (prefix \"${ID_PREFIXES.event}\")` });\nexport const PageIdSchema = z\n .string()\n .refine(isPageId, { message: `Expected a page id (prefix \"${ID_PREFIXES.page}\")` });\nexport const ServiceIdSchema = z\n .string()\n .refine(isServiceId, { message: `Expected a service id (prefix \"${ID_PREFIXES.service}\")` });\nexport const ThemeIdSchema = z\n .string()\n .refine(isThemeId, { message: `Expected a theme id (prefix \"${ID_PREFIXES.theme}\")` });\nexport const PaletteEntryIdSchema = z\n .string()\n .refine(isPaletteEntryId, { message: `Expected a palette-entry id (prefix \"${ID_PREFIXES.palette}\")` });\n\nexport const LedgerKindSchema = z.enum([\n 'orbital',\n 'entity',\n 'trait',\n 'event',\n 'page',\n 'service',\n 'theme',\n]);\n\nexport const LedgerEntrySchema = z.object({\n id: z.string(),\n kind: LedgerKindSchema,\n bakedName: z.string(),\n curName: z.string(),\n renames: z.array(\n z.object({ from: z.string(), to: z.string(), at: z.string() }),\n ),\n owner: z.enum(['std', 'io', 'workspace']),\n parent: TraitIdSchema.optional(),\n});\n\nexport const IdentityLedgerSchema = z.object({\n schemaVersion: z.literal(1),\n entries: z.record(LedgerEntrySchema),\n});\n","/**\n * JSON primitives — the universal \"data crossed a boundary\" type.\n *\n * Every value that arrives over the wire from an LLM (tool-call args),\n * from disk (workspace files), or from an HTTP body before\n * domain-specific validation is a `JsonValue`. Narrow with a typed\n * predicate (`is`-guard) at the boundary; don't widen back to `unknown`.\n *\n * `JsonObject` and `ToolArgs` are aliases for the common\n * `Record<string, JsonValue>` shape. `ToolArgs` is the name the\n * agent surface uses for LLM-emitted tool-call arguments; `JsonObject`\n * is the general-purpose alias. They are the same type — the alias\n * exists so call sites read at the right semantic level.\n *\n * Why not `Record<string, unknown>`? Two reasons. (1) `unknown` widens\n * back to anything, which defeats the purpose of typing the boundary.\n * (2) The `@almadar/eslint-plugin/no-record-string-unknown` rule blocks\n * the wider form — `JsonValue`-based records are the typed answer.\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\n\n/**\n * Recursive JSON value union — every shape JSON can carry.\n */\nexport type JsonValue =\n | string\n | number\n | boolean\n | null\n | JsonValue[]\n | { [key: string]: JsonValue };\n\n/**\n * JSON object — keyed string→JsonValue. The wire form of arbitrary\n * structured data. Replaces `Record<string, unknown>` at typed\n * boundaries (LLM emits, file reads, HTTP bodies).\n */\nexport type JsonObject = { [key: string]: JsonValue };\n\n/** Zod schema for JsonValue — the one boundary validator for parsed-JSON slots. */\nexport const JsonValueSchema: z.ZodType<JsonValue> = z.lazy(() =>\n z.union([z.string(), z.number(), z.boolean(), z.null(), z.array(JsonValueSchema), z.record(JsonValueSchema)]),\n);\n\n/**\n * LLM tool-call arguments — same shape as `JsonObject`, named for the\n * agent-surface call site. Each tool's `execute(args: ToolArgs)`\n * receives this and narrows via an `is`-guard predicate before any\n * field access.\n */\nexport type ToolArgs = JsonObject;\n\n/**\n * Universal type-guard input — every runtime value shape a predicate can\n * be handed, enumerated instead of `unknown` (the repo bans `unknown`\n * even at guard boundaries). Primitives cover every `typeof` result;\n * `object` covers arrays, records, class instances, and functions.\n */\nexport type RuntimeValue =\n | string\n | number\n | bigint\n | boolean\n | symbol\n | Date\n | null\n | undefined\n | object;\n\n/**\n * Type guard: is the given value a JSON primitive (non-array,\n * non-object)? Used by walkers that decide whether to recurse.\n */\nexport function isJsonPrimitive(\n value: JsonValue,\n): value is string | number | boolean | null {\n return (\n value === null\n || typeof value === 'string'\n || typeof value === 'number'\n || typeof value === 'boolean'\n );\n}\n\n/**\n * Type guard: is the given value a JSON object (non-array, non-null)?\n */\nexport function isJsonObject(value: JsonValue): value is JsonObject {\n return (\n value !== null\n && typeof value === 'object'\n && !Array.isArray(value)\n );\n}\n\n/**\n * Type guard: is the given value a JSON array?\n */\nexport function isJsonArray(value: JsonValue): value is JsonValue[] {\n return Array.isArray(value);\n}\n","/**\n * Field Types for Orbital Units\n *\n * Extracted from schema/data-entities.ts for the orbitals module.\n * These types define the field structure within orbital entities.\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\nimport type { EntityId } from './identity.js';\nimport { EntityIdSchema } from './identity.js';\nimport type { JsonValue, RuntimeValue } from './json.js';\nimport { JsonValueSchema } from './json.js';\n\n// ============================================================================\n// Field Types\n// ============================================================================\n\n/**\n * Supported field types for entity fields.\n *\n * @example\n * { name: 'status', type: 'enum', values: ['draft', 'published'] }\n * { name: 'authorId', type: 'relation', relation: { entity: 'User', cardinality: 'one' } }\n */\nexport type FieldType =\n | 'string'\n | 'number'\n | 'boolean'\n | 'date'\n | 'timestamp'\n | 'datetime'\n // Semantic string domains. `.lolo` already types `date`/`datetime` rather\n // than annotating them, so these belong in the type system for the same\n // reason: a field's domain is a declared fact, not a decoration. They\n // replaced the optional `format` property, which had zero producers.\n | 'email'\n | 'url'\n | 'phone'\n | 'uuid'\n | 'image'\n | 'array'\n | 'object'\n | 'enum'\n | 'relation'\n | 'trait'\n | 'slot'\n | 'pattern';\n\n/** Every `FieldType`, as a runtime array. Downstream imports this instead of\n * re-listing the union — five copies had already drifted apart. */\nexport const FIELD_TYPES = [\n 'string',\n 'number',\n 'boolean',\n 'date',\n 'timestamp',\n 'datetime',\n 'email',\n 'url',\n 'phone',\n 'uuid',\n 'image',\n 'array',\n 'object',\n 'enum',\n 'relation',\n 'trait',\n 'slot',\n 'pattern',\n] as const satisfies readonly FieldType[];\n\n/** The semantic string domains — constrained strings, validatable by value. */\nexport const SEMANTIC_STRING_TYPES = ['email', 'url', 'phone', 'uuid', 'image'] as const;\n\nexport type SemanticStringType = (typeof SEMANTIC_STRING_TYPES)[number];\n\n/** Is this a semantic string domain (as opposed to a bare `string`)? */\nexport function isSemanticStringType(type: FieldType): type is SemanticStringType {\n return (SEMANTIC_STRING_TYPES as readonly string[]).includes(type);\n}\n\nexport const FieldTypeSchema = z.enum(FIELD_TYPES);\n\n// ============================================================================\n// Relation Configuration\n// ============================================================================\n\n/**\n * Cardinality for relation fields.\n * Matches Rust compiler's Cardinality enum.\n */\nexport type RelationCardinality = \n | 'one' \n | 'many' \n | 'one-to-many' \n | 'many-to-one' \n | 'many-to-many';\n\nexport const RelationCardinalitySchema = z.enum([\n 'one',\n 'many',\n 'one-to-many',\n 'many-to-one',\n 'many-to-many',\n]);\n\n/**\n * Configuration for relation fields (foreign keys).\n * Matches Rust compiler's RelationDefinition format.\n */\nexport type RelationConfig = {\n /** Target entity name (e.g., 'User', 'Task') - matches Rust's `entity` field */\n entity: string;\n /** V4 dual-carry id sibling of `entity` — optional until the Phase-7 flip. */\n entityId?: EntityId;\n /** Field on target entity (defaults to 'id') */\n field?: string;\n /** \n * Cardinality: one, many, one-to-many, many-to-one, many-to-many\n * Matches Rust compiler's cardinality format\n */\n cardinality?: RelationCardinality;\n /** Delete behavior */\n onDelete?: 'cascade' | 'nullify' | 'restrict';\n /** \n * Foreign key field name (for legacy compatibility).\n * @deprecated Use field instead\n */\n foreignKey?: string;\n /**\n * Target entity name (for legacy compatibility).\n * @deprecated Use entity instead\n */\n target?: string;\n /**\n * Cardinality type alias (for legacy compatibility).\n * @deprecated Use cardinality instead\n */\n type?: RelationCardinality;\n};\n\nexport const RelationConfigSchema = z.object({\n entity: z.string().min(1, 'Target entity is required'),\n entityId: EntityIdSchema.optional(),\n field: z.string().optional(),\n cardinality: RelationCardinalitySchema.optional(),\n onDelete: z.enum(['cascade', 'nullify', 'restrict']).optional(),\n // Legacy compatibility fields\n foreignKey: z.string().optional(),\n target: z.string().optional(),\n type: RelationCardinalitySchema.optional(),\n}).transform((data) => {\n // Normalize legacy format to standard format\n const normalized: RelationConfig = {\n entity: data.entity || data.target || '',\n entityId: data.entityId,\n cardinality: data.cardinality || data.type,\n field: data.field,\n onDelete: data.onDelete,\n };\n return normalized;\n});\n\nexport type RelationConfigInput = z.input<typeof RelationConfigSchema>;\n\n// ============================================================================\n// Field Format\n// ============================================================================\n\n/**\n * Value rules for the semantic string domains — one owner, so the seeders, the\n * validators and the verifiers cannot drift apart on what counts as valid.\n *\n * These replaced the old optional `format` property, which had zero producers\n * anywhere in the repo and no Rust counterpart at all: `format` was unreachable\n * from `.lolo`, so every consumer fell back to guessing from field names.\n */\nconst EMAIL_RE = /^[^\\s@]+@[^\\s@.]+\\.[^\\s@]+$/;\nconst URL_RE = /^https?:\\/\\/[^\\s]+$/;\nconst PHONE_RE = /^[+]?[\\d\\s().-]{7,}$/;\nconst UUID_RE = /^[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}$/i;\n\nexport function isEmailValue(value: string): boolean {\n return EMAIL_RE.test(value);\n}\n\nexport function isUrlValue(value: string): boolean {\n return URL_RE.test(value);\n}\n\nexport function isPhoneValue(value: string): boolean {\n return PHONE_RE.test(value);\n}\n\nexport function isUuidValue(value: string): boolean {\n return UUID_RE.test(value);\n}\n\n/** Does `value` satisfy the declared semantic domain? `image` is a URL. */\nexport function isSemanticStringValue(type: SemanticStringType, value: string): boolean {\n switch (type) {\n case 'email':\n return isEmailValue(value);\n case 'url':\n case 'image':\n return isUrlValue(value);\n case 'phone':\n return isPhoneValue(value);\n case 'uuid':\n return isUuidValue(value);\n }\n}\n\n// ============================================================================\n// Entity Field — discriminated union by `type`\n// ============================================================================\n\n/**\n * Field-type tags that don't carry a type-dependent payload. The base\n * `EntityField` shape applies as-is.\n */\ntype ScalarFieldType =\n | 'string'\n | 'number'\n | 'boolean'\n | 'date'\n | 'timestamp'\n | 'datetime'\n | 'email'\n | 'url'\n | 'phone'\n | 'uuid'\n | 'image'\n | 'trait'\n | 'slot'\n | 'pattern';\n\n/** Fields shared across every variant. */\ntype EntityFieldBase = {\n /**\n * Field name (camelCase). Optional for nested item/property descriptors\n * where the name is implied by the parent (`items`, `properties[k]`).\n * Mirrors Rust's `FieldDefinition.name: Option<String>`.\n */\n name?: string;\n /** Whether the field is required */\n required?: boolean;\n /** Default value — parsed from `.orb`, always JSON-shaped. */\n default?: JsonValue;\n /** Minimum value (for number) or length (for string) */\n min?: number;\n /** Maximum value or length */\n max?: number;\n /** Object property schemas keyed by property name (for object type).\n * Mirrors Rust's `FieldDefinition.properties: Option<HashMap<String,\n * FieldDefinition>>`. Populated by the lolo lowerer when a field /\n * config slot's type expression resolves to a struct shape\n * (`TypeExpr::Object`), including named-type aliases like `[MetricSpec]`. */\n properties?: Record<string, EntityField>;\n /** Runtime-managed widget state (authored `@intrinsic` in `.lolo`). Exempt\n * from the explicit-binding rule and never a domain-data bind target. */\n intrinsic?: boolean;\n /** Human/semantic description (authored `@description \"...\"` in `.lolo`).\n * Authoring/build-time metadata — factory-signature catalog, embeddings,\n * curation field-matching; the runtime ignores it. */\n description?: string;\n /** User-vocabulary synonyms (authored `@synonyms \"...\"` in `.lolo`).\n * Free text feeding catalog search / curation field-matching. */\n synonyms?: string;\n};\n\n/**\n * Scalar / structural fields — no type-dependent payload required.\n * `values?` is permitted as an OPTIONAL UI/validation hint (e.g. lolo's\n * `'a' | 'b' | 'c'` string-union sugar lowers to `type: 'string', values:\n * [...]`). Only `EnumEntityField` MANDATES values.\n */\nexport type ScalarEntityField = EntityFieldBase & {\n type: ScalarFieldType;\n /** Optional vocabulary hint for scalar fields (e.g. string unions\n * authored as `'a'|'b'|'c'` in lolo). Not required at this variant. */\n values?: string[];\n};\n\n/** `type: 'enum'` REQUIRES the closed vocabulary in `values`. */\nexport type EnumEntityField = EntityFieldBase & {\n type: 'enum';\n /** Closed string vocabulary the field accepts. */\n values: string[];\n};\n\n/** `type: 'relation'` REQUIRES the relation target binding. */\nexport type RelationEntityField = EntityFieldBase & {\n type: 'relation';\n /** Relation target binding (entity + cardinality). */\n relation: RelationConfig;\n};\n\n/** `type: 'array'` — element schema in `items` strongly preferred but\n * optional for legacy compatibility with codegen-emitted scalar-array\n * fields (e.g. `{type: 'array', default: []}`). The lolo lowerer + Rust\n * validator catch typed-element-required cases downstream. */\nexport type ArrayEntityField = EntityFieldBase & {\n type: 'array';\n /** Element schema for the array. */\n items?: EntityField;\n};\n\n/**\n * `type: 'object'` — a fixed-key struct (fields in `properties`) OR a\n * dynamic-key map (`Map K V` in `.lolo`; the uniform value schema lives in\n * `items`, mirroring an array's element schema). A distinct variant so `items`\n * is statically allowed only on object/array fields, never on scalars.\n */\nexport type ObjectEntityField = EntityFieldBase & {\n type: 'object';\n /** Uniform value schema for a dynamic-key map (`Map K V`). */\n items?: EntityField;\n};\n\n/**\n * Entity field definition — discriminated union by `type`. Each variant\n * statically enforces its dependent payload (`values` for enum,\n * `relation` for relation, `items` for array) so TS / Zod / JSON Schema\n * consumers all agree on the dependency, not just the Rust validator.\n *\n * @example\n * { name: 'status', type: 'enum', values: ['draft', 'published'] }\n * { name: 'authorId', type: 'relation', relation: { entity: 'User', cardinality: 'one' } }\n * { name: 'tags', type: 'array', items: { type: 'string' } }\n */\nexport type EntityField =\n | ScalarEntityField\n | EnumEntityField\n | RelationEntityField\n | ArrayEntityField\n | ObjectEntityField;\n\n/**\n * Alias map for legacy/loose field-type spellings. Preprocessed into the\n * canonical `FieldType` enum before zod validates. Without this, agent-produced\n * schemas using `text`/`int`/`float`/`ts` were rejected at parse time — this\n * normalizes them so the rest of the pipeline sees only canonical types.\n */\nconst FIELD_TYPE_ALIASES: Record<string, FieldType> = {\n text: 'string',\n int: 'number',\n float: 'number',\n ts: 'timestamp',\n};\n\n/**\n * Zod schema for `EntityField`. Preprocess normalizes:\n * - legacy `type` aliases (text → string, int → number, etc.)\n * - legacy `enum: string[]` alias → `values: string[]`\n *\n * Branches on `type` so TS narrows the parsed output to the matching\n * discriminated-union variant.\n */\n// The third type param stays `unknown`: zod v3 bakes `unknown` into\n// `z.preprocess`'s input type, and the recursion needs the explicit annotation.\nexport const EntityFieldSchema: z.ZodType<EntityField, z.ZodTypeDef, unknown> = z.lazy(() => {\n const baseFieldShape = {\n name: z.string().min(1, 'Field name is required').optional(),\n required: z.boolean().optional(),\n default: JsonValueSchema.optional(),\n min: z.number().optional(),\n max: z.number().optional(),\n properties: z.record(EntityFieldSchema).optional(),\n intrinsic: z.boolean().optional(),\n description: z.string().optional(),\n synonyms: z.string().optional(),\n };\n\n /** Build a scalar variant schema. `values?` is permitted as a hint;\n * only the enum variant mandates a non-empty values array. */\n function scalarVariant<T extends ScalarFieldType>(t: T) {\n return z.object({\n ...baseFieldShape,\n type: z.literal(t),\n values: z.array(z.string()).optional(),\n });\n }\n\n return z.preprocess(\n (input) => {\n if (\n input === null ||\n typeof input !== 'object' ||\n !('type' in input) ||\n typeof (input as { type?: RuntimeValue }).type !== 'string'\n ) {\n return input;\n }\n const obj = input as { type: string; enum?: RuntimeValue; values?: RuntimeValue };\n const next: { type: string; enum?: RuntimeValue; values?: RuntimeValue } = { ...obj };\n const aliased = FIELD_TYPE_ALIASES[obj.type];\n if (aliased !== undefined) next.type = aliased;\n // Fold legacy `enum: string[]` into `values: string[]`.\n if (next.enum !== undefined && next.values === undefined) {\n next.values = next.enum;\n }\n delete next.enum;\n return next;\n },\n z.discriminatedUnion('type', [\n scalarVariant('string'),\n scalarVariant('number'),\n scalarVariant('boolean'),\n scalarVariant('date'),\n scalarVariant('timestamp'),\n scalarVariant('datetime'),\n scalarVariant('email'),\n scalarVariant('url'),\n scalarVariant('phone'),\n scalarVariant('uuid'),\n scalarVariant('image'),\n scalarVariant('trait'),\n scalarVariant('slot'),\n scalarVariant('pattern'),\n // Enum variant — REQUIRES non-empty values.\n z.object({\n ...baseFieldShape,\n type: z.literal('enum'),\n values: z.array(z.string()).min(1, 'Enum field requires a non-empty `values` array'),\n }),\n // Relation variant — REQUIRES relation config.\n z.object({\n ...baseFieldShape,\n type: z.literal('relation'),\n relation: RelationConfigSchema,\n }),\n // Array variant — items optional to match relaxed TS shape.\n z.object({\n ...baseFieldShape,\n type: z.literal('array'),\n items: EntityFieldSchema.optional(),\n }),\n // Object variant — fixed-key struct (`properties`) or dynamic-key\n // map (`Map K V`, uniform value schema in `items`).\n z.object({\n ...baseFieldShape,\n type: z.literal('object'),\n items: EntityFieldSchema.optional(),\n values: z.array(z.string()).optional(),\n }),\n ]),\n );\n});\n\nexport type EntityFieldInput = z.input<typeof EntityFieldSchema>;\n\n// ============================================================================\n// Type Aliases (for cleaner imports)\n// ============================================================================\n\n/** Alias for EntityField - preferred name */\nexport type Field = EntityField;\n\n/** Alias for EntityFieldSchema - preferred name */\nexport const FieldSchema = EntityFieldSchema;\n","/**\n * Asset Types for Semantic Asset References\n *\n * Defines types for abstracting asset paths into semantic references.\n * Assets are resolved from SemanticAssetRef to actual paths at compile time.\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\n\n// ============================================================================\n// Entity Roles\n// ============================================================================\n\n/**\n * Entity roles in game contexts\n */\nexport const ENTITY_ROLES = [\n 'player',\n 'enemy',\n 'npc',\n 'item',\n 'tile',\n 'projectile',\n 'effect',\n 'ui',\n 'decoration',\n 'vehicle',\n] as const;\n\nexport type EntityRole = (typeof ENTITY_ROLES)[number];\n\nexport const EntityRoleSchema = z.enum(ENTITY_ROLES);\n\n// ============================================================================\n// Visual Styles\n// ============================================================================\n\n/**\n * Visual art styles for games\n */\nexport const VISUAL_STYLES = ['pixel', 'vector', 'hd', '1-bit', 'isometric'] as const;\n\nexport type VisualStyle = (typeof VISUAL_STYLES)[number];\n\nexport const VisualStyleSchema = z.enum(VISUAL_STYLES);\n\n// ============================================================================\n// Asset Dimension + Aspect (render metadata carried with the asset / the need)\n// ============================================================================\n\n/**\n * Whether the asset is a 2D sprite/image or a 3D model. Set by the consuming\n * canvas: the same entity role is a 2D sprite-sheet on a tile board and a 3D\n * rigged model on a 3D board.\n */\nexport const ASSET_DIMENSIONS = ['2d', '3d'] as const;\n\nexport type AssetDimension = (typeof ASSET_DIMENSIONS)[number];\n\nexport const AssetDimensionSchema = z.enum(ASSET_DIMENSIONS);\n\n/**\n * Rendering aspect ratio of an asset: square (tiles/sprites/portraits/icons),\n * 16:9 (scene backdrops), 5:7 (cards), 8:1 (effect frame strips).\n */\nexport const ASSET_ASPECTS = ['1:1', '16:9', '5:7', '8:1'] as const;\n\nexport type AssetAspect = (typeof ASSET_ASPECTS)[number];\n\nexport const AssetAspectSchema = z.enum(ASSET_ASPECTS);\n\n// ============================================================================\n// Animation Name + Sheet Direction\n// ============================================================================\n\n/**\n * Animation names matching a sprite sheet's row layout. Canonical home for\n * this vocabulary — `@almadar/ui`'s `spriteAnimationTypes.ts` re-exports it\n * rather than redeclaring, so board `.lolo` config and the render library\n * agree on one enum.\n */\nexport const ANIMATION_NAMES = ['idle', 'walk', 'attack', 'hit', 'death'] as const;\n\nexport type AnimationName = (typeof ANIMATION_NAMES)[number];\n\nexport const AnimationNameSchema = z.enum(ANIMATION_NAMES);\n\n/**\n * Sheet file directions (physical PNG files a sprite sheet ships as).\n * Legacy hand-drawn packs ship only se/sw and mirror-flip for ne/nw (a cheat\n * that shows the face while walking away); 3D-baked sheets ship all four real\n * directions — the renderer prefers a real sheet and keeps the flip only as\n * the legacy fallback.\n */\nexport const SPRITE_DIRECTIONS = ['se', 'sw', 'ne', 'nw'] as const;\n\nexport type SpriteDirection = (typeof SPRITE_DIRECTIONS)[number];\n\nexport const SpriteDirectionSchema = z.enum(SPRITE_DIRECTIONS);\n\n/**\n * Camera projections a baked sprite sheet can ship. `iso` is directional\n * (se/sw physical sheets, ne/nw by mirror); `front`/`top`/`perspective` are\n * single fixed-camera sheets (the mesh reference-sheet camera vocabulary).\n */\nexport const SHEET_PROJECTIONS = ['iso', 'front', 'back', 'top', 'perspective'] as const;\n\nexport type SheetProjection = (typeof SHEET_PROJECTIONS)[number];\n\nexport const SheetProjectionSchema = z.enum(SHEET_PROJECTIONS);\n\n// ============================================================================\n// Animation Definition\n// ============================================================================\n\n/**\n * Definition for a single named animation within a sprite sheet: which row\n * it occupies, how many frames it has, and its playback rate. This is the\n * shape actually consumed by `@almadar/ui`'s sprite-sheet renderer\n * (`spriteAnimation.ts`'s `frameRect`/`getCurrentFrameFromDef`) — moved here\n * verbatim rather than reconciled with a differently-shaped guess, since\n * `@almadar/ui`'s version is the one with real production consumers.\n */\nexport interface AnimationDef {\n /** Row index in the sprite sheet (0-based; each animation occupies one row). */\n row: number;\n /** Number of frames in this animation. */\n frames: number;\n /** Frames per second. */\n frameRate: number;\n /** Whether the animation loops. */\n loop: boolean;\n}\n\nexport const AnimationDefSchema = z.object({\n row: z.number().int().nonnegative(),\n frames: z.number().int().positive(),\n frameRate: z.number().positive(),\n loop: z.boolean(),\n});\n\n// ============================================================================\n// Sprite Sheet Atlas\n// ============================================================================\n\n/**\n * Parsed sprite-sheet atlas JSON — the contract a `spriteSheet`-role `Asset.url`\n * resolves to when fetched (see `Asset.url` usage in `@almadar/ui`'s\n * `useUnitSpriteAtlas`). A unit's `sprite?: Asset` stays the static single-pose\n * image; `spriteSheet?: Asset` is a SEPARATE reference whose URL points at a\n * `SpriteSheetAtlas`-shaped JSON manifest (e.g. `.../guardian-sprite-sheet.json`),\n * not a PNG. Frame-cutting geometry lives here, not inlined onto `Asset` — an\n * `Asset` traveling through `render-ui` every tick stays small.\n */\nexport interface SpriteSheetAtlas {\n /** Unit archetype key. */\n unit?: string;\n /** Visual type key. */\n type?: string;\n /** Width of a single frame in pixels. */\n frameWidth: number;\n /** Height of a single frame in pixels. */\n frameHeight: number;\n /** Number of columns (frames per row). */\n columns: number;\n /** Number of rows (animations). */\n rows: number;\n /** Directions present as physical PNG files. */\n directions: SpriteDirection[];\n /** Relative PNG sheet paths per direction. */\n sheets: Partial<Record<SpriteDirection, string>>;\n /** Animation row layout keyed by animation name. */\n animations: Partial<Record<AnimationName, AnimationDef>>;\n /**\n * Per-projection sheet PNGs (additive; absent on legacy atlases). `iso`\n * mirrors `sheets` (directional se/sw); the fixed cameras carry one sheet\n * each. `sheets` remains the iso back-compat alias — writers emit both.\n */\n projections?: {\n iso?: Partial<Record<SpriteDirection, string>>;\n front?: string;\n back?: string;\n top?: string;\n perspective?: string;\n };\n}\n\nexport const SpriteSheetAtlasSchema = z.object({\n unit: z.string().optional(),\n type: z.string().optional(),\n frameWidth: z.number().positive(),\n frameHeight: z.number().positive(),\n columns: z.number().int().positive(),\n rows: z.number().int().positive(),\n directions: z.array(SpriteDirectionSchema),\n sheets: z.record(SpriteDirectionSchema, z.string()),\n animations: z.record(AnimationNameSchema, AnimationDefSchema),\n projections: z\n .object({\n iso: z.record(SpriteDirectionSchema, z.string()).optional(),\n front: z.string().optional(),\n back: z.string().optional(),\n top: z.string().optional(),\n perspective: z.string().optional(),\n })\n .optional(),\n});\n\n// ============================================================================\n// Texture Atlas — named-subrect packed sheet (the industry standard)\n// ============================================================================\n\n/**\n * One named sub-rectangle inside a packed sheet. Mirrors the ShoeBox /\n * TexturePacker `<SubTexture>` element every Kenney `Spritesheet/*.xml` ships\n * (`x`/`y`/`width`/`height` = the rect in the sheet PNG; `frameX`/`frameY`/\n * `frameWidth`/`frameHeight` = the trim/pad offsets for sprites packed with\n * transparent edges removed — optional, present only on trimmed atlases).\n */\nexport interface SubTexture {\n x: number;\n y: number;\n width: number;\n height: number;\n frameX?: number;\n frameY?: number;\n frameWidth?: number;\n frameHeight?: number;\n}\n\nexport const SubTextureSchema = z.object({\n x: z.number().nonnegative(),\n y: z.number().nonnegative(),\n width: z.number().positive(),\n height: z.number().positive(),\n frameX: z.number().optional(),\n frameY: z.number().optional(),\n frameWidth: z.number().positive().optional(),\n frameHeight: z.number().positive().optional(),\n});\n\n/**\n * A packed sheet + its named sub-rectangles — the canonical parse target for a\n * Kenney `Spritesheet/*.xml` atlas. A STATIC tile/prop/UI Asset references one\n * of these: `{ url: <sheet.png>, atlas: <this.json>, sprite: \"grass.png\" }` →\n * the renderer fetches the sheet + atlas ONCE and blits the named sub-rect,\n * instead of loading N individual PNGs. (Animated actors use `SpriteSheetAtlas`\n * instead; a uniform-grid tile page uses `Tilesheet`.)\n */\nexport interface TextureAtlas {\n /** Relative path to the sheet PNG the sub-rects index into (the atlas's own `imagePath`). */\n imagePath: string;\n /** Sub-rectangles keyed by their atlas name (e.g. `\"grass.png\"`). */\n subTextures: Record<string, SubTexture>;\n}\n\nexport const TextureAtlasSchema = z.object({\n imagePath: z.string(),\n subTextures: z.record(z.string(), SubTextureSchema),\n});\n\n// ============================================================================\n// Tilesheet — uniform-grid packed page (cut by index)\n// ============================================================================\n\n/**\n * A uniform-grid tile page — the shape a Kenney `Tilesheet/` sheet takes (e.g.\n * Pirate Pack: \"each tile is 64×64, no margin\"). Tiles are cut by `(col,row)`\n * index rather than by named rect. `names` is present only when a sibling\n * `.xml`/`.txt` supplies an index→name list; otherwise a tile is addressed by\n * its `\"col,row\"` (or flat index) via `Asset.sprite`.\n */\nexport interface Tilesheet {\n /** Relative path to the tile sheet PNG. */\n imagePath: string;\n /** Width of one tile cell in pixels. */\n tileWidth: number;\n /** Height of one tile cell in pixels. */\n tileHeight: number;\n /** Number of columns in the grid. */\n columns: number;\n /** Number of rows in the grid. */\n rows: number;\n /** Outer margin before the first tile, in pixels (default 0). */\n margin?: number;\n /** Gap between adjacent tiles, in pixels (default 0). */\n spacing?: number;\n /** Optional index→name labels when a descriptor supplies them. */\n names?: string[];\n}\n\nexport const TilesheetSchema = z.object({\n imagePath: z.string(),\n tileWidth: z.number().positive(),\n tileHeight: z.number().positive(),\n columns: z.number().int().positive(),\n rows: z.number().int().positive(),\n margin: z.number().nonnegative().optional(),\n spacing: z.number().nonnegative().optional(),\n names: z.array(z.string()).optional(),\n});\n\n// ============================================================================\n// Semantic Asset Reference\n// ============================================================================\n\n/**\n * Semantic reference to an asset (not a hardcoded path).\n * Resolved to actual paths at compile time via asset maps.\n */\nexport type SemanticAssetRef = {\n /**\n * Entity role — a free string. Core no longer constrains the vocabulary to\n * `EntityRole` (that enum stays an exported shared reference for the asset\n * tool + renderer); genre boards may use their own roles (`boss`, `tower`, …).\n */\n role: string;\n /** Sub-category within role (hero, slime, coin, etc.) */\n category: string;\n /** Required animations for this entity */\n animations?: string[];\n /** Visual style preference */\n style?: VisualStyle;\n /** Variant identifier (for multiple versions) */\n variant?: string;\n /** 2D sprite vs 3D model — the rendering dimension the consuming canvas needs. */\n dimension?: AssetDimension;\n /** Rendering aspect ratio (square sprite/portrait/tile, 16:9 backdrop, 5:7 card, 8:1 fx-strip). */\n aspect?: AssetAspect;\n};\n\nexport const SemanticAssetRefSchema = z.object({\n role: z.string().min(1),\n category: z.string().min(1),\n animations: z.array(z.string()).optional(),\n style: VisualStyleSchema.optional(),\n variant: z.string().optional(),\n dimension: AssetDimensionSchema.optional(),\n aspect: AssetAspectSchema.optional(),\n});\n\n// ============================================================================\n// Asset — the UNIFIED asset type\n// ============================================================================\n\n/**\n * The single asset type: a `SemanticAssetRef` (role/dimension/animations/aspect/style)\n * WITH its resolved URL folded in. Used everywhere an asset is referenced — a lolo\n * board `assetManifest` (`Map string Asset`), every `@almadar/ui` game prop, the\n * asset-workflow's resolved/pool assets, and the inspector picker. Replaces the bare\n * `AssetUrl`-string asset field so the render metadata travels WITH the asset (no\n * pixel-dimension or filename heuristics needed to know sheet-vs-frame / 2d-vs-3d).\n */\nexport interface Asset extends SemanticAssetRef {\n /** The resolved asset URL. When `atlas`/`sprite` are set this is the SHEET png; otherwise a standalone image. */\n url: AssetUrl;\n /**\n * Optional atlas JSON (a `TextureAtlas` or `Tilesheet`) that slices `url`.\n * When present with `sprite`, the renderer fetches sheet + atlas once and\n * blits one sub-rect instead of loading a standalone PNG. Absent → `url` is\n * a plain whole-image asset (the existing, non-atlas path).\n */\n atlas?: AssetUrl;\n /**\n * The sub-texture selector within `atlas`: a `SubTexture` name for a\n * `TextureAtlas` (e.g. `\"grass.png\"`), or a `\"col,row\"`/flat index for a\n * `Tilesheet`. Only meaningful alongside `atlas`.\n */\n sprite?: string;\n /** Optional display name (inspector picker). */\n name?: string;\n /** Optional thumbnail URL (inspector picker grid). */\n thumbnailUrl?: string;\n}\n\nexport const AssetSchema = SemanticAssetRefSchema.extend({\n url: z.string(),\n atlas: z.string().optional(),\n sprite: z.string().optional(),\n name: z.string().optional(),\n thumbnailUrl: z.string().optional(),\n});\n\n// ============================================================================\n// Asset Catalog\n// ============================================================================\n\n/**\n * Single browsable asset in the inspector picker catalog.\n * Backs the asset/icon pickers — a flat list the inspector renders for\n * the user to choose from when a config field's type is `'asset'`.\n */\nexport interface AssetCatalogEntry {\n /** Resolvable URL to the asset. */\n url: string;\n /** Display name for the asset. */\n name: string;\n /** Grouping category within the catalog. */\n category: string;\n /** Asset kind the picker dispatches on. */\n kind: 'image' | 'spritesheet' | 'audio' | 'scene' | 'portrait' | 'model' | 'other';\n /** Optional thumbnail URL for grid previews. */\n thumbnailUrl?: string;\n /** 2D sprite vs 3D model — the asset's actual rendering dimension. */\n dimension?: AssetDimension;\n /** The asset's actual rendering aspect ratio. */\n aspect?: AssetAspect;\n}\n\nexport const AssetCatalogEntrySchema = z.object({\n url: z.string(),\n name: z.string(),\n category: z.string(),\n kind: z.enum(['image', 'spritesheet', 'audio', 'scene', 'portrait', 'model', 'other']),\n thumbnailUrl: z.string().optional(),\n dimension: AssetDimensionSchema.optional(),\n aspect: AssetAspectSchema.optional(),\n});\n\n/**\n * Flat list of browsable assets surfaced by the inspector pickers.\n */\nexport type AssetCatalog = AssetCatalogEntry[];\n\nexport const AssetCatalogSchema = z.array(AssetCatalogEntrySchema);\n\n/**\n * Asset-reference URL marker. A plain alias over `string` — the value is a\n * resolvable asset URL — but the named type lets the pattern-sync tool\n * (`tools/almadar-pattern-sync/parser.ts`) detect a component prop as an asset\n * field (tagged `asset`) the same way `EventKey`/`LucideIcon` are detected by\n * type identity. Components annotate image/url props as `AssetUrl` (`src`,\n * `backgroundImage`, `avatar`, …); the generator emits a `string` config knob\n * declared as the `asset` config type, which the property inspector dispatches\n * an AssetPicker on. Not branded — asset urls originate from user data, so cast\n * friction would buy nothing; the value is the marker the tool finds.\n */\nexport type AssetUrl = string;\n\n// ============================================================================\n// ScenePos — neutral scene coordinate\n// ============================================================================\n\n/**\n * A neutral position in scene space: 2D (`x`,`y`) or optionally 3D (`x`,`y`,`z`).\n * The single coordinate type shared by every drawable descriptor and camera pose\n * across the 2D and 3D canvas hosts, so a scene composes from the same `{x,y,z?}`\n * regardless of projection or painter. Logical, not pixel — the host's projector\n * maps a `ScenePos` to screen space.\n */\nexport interface ScenePos {\n x: number;\n y: number;\n z?: number;\n}\n\nexport const ScenePosSchema = z.object({\n x: z.number(),\n y: z.number(),\n z: z.number().optional(),\n});\n\n// ============================================================================\n// Camera — neutral camera pose shared by the 2D and 3D canvas hosts\n// ============================================================================\n\n/**\n * Camera behaviors, unifying the former per-host vocab (2D `camera` string +\n * 3D `cameraMode`). `isometric`/`top-down`/`front` are fixed framings (`front` =\n * the straight-on flat elevation — side-scroller / reference-sheet view);\n * `follow`/`chase` track a target; `perspective` is the 3D dramatic framing.\n */\nexport const CAMERA_MODES = ['isometric', 'perspective', 'top-down', 'front', 'follow', 'chase'] as const;\n\nexport type CameraMode = (typeof CAMERA_MODES)[number];\n\nexport const CameraModeSchema = z.enum(CAMERA_MODES);\n\n/**\n * A neutral camera pose shared by the 2D and 3D canvas hosts, so `type: canvas`\n * carries one camera object regardless of painter. `pos`/`target` are `ScenePos`\n * (logical scene space, not pixels); `zoom` scales the view (the former `scale`);\n * `fov` is the 3D field of view; `mode` selects the framing/tracking behavior.\n * Every field is optional — an omitted camera means the host's default framing.\n */\nexport interface Camera {\n pos?: ScenePos;\n target?: ScenePos;\n zoom?: number;\n fov?: number;\n mode?: CameraMode;\n /** Orbit the mode's framing position around the vertical axis through the target, in radians (3D hosts only). */\n azimuth?: number;\n}\n\nexport const CameraSchema = z.object({\n pos: ScenePosSchema.optional(),\n target: ScenePosSchema.optional(),\n zoom: z.number().optional(),\n fov: z.number().optional(),\n mode: CameraModeSchema.optional(),\n azimuth: z.number().optional(),\n});\n\n// ============================================================================\n// Type Exports\n// ============================================================================\n\nexport type SemanticAssetRefInput = z.input<typeof SemanticAssetRefSchema>;\nexport type AnimationDefInput = z.input<typeof AnimationDefSchema>;\nexport type AssetCatalogEntryInput = z.input<typeof AssetCatalogEntrySchema>;\nexport type SpriteSheetAtlasInput = z.input<typeof SpriteSheetAtlasSchema>;\n\n// ============================================================================\n// Helper Functions\n// ============================================================================\n\n/**\n * Creates a semantic asset key from role and category.\n * \n * Generates a unique asset identifier by combining role and category\n * with a colon separator. Used for asset management and lookup.\n * \n * @param {EntityRole} role - Entity role (e.g., 'player', 'enemy')\n * @param {string} category - Asset category (e.g., 'sprite', 'animation')\n * @returns {string} Asset key in format 'role:category'\n * \n * @example\n * createAssetKey('player', 'sprite'); // returns 'player:sprite'\n * createAssetKey('enemy', 'animation'); // returns 'enemy:animation'\n */\nexport function createAssetKey(role: EntityRole, category: string): string {\n return `${role}:${category}`;\n}\n\n/**\n * Parses an asset key into role and category components.\n * \n * Deconstructs an asset key string (format 'role:category') into its\n * constituent parts. Returns null if the key format is invalid.\n * \n * @param {string} key - Asset key in format 'role:category'\n * @returns {{ role: string; category: string } | null} Parsed components or null\n * \n * @example\n * parseAssetKey('player:sprite'); // returns { role: 'player', category: 'sprite' }\n * parseAssetKey('enemy:animation'); // returns { role: 'enemy', category: 'animation' }\n * parseAssetKey('invalid'); // returns null\n */\nexport function parseAssetKey(key: string): { role: string; category: string } | null {\n const parts = key.split(':');\n if (parts.length !== 2) return null;\n return { role: parts[0], category: parts[1] };\n}\n\n/**\n * Gets common animations for an entity role.\n * \n * Returns an array of default animation names appropriate for the\n * specified entity role. Used for asset configuration and validation.\n * \n * @param {EntityRole} role - Entity role\n * @returns {string[]} Array of default animation names\n * \n * @example\n * getDefaultAnimationsForRole('player'); // returns ['idle', 'run', 'jump', 'fall', 'attack', 'hurt', 'die']\n * getDefaultAnimationsForRole('enemy'); // returns ['idle', 'walk', 'attack', 'hurt', 'die']\n */\nexport function getDefaultAnimationsForRole(role: EntityRole): string[] {\n switch (role) {\n case 'player':\n return ['idle', 'run', 'jump', 'fall', 'attack', 'hurt', 'die'];\n case 'enemy':\n return ['idle', 'walk', 'attack', 'hurt', 'die'];\n case 'npc':\n return ['idle', 'walk', 'talk'];\n case 'item':\n return ['idle', 'collected'];\n case 'tile':\n return ['static'];\n case 'projectile':\n return ['fly', 'hit', 'expire'];\n case 'effect':\n return ['play'];\n case 'ui':\n return ['normal', 'hover', 'pressed', 'disabled'];\n case 'decoration':\n return ['idle'];\n case 'vehicle':\n return ['idle', 'move', 'brake'];\n default:\n return ['idle'];\n }\n}\n\n/**\n * Validates that an asset reference has required animations.\n * \n * Checks if an asset reference contains all required animations.\n * Returns an error message if validation fails, or null if valid.\n * \n * @param {SemanticAssetRef} assetRef - Asset reference to validate\n * @param {string[]} requiredAnimations - Required animation names\n * @returns {string | null} Error message or null if valid\n * \n * @example\n * validateAssetAnimations(assetRef, ['idle', 'run']); // returns null if valid\n * validateAssetAnimations(assetRef, ['missing-animation']); // returns error message\n */\nexport function validateAssetAnimations(\n assetRef: SemanticAssetRef,\n requiredAnimations: string[]\n): { valid: boolean; missing: string[] } {\n const provided = assetRef.animations || [];\n const missing = requiredAnimations.filter((anim) => !provided.includes(anim));\n return { valid: missing.length === 0, missing };\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';\nimport type { RuntimeValue } from './json.js';\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 */\n/** Object literal branch of an S-expression atom (payload data, props, etc.). */\nexport interface SExprObject {\n [key: string]: SExpr;\n}\nexport type SExprAtom = string | number | boolean | null | SExprObject;\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 * Recursive schema for s-expr-shaped DATA in literal positions (object\n * values, effect arguments). Unlike `SExprSchema`, arrays may be empty or\n * non-operator-headed — literal data lists (`children: []`, `tiles: [...]`)\n * are valid here; only call positions get the operator-head refine.\n */\nexport const SExprDataSchema: z.ZodType<SExpr> = z.lazy(() =>\n z.union([SExprAtomSchema, z.array(SExprDataSchema)]),\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(SExprDataSchema), // 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: RuntimeValue): 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 {RuntimeValue} 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: RuntimeValue): 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 {RuntimeValue} 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: RuntimeValue): 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 {RuntimeValue} 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: RuntimeValue): 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 * `user` is the authenticated user / agent context (see binding.ts) and is\n * read-only in guards/effects/ticks — atoms reference `@user.id` and\n * `@user.role` for ownership / role-based gating.\n * `callsitePayload` is the call-site-captured event payload emitted by the\n * compiler's inline-trait hoisting; the runtime BindingResolver resolves it\n * at the composing effect.\n */\nexport const CORE_BINDINGS = ['entity', 'payload', 'state', 'now', 'config', 'computed', 'trait', 'user', 'callsitePayload'] 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// ============================================================================\n// Runtime Evaluation Types\n// ============================================================================\n\n/** Evaluation context for guards and s-expressions. Recursive. */\nexport interface EvalContext {\n [key: string]: string | number | boolean | Date | null | string[] | EvalContext | undefined;\n}\n\n/**\n * A single value carried by an event payload field. The top-level payload\n * is always an object; the VALUES in that object can be primitives, nested\n * objects, or arrays of the same. Arrays are allowed so real-world emits\n * like `{ files: [{ name, size, type }, ...] }` or `{ selected: string[] }`\n * are typed natively instead of forcing consumers to wrap at every call.\n *\n * `Date` is included so `EntityRow` (whose values are `FieldValue`, which\n * includes `Date`) is assignable to a payload field without a cast —\n * emitted entity rows flow through the bus without boundary widening.\n */\nexport type EventPayloadValue =\n | string\n | number\n | boolean\n | Date\n | null\n | undefined\n | EventPayload\n | readonly EventPayloadValue[];\n\n/**\n * Typed event payload. Object-shaped so it's assignable to the bus's\n * `EventPayload` parameter without casts.\n */\nexport interface EventPayload {\n [key: string]: EventPayloadValue;\n}\n\n/**\n * Runtime guard for `EventPayloadValue` — narrows interpreter-produced\n * `unknown` values at typed substrate boundaries (e.g. `TraceContext.emit`).\n */\nexport function isEventPayloadValue(value: RuntimeValue): value is EventPayloadValue {\n if (value === null || value === undefined) return true;\n const kind = typeof value;\n if (kind === 'string' || kind === 'number' || kind === 'boolean') return true;\n if (value instanceof Date) return true;\n if (Array.isArray(value)) return value.every((item: RuntimeValue) => isEventPayloadValue(item));\n if (kind === 'object' && value !== null && typeof value === 'object') {\n return Object.values(value).every((item: RuntimeValue) => isEventPayloadValue(item));\n }\n return false;\n}\n\n/**\n * Allowed leaf value for `LogMeta`. Mirrors `EventPayloadValue` shape so\n * the same row/list data flows through logs without manual flattening,\n * with `Error` added since structured logs carry exception detail.\n */\nexport type LogMetaValue =\n | string\n | number\n | boolean\n | Date\n | null\n | undefined\n | Error\n | LogMeta\n | readonly LogMetaValue[];\n\n/** Structured log/event metadata. Recursive to support nested log data. */\nexport interface LogMeta {\n [key: string]: LogMetaValue;\n}\n","/**\n * Entity Types for Orbital Units\n *\n * Defines the OrbitalEntity type - the nucleus of an Orbital Unit.\n *\n * @packageDocumentation\n */\n\nimport { z } from 'zod';\nimport type { EntityId } from './identity.js';\nimport { EntityFieldSchema, type EntityField } from './field.js';\nimport { SemanticAssetRefSchema, type SemanticAssetRef } from './asset.js';\nimport { JsonValueSchema, type RuntimeValue } from './json.js';\nimport { SExprSchema, type SExpr } from './expression.js';\n\n// ============================================================================\n// Entity Persistence\n// ============================================================================\n\n/**\n * Entity persistence types.\n *\n * - persistent: Stored in database (has collection)\n * - runtime: Exists only at runtime (not persisted)\n */\nexport type EntityPersistence = 'persistent' | 'runtime';\n\nexport const EntityPersistenceSchema = z.enum([\n 'persistent',\n 'runtime',\n]);\n\n// ============================================================================\n// Orbital Entity\n// ============================================================================\n\n/**\n * OrbitalEntity - the nucleus of an Orbital Unit.\n *\n * This is a simplified entity definition optimized for orbital composition.\n * Collection names are derived automatically from persistence type if not provided.\n */\nexport type OrbitalEntity = {\n /** V4 dual-carry id sibling of `name` — optional until the Phase-7 flip. */\n id?: EntityId;\n\n /** Entity name (PascalCase, e.g., \"Task\", \"User\") */\n name: string;\n\n /** Entity persistence type (defaults to 'persistent' if not specified) */\n persistence?: EntityPersistence;\n\n /** Whether this entity's state is shared across all bound traits (vs per-trait copy). Orthogonal to persistence. */\n shared?: boolean;\n\n /**\n * Whether this entity types the ambient `@user` viewer. Orthogonal to both\n * `persistence` and `shared`: `[persistent: people, identity]` is an\n * app-owned user directory, `[runtime, identity]` the provider-supplied\n * current viewer. At most one per composed program.\n */\n identity?: boolean;\n\n /**\n * `@read` — a per-row predicate (`@entity` = candidate row, `@user` =\n * viewer) ANDed with any call-site `filter:`. The un-bypassable twin of\n * `filter:`, enforced once for every trait that fetches this entity.\n */\n read_policy?: SExpr;\n\n /** `@create` — `@entity` binds the incoming data about to become a row. */\n create_policy?: SExpr;\n\n /** `@update` — `@entity` binds the existing row before mutation. */\n update_policy?: SExpr;\n\n /** `@delete` — same binding shape as `@update`. */\n delete_policy?: SExpr;\n\n /**\n * `@<op> none \"<reason>\"` — a directive's omission, DECLARED.\n *\n * Runtime behaviour is identical to leaving the directive out (an absent\n * policy is allow-all). It records that the author concluded no per-row\n * predicate can express the rule — usually because visibility depends on a\n * DIFFERENT entity, which a per-row predicate cannot join across. Without\n * it a lint must flag considered and forgotten omissions alike, and a lint\n * that flags correct code is one people learn to ignore.\n */\n access_waivers?: {\n read?: string;\n create?: string;\n update?: string;\n delete?: string;\n };\n\n /** Collection name (auto-derived if not provided for persistent entities) */\n collection?: string;\n\n /** Entity fields */\n fields: EntityField[];\n\n /** Pre-authored instances (seed data or static reference data) */\n instances?: EntityRow[];\n\n /** Auto-add createdAt/updatedAt timestamps */\n timestamps?: boolean;\n\n /** Soft delete support */\n softDelete?: boolean;\n\n /** Human-readable description */\n description?: string;\n\n /** Visual prompt for AI generation */\n visual_prompt?: string;\n\n /** Semantic asset reference for visual representation (games) */\n assetRef?: SemanticAssetRef;\n};\n\nexport const OrbitalEntitySchema = z.object({\n name: z.string().min(1, 'Entity name is required'),\n persistence: EntityPersistenceSchema.default('persistent'),\n shared: z.boolean().optional(),\n // Must stay in step with the Rust serde field (`EntityDefinition.identity`,\n // orbital-core/src/schema/types.rs). `z.object()` STRIPS unknown keys rather\n // than rejecting them, so a Rust-only field works on the compiled path and\n // silently vanishes on the interpreter path.\n identity: z.boolean().optional(),\n // Same \"must stay in step with Rust serde\" hazard as `identity` above —\n // these four mirror `EntityDefinition.{read,create,update,delete}_policy`.\n // Rust has no `rename_all` on this struct, so the wire key IS snake_case\n // (unlike this file's other camelCase fields, which are Rust-side-absent\n // and so never hit this cross-language constraint — see `visual_prompt`\n // just below for the existing precedent).\n read_policy: SExprSchema.optional(),\n create_policy: SExprSchema.optional(),\n update_policy: SExprSchema.optional(),\n delete_policy: SExprSchema.optional(),\n // Snake_case for the same cross-language reason as the four policies above.\n access_waivers: z\n .object({\n read: z.string().optional(),\n create: z.string().optional(),\n update: z.string().optional(),\n delete: z.string().optional(),\n })\n .optional(),\n collection: z.string().optional(),\n fields: z.array(EntityFieldSchema).min(1, 'At least one field is required'),\n instances: z.array(z.record(JsonValueSchema)).optional(),\n timestamps: z.boolean().optional(),\n softDelete: z.boolean().optional(),\n description: z.string().optional(),\n visual_prompt: z.string().optional(),\n assetRef: SemanticAssetRefSchema.optional(),\n});\n\nexport type OrbitalEntityInput = z.input<typeof OrbitalEntitySchema>;\n\n// ============================================================================\n// Type Aliases (for cleaner imports)\n// ============================================================================\n\n/** Alias for OrbitalEntity - preferred name */\nexport type Entity = OrbitalEntity;\n\n/** Alias for OrbitalEntitySchema - preferred name */\nexport const EntitySchema = OrbitalEntitySchema;\n\n// ============================================================================\n// Utility Functions\n// ============================================================================\n\n/**\n * Derives the collection name for a persistent entity.\n * \n * Generates the database collection name by converting the entity name\n * to lowercase and adding an 's' suffix (simple pluralization).\n * Returns undefined for non-persistent (runtime) entities.\n * \n * @param {OrbitalEntity} entity - Entity to derive collection name for\n * @returns {string | undefined} Collection name or undefined for non-persistent entities\n * \n * @example\n * deriveCollection({ name: 'User', persistence: 'persistent' }); // returns 'users'\n * deriveCollection({ name: 'Task', persistence: 'runtime' }); // returns undefined\n */\nexport function deriveCollection(entity: OrbitalEntity): string | undefined {\n if (entity.persistence !== 'persistent') {\n return undefined;\n }\n // Lowercase + 's' suffix (simple pluralization)\n return entity.name.toLowerCase() + 's';\n}\n\n/**\n * Checks if an entity is runtime-only (not persisted).\n * \n * Type guard to determine if an entity exists only at runtime\n * and is not stored in the database.\n * \n * @param {OrbitalEntity} entity - Entity to check\n * @returns {boolean} True if entity is runtime-only, false otherwise\n * \n * @example\n * isRuntimeEntity({ persistence: 'runtime' }); // returns true\n * isRuntimeEntity({ persistence: 'persistent' }); // returns false\n */\nexport function isRuntimeEntity(entity: OrbitalEntity): boolean {\n return entity.persistence === 'runtime';\n}\n\n/**\n * Checks whether an entity's persistence mode allows `persistence` /\n * `collection` overrides at the factory call site.\n *\n * Only `persistent` entities (explicit or default) support these overrides.\n * Runtime entities are fixed; callers must not expose `persistence` or\n * `collection` params for them.\n *\n * @param persistence - The entity persistence mode (undefined = default persistent)\n * @returns True when overrides are allowed, false otherwise\n *\n * @example\n * persistenceModeAllowsOverrides('persistent'); // returns true\n * persistenceModeAllowsOverrides('runtime'); // returns false\n * persistenceModeAllowsOverrides(undefined); // returns true (default persistent)\n */\nexport function persistenceModeAllowsOverrides(\n persistence: EntityPersistence | undefined,\n): boolean {\n return persistence === 'persistent' || persistence === undefined;\n}\n\n// ============================================================================\n// Entity Instance Data (Runtime)\n// ============================================================================\n\n/**\n * A single field value at runtime.\n * Union of all possible types from FieldType: string, number, boolean, date, array, nested.\n * The nested-record branch's index signature tolerates `undefined` so that\n * TypeScript optional properties (`x?: string`, carrying `string | undefined`)\n * on EntityRow extenders typecheck without ceremony. At JSON serialization\n * time `undefined` is equivalent to \"key absent\" and never appears on the\n * wire; the inclusion here is a pure type-surface accommodation.\n */\nexport type FieldValue = string | number | boolean | Date | null | string[] | FieldValue[] | { [key: string]: FieldValue | undefined };\n\n/**\n * Runtime guard for `FieldValue` — narrows interpreter-produced `unknown`\n * values at typed substrate boundaries (e.g. `IntegrationContext.http` body).\n */\nexport function isFieldValue(value: RuntimeValue): value is FieldValue {\n if (value === null) return true;\n const kind = typeof value;\n if (kind === 'string' || kind === 'number' || kind === 'boolean') return true;\n if (value instanceof Date) return true;\n if (Array.isArray(value)) return value.every((item: RuntimeValue) => isFieldValue(item));\n if (kind === 'object' && value !== null && typeof value === 'object') {\n return Object.values(value).every((item: RuntimeValue) => item === undefined || isFieldValue(item));\n }\n return false;\n}\n\n/**\n * One instance of an entity with actual field values.\n * The shape is determined by the Entity definition at schema time.\n *\n * @example\n * // Entity defines: Patient { fullName: string, age: number, active: boolean }\n * // EntityRow is: { id: \"p1\", fullName: \"Sarah\", age: 34, active: true }\n */\nexport type EntityRow = { id?: string } & Record<string, FieldValue | undefined>;\n\n/**\n * A field-TYPED `EntityRow` — the SINGLE entity type, refined with a concrete\n * field SHAPE `S`. Non-optional members of `S` are REQUIRED, each with its real\n * type; the result stays `& EntityRow`, so the index signature is intact and\n * every other field is still field-open — any domain entity that provides those\n * fields satisfies it.\n *\n * One declaration, two jobs: (1) TypeScript enforces the bound entity has the\n * fields WITH their types (a behavior binding a thinner/mistyped entity fails to\n * typecheck); and (2) pattern-sync reads the same type and writes the entity\n * prop's field shape (`properties` + `requiredFields`) onto the registry, so\n * lolo-ui emits a COMPLETE `entity { … }` (every field, typed + demo-seeded) and\n * the `ORB_X_ENTITY_PROP_CONTRACT` validator rejects an incompatible bind at\n * `orbital validate`. (A raw `EntityRow & { rating: number }` intersection is\n * equivalent for one-off shapes.)\n *\n * @example\n * // HeroOrganism renders entity.title / entity.subtitle:\n * entity?: EntityWith<{ title: string; subtitle?: string }>;\n * // entity.title → string (required)\n * // entity.subtitle → string | undefined (optional)\n * // entity.other → FieldValue | undefined (still field-open)\n */\n// `S extends object` (not `Record<string, FieldValue>`) so a plain `interface`\n// row shape satisfies it — interfaces lack the implicit index signature `Record`\n// requires. FieldValue-compatibility is still enforced structurally: `& EntityRow`\n// intersects every field with the `FieldValue | undefined` index signature, so a\n// non-FieldValue field (e.g. a React `LucideIcon`) collapses to `never` at use.\nexport type EntityWith<S extends object> = EntityRow & S;\n\n/**\n * Collection of entity instances keyed by entity name.\n * Used by OrbPreview mockData, OrbitalServerRuntime state, data grids, etc.\n *\n * @example\n * const data: EntityData = {\n * Patient: [{ id: \"1\", fullName: \"Sarah\", age: 34 }],\n * QueueEntry: [{ id: \"1\", patientName: \"Sarah\", waitMinutes: 12 }],\n * };\n */\nexport type EntityData = Record<string, EntityRow[]>;\n","/**\n * The one owner of mock-seed value synthesis.\n *\n * Five synthesizers used to hold four different policies on a field's declared\n * `default`, so the same entity seeded differently depending on which path\n * rendered it. This module is the single policy; callers supply only entropy.\n *\n * @packageDocumentation\n */\n\nimport type {\n ArrayEntityField,\n EntityField,\n ObjectEntityField,\n RelationEntityField,\n} from '../types/field.js';\nimport type { EntityPersistence, EntityRow, FieldValue } from '../types/entity.js';\nimport { isFieldValue } from '../types/entity.js';\nimport {\n randomBoolean,\n randomEmail,\n randomInt,\n randomPhone,\n randomStraddlingDate,\n randomUrl,\n randomUuid,\n randomWords,\n} from './random.js';\n\n/**\n * Entropy source. `'seeded'` draws from the shared LCG — stateful and\n * order-dependent, so a value depends on how many draws earlier rows consumed.\n * `'index'` is a pure function of `(field, index)`, which is the only strategy\n * Rust can reproduce and therefore the one parity is asserted on.\n */\nexport type SampleStrategy = 'seeded' | 'index';\n\n/** Recursion cap for self-referential `items` / `properties` walks. */\nconst MAX_NESTED_DEPTH = 3;\n\n/** Keys never synthesized — the caller's row loop owns them. */\nconst RESERVED_FIELD_NAMES: ReadonlySet<string> = new Set(['id', 'createdAt', 'updatedAt']);\n\nexport interface SampleEntity {\n readonly name: string;\n readonly persistence?: EntityPersistence;\n readonly fields: readonly EntityField[];\n}\n\nexport interface SampleContext {\n readonly entityName: string;\n /** 1-based row ordinal. Row 1 always yields `values[0]`. */\n readonly index: number;\n readonly strategy: SampleStrategy;\n /** Declared persistence of the OWNING entity; undefined means persistent. */\n readonly persistence?: EntityPersistence;\n readonly depth?: number;\n}\n\n/**\n * Image-bearing field names that still resolve to a real photo.\n *\n * A stopgap, kept verbatim from the two copies it replaces: no entity field in\n * the corpus can express an image type yet, and 470 string fields are named\n * this way, so deleting it would render broken `<img>` corpus-wide. Retire it\n * once a real `image` type exists — not before.\n */\nexport const IMAGE_FIELD_NAMES: ReadonlySet<string> = new Set([\n 'image', 'imageurl', 'image_url',\n 'photo', 'photourl', 'photo_url',\n 'avatar', 'avatarurl', 'avatar_url',\n 'thumbnail', 'thumbnailurl', 'thumbnail_url',\n 'picture', 'pictureurl',\n 'cover', 'coverurl',\n 'banner', 'bannerurl',\n]);\n\n/** Deterministic stock-photo URL; the same entity+field renders the same image. */\nexport function sampleImageUrl(\n entityName: string,\n fieldName: string,\n ctx: SampleContext,\n width = 400,\n height = 400,\n): string {\n const salt = ctx.strategy === 'seeded' ? randomInt({ min: 0, max: 1000 }) : ctx.index;\n const seed = `${entityName}-${fieldName}-${salt}`;\n return `https://picsum.photos/seed/${encodeURIComponent(seed)}/${width}/${height}`;\n}\n\n/** `targetType` / `target_type` -> `Target Type`, for readable sample text. */\nfunction titleCase(name: string): string {\n const spaced = name\n .split('')\n .flatMap((c) => (c === '_' || c === '-' ? [' '] : c === c.toUpperCase() && c !== c.toLowerCase() ? [' ', c] : [c]))\n .join('');\n return spaced\n .split(/\\s+/)\n .filter((w) => w.length > 0)\n .map((w) => w.charAt(0).toUpperCase() + w.slice(1))\n .join(' ');\n}\n\n/** Lowercase, punctuation-free fragment safe to embed in an email or URL. */\nfunction slug(name: string): string {\n return name.replace(/[^a-zA-Z0-9]/g, '').toLowerCase() || 'value';\n}\n\n/** A deterministic, validator-satisfying UUID for the pure-index strategy. */\nfunction indexUuid(index: number): string {\n return `00000000-0000-4000-8000-${index.toString(16).padStart(12, '0').slice(-12)}`;\n}\n\n/** The closed vocabulary a field declares, if any. */\nfunction declaredValues(field: EntityField): readonly string[] | undefined {\n const values = 'values' in field ? field.values : undefined;\n return values && values.length > 0 ? values : undefined;\n}\n\n/**\n * Is `field.default` a value the synthesizer must return verbatim?\n *\n * Exported so codegen and tests share the one predicate rather than restating it.\n */\nexport function isDeclaredDefaultHonored(field: EntityField): boolean {\n const value = field.default;\n if (value === undefined || value === null) return false;\n if (typeof value === 'number' || typeof value === 'boolean') return true;\n if (Array.isArray(value)) return true;\n if (typeof value === 'object') return true;\n if (typeof value !== 'string') return false;\n\n const values = declaredValues(field);\n // Gate 3: '' is a placeholder unless the field's own vocabulary declares it.\n if (value === '') return values !== undefined && values.includes('');\n // A default on a closed vocabulary of a collection is a new-record default,\n // not a claim about existing rows — so the row cycle wins over it.\n return values === undefined;\n}\n\n/** Rows to synthesize. A `[runtime]` entity is a per-orbital singleton. */\nexport function sampleRowCount(entity: SampleEntity, requested: number): number {\n return entity.persistence === 'runtime' ? 1 : requested;\n}\n\nfunction sampleText(field: EntityField, ctx: SampleContext): string {\n const fieldName = field.name ?? 'field';\n if (IMAGE_FIELD_NAMES.has(fieldName.toLowerCase())) {\n return sampleImageUrl(ctx.entityName, fieldName, ctx);\n }\n return ctx.strategy === 'seeded'\n ? randomWords(2)\n : `${titleCase(fieldName)} ${ctx.index}`;\n}\n\nfunction sampleDate(ctx: SampleContext, dateOnly: boolean): string {\n if (ctx.strategy === 'index') {\n const month = String((ctx.index % 12) + 1).padStart(2, '0');\n return dateOnly ? `2026-${month}-15` : `2026-${month}-15T00:00:00.000Z`;\n }\n const iso = randomStraddlingDate({ days: 15 }).toISOString();\n return dateOnly ? iso.split('T')[0]! : iso;\n}\n\nfunction sampleRelation(field: RelationEntityField): FieldValue {\n // Placeholder; the caller's post-pass links real sibling ids.\n return field.relation?.cardinality === 'one' ? '' : [];\n}\n\nfunction sampleArray(field: ArrayEntityField, ctx: SampleContext): FieldValue {\n const depth = ctx.depth ?? 0;\n if (!field.items || depth >= MAX_NESTED_DEPTH) return [];\n const count = ctx.strategy === 'seeded' ? randomInt({ min: 3, max: 5 }) : 3;\n const elementName = field.name ?? 'item';\n const out: FieldValue[] = [];\n for (let i = 0; i < count; i++) {\n const element: EntityField = { ...field.items, name: `${elementName}[${i}]` };\n out.push(\n sampleFieldValue(element, {\n ...ctx,\n index: ctx.index * 10 + i,\n depth: depth + 1,\n }) ?? null,\n );\n }\n return out;\n}\n\nfunction sampleObject(field: ObjectEntityField, ctx: SampleContext): FieldValue {\n const depth = ctx.depth ?? 0;\n if (!field.properties || depth >= MAX_NESTED_DEPTH) return null;\n const out: Record<string, FieldValue> = {};\n for (const [propName, propField] of Object.entries(field.properties)) {\n const child: EntityField = { ...propField, name: propName };\n out[propName] = sampleFieldValue(child, { ...ctx, depth: depth + 1 }) ?? null;\n }\n return out;\n}\n\n/**\n * One sample value for one field. `undefined` means OMIT the key.\n *\n * Order matters — see the three gates in the plan. Gates 1 and 2 read declared\n * schema properties (`persistence`, `intrinsic`), never field names.\n */\nexport function sampleFieldValue(field: EntityField, ctx: SampleContext): FieldValue | undefined {\n const honoredDefault =\n field.default !== undefined && isFieldValue(field.default) ? field.default : undefined;\n\n // Gate 2: the owning trait computes this, so the data layer must not write it.\n if (field.intrinsic === true) return honoredDefault;\n\n // Gate 1: a runtime singleton's seeded row must equal its declared-defaults\n // projection, or persistence disagrees with the default layer in the @entity\n // merge and boots the machine into the wrong state.\n const isRuntime = ctx.persistence === 'runtime';\n if (isRuntime && honoredDefault !== undefined) return honoredDefault;\n\n if (!isRuntime && isDeclaredDefaultHonored(field) && honoredDefault !== undefined) {\n return honoredDefault;\n }\n\n const values = declaredValues(field);\n if (values) {\n // Row 1 yields values[0], which is the declared default for 85% of fields.\n const ordinal = isRuntime ? 1 : ctx.index;\n return values[(ordinal - 1) % values.length]!;\n }\n\n switch (field.type) {\n case 'string':\n return sampleText(field, ctx);\n // Semantic domains synthesize a value that SATISFIES their own validator —\n // the property that keeps the seeder and the validator from drifting.\n case 'email':\n return ctx.strategy === 'seeded'\n ? randomEmail()\n : `${slug(field.name ?? 'user')}${ctx.index}@example.com`;\n case 'url':\n return ctx.strategy === 'seeded'\n ? randomUrl()\n : `https://example.com/${slug(field.name ?? 'link')}/${ctx.index}`;\n case 'phone':\n return ctx.strategy === 'seeded'\n ? randomPhone()\n : `+1-555-${String(1000 + (ctx.index % 9000)).padStart(4, '0')}`;\n case 'uuid':\n return ctx.strategy === 'seeded' ? randomUuid() : indexUuid(ctx.index);\n case 'image':\n return sampleImageUrl(ctx.entityName, field.name ?? 'image', ctx);\n case 'number': {\n // A declared range constrains the value; an UNdeclared one must not, or\n // the index ladder silently flattens once it passes an invented ceiling.\n if (ctx.strategy === 'seeded') {\n return randomInt({ min: field.min ?? 0, max: field.max ?? 100 });\n }\n const stepped = (field.min ?? 0) + ctx.index * 10;\n return field.max !== undefined && stepped > field.max ? field.max : stepped;\n }\n case 'boolean':\n return ctx.strategy === 'seeded' ? randomBoolean() : ctx.index % 2 === 0;\n case 'date':\n return sampleDate(ctx, true);\n case 'timestamp':\n case 'datetime':\n return sampleDate(ctx, false);\n case 'enum':\n // Reached only when the enum declares no values — a malformed field.\n return null;\n case 'relation':\n return sampleRelation(field);\n case 'array':\n return sampleArray(field, ctx);\n case 'object':\n return sampleObject(field, ctx);\n case 'trait':\n case 'slot':\n case 'pattern':\n return undefined;\n default:\n return sampleText(field, ctx);\n }\n}\n\n/** One row. Reserved keys are left to the caller. */\nexport function sampleRow(\n entity: SampleEntity,\n ctx: Omit<SampleContext, 'entityName' | 'depth'>,\n): EntityRow {\n const row: EntityRow = {};\n for (const field of entity.fields) {\n const name = field.name;\n if (!name || RESERVED_FIELD_NAMES.has(name)) continue;\n const value = sampleFieldValue(field, {\n ...ctx,\n entityName: entity.name,\n persistence: ctx.persistence ?? entity.persistence,\n });\n if (value !== undefined) row[name] = value;\n }\n return row;\n}\n\n/** `count` rows, 1-based, honoring the runtime-singleton gate. */\nexport function sampleRows(\n entity: SampleEntity,\n count: number,\n strategy: SampleStrategy,\n): EntityRow[] {\n const rowCount = sampleRowCount(entity, count);\n const rows: EntityRow[] = [];\n for (let i = 1; i <= rowCount; i++) {\n rows.push(sampleRow(entity, { index: i, strategy, persistence: entity.persistence }));\n }\n return rows;\n}\n"]}
|