@almadar/runtime 6.53.0 → 6.55.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.
@@ -1,5 +1,5 @@
1
1
  import { Router } from 'express';
2
- import { I as IEventBus, R as RuntimeEvent, a as EventListener, U as Unsubscribe, T as TraitDefinition, b as RuntimeConfig, c as TransitionObserver, d as TraitState, C as ConfigContext, e as TransitionResult, f as EvaluationContextExtensions, E as EffectHandlers } from './types-BcPORH_x.js';
2
+ import { I as IEventBus, R as RuntimeEvent, a as EventListener, U as Unsubscribe, T as TraitDefinition, b as RuntimeConfig, c as TransitionObserver, d as TraitState, C as ConfigContext, e as TransitionResult, f as EvaluationContextExtensions, E as EffectHandlers } from './types-BOF75lWr.js';
3
3
  import { EventPayload, EventId, EntityRow, UserContext, Orbital, ServiceCallResult, TraitConfig, DeclaredTraitConfig, Entity, OrbitalSchema, Trait, PatternConfig, ResolvedPatternProps, SExpr, BusEventSource, RawUserClaims, OrbitalDefinition, TraitTick } from '@almadar/core';
4
4
 
5
5
  /**
@@ -1152,6 +1152,11 @@ declare class OrbitalServerRuntime {
1152
1152
  private substrateHandlers;
1153
1153
  private substrateHandlersPromise;
1154
1154
  private resolvedSchema;
1155
+ /** App-level theme key from the schema's `theme "<key>"` header — the
1156
+ * `@currentTheme` fallback between an orbital's own `theme` and
1157
+ * `DEFAULT_THEME_KEY`. Set at registration, before the orbital loops
1158
+ * (`resolvedSchema` is assigned only after them). */
1159
+ private appThemeKey;
1155
1160
  /** Wired by the hosting server (e.g. the playground SSE endpoint) via `setLiveBroadcastSink`. */
1156
1161
  private liveBroadcastSink;
1157
1162
  /**
@@ -1291,6 +1296,25 @@ declare class OrbitalServerRuntime {
1291
1296
  * Clear the preprocessing cache.
1292
1297
  */
1293
1298
  clearPreprocessCache(): void;
1299
+ /**
1300
+ * Resolve an entity definition by name across every registered orbital's
1301
+ * resolved primary entity. Used by relation-option injection to find the
1302
+ * relation TARGET entity (usually another orbital's primary).
1303
+ */
1304
+ private findEntityDefByName;
1305
+ /**
1306
+ * Server-side relation-option injection — the interpreter's mirror of the
1307
+ * compiled path's build-time `relationsData` generation (orbital-rust
1308
+ * registry.rs). Walks a render-ui pattern tree; for every form pattern
1309
+ * (form / form-section / inline-edit-form / wizard-step) and detail-panel
1310
+ * whose linked entity declares relation-typed fields among the node's
1311
+ * `fields`, reads the relation TARGET entity's rows from the persistence
1312
+ * adapter and attaches `relationsData: { <field>: [{value, label}] }`.
1313
+ * Label contract identical to codegen: `name || title || id`. Options are
1314
+ * re-read on every render-ui, so they refresh with each re-render exactly
1315
+ * like any fetch. Authored `relationsData` is never overwritten.
1316
+ */
1317
+ private injectRelationOptions;
1294
1318
  /**
1295
1319
  * Register a single orbital
1296
1320
  */
@@ -1,4 +1,4 @@
1
1
  import 'express';
