@almadar/core 10.96.0 → 10.99.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.
Files changed (101) hide show
  1. package/README.md +25 -0
  2. package/dist/builders.d.ts +5 -4
  3. package/dist/builders.js +60 -34
  4. package/dist/builders.js.map +1 -1
  5. package/dist/bus-BGDM3Xot.d.ts +565 -0
  6. package/dist/domain-Ds_7wZIL.d.ts +16213 -0
  7. package/dist/{effect-Bw8T4qh5.d.ts → effect-CW_IT0Jn.d.ts} +59 -4
  8. package/dist/{entityAccess-DfoXs9mc.d.ts → entityAccess-BLpOMojb.d.ts} +3 -3
  9. package/dist/{expression-WfTp2arD.d.ts → expression-DRwzVnMu.d.ts} +5 -1
  10. package/dist/factory/index.d.ts +5 -5
  11. package/dist/factory/index.js +22 -0
  12. package/dist/factory/index.js.map +1 -1
  13. package/dist/factory-runtime/index.d.ts +5 -4
  14. package/dist/factory-runtime/index.js +176 -34
  15. package/dist/factory-runtime/index.js.map +1 -1
  16. package/dist/fixtures.d.ts +45 -0
  17. package/dist/fixtures.js +693 -0
  18. package/dist/fixtures.js.map +1 -0
  19. package/dist/{index-CN16-h3i.d.ts → index-CHHuux4I.d.ts} +9 -375
  20. package/dist/index.d.ts +19 -15
  21. package/dist/index.js +9070 -44
  22. package/dist/index.js.map +1 -1
  23. package/dist/mock/index.d.ts +6 -5
  24. package/dist/mock/index.js +14 -0
  25. package/dist/mock/index.js.map +1 -1
  26. package/dist/patterns/component-mapping.json +1 -1
  27. package/dist/patterns/event-contracts.json +1 -1
  28. package/dist/patterns/index.d.ts +12 -8
  29. package/dist/patterns/index.js +15 -4
  30. package/dist/patterns/index.js.map +1 -1
  31. package/dist/patterns/patterns-registry.json +1 -1
  32. package/dist/patterns/registry.json +1 -1
  33. package/dist/{schema-DPpES4qj.d.ts → schema-BVjtoRYf.d.ts} +2134 -23608
  34. package/dist/state-machine/index.d.ts +1 -1
  35. package/dist/themes/index.d.ts +19 -0
  36. package/dist/themes/index.js +9251 -0
  37. package/dist/themes/index.js.map +1 -0
  38. package/dist/{trait-DXXRrRMP.d.ts → trait-C9lr222u.d.ts} +26 -26
  39. package/dist/types/index.d.ts +8 -6
  40. package/dist/types/index.js +208 -41
  41. package/dist/types/index.js.map +1 -1
  42. package/dist/{types-BMaTUGyk.d.ts → types-BoyvM79n.d.ts} +2 -2
  43. package/fixtures/events-wire/cascade-emitted-events/request.json +9 -0
  44. package/fixtures/events-wire/cascade-emitted-events/response.json +30 -0
  45. package/fixtures/events-wire/client-effects-by-trait/request.json +4 -0
  46. package/fixtures/events-wire/client-effects-by-trait/response.json +52 -0
  47. package/fixtures/events-wire/effect-results/request.json +9 -0
  48. package/fixtures/events-wire/effect-results/response.json +42 -0
  49. package/fixtures/events-wire/effect-results-every-kind/request.json +9 -0
  50. package/fixtures/events-wire/effect-results-every-kind/response.json +70 -0
  51. package/fixtures/events-wire/guard-rejected/request.json +6 -0
  52. package/fixtures/events-wire/guard-rejected/response.json +11 -0
  53. package/fixtures/events-wire/live-push/live-push.json +12 -0
  54. package/fixtures/events-wire/live-push/request.json +9 -0
  55. package/fixtures/events-wire/live-push/response.json +33 -0
  56. package/fixtures/events-wire/navigate-1/request.json +5 -0
  57. package/fixtures/events-wire/navigate-1/response.json +16 -0
  58. package/fixtures/events-wire/navigate-2/request.json +8 -0
  59. package/fixtures/events-wire/navigate-2/response.json +19 -0
  60. package/fixtures/events-wire/navigate-3/request.json +8 -0
  61. package/fixtures/events-wire/navigate-3/response.json +22 -0
  62. package/fixtures/events-wire/navigate-back/request.json +5 -0
  63. package/fixtures/events-wire/navigate-back/response.json +15 -0
  64. package/fixtures/events-wire/render-ui-3/request.json +5 -0
  65. package/fixtures/events-wire/render-ui-3/response.json +20 -0
  66. package/fixtures/events-wire/render-ui-4/request.json +5 -0
  67. package/fixtures/events-wire/render-ui-4/response.json +41 -0
  68. package/fixtures/events-wire/render-ui-5/request.json +9 -0
  69. package/fixtures/events-wire/render-ui-5/response.json +52 -0
  70. package/fixtures/events-wire/render-ui-clear/request.json +5 -0
  71. package/fixtures/events-wire/render-ui-clear/response.json +27 -0
  72. package/fixtures/events-wire/sse-stream/request.json +9 -0
  73. package/fixtures/events-wire/sse-stream/response.json +79 -0
  74. package/fixtures/events-wire/sse-stream/stream.json +131 -0
  75. package/fixtures/events-wire/stateless-traits/request.json +27 -0
  76. package/fixtures/events-wire/stateless-traits/response.json +15 -0
  77. package/fixtures/theme-tokens/every-key.json +43 -0
  78. package/package.json +18 -3
  79. package/themes/almadar-website.json +207 -0
  80. package/themes/almadar.json +203 -0
  81. package/themes/atelier.json +459 -0
  82. package/themes/bloomberg-dense.json +459 -0
  83. package/themes/clay.json +445 -0
  84. package/themes/comic.json +457 -0
  85. package/themes/corporate.json +445 -0
  86. package/themes/game-adventure.json +229 -0
  87. package/themes/game-rpg.json +230 -0
  88. package/themes/game-sci-fi.json +229 -0
  89. package/themes/game-ui-pack.json +230 -0
  90. package/themes/gazette.json +445 -0
  91. package/themes/glass.json +445 -0
  92. package/themes/kiosk.json +441 -0
  93. package/themes/linear-clean.json +459 -0
  94. package/themes/minimalist.json +445 -0
  95. package/themes/neon.json +445 -0
  96. package/themes/notion-editorial.json +459 -0
  97. package/themes/prism.json +203 -0
  98. package/themes/retro.json +445 -0
  99. package/themes/terminal.json +457 -0
  100. package/themes/trait-wars.json +493 -0
  101. package/themes/wireframe.json +445 -0