2
- export { F as ClientEffectTuple, G as ClientNavigateTuple, H as ClientNotifyTuple, J as ClientRenderUITuple, K as EffectResult, e as InMemoryPersistence, M as LiveBroadcastItem, N as LoaderConfig, O as OrbitalEventRequest, f as OrbitalEventResponse, Q as OrbitalServerRuntime, g as OrbitalServerRuntimeConfig, P as PersistenceAdapter, R as RegisteredOrbital, l as RuntimeOrbital, m as RuntimeOrbitalSchema, n as RuntimeTrait, T as RuntimeTraitTick, p as collectDeclaredConfigDefaults, V as createOrbitalServerRuntime } from './OrbitalServerRuntime-DRvduqA7.js';
3
- import './types-BcPORH_x.js';
2
+ export { F as ClientEffectTuple, G as ClientNavigateTuple, H as ClientNotifyTuple, J as ClientRenderUITuple, K as EffectResult, e as InMemoryPersistence, M as LiveBroadcastItem, N as LoaderConfig, O as OrbitalEventRequest, f as OrbitalEventResponse, Q as OrbitalServerRuntime, g as OrbitalServerRuntimeConfig, P as PersistenceAdapter, R as RegisteredOrbital, l as RuntimeOrbital, m as RuntimeOrbitalSchema, n as RuntimeTrait, T as RuntimeTraitTick, p as collectDeclaredConfigDefaults, V as createOrbitalServerRuntime } from './OrbitalServerRuntime-COuVFqev.js';
3
+ import './types-BOF75lWr.js';
4
4
  import '@almadar/core';
@@ -1,5 +1,5 @@
1
- import { createTickScheduler, EventBus, createUnifiedLoader, MockPersistenceAdapter, InMemoryPersistence, preprocessSchema, normalizeCallSiteConfigToValues, StateMachineManager, parseDurationString, validateEventPayload, formatPayloadValidationError, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, EffectExecutor } from './chunk-DERIA6MO.js';
2
- export { InMemoryPersistence, collectDeclaredConfigDefaults } from './chunk-DERIA6MO.js';
1
+ import { createTickScheduler, EventBus, createUnifiedLoader, MockPersistenceAdapter, InMemoryPersistence, preprocessSchema, normalizeCallSiteConfigToValues, StateMachineManager, parseDurationString, validateEventPayload, formatPayloadValidationError, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, EffectExecutor } from './chunk-7CQLNJLN.js';
2
+ export { InMemoryPersistence, collectDeclaredConfigDefaults } from './chunk-7CQLNJLN.js';
3
3
  import { isValidCronExpression } from './chunk-OU3ITB5S.js';
4
4
  import { createContextFromBindings, resolveCallSitePayloadCaptures, applyRowAccess, checkMutationAccess, accessDeniedMessage } from './chunk-ZJ62H3ES.js';
5
5
  import './chunk-T4VDAB4C.js';
@@ -10,6 +10,7 @@ import * as nodeModule from 'module';
10
10
  import { evaluateListenPayloadExpr, evaluateGuard, evaluate } from '@almadar/evaluator';
11
11
  import { DEFAULT_VIEWER, buildResolvedTraitConfigs, isInlineTrait, isEntityCall, applyListenPayloadMapping, personaFromIdentityRow, normalizeUserContext, isRuntimeEntity, isPageReference } from '@almadar/core';
12
12
  import { ownerFieldsFromSchema, identityEntityName, entityAccessPolicies } from '@almadar/core/mock';
13
+ import { getPatternFieldsContract } from '@almadar/core/patterns';
13
14
 
14
15
  // src/identity/routing.ts
15
16
  function eventRouteKey(eventName, eventId) {
@@ -129,6 +130,11 @@ var OrbitalServerRuntime = class {
129
130
  substrateHandlers = null;
130
131
  substrateHandlersPromise = null;
131
132
  resolvedSchema = null;
133
+ /** App-level theme key from the schema's `theme "<key>"` header — the
134
+ * `@currentTheme` fallback between an orbital's own `theme` and
135
+ * `DEFAULT_THEME_KEY`. Set at registration, before the orbital loops
136
+ * (`resolvedSchema` is assigned only after them). */
137
+ appThemeKey;
132
138
  /** Wired by the hosting server (e.g. the playground SSE endpoint) via `setLiveBroadcastSink`. */
133
139
  liveBroadcastSink = null;
134
140
  /**
@@ -301,6 +307,7 @@ var OrbitalServerRuntime = class {
301
307
  if (this.config.debug) {
302
308
  registerLog.debug("register:schema", { name: schema.name });
303
309
  }
310
+ this.appThemeKey = themeDataKey(schema.theme) || void 0;
304
311
  if (needsPreprocessing(schema)) {
305
312
  await this.ensureLoader();
306
313
  if (this.loader) {
@@ -367,6 +374,7 @@ var OrbitalServerRuntime = class {
367
374
  if (this.config.debug) {
368
375
  registerLog.debug("register:schema-sync", { name: schema.name });
369
376
  }
377
+ this.appThemeKey = themeDataKey(schema.theme) || void 0;
370
378
  this.applyIdentityOwnerFields(schema);
371
379
  for (const orbital of schema.orbitals) {
372
380
  this.registerOrbital(orbital);
@@ -520,6 +528,81 @@ var OrbitalServerRuntime = class {
520
528
  clearPreprocessCache() {
521
529
  this.preprocessedCache.clear();
522
530
  }
531
+ /**
532
+ * Resolve an entity definition by name across every registered orbital's
533
+ * resolved primary entity. Used by relation-option injection to find the
534
+ * relation TARGET entity (usually another orbital's primary).
535
+ */
536
+ findEntityDefByName(name) {
537
+ for (const registered of this.orbitals.values()) {
538
+ if (registered.entity?.name === name) return registered.entity;
539
+ }
540
+ return void 0;
541
+ }
542
+ /**
543
+ * Server-side relation-option injection — the interpreter's mirror of the
544
+ * compiled path's build-time `relationsData` generation (orbital-rust
545
+ * registry.rs). Walks a render-ui pattern tree; for every form pattern
546
+ * (form / form-section / inline-edit-form / wizard-step) and detail-panel
547
+ * whose linked entity declares relation-typed fields among the node's
548
+ * `fields`, reads the relation TARGET entity's rows from the persistence
549
+ * adapter and attaches `relationsData: { <field>: [{value, label}] }`.
550
+ * Label contract identical to codegen: `name || title || id`. Options are
551
+ * re-read on every render-ui, so they refresh with each re-render exactly
552
+ * like any fetch. Authored `relationsData` is never overwritten.
553
+ */
554
+ async injectRelationOptions(pattern, registered, traitName) {
555
+ if (pattern === null || typeof pattern !== "object") return;
556
+ const linkedEntityName = registered.traits.find((t) => t.name === traitName)?.linkedEntity ?? registered.entity?.name;
557
+ if (!linkedEntityName) return;
558
+ const entityDef = this.findEntityDefByName(linkedEntityName);
559
+ if (!entityDef?.fields) return;
560
+ const relationTargets = /* @__PURE__ */ new Map();
561
+ for (const field of entityDef.fields) {
562
+ if (field.type === "relation" && field.relation?.entity && field.name) {
563
+ relationTargets.set(field.name, field.relation.entity);
564
+ }
565
+ }
566
+ if (relationTargets.size === 0) return;
567
+ const visit = async (node) => {
568
+ if (node === null || node === void 0 || typeof node !== "object") return;
569
+ if (Array.isArray(node)) {
570
+ for (const child of node) await visit(child);
571
+ return;
572
+ }
573
+ const record = node;
574
+ const nodeType = record["type"];
575
+ const fields = record["fields"];
576
+ if (typeof nodeType === "string" && // Which patterns consume entity-bound field lists is DECLARED per
577
+ // component via `@fieldsContract` and read from the pattern registry
578
+ // — never a hardcoded name list. Both contracts get relation options
579
+ // (form selects need choices; display fields need label resolution).
580
+ getPatternFieldsContract(nodeType) !== void 0 && Array.isArray(fields) && record["relationsData"] === void 0) {
581
+ const relationsData = {};
582
+ for (const fieldEntry of fields) {
583
+ const fieldName = typeof fieldEntry === "string" ? fieldEntry : fieldEntry !== null && typeof fieldEntry === "object" && !Array.isArray(fieldEntry) ? String(
584
+ fieldEntry["name"] ?? fieldEntry["key"] ?? ""
585
+ ) : "";
586
+ const targetEntity = fieldName ? relationTargets.get(fieldName) : void 0;
587
+ if (!targetEntity) continue;
588
+ try {
589
+ const rows = await this.persistence.list(targetEntity);
590
+ relationsData[fieldName] = rows.map((r) => ({
591
+ value: String(r.id ?? ""),
592
+ label: String(r.name ?? r.title ?? r.id ?? "")
593
+ }));
594
+ } catch {
595
+ }
596
+ }
597
+ if (Object.keys(relationsData).length > 0) {
598
+ record["relationsData"] = relationsData;
599
+ }
600
+ }
601
+ const children = record["children"];
602
+ if (children !== void 0) await visit(children);
603
+ };
604
+ await visit(pattern);
605
+ }
523
606
  /**
524
607
  * Register a single orbital
525
608
  */
@@ -1668,7 +1751,8 @@ var OrbitalServerRuntime = class {
1668
1751
  }
1669
1752
  },
1670
1753
  // Client-side effects - collect for forwarding to client
1671
- renderUI: (slot, pattern, props, priority) => {
1754
+ renderUI: async (slot, pattern, props, priority) => {
1755
+ await this.injectRelationOptions(pattern, registered, traitName);
1672
1756
  const patternNode = pattern !== null && typeof pattern === "object" && !Array.isArray(pattern) ? pattern : null;
1673
1757
  const patternEntity = patternNode?.entity;
1674
1758
  const entityRow = patternEntity !== null && typeof patternEntity === "object" && !Array.isArray(patternEntity) ? patternEntity : null;
@@ -1741,7 +1825,7 @@ var OrbitalServerRuntime = class {
1741
1825
  if (sigilPages.length > 0) {
1742
1826
  bindings.pages = sigilPages;
1743
1827
  }
1744
- const sigilTheme = themeDataKey(registered.schema.theme) || DEFAULT_THEME_KEY;
1828
+ const sigilTheme = themeDataKey(registered.schema.theme) || this.appThemeKey || DEFAULT_THEME_KEY;
1745
1829
  bindings.currentTheme = sigilTheme;
1746
1830
  const entityFieldDefaults = collectDeclaredEntityDefaults(registered.entity);
1747
1831
  const traitFieldState = registered.traitFieldStates.get(this.sharedFieldKey(registered, traitName));
@@ -1,4 +1,4 @@
1
- import { I as IEventBus } from './types-BcPORH_x.js';
1
+ import { I as IEventBus } from './types-BOF75lWr.js';
2
2
  import { EventPayload } from '@almadar/core';
3
3
 
4
4
  /**
@@ -1563,7 +1563,7 @@ var EffectExecutor = class _EffectExecutor {
1563
1563
  const pattern = patternRaw === null ? null : patternRaw;
1564
1564
  const props = args[2];
1565
1565
  const priority = args[3];
1566
- this.handlers.renderUI(slot, pattern, props, priority);
1566
+ await this.handlers.renderUI(slot, pattern, props, priority);
1567
1567
  } else {
1568
1568
  this.logUnsupported("render-ui");
1569
1569
  }
@@ -2101,7 +2101,7 @@ var mockLog = createLogger("almadar:runtime:mock");
2101
2101
  var DEFAULT_MOCK_SEED = 42;
2102
2102
  var SEED_REFERENCE_TIMESTAMP = "2024-01-01T00:00:00.000Z";
2103
2103
  var MS_PER_DAY = 864e5;
2104
- var MockPersistenceAdapter = class {
2104
+ var MockPersistenceAdapter = class _MockPersistenceAdapter {
2105
2105
  stores = /* @__PURE__ */ new Map();
2106
2106
  schemas = /* @__PURE__ */ new Map();
2107
2107
  idCounters = /* @__PURE__ */ new Map();
@@ -2349,6 +2349,7 @@ var MockPersistenceAdapter = class {
2349
2349
  // ============================================================================
2350
2350
  async create(entityType, data) {
2351
2351
  const store = this.getStore(entityType);
2352
+ this.assertFileValuesWithinCeiling(entityType, data);
2352
2353
  const id = this.nextId(entityType);
2353
2354
  const now = (/* @__PURE__ */ new Date()).toISOString();
2354
2355
  const withDefaults = this.applyFieldDefaults(entityType, data);
@@ -2361,6 +2362,27 @@ var MockPersistenceAdapter = class {
2361
2362
  store.set(id, item);
2362
2363
  return { id };
2363
2364
  }
2365
+ /**
2366
+ * Mock-mode file storage ceiling: a `file`-typed value whose `url` is a
2367
+ * `data:` URI keeps the whole payload in this in-memory/localStorage
2368
+ * store. Above the ceiling the write is REJECTED with a clear error —
2369
+ * never silently truncated or corrupted. Real deployments store bytes in
2370
+ * object storage and keep only the URL, so the ceiling is mock-only.
2371
+ */
2372
+ static FILE_DATA_URI_CEILING_BYTES = 2 * 1024 * 1024;
2373
+ assertFileValuesWithinCeiling(entityType, data) {
2374
+ for (const [fieldName, value] of Object.entries(data)) {
2375
+ if (value === null || typeof value !== "object" || Array.isArray(value)) continue;
2376
+ const candidate = value;
2377
+ if (typeof candidate.url !== "string" || !candidate.url.startsWith("data:")) continue;
2378
+ const bytes = typeof candidate.sizeBytes === "number" ? candidate.sizeBytes : candidate.url.length;
2379
+ if (bytes > _MockPersistenceAdapter.FILE_DATA_URI_CEILING_BYTES) {
2380
+ throw new Error(
2381
+ `${entityType}.${fieldName}: the playground mock store cannot persist files larger than ${_MockPersistenceAdapter.FILE_DATA_URI_CEILING_BYTES / (1024 * 1024)}MB (got ${(bytes / (1024 * 1024)).toFixed(1)}MB). Use a smaller file - production deployments store file bytes in object storage instead of the row.`
2382
+ );
2383
+ }
2384
+ }
2385
+ }
2364
2386
  /**
2365
2387
  * Fill in any entity-declared field defaults that the caller omitted.
2366
2388
  * SAVE payloads coming from form-section only carry the fields the user
@@ -2382,6 +2404,7 @@ var MockPersistenceAdapter = class {
2382
2404
  }
2383
2405
  async update(entityType, id, data) {
2384
2406
  const store = this.getStore(entityType);
2407
+ this.assertFileValuesWithinCeiling(entityType, data);
2385
2408
  const existing = store.get(id);
2386
2409
  if (!existing) {
2387
2410
  throw new Error(`Entity ${entityType} with id ${id} not found`);
@@ -1,4 +1,4 @@
1
- import { E as EffectHandlers } from './types-BcPORH_x.js';
1
+ import { E as EffectHandlers } from './types-BOF75lWr.js';
2
2
  import { EventPayload } from '@almadar/core';
3
3
 
4
4
  /**
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
- import { g as RuntimePatternValue, B as BindingContext, f as EvaluationContextExtensions, P as PatternProps, E as EffectHandlers, h as EffectContext, i as ExecutionEnvironment, j as EffectResult, T as TraitDefinition } from './types-BcPORH_x.js';
2
- export { k as BrowserFileMeta, l as BrowserFilePickerOptions, m as BrowserGeolocationOptions, n as BrowserGeolocationPosition, C as ConfigContext, o as Effect, a as EventListener, H as HANDLER_MANIFEST, I as IEventBus, b as RuntimeConfig, R as RuntimeEvent, d as TraitState, c as TransitionObserver, e as TransitionResult, U as Unsubscribe } from './types-BcPORH_x.js';
3
- import { U as UnifiedLoaderOptions, S as SchemaLoader, I as ImportChainLike, L as LoadResult, a as LoadedSchema, b as LoadedOrbital, P as PersistenceAdapter } from './OrbitalServerRuntime-DRvduqA7.js';
4
- export { E as EntitySharingMap, c as EventBus, d as EventNamespaceMap, e as InMemoryPersistence, O as OrbitalEventRequest, f as OrbitalEventResponse, g as OrbitalServerRuntimeConfig, h as PreprocessOptions, i as PreprocessResult, j as PreprocessedSchema, k as ProcessEventOptions, R as RegisteredOrbital, l as RuntimeOrbital, m as RuntimeOrbitalSchema, n as RuntimeTrait, o as StateMachineManager, p as collectDeclaredConfigDefaults, q as collectDeclaredEntityDefaults, r as createInitialTraitState, s as findInitialState, t as findTransition, u as getIsolatedCollectionName, v as getNamespacedEvent, w as isBrowser, x as isElectron, y as isNamespacedEvent, z as isNode, A as normalizeEventKey, B as parseNamespacedEvent, C as preprocessSchema, D as processEvent } from './OrbitalServerRuntime-DRvduqA7.js';
1
+ import { g as RuntimePatternValue, B as BindingContext, f as EvaluationContextExtensions, P as PatternProps, E as EffectHandlers, h as EffectContext, i as ExecutionEnvironment, j as EffectResult, T as TraitDefinition } from './types-BOF75lWr.js';
2
+ export { k as BrowserFileMeta, l as BrowserFilePickerOptions, m as BrowserGeolocationOptions, n as BrowserGeolocationPosition, C as ConfigContext, o as Effect, a as EventListener, H as HANDLER_MANIFEST, I as IEventBus, b as RuntimeConfig, R as RuntimeEvent, d as TraitState, c as TransitionObserver, e as TransitionResult, U as Unsubscribe } from './types-BOF75lWr.js';
3
+ import { U as UnifiedLoaderOptions, S as SchemaLoader, I as ImportChainLike, L as LoadResult, a as LoadedSchema, b as LoadedOrbital, P as PersistenceAdapter } from './OrbitalServerRuntime-COuVFqev.js';
4
+ export { E as EntitySharingMap, c as EventBus, d as EventNamespaceMap, e as InMemoryPersistence, O as OrbitalEventRequest, f as OrbitalEventResponse, g as OrbitalServerRuntimeConfig, h as PreprocessOptions, i as PreprocessResult, j as PreprocessedSchema, k as ProcessEventOptions, R as RegisteredOrbital, l as RuntimeOrbital, m as RuntimeOrbitalSchema, n as RuntimeTrait, o as StateMachineManager, p as collectDeclaredConfigDefaults, q as collectDeclaredEntityDefaults, r as createInitialTraitState, s as findInitialState, t as findTransition, u as getIsolatedCollectionName, v as getNamespacedEvent, w as isBrowser, x as isElectron, y as isNamespacedEvent, z as isNode, A as normalizeEventKey, B as parseNamespacedEvent, C as preprocessSchema, D as processEvent } from './OrbitalServerRuntime-COuVFqev.js';
5
5
  import { EvaluationContext, SExpressionEvaluator } from '@almadar/evaluator';
6
6
  export { EvaluationContext, createMinimalContext } from '@almadar/evaluator';
7
7
  import { RenderBindingMarker, SExpr, TraitConfigObject, EventPayload, PatternConfig, EntityId, EntityField, EntityRow, EntityPersistence, ServiceParams, EntityAccessPolicies, PayloadField, OrbitalDefinition, OrbitalSchema } from '@almadar/core';
@@ -686,6 +686,15 @@ declare class MockPersistenceAdapter implements PersistenceAdapter {
686
686
  create(entityType: string, data: EntityRow): Promise<{
687
687
  id: string;
688
688
  }>;
689
+ /**
690
+ * Mock-mode file storage ceiling: a `file`-typed value whose `url` is a
691
+ * `data:` URI keeps the whole payload in this in-memory/localStorage
692
+ * store. Above the ceiling the write is REJECTED with a clear error —
693
+ * never silently truncated or corrupted. Real deployments store bytes in
694
+ * object storage and keep only the URL, so the ceiling is mock-only.
695
+ */
696
+ private static readonly FILE_DATA_URI_CEILING_BYTES;
697
+ private assertFileValuesWithinCeiling;
689
698
  /**
690
699
  * Fill in any entity-declared field defaults that the caller omitted.
691
700
  * SAVE payloads coming from form-section only carry the fields the user
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { EffectExecutor } from './chunk-DERIA6MO.js';
2
- export { EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, MockPersistenceAdapter, StateMachineManager, TickScheduler, buildEmitsFromTraits, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, createInitialTraitState, createMockPersistence, createTestExecutor, createTickScheduler, createUnifiedLoader, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, isBrowser, isElectron, isNamespacedEvent, isNode, isValidDurationString, normalizeCallSiteConfigToValues, normalizeEventKey, parseDurationString, parseNamespacedEvent, preprocessSchema, processEvent, validateEventPayload, validatePayloadShapes } from './chunk-DERIA6MO.js';
1
+ import { EffectExecutor } from './chunk-7CQLNJLN.js';
2
+ export { EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, MockPersistenceAdapter, StateMachineManager, TickScheduler, buildEmitsFromTraits, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, createInitialTraitState, createMockPersistence, createTestExecutor, createTickScheduler, createUnifiedLoader, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, isBrowser, isElectron, isNamespacedEvent, isNode, isValidDurationString, normalizeCallSiteConfigToValues, normalizeEventKey, parseDurationString, parseNamespacedEvent, preprocessSchema, processEvent, validateEventPayload, validatePayloadShapes } from './chunk-7CQLNJLN.js';
3
3
  export { cronMatches, cronMinuteKey, isValidCronExpression, parseCron, parseCronField } from './chunk-OU3ITB5S.js';
4
4
  import { createContextFromBindings, applyRowAccess, checkMutationAccess, accessDeniedMessage } from './chunk-ZJ62H3ES.js';
5
5
  export { CALLSITE_PAYLOAD_PREFIX, applyRowAccess, checkMutationAccess, containsBindings, createContextFromBindings, createMinimalContext, deferEntityBindings, extractBindings, interpolateProps, interpolateValue, resolveCallSitePayloadCaptures } from './chunk-ZJ62H3ES.js';
@@ -183,8 +183,11 @@ interface EffectHandlers {
183
183
  sendServer?: (event: string, payload?: EventPayload) => void;
184
184
  /** Render UI to a slot (client only). `pattern` is the post-interpolation
185
185
  * `PatternConfig` from the trait's `(render-ui slot pattern)` SExpr, or
186
- * `null` when the trait clears the slot (`render-ui slot null`). */
187
- renderUI?: (slot: string, pattern: PatternConfig | null, props?: PatternProps, priority?: number) => void;
186
+ * `null` when the trait clears the slot (`render-ui slot null`).
187
+ * May be async: the server runtime injects relation option data
188
+ * (relationsData) read from the persistence adapter before pushing —
189
+ * the interpreter's mirror of codegen's build-time relationsData. */
190
+ renderUI?: (slot: string, pattern: PatternConfig | null, props?: PatternProps, priority?: number) => void | Promise<void>;
188
191
  /** Navigate to a route (client only) */
189
192
  navigate?: (path: string, params?: {
190
193
  [key: string]: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/runtime",
3
- "version": "6.53.0",
3
+ "version": "6.55.0",
4
4
  "description": "Interpreted runtime for Almadar orbital applications (OrbitalServerRuntime)",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -57,11 +57,11 @@
57
57
  "access": "public"
58
58
  },
59
59
  "dependencies": {
60
- "@almadar/core": "^10.55.0",
61
- "@almadar/evaluator": "^2.40.0",
60
+ "@almadar/core": "^10.62.0",
61
+ "@almadar/evaluator": "^2.41.0",
62
62
  "@almadar/logger": "^1.11.0",
63
63
  "@almadar/server": "^2.34.0",
64
- "@almadar/std": "^16.168.0"
64
+ "@almadar/std": "^16.178.0"
65
65
  },
66
66
  "peerDependencies": {
67
67
  "express": "^5.0.0"