@@ -0,0 +1,565 @@
1
+ import { F as FieldValue, S as ServerReportedEffect, N as NamespacedEffectName, g as EntityRow, d as OrbitalId, T as TraitId, b as EventId, h as PatternConfig, i as ResolvedPatternProps, A as AnyPatternConfig } from './effect-CW_IT0Jn.js';
2
+ import { z } from 'zod';
3
+ import { a as EventPayloadValue, b as EventPayload } from './expression-DRwzVnMu.js';
4
+
5
+ /**
6
+ * Authenticated user context — what `@user.x` resolves against.
7
+ *
8
+ * The canonical shape for the `user` binding root, shared by both execution
9
+ * paths: the JS interpreter resolves `@user.id` through
10
+ * `EvaluationContext.user`, and the compiled shell emits `user?.id` against the
11
+ * `UserContext` its `@app/shared` re-exports from here.
12
+ *
13
+ * `id` is the field the behavior library reads for ownership scoping and `role`
14
+ * the field it reads for capability gating. Auth providers that name the subject
15
+ * `uid` must normalize at their boundary — {@link normalizeUserContext} does that.
16
+ *
17
+ * @packageDocumentation
18
+ */
19
+
20
+ /** Authenticated user / agent identity behind `@user.x` bindings. */
21
+ interface UserContext {
22
+ /** Stable subject identifier. `@user.id` — the ownership key. */
23
+ id: string;
24
+ /** `@user.email` */
25
+ email?: string;
26
+ /** `@user.name` — display name. */
27
+ name?: string;
28
+ /** `@user.role` — single role string, compared against a policy's allowed list. */
29
+ role?: string;
30
+ /** `@user.permissions` — fine-grained capability strings. */
31
+ permissions?: string[];
32
+ /** Additional provider claims, readable as `@user.<claim>`. */
33
+ [key: string]: FieldValue | undefined;
34
+ }
35
+ /**
36
+ * The identity of an unauthenticated viewer. A resolvable object rather than
37
+ * `undefined` so a role predicate evaluates to a definite `false` instead of
38
+ * comparing against nothing.
39
+ */
40
+ declare const ANONYMOUS_USER: UserContext;
41
+ /** Provider-shaped identity claims, before normalization. */
42
+ interface RawUserClaims {
43
+ id?: string;
44
+ uid?: string;
45
+ email?: string | null;
46
+ name?: string;
47
+ displayName?: string | null;
48
+ role?: string;
49
+ permissions?: string[];
50
+ [key: string]: FieldValue | undefined;
51
+ }
52
+ /** Zod twin of `RawUserClaims` — the wire shape of `OrbitalEventRequest.user`. */
53
+ declare const RawUserClaimsSchema: z.ZodType<RawUserClaims>;
54
+ /**
55
+ * Normalize provider claims into a {@link UserContext}.
56
+ *
57
+ * Firebase (and most OIDC providers) name the subject `uid` and the display name
58
+ * `displayName`, while every `.lolo` behavior reads `@user.id` / `@user.name`.
59
+ * Without this normalization `@user.id` is `undefined` against a fully
60
+ * authenticated request and every ownership filter silently matches no rows.
61
+ * `uid` is preserved so `@user.uid` keeps working.
62
+ *
63
+ * Returns `undefined` for absent or subject-less claims so callers can
64
+ * distinguish "no auth ran" from "anonymous"; use {@link ANONYMOUS_USER} where a
65
+ * definite identity is required.
66
+ */
67
+ declare function normalizeUserContext(claims: RawUserClaims | null | undefined): UserContext | undefined;
68
+ /**
69
+ * Turn a row of an app's `[identity]` entity into a viewer.
70
+ *
71
+ * There is no separate persona shape: an identity row IS the persona
72
+ * (`Almadar_LOLO_Identity.md` §4.3), so this only guards the one field the
73
+ * behavior library requires — a non-empty string `id` — and passes every other
74
+ * declared field through as a `@user.<field>` claim. Rows without a usable id
75
+ * yield `undefined` rather than a persona nobody can own rows as.
76
+ */
77
+ declare function personaFromIdentityRow(row: Record<string, FieldValue | undefined>): UserContext | undefined;
78
+ /**
79
+ * The viewer a host presents when nothing named one.
80
+ *
81
+ * Without this, `@user` is `Null` in headless verify and preview, so every
82
+ * `viewerName: @user.name` binding renders blank and the account menu never
83
+ * appears — an app that cannot say who you are. Worse, an ownership filter that
84
+ * works and one that is broken both render an empty table.
85
+ *
86
+ * `role` is deliberately EMPTY, not a guess. A default of `admin` would silently
87
+ * flip which branch renders at the 38 `@user.role` comparisons in the corpus;
88
+ * an empty role matches no literal, exactly as `Null` did, so this fixes
89
+ * "undefined at runtime" without changing a single guard outcome.
90
+ */
91
+ declare const DEFAULT_VIEWER: UserContext;
92
+ /**
93
+ * The viewer to present an app as when nothing named one.
94
+ *
95
+ * `DEFAULT_VIEWER` is synthetic — `viewer-1` is in no app's roster — so under it
96
+ * every ownership predicate (`@entity.<owner> == @user.id`) matches zero rows and
97
+ * a correctly-scoped app renders empty tables everywhere. That is indistinguishable
98
+ * on screen from a broken filter, which is exactly the failure DEFAULT_VIEWER's own
99
+ * comment warns about.
100
+ *
101
+ * So when the app declares an `[identity]` roster, the default viewer is a REAL
102
+ * member of it. `DEFAULT_VIEWER` remains the fallback for apps that declare no
103
+ * identity entity, where there is nobody to be.
104
+ *
105
+ * Both execution paths share this rule; the Rust twin is
106
+ * `orbital-core::runtime::persona::resolve_default_viewer`.
107
+ */
108
+ declare function resolveDefaultViewer(roster: readonly UserContext[]): UserContext;
109
+ /** Look a persona up in a roster by id, or by role when no id matches. */
110
+ declare function findPersonaInRoster(roster: readonly UserContext[], idOrRole: string): UserContext | undefined;
111
+ /**
112
+ * Resolve a persona spec — a bare id/role (`Person Id 3`, `moderator`) or a full
113
+ * JSON `UserContext` — into a viewer. This is the `ALMADAR_PERSONA` contract,
114
+ * shared by every host that presents an app as somebody.
115
+ *
116
+ * The roster is the app's OWN declared personas — the seeded rows of its
117
+ * `[identity]` entity (`Almadar_LOLO_Identity.md` §4.3) — supplied by the host
118
+ * that has them in hand (the runtime's live store on the interpreter path, the
119
+ * schema-derived seed rows on the compiled path). There is no global roster:
120
+ * an app without an `[identity]` entity resolves only JSON-form specs.
121
+ *
122
+ * Throws on anything unresolvable rather than returning `undefined`: "no persona"
123
+ * and "persona silently ignored" look identical on screen, so a bad spec must
124
+ * fail at boot instead of rendering as nobody.
125
+ */
126
+ declare function resolvePersonaSpec(spec: string, roster: readonly UserContext[]): UserContext;
127
+ /**
128
+ * Marks a bearer token as a mocked dev identity rather than a real ID token.
129
+ * The prefix is deliberately unmistakable: a server accepts these ONLY behind an
130
+ * explicit dev opt-in, so a production deployment rejects them like any other
131
+ * malformed token.
132
+ */
133
+ declare const DEV_TOKEN_PREFIX = "almadar-dev.";
134
+ /**
135
+ * Encode a viewer as a dev bearer token.
136
+ *
137
+ * Carries the WHOLE identity, not just the subject: real Firebase claims have no
138
+ * `role`, so a server that only reads `uid` leaves every `@user.role` gate inert
139
+ * even for a signed-in user. URI-encoded JSON keeps the token header-safe (no
140
+ * spaces or delimiters) and works unchanged in Node and the browser.
141
+ */
142
+ declare function encodeDevIdentityToken(user: UserContext): string;
143
+ /**
144
+ * Decode a dev bearer token back into a viewer, or `undefined` if it is not one
145
+ * / is malformed — callers fail closed rather than inventing an identity.
146
+ */
147
+ declare function decodeDevIdentityToken(token: string): UserContext | undefined;
148
+
149
+ /**
150
+ * Server-side effect result — the wire shape a server-executed effect
151
+ * (`SERVER_REPORTED_EFFECTS` in `effect.ts`) reports back to the client,
152
+ * closing the circuit on `OrbitalEventResponse.effectResults`.
153
+ *
154
+ * Promoted from `@almadar/runtime`'s `ServerEffectHandlers.ts` (the JS
155
+ * interpreter's own definition, canonical per `CLAUDE.md`'s "converge on
156
+ * the TypeScript implementation" ruling) so `@almadar/core` owns the one
157
+ * shape both execution paths report against.
158
+ *
159
+ * @packageDocumentation
160
+ */
161
+
162
+ /**
163
+ * Result entry recorded for each effect invocation. Mirrors the server
164
+ * runtime's `EffectResult`. Callers who want telemetry pass an array that
165
+ * the factory appends to; otherwise it's unused.
166
+ */
167
+ interface ServerBatchSummary {
168
+ operations: EntityRow[];
169
+ completedCount: number;
170
+ totalCount: number;
171
+ }
172
+ /** Zod twin of `ServerBatchSummary`. */
173
+ declare const ServerBatchSummarySchema: z.ZodType<ServerBatchSummary>;
174
+ interface ServerEffectResult {
175
+ /**
176
+ * The reported effect's head (`SERVER_REPORTED_EFFECTS`, derived from the
177
+ * effect union in `effect.ts`), or `"substrate"` — the one wire grouping
178
+ * for the namespaced operators (`trace/*`, `memory/*`, `session/*`,
179
+ * `behavior/*`, `compose/*`), whose head rides `name`.
180
+ */
181
+ effect: ServerReportedEffect | "substrate";
182
+ action?: string;
183
+ entityType?: string;
184
+ /** The invoked namespaced operator (e.g. `"memory/store"`), set only on `effect: "substrate"`. */
185
+ name?: NamespacedEffectName;
186
+ /** Entity row for CRUD/set/swap, the batch summary for `persist batch`, the raw service/substrate result. */
187
+ data?: EntityRow | ServerBatchSummary | EventPayloadValue;
188
+ success: boolean;
189
+ /**
190
+ * Set when a persist failed because an access policy rejected it or the
191
+ * write resolved no row key — mirrors `OrbitalServerRuntime.EffectResult`
192
+ * so the offline-preview and real-server persist paths report the same
193
+ * denial discriminator to the verification trace.
194
+ */
195
+ denied?: true;
196
+ error?: string;
197
+ /** Coded failure reason for a persist that resolved no target row. */
198
+ code?: "not-found" | "no-row-key";
199
+ }
200
+ /** Zod twin of `ServerEffectResult`. */
201
+ declare const ServerEffectResultSchema: z.ZodType<ServerEffectResult>;
202
+
203
+ /**
204
+ * Declared event key. A trait's event names (INIT, SAVE, CLOSE,
205
+ * CONFIRM_REMOVE, ...) flow through the orbital schema and the UI as
206
+ * strings; this alias marks "this string is a declared event key, not
207
+ * arbitrary text."
208
+ *
209
+ * Component props typed as `EventKey` are detected by the pattern-sync
210
+ * tool (`tools/almadar-pattern-sync/parser.ts`) via a TS-type lookup and
211
+ * marked as `kind: "event"` in the patterns registry
212
+ * (`@almadar/patterns`). Consumers of the registry — the Rust compiler's
213
+ * inline phase and the `@almadar/runtime` preprocess — read that marker
214
+ * to apply call-site `events: { OLD: NEW }` renames to render-ui trees
215
+ * without name-matching heuristics.
216
+ *
217
+ * Plain alias over `string`. Not branded because event keys originate
218
+ * from user data at runtime (orb schema literals, bus emits), so cast
219
+ * friction would buy nothing. The value of the alias is at the type
220
+ * surface — it's a marker the pattern-sync tool can find via
221
+ * `getSymbolAtLocation`.
222
+ */
223
+ type EventKey = string;
224
+ /**
225
+ * Phantom-typed brand for declarative bus-emit props on UI components.
226
+ *
227
+ * Used by component authors to BOTH mark a prop as a bus-event reference
228
+ * AND document the payload shape that the component will fire onto the
229
+ * bus when that prop is bound. Authors write:
230
+ *
231
+ * // Tabs.tsx
232
+ * export interface TabsProps {
233
+ * tabChangeEvent?: EventEmit<{ tabId: string }>;
234
+ * }
235
+ *
236
+ * Consumers see only the structural `string` (no UX impact: passing a
237
+ * literal `"TAB_CHANGED"` keeps working). The phantom `P` parameter
238
+ * carries the bus-payload schema at the type level for pattern-sync to
239
+ * extract.
240
+ *
241
+ * Pattern-sync (`tools/almadar-pattern-sync/parser.ts`) detects this
242
+ * brand via TS type-lookup (mirrors how it detects `EventKey`) and
243
+ * writes two registry fields per prop:
244
+ * - `kind: "event-ref"` — the discriminant rules read in lolo / orb
245
+ * validator to know "this prop's string value is a bus event name."
246
+ * - `emitPayloadSchema` — the structural shape of `P`, serialized as
247
+ * the same JSON-Schema-shaped record Almadar uses for trait
248
+ * `payloadSchema`. Validator rules cross-check this against the
249
+ * trait's declared `emits { EVENT { ... } }` payload to catch mismatches
250
+ * at parse / validate time instead of runtime.
251
+ *
252
+ * Example payload bus emission inside the component (no wrapper —
253
+ * `EventEmit<P>` erases to `string`):
254
+ *
255
+ * if (tabChangeEvent) eventBus.emit(`UI:${tabChangeEvent}`, { tabId });
256
+ *
257
+ * The brand is structurally an unused optional readonly property; TS
258
+ * never asks for it at construction, so authors and consumers never
259
+ * see it.
260
+ */
261
+ type EventEmit<P> = string & {
262
+ readonly __emitPayload?: P;
263
+ };
264
+ /**
265
+ * Phantom-typed brand for declarative bus-listen props on UI components.
266
+ *
267
+ * Mirror of `EventEmit<P>`. Used by future patterns where a UI component
268
+ * subscribes to a bus event and forwards its payload upward via prop
269
+ * (e.g. an editor pattern that listens for `EXTERNAL_RESET` and exposes
270
+ * the consumed payload to the parent). Pattern-sync detects this brand
271
+ * the same way as `EventEmit<P>` and writes:
272
+ * - `kind: "event-listen"` (or a sub-discriminant of `event-ref`)
273
+ * - `listenPayloadSchema` with the structural shape of `P`
274
+ *
275
+ * Validator rules use this to verify the trait the prop is bound to
276
+ * actually emits a payload of the expected shape.
277
+ *
278
+ * Reserved for symmetry; no @almadar/ui component uses it as of this
279
+ * commit. Add usages incrementally as patterns require them.
280
+ */
281
+ type EventListen<P> = string & {
282
+ readonly __listenPayload?: P;
283
+ };
284
+ /**
285
+ * Identifies the origin of a bus event. Used by cross-trait listeners to
286
+ * filter emits from specific orbitals, traits, transitions, or ticks.
287
+ *
288
+ * `transition` and `tick` are optional runtime-internal details; most
289
+ * consumers only care about `orbital` and `trait`.
290
+ */
291
+ interface BusEventSource {
292
+ orbital?: string;
293
+ /** V4 dual-carry id sibling of `orbital` — stable across an orbital rename. */
294
+ orbitalId?: OrbitalId;
295
+ trait?: string;
296
+ /** V4 dual-carry id sibling of `trait` — stable across a trait rename. */
297
+ traitId?: TraitId;
298
+ /** V4 dual-carry id of the emitted event — stable across an event rename. */
299
+ eventId?: EventId;
300
+ transition?: string;
301
+ tick?: string;
302
+ /**
303
+ * True when the orbital bridge re-broadcasts an event onto the bus
304
+ * (any source — both echoes of the dispatched event and server-side
305
+ * cascade emits via `(emit X)` / `fetch.emit.success`). Cross-trait
306
+ * listeners filter on this flag so the click-time qualified emit
307
+ * (which has no `fromBridge`) doesn't double-fire alongside the
308
+ * post-server bridge confirmation. See `dispatched` for the narrower
309
+ * "echo of the just-dispatched event" signal.
310
+ */
311
+ fromBridge?: boolean;
312
+ /**
313
+ * True ONLY for bridge echoes the receiving tab already processed, so
314
+ * the originating trait's self-subscription skips them instead of
315
+ * re-dispatching its own echo (infinite loop / double execution).
316
+ * Set by path 1 of useOrbitalBridge (compiled shell — echo of the
317
+ * just-dispatched event; server-side cascade emits there carry
318
+ * `fromBridge: true` but NOT `dispatched`, so they still reach the
319
+ * source trait's transition handler, e.g. `loading -> browsing` on a
320
+ * fetch's `emit.success`) and by ServerBridge (runtime path — stamped
321
+ * on exactly one response-cascade echo per event the dispatch delivered
322
+ * locally on the bare key, `stampLocallyDeliveredEchoes`; server-only
323
+ * results stay unstamped). Cross-trait `listens` never filter on this
324
+ * flag, so their delivery is unaffected. Push-leg events from OTHER
325
+ * tabs (multiplayer) are never stamped.
326
+ */
327
+ dispatched?: boolean;
328
+ /**
329
+ * The client that originated the dispatch whose effects emitted this
330
+ * event (from `OrbitalEventRequest.clientId`); absent for headless
331
+ * dispatches (ticks, circuit-router probes, walkers). The server-side
332
+ * listens fan-out skips client-originated cascade emits — under dual
333
+ * execution the originating client relays every cascade hop through the
334
+ * bridge itself, so the server dispatching the same hop double-ran it
335
+ * (one Send persisted two rows). Headless topology keeps the fan-out:
336
+ * there is no client to drive the circuit.
337
+ */
338
+ originClientId?: string;
339
+ }
340
+ /** Zod twin of `BusEventSource`. */
341
+ declare const BusEventSourceSchema: z.ZodType<BusEventSource, z.ZodTypeDef, object>;
342
+ /**
343
+ * An event flowing on the bus.
344
+ *
345
+ * The `source` field is structured so cross-trait listeners can match
346
+ * `event.source?.orbital === 'X' && event.source?.trait === 'Y'` without
347
+ * parsing a delimiter.
348
+ */
349
+ interface BusEvent {
350
+ /** Event type identifier (e.g., 'CartItemLoaded', 'TASK_COMPLETED') */
351
+ type: EventKey;
352
+ /** Optional structured payload */
353
+ payload?: EventPayload;
354
+ /** Timestamp when the event was emitted */
355
+ timestamp: number;
356
+ /** Optional origin info for filtering */
357
+ source?: BusEventSource;
358
+ }
359
+ /** Bus event listener callback. */
360
+ type BusEventListener = (event: BusEvent) => void;
361
+ /** Returned by `on()` / `once()` to detach a listener. */
362
+ type Unsubscribe = () => void;
363
+ /**
364
+ * One event a transition's effects emitted, carried back to the client to
365
+ * re-dispatch (in order) so the state machine advances through the
366
+ * cascade without server-side recursion. Named/shaped to match the
367
+ * generated compiled-path `EmittedEvent` (orbital-shell-typescript's
368
+ * `shared/types.ts`) so the two execution paths agree on one shape.
369
+ */
370
+ interface EmittedEvent {
371
+ event: string;
372
+ payload?: EventPayload;
373
+ source?: BusEventSource;
374
+ }
375
+ /** Zod twin of `EmittedEvent`. Third type param `object`, see `BusEventSourceSchema`. */
376
+ declare const EmittedEventSchema: z.ZodType<EmittedEvent, z.ZodTypeDef, object>;
377
+ /**
378
+ * Client-side effect tuple shipped in `OrbitalEventResponse.clientEffects`.
379
+ * Restricted to the effect kinds the client knows how to apply to the
380
+ * UI: render-ui (slot mutation, including the `toast` slot that carries
381
+ * what used to be the separate notify effect) and navigate (route change).
382
+ * Server-only effects (persist, set, fetch, ...) execute on the server and
383
+ * surface their results via `effectResults` and `emittedEvents`, not here.
384
+ *
385
+ * Shape note: the wire form is broader than `RenderUIEffect` /
386
+ * `NavigateEffect` from `@almadar/core/types/effect.ts` in two places — the
387
+ * runtime appends an interpolated `props` object plus an optional `priority`
388
+ * slot to render-ui (slot 4 + 5), and `navigate`'s optional argument may
389
+ * surface as `undefined` rather than absent. The local union spells those
390
+ * variants out explicitly so consumers (ServerBridge.tsx parser, debugger
391
+ * inspector) get accurate completions instead of `unknown[]`.
392
+ *
393
+ * `slot` is a plain `string` in this wire shape (not `UISlot`'s literal
394
+ * union) because the runtime forwards the raw string from the trait's
395
+ * `(render-ui slot ...)` SExpr without re-validating against the registry —
396
+ * registry validation lives in `orbital validate` / `lolo` parse, not here.
397
+ */
398
+ type ClientRenderUITuple = ['render-ui', string, PatternConfig | null] | ['render-ui', string, PatternConfig | null, ResolvedPatternProps] | ['render-ui', string, PatternConfig | null, ResolvedPatternProps | undefined, number | undefined];
399
+ type ClientNavigateTuple = ['navigate', string] | ['navigate', string, Record<string, string> | undefined] | ['navigate', string, Record<string, string> | undefined, {
400
+ crumb?: string;
401
+ }];
402
+ type ClientNavigateBackTuple = ['navigate-back'];
403
+ type ClientEffectTuple = ClientRenderUITuple | ClientNavigateTuple | ClientNavigateBackTuple;
404
+ /** Zod twin of `ClientRenderUITuple` — one variant per fixed arity (3/4/5), unioned. */
405
+ declare const ClientRenderUITupleSchema: z.ZodUnion<[z.ZodTuple<[z.ZodLiteral<"render-ui">, z.ZodString, z.ZodType<AnyPatternConfig | null, z.ZodTypeDef, AnyPatternConfig | null>], null>, z.ZodTuple<[z.ZodLiteral<"render-ui">, z.ZodString, z.ZodType<AnyPatternConfig | null, z.ZodTypeDef, AnyPatternConfig | null>, z.ZodType<ResolvedPatternProps, z.ZodTypeDef, ResolvedPatternProps>], null>, z.ZodTuple<[z.ZodLiteral<"render-ui">, z.ZodString, z.ZodType<AnyPatternConfig | null, z.ZodTypeDef, AnyPatternConfig | null>, z.ZodOptional<z.ZodType<ResolvedPatternProps, z.ZodTypeDef, ResolvedPatternProps>>, z.ZodOptional<z.ZodNumber>], null>]>;
406
+ /** Zod twin of `ClientNavigateTuple` — one variant per fixed arity (2/3/4), unioned. */
407
+ declare const ClientNavigateTupleSchema: z.ZodUnion<[z.ZodTuple<[z.ZodLiteral<"navigate">, z.ZodString], null>, z.ZodTuple<[z.ZodLiteral<"navigate">, z.ZodString, z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>], null>, z.ZodTuple<[z.ZodLiteral<"navigate">, z.ZodString, z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodString>>, z.ZodObject<{
408
+ crumb: z.ZodOptional<z.ZodString>;
409
+ }, "strip", z.ZodTypeAny, {
410
+ crumb?: string | undefined;
411
+ }, {
412
+ crumb?: string | undefined;
413
+ }>], null>]>;
414
+ /** Zod twin of `ClientNavigateBackTuple`. */
415
+ declare const ClientNavigateBackTupleSchema: z.ZodTuple<[z.ZodLiteral<"navigate-back">], null>;
416
+ /** Zod twin of `ClientEffectTuple`. */
417
+ declare const ClientEffectTupleSchema: z.ZodType<ClientEffectTuple>;
418
+ /**
419
+ * Client → server event dispatch request. The single upstream owner of
420
+ * this shape — both the JS interpreter (`@almadar/runtime`'s
421
+ * `OrbitalEventRequest`) and the compiled path's generated `EventRequest`
422
+ * (orbital-shell-typescript's `shared/types.ts`, mirrored 1:1 in
423
+ * `orbital-core`) carry the same fields, so the two execution paths cannot
424
+ * drift.
425
+ */
426
+ interface OrbitalEventRequest {
427
+ event: string;
428
+ /**
429
+ * V4 dual-carry id sibling of `event` — the fired event's id, when known
430
+ * (e.g. threaded from a `listens[].triggersId`). Optional; absent means
431
+ * the state machine dispatches by name only (legacy).
432
+ */
433
+ eventId?: EventId;
434
+ payload?: EventPayload;
435
+ entityId?: string;
436
+ /**
437
+ * Scoped-listen delivery: dispatch to THIS trait only. A listens-matched
438
+ * trigger is addressed to the listening trait; without this, a trigger
439
+ * renamed to INIT broadcast orbital-wide and re-ran every trait's
440
+ * initializer (R-SCOPED-LISTEN-INIT-RENAME-FREEZE re-fire cascade).
441
+ */
442
+ targetTrait?: string;
443
+ /** Provider claims for `@user` bindings, normalized by `normalizeUserContext`. */
444
+ user?: RawUserClaims;
445
+ /** Per-tab client identity (UUID) — excludes this request's origin from live-broadcast delivery. */
446
+ clientId?: string;
447
+ /**
448
+ * Broadcast-class marker (T6, docs/Almadar_Tick_Loop.md §3a): the name of
449
+ * the tick that emitted this event. Tick-stamped dispatches are
450
+ * latest-state broadcasts — the client fires them without awaiting the
451
+ * response, and the server relays them to OTHER tabs coalesced
452
+ * (newest-per-key) at a snapshot rate instead of 1:1.
453
+ */
454
+ tick?: string;
455
+ /** Emitting trait for a tick-stamped dispatch — builds the relay's BusEventSource (sourceless emits are dropped client-side). */
456
+ sourceTrait?: string;
457
+ /**
458
+ * Stateless addressing: the traits this dispatch runs against, each with
459
+ * the scope it dispatches `from` (a single-element array is the common
460
+ * case; a listens fan-out that crosses traits carries more than one). The
461
+ * compiled server is stateless-per-trait too (`handlers.rs:510-532` seeds
462
+ * state from `currentState`) — this generalizes that mechanism instead of
463
+ * the retired single `currentState`/`fields` pair.
464
+ */
465
+ traits?: Array<{
466
+ trait: string;
467
+ from: string;
468
+ }>;
469
+ /**
470
+ * The dispatching traits' current `@entity` frames (declared defaults <
471
+ * fetched row < `[shared]` frame), keyed by trait name. The server layers
472
+ * each row over the one it resolves via `resolveEntityView` so guards and
473
+ * effects read the same values the client does.
474
+ */
475
+ entityByTrait?: Record<string, EntityRow>;
476
+ /** The orbital/behavior name this dispatch targets, for stateless multi-orbital addressing. */
477
+ behavior?: string;
478
+ }
479
+ /**
480
+ * Server → client event dispatch response. Mirrors the compiled path's
481
+ * generated `EventResponse` (orbital-shell-typescript's `shared/types.ts`,
482
+ * mirrored 1:1 in `orbital-core`'s `effects/response.rs`) — canonical = the
483
+ * TS runtime's `OrbitalEventResponse` (`@almadar/runtime`'s
484
+ * `OrbitalServerRuntime.ts`).
485
+ */
486
+ interface OrbitalEventResponse {
487
+ success: boolean;
488
+ transitioned: boolean;
489
+ /** Whole-orbital state snapshot, keyed by trait name. */
490
+ states: Record<string, string>;
491
+ /**
492
+ * Events emitted during processing, in declaration order. ALWAYS present
493
+ * (`[]` when none) — the compiled Hono path used to omit this field on a
494
+ * no-cascade response, which forced every consumer to optional-chain a
495
+ * field that is really always there.
496
+ *
497
+ * Each entry carries a `source: BusEventSource` so the client-side
498
+ * ServerBridge can re-broadcast on the qualified `UI:Orbital.Trait.EVENT`
499
+ * bus key. Without source the re-broadcast skips the entry and downstream
500
+ * listeners (e.g. ContactBrowse waiting for ContactLoaded after a fetch)
501
+ * never fire — the dashboard-layout that ContactLoaded renders disappears.
502
+ */
503
+ emittedEvents: EmittedEvent[];
504
+ /** Fetched/queried entity collections this response carries, keyed by entity name. */
505
+ data?: Record<string, EntityRow[]>;
506
+ /**
507
+ * `@entity` fields this transition's server-side `set` effects wrote,
508
+ * post-effect, keyed by trait name — the response-side twin of the
509
+ * request's `entityByTrait`. The client merges them over its own effect
510
+ * results (server wins).
511
+ */
512
+ entityByTrait?: Record<string, EntityRow>;
513
+ /** Client-side effects to execute (render-ui, navigate). */
514
+ clientEffects?: ClientEffectTuple[];
515
+ /**
516
+ * Same effects as `clientEffects`, paired with the producing trait name.
517
+ * Consumers that need per-trait attribution (e.g. `<TraitFrame>` resolving
518
+ * `@trait.X` bindings) read from this field; legacy consumers ignore it
519
+ * and continue with the flat `clientEffects` array unchanged.
520
+ *
521
+ * Same length and ordering as `clientEffects`; entries are 1:1 by index.
522
+ */
523
+ clientEffectsByTrait?: Array<{
524
+ traitName: string;
525
+ effect: ClientEffectTuple;
526
+ }>;
527
+ /** Results from server-side effects (persist, call-service, set). */
528
+ effectResults?: ServerEffectResult[];
529
+ /** Guard that failed, addressed as `"<Trait>.<event>"`, for debugging. */
530
+ guardFailed?: string;
531
+ error?: string;
532
+ }
533
+ /** Zod twin of `OrbitalEventRequest`. Third type param `object`, see `BusEventSourceSchema`. */
534
+ declare const OrbitalEventRequestSchema: z.ZodType<OrbitalEventRequest, z.ZodTypeDef, object>;
535
+ /** Zod twin of `OrbitalEventResponse`. Third type param `object`, see `BusEventSourceSchema`. */
536
+ declare const OrbitalEventResponseSchema: z.ZodType<OrbitalEventResponse, z.ZodTypeDef, object>;
537
+ /**
538
+ * One persist-envelope success emit, handed to the live-broadcast sink
539
+ * (`OrbitalServerRuntime.setLiveBroadcastSink`) and relayed to every OTHER
540
+ * connected client. Fired only from the `persist` effect's `emit:{success}`
541
+ * envelope (batch and single-op) — never from the generic emit funnel — so
542
+ * transport layers can fan it out without matching on event names. Promoted
543
+ * from `@almadar/runtime`'s own `LiveBroadcastItem` (canonical per Program
544
+ * A's "converge on the TS runtime" ruling) so `orbital-server`'s `GET
545
+ * /api/events` broadcast mirrors the same shape.
546
+ */
547
+ interface LiveBroadcastItem {
548
+ event: string;
549
+ payload?: EventPayload;
550
+ source: BusEventSource;
551
+ /** `clientId` of the request that produced this emit; excluded from delivery by the transport. */
552
+ originClientId?: string;
553
+ }
554
+ /** Zod twin of `LiveBroadcastItem`. Third type param `object`, see `BusEventSourceSchema`. */
555
+ declare const LiveBroadcastItemSchema: z.ZodType<LiveBroadcastItem, z.ZodTypeDef, object>;
556
+ /** @deprecated use {@link OrbitalEventRequest}. Kept until every referrer migrates (Program A wave A8). */
557
+ type EventDispatchRequest = OrbitalEventRequest;
558
+ /** @deprecated use {@link OrbitalEventRequestSchema}. */
559
+ declare const EventDispatchRequestSchema: z.ZodType<OrbitalEventRequest, z.ZodTypeDef, object>;
560
+ /** @deprecated use {@link OrbitalEventResponse}. Kept until every referrer migrates (Program A wave A8). */
561
+ type EventDispatchResponse = OrbitalEventResponse;
562
+ /** @deprecated use {@link OrbitalEventResponseSchema}. */
563
+ declare const EventDispatchResponseSchema: z.ZodType<OrbitalEventResponse, z.ZodTypeDef, object>;
564
+
565
+ export { ANONYMOUS_USER as A, type BusEvent as B, type ClientEffectTuple as C, DEFAULT_VIEWER as D, type EmittedEvent as E, ServerEffectResultSchema as F, type Unsubscribe as G, decodeDevIdentityToken as H, encodeDevIdentityToken as I, findPersonaInRoster as J, normalizeUserContext as K, type LiveBroadcastItem as L, personaFromIdentityRow as M, resolveDefaultViewer as N, type OrbitalEventRequest as O, resolvePersonaSpec as P, type RawUserClaims as R, type ServerBatchSummary as S, type UserContext as U, type OrbitalEventResponse as a, type BusEventListener as b, type BusEventSource as c, BusEventSourceSchema as d, ClientEffectTupleSchema as e, type ClientNavigateBackTuple as f, ClientNavigateBackTupleSchema as g, type ClientNavigateTuple as h, ClientNavigateTupleSchema as i, type ClientRenderUITuple as j, ClientRenderUITupleSchema as k, DEV_TOKEN_PREFIX as l, EmittedEventSchema as m, type EventDispatchRequest as n, EventDispatchRequestSchema as o, type EventDispatchResponse as p, EventDispatchResponseSchema as q, type EventEmit as r, type EventKey as s, type EventListen as t, LiveBroadcastItemSchema as u, OrbitalEventRequestSchema as v, OrbitalEventResponseSchema as w, RawUserClaimsSchema as x, ServerBatchSummarySchema as y, type ServerEffectResult as z };