@almadar/runtime 6.43.0 → 6.45.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/{OrbitalServerRuntime-f0EZSw4f.d.ts → OrbitalServerRuntime-A2h0EikK.d.ts} +29 -1
- package/dist/OrbitalServerRuntime.d.ts +2 -2
- package/dist/OrbitalServerRuntime.js +98 -12
- package/dist/ServerBridge.d.ts +1 -1
- package/dist/{chunk-2SM626PK.js → chunk-FIBEYLME.js} +365 -4
- package/dist/createOsHandlers.d.ts +1 -1
- package/dist/index.d.ts +49 -6
- package/dist/index.js +2 -2
- package/dist/{types-p_L8-Sk4.d.ts → types-CL03tjGU.d.ts} +21 -2
- package/package.json +4 -4
|
@@ -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-
|
|
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-CL03tjGU.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
|
/**
|
|
@@ -937,6 +937,13 @@ interface RegisteredOrbital {
|
|
|
937
937
|
* `state.fields`. The trait's `@entity` binding is a three-layer merge:
|
|
938
938
|
* declared entity field defaults < persistence entityData < this map.
|
|
939
939
|
* Mutated only by the `set` effect handler.
|
|
940
|
+
*
|
|
941
|
+
* For a `[shared]` linked entity the map is keyed `$shared::<entityName>`
|
|
942
|
+
* instead of the trait name — ONE frame across every bound trait, the
|
|
943
|
+
* server half of the client hook's `sharedKeyByTraitName` groups. Without
|
|
944
|
+
* it a writer trait's `(set @entity.X …)` was invisible to a sibling's
|
|
945
|
+
* effect interpolation (the chat thread's refetch filter read "" while the
|
|
946
|
+
* composer held the open channel).
|
|
940
947
|
*/
|
|
941
948
|
traitFieldStates: Map<string, EntityRow>;
|
|
942
949
|
}
|
|
@@ -1199,6 +1206,14 @@ declare class OrbitalServerRuntime {
|
|
|
1199
1206
|
* std registry on disk.
|
|
1200
1207
|
*/
|
|
1201
1208
|
register(schema: OrbitalSchema): Promise<void>;
|
|
1209
|
+
/**
|
|
1210
|
+
* Teach the mock seeder which columns hold the viewer's id, derived from the
|
|
1211
|
+
* schema's `[identity]` entity. No-op for a program that declares none, so
|
|
1212
|
+
* unmigrated apps seed exactly as before. Mirrors
|
|
1213
|
+
* `orbital-core/src/runtime/seed.rs::owner_fields_from_schema` — a feature
|
|
1214
|
+
* that lives on only one execution path is not a feature.
|
|
1215
|
+
*/
|
|
1216
|
+
private applyIdentityOwnerFields;
|
|
1202
1217
|
/**
|
|
1203
1218
|
* Register an OrbitalSchema synchronously (for backward compatibility).
|
|
1204
1219
|
* Note: This version doesn't wait for instance seeding to complete.
|
|
@@ -1333,6 +1348,19 @@ declare class OrbitalServerRuntime {
|
|
|
1333
1348
|
setDefaultUser(user: UserContext | undefined): void;
|
|
1334
1349
|
/** The viewer a dev host is currently presenting the app as. */
|
|
1335
1350
|
getDefaultUser(): UserContext | undefined;
|
|
1351
|
+
/**
|
|
1352
|
+
* `traitFieldStates` key for one trait: its own name, or — when its linked
|
|
1353
|
+
* entity is `[shared]` — `$shared::<entityName>` so every trait bound to
|
|
1354
|
+
* that entity reads/writes ONE frame. The server twin of the client hook's
|
|
1355
|
+
* `sharedKeyByTraitName` (useTraitStateMachine): without it, a sibling
|
|
1356
|
+
* trait's effect interpolation (a fetch filter reading
|
|
1357
|
+
* `@entity.activeChannel`) never saw the writer's `(set …)`.
|
|
1358
|
+
*/
|
|
1359
|
+
private sharedFieldKey;
|
|
1360
|
+
/** Resolve an entity name to its declared `shared` flag: the orbital's own
|
|
1361
|
+
* entity, its auxiliary entities, then other registered orbitals' primary
|
|
1362
|
+
* entities (cross-orbital binds like a membership rail in the chat page). */
|
|
1363
|
+
private isSharedEntity;
|
|
1336
1364
|
/**
|
|
1337
1365
|
* Process an event for an orbital
|
|
1338
1366
|
*
|
|
@@ -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-
|
|
3
|
-
import './types-
|
|
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-A2h0EikK.js';
|
|
3
|
+
import './types-CL03tjGU.js';
|
|
4
4
|
import '@almadar/core';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createTickScheduler, EventBus, createUnifiedLoader, MockPersistenceAdapter, InMemoryPersistence, preprocessSchema, normalizeCallSiteConfigToValues, StateMachineManager, parseDurationString, createContextFromBindings, validateEventPayload, formatPayloadValidationError, collectDeclaredConfigDefaults, resolveCallSitePayloadCaptures, collectDeclaredEntityDefaults, EffectExecutor } from './chunk-
|
|
2
|
-
export { InMemoryPersistence, collectDeclaredConfigDefaults } from './chunk-
|
|
1
|
+
import { createTickScheduler, EventBus, createUnifiedLoader, MockPersistenceAdapter, InMemoryPersistence, preprocessSchema, normalizeCallSiteConfigToValues, StateMachineManager, parseDurationString, createContextFromBindings, validateEventPayload, formatPayloadValidationError, collectDeclaredConfigDefaults, resolveCallSitePayloadCaptures, collectDeclaredEntityDefaults, EffectExecutor } from './chunk-FIBEYLME.js';
|
|
2
|
+
export { InMemoryPersistence, collectDeclaredConfigDefaults } from './chunk-FIBEYLME.js';
|
|
3
3
|
import { isValidCronExpression } from './chunk-OU3ITB5S.js';
|
|
4
4
|
import './chunk-T4VDAB4C.js';
|
|
5
5
|
import './chunk-SCRAHWOC.js';
|
|
@@ -7,7 +7,8 @@ import './chunk-MLKGABMK.js';
|
|
|
7
7
|
import { createLogger } from '@almadar/logger';
|
|
8
8
|
import * as nodeModule from 'module';
|
|
9
9
|
import { evaluateListenPayloadExpr, evaluateGuard, evaluate } from '@almadar/evaluator';
|
|
10
|
-
import { buildResolvedTraitConfigs, isInlineTrait, isEntityCall, applyListenPayloadMapping, normalizeUserContext } from '@almadar/core';
|
|
10
|
+
import { DEFAULT_VIEWER, buildResolvedTraitConfigs, isInlineTrait, isEntityCall, applyListenPayloadMapping, normalizeUserContext, isRuntimeEntity } from '@almadar/core';
|
|
11
|
+
import { ownerFieldsFromSchema, identityEntityName } from '@almadar/core/mock';
|
|
11
12
|
|
|
12
13
|
// src/identity/routing.ts
|
|
13
14
|
function eventRouteKey(eventName, eventId) {
|
|
@@ -115,7 +116,12 @@ var OrbitalServerRuntime = class {
|
|
|
115
116
|
// Default to mock mode for preview
|
|
116
117
|
autoPreprocess: false,
|
|
117
118
|
namespaceEvents: true,
|
|
118
|
-
...config
|
|
119
|
+
...config,
|
|
120
|
+
// `@user` is never Null. A host that named no viewer (no ALMADAR_PERSONA,
|
|
121
|
+
// no auth yet) otherwise renders every `viewerName: @user.name` blank, so
|
|
122
|
+
// the app cannot say who you are. DEFAULT_VIEWER carries an empty `role`,
|
|
123
|
+
// so no `@user.role` guard changes outcome — see its doc in @almadar/core.
|
|
124
|
+
defaultUser: config.defaultUser ?? DEFAULT_VIEWER
|
|
119
125
|
};
|
|
120
126
|
this.eventBus = new EventBus();
|
|
121
127
|
if (config.loaderConfig?.loader) {
|
|
@@ -135,7 +141,9 @@ var OrbitalServerRuntime = class {
|
|
|
135
141
|
// Let the dev viewer own some seeded rows, so ownership-scoped views
|
|
136
142
|
// ("only mine") have data instead of being indistinguishable from a
|
|
137
143
|
// broken filter. Columns are declared, never inferred by name.
|
|
138
|
-
|
|
144
|
+
// `this.config`, not `config` — the DEFAULT_VIEWER fallback is applied
|
|
145
|
+
// there, and reading the raw param leaves every seeded row unowned.
|
|
146
|
+
ownerId: this.config.defaultUser?.id,
|
|
139
147
|
ownerFields: config.mockOwnerFields
|
|
140
148
|
});
|
|
141
149
|
if (config.debug) {
|
|
@@ -293,6 +301,7 @@ var OrbitalServerRuntime = class {
|
|
|
293
301
|
registerLog.warn("register:no-loader", { name: schema.name });
|
|
294
302
|
}
|
|
295
303
|
}
|
|
304
|
+
this.applyIdentityOwnerFields(schema);
|
|
296
305
|
for (const orbital of schema.orbitals) {
|
|
297
306
|
await this.registerOrbitalAsync(orbital);
|
|
298
307
|
}
|
|
@@ -301,6 +310,23 @@ var OrbitalServerRuntime = class {
|
|
|
301
310
|
this.resolvedSchema = schema;
|
|
302
311
|
this.resolvedTraitConfigs = buildResolvedTraitConfigs(schema);
|
|
303
312
|
}
|
|
313
|
+
/**
|
|
314
|
+
* Teach the mock seeder which columns hold the viewer's id, derived from the
|
|
315
|
+
* schema's `[identity]` entity. No-op for a program that declares none, so
|
|
316
|
+
* unmigrated apps seed exactly as before. Mirrors
|
|
317
|
+
* `orbital-core/src/runtime/seed.rs::owner_fields_from_schema` — a feature
|
|
318
|
+
* that lives on only one execution path is not a feature.
|
|
319
|
+
*/
|
|
320
|
+
applyIdentityOwnerFields(schema) {
|
|
321
|
+
if (!(this.persistence instanceof MockPersistenceAdapter)) return;
|
|
322
|
+
const derived = ownerFieldsFromSchema(schema);
|
|
323
|
+
if (derived.length === 0) return;
|
|
324
|
+
this.persistence.addOwnerFields(derived);
|
|
325
|
+
persistLog.debug("mock:identity-owner-fields", {
|
|
326
|
+
identity: identityEntityName(schema),
|
|
327
|
+
columns: derived
|
|
328
|
+
});
|
|
329
|
+
}
|
|
304
330
|
/**
|
|
305
331
|
* Register an OrbitalSchema synchronously (for backward compatibility).
|
|
306
332
|
* Note: This version doesn't wait for instance seeding to complete.
|
|
@@ -310,6 +336,7 @@ var OrbitalServerRuntime = class {
|
|
|
310
336
|
if (this.config.debug) {
|
|
311
337
|
registerLog.debug("register:schema-sync", { name: schema.name });
|
|
312
338
|
}
|
|
339
|
+
this.applyIdentityOwnerFields(schema);
|
|
313
340
|
for (const orbital of schema.orbitals) {
|
|
314
341
|
this.registerOrbital(orbital);
|
|
315
342
|
}
|
|
@@ -317,6 +344,7 @@ var OrbitalServerRuntime = class {
|
|
|
317
344
|
this.setupTicks();
|
|
318
345
|
this.resolvedSchema = schema;
|
|
319
346
|
this.resolvedTraitConfigs = buildResolvedTraitConfigs(schema);
|
|
347
|
+
this.applyIdentityOwnerFields(schema);
|
|
320
348
|
}
|
|
321
349
|
/**
|
|
322
350
|
* Returns the schema that this runtime is currently executing, post-
|
|
@@ -622,6 +650,16 @@ var OrbitalServerRuntime = class {
|
|
|
622
650
|
const routeKey = eventRouteKey(bareEvent, listener.eventId);
|
|
623
651
|
const cleanup = this.eventBus.on(routeKey, async (event) => {
|
|
624
652
|
if (!matcher(event.source)) return;
|
|
653
|
+
if (event.source?.originClientId !== void 0) {
|
|
654
|
+
if (this.config.debug) {
|
|
655
|
+
xOrbitalLog.debug("listen:skip-client-origin", {
|
|
656
|
+
receiverTrait: trait.name,
|
|
657
|
+
event: listener.event,
|
|
658
|
+
originClientId: event.source.originClientId
|
|
659
|
+
});
|
|
660
|
+
}
|
|
661
|
+
return;
|
|
662
|
+
}
|
|
625
663
|
if (this.config.debug) {
|
|
626
664
|
xOrbitalLog.debug("listen:received", () => ({
|
|
627
665
|
receiverOrbital: orbitalName,
|
|
@@ -887,6 +925,34 @@ var OrbitalServerRuntime = class {
|
|
|
887
925
|
// ==========================================================================
|
|
888
926
|
// Event Processing
|
|
889
927
|
// ==========================================================================
|
|
928
|
+
/**
|
|
929
|
+
* `traitFieldStates` key for one trait: its own name, or — when its linked
|
|
930
|
+
* entity is `[shared]` — `$shared::<entityName>` so every trait bound to
|
|
931
|
+
* that entity reads/writes ONE frame. The server twin of the client hook's
|
|
932
|
+
* `sharedKeyByTraitName` (useTraitStateMachine): without it, a sibling
|
|
933
|
+
* trait's effect interpolation (a fetch filter reading
|
|
934
|
+
* `@entity.activeChannel`) never saw the writer's `(set …)`.
|
|
935
|
+
*/
|
|
936
|
+
sharedFieldKey(registered, traitName) {
|
|
937
|
+
const trait = registered.traits.find((t) => t.name === traitName);
|
|
938
|
+
const linked = trait?.linkedEntity ?? registered.entity.name;
|
|
939
|
+
return this.isSharedEntity(registered, linked) ? `$shared::${linked}` : traitName;
|
|
940
|
+
}
|
|
941
|
+
/** Resolve an entity name to its declared `shared` flag: the orbital's own
|
|
942
|
+
* entity, its auxiliary entities, then other registered orbitals' primary
|
|
943
|
+
* entities (cross-orbital binds like a membership rail in the chat page). */
|
|
944
|
+
isSharedEntity(registered, entityName) {
|
|
945
|
+
if (registered.entity.name === entityName) return registered.entity.shared === true;
|
|
946
|
+
for (const aux of registered.schema.auxiliaryEntities ?? []) {
|
|
947
|
+
if (typeof aux === "object" && !isEntityCall(aux) && aux.name === entityName) {
|
|
948
|
+
return aux.shared === true;
|
|
949
|
+
}
|
|
950
|
+
}
|
|
951
|
+
for (const other of this.orbitals.values()) {
|
|
952
|
+
if (other.entity.name === entityName) return other.entity.shared === true;
|
|
953
|
+
}
|
|
954
|
+
return false;
|
|
955
|
+
}
|
|
890
956
|
/**
|
|
891
957
|
* Process an event for an orbital
|
|
892
958
|
*
|
|
@@ -982,9 +1048,10 @@ var OrbitalServerRuntime = class {
|
|
|
982
1048
|
}
|
|
983
1049
|
}
|
|
984
1050
|
const entityByTrait = {};
|
|
985
|
-
for (const
|
|
1051
|
+
for (const trait of registered.traits) {
|
|
1052
|
+
const fields = registered.traitFieldStates.get(this.sharedFieldKey(registered, trait.name));
|
|
986
1053
|
if (fields && Object.keys(fields).length > 0) {
|
|
987
|
-
entityByTrait[name] = fields;
|
|
1054
|
+
entityByTrait[trait.name] = fields;
|
|
988
1055
|
}
|
|
989
1056
|
}
|
|
990
1057
|
const results = registered.manager.sendEvent(
|
|
@@ -1099,6 +1166,9 @@ var OrbitalServerRuntime = class {
|
|
|
1099
1166
|
if (stamp.eventId === void 0 && emitContract?.eventId !== void 0) {
|
|
1100
1167
|
stamp.eventId = emitContract.eventId;
|
|
1101
1168
|
}
|
|
1169
|
+
if (originClientId !== void 0 && stamp.originClientId === void 0) {
|
|
1170
|
+
stamp.originClientId = originClientId;
|
|
1171
|
+
}
|
|
1102
1172
|
this.eventBus.emit(event, eventPayload, stamp, eventRouteKey(event, stamp.eventId));
|
|
1103
1173
|
const emittedItem = { event, payload: eventPayload, source: stamp };
|
|
1104
1174
|
emittedEvents.push(emittedItem);
|
|
@@ -1127,10 +1197,11 @@ var OrbitalServerRuntime = class {
|
|
|
1127
1197
|
}
|
|
1128
1198
|
},
|
|
1129
1199
|
set: async (targetId, field, value) => {
|
|
1130
|
-
|
|
1200
|
+
const fieldKey = this.sharedFieldKey(registered, traitName);
|
|
1201
|
+
let fieldState = registered.traitFieldStates.get(fieldKey);
|
|
1131
1202
|
if (!fieldState) {
|
|
1132
1203
|
fieldState = {};
|
|
1133
|
-
registered.traitFieldStates.set(
|
|
1204
|
+
registered.traitFieldStates.set(fieldKey, fieldState);
|
|
1134
1205
|
}
|
|
1135
1206
|
fieldState[field] = value;
|
|
1136
1207
|
effectResults.push({
|
|
@@ -1503,7 +1574,10 @@ var OrbitalServerRuntime = class {
|
|
|
1503
1574
|
bindings: bindingsRef ?? {},
|
|
1504
1575
|
context: contextRef ?? { traitName, orbitalName: registered.schema.name, state: "unknown", transition: "unknown" },
|
|
1505
1576
|
debug: this.config.debug,
|
|
1506
|
-
contextExtensions: this.config.contextExtensions
|
|
1577
|
+
contextExtensions: this.config.contextExtensions,
|
|
1578
|
+
// Same render-time marker boundary as the outer executor
|
|
1579
|
+
// (including the [shared]-defers-regardless-of-persistence rule).
|
|
1580
|
+
deferRenderBindings: registered.entity === void 0 || isRuntimeEntity(registered.entity) || registered.entity.shared === true
|
|
1507
1581
|
});
|
|
1508
1582
|
for (const innerEffect of atomicEffects) {
|
|
1509
1583
|
if (atomicFailed) break;
|
|
@@ -1591,7 +1665,7 @@ var OrbitalServerRuntime = class {
|
|
|
1591
1665
|
};
|
|
1592
1666
|
}
|
|
1593
1667
|
const entityFieldDefaults = collectDeclaredEntityDefaults(registered.entity);
|
|
1594
|
-
const traitFieldState = registered.traitFieldStates.get(traitName);
|
|
1668
|
+
const traitFieldState = registered.traitFieldStates.get(this.sharedFieldKey(registered, traitName));
|
|
1595
1669
|
if (entityFieldDefaults || traitFieldState) {
|
|
1596
1670
|
bindings.entity = {
|
|
1597
1671
|
...entityFieldDefaults ?? {},
|
|
@@ -1616,7 +1690,19 @@ var OrbitalServerRuntime = class {
|
|
|
1616
1690
|
bindings,
|
|
1617
1691
|
context,
|
|
1618
1692
|
debug: this.config.debug,
|
|
1619
|
-
contextExtensions: this.config.contextExtensions
|
|
1693
|
+
contextExtensions: this.config.contextExtensions,
|
|
1694
|
+
// Carry `@entity`-dependent render-ui leaves as render-time markers
|
|
1695
|
+
// for runtime-only (and unlinked) entities: the client's local state
|
|
1696
|
+
// machines execute the same `(set)` writes, so the renderer resolves
|
|
1697
|
+
// markers against its live store — otherwise these SSE-pushed eager
|
|
1698
|
+
// props clobber the client's live marker frames on every event.
|
|
1699
|
+
// Persistent NON-shared entities stay eager: their `@entity` merges
|
|
1700
|
+
// persistence rows the client does not hold. A `[shared]` entity is
|
|
1701
|
+
// deferred REGARDLESS of persistence — its trait frame's scalars are
|
|
1702
|
+
// client-held by contract (one live frame across bound traits), and
|
|
1703
|
+
// the eager clobber pinned the chat composer's controlled input to
|
|
1704
|
+
// the server's flush-time "" on every keystroke round-trip.
|
|
1705
|
+
deferRenderBindings: registered.entity === void 0 || isRuntimeEntity(registered.entity) || registered.entity.shared === true
|
|
1620
1706
|
});
|
|
1621
1707
|
await executor.executeAll(effects);
|
|
1622
1708
|
}
|
package/dist/ServerBridge.d.ts
CHANGED
|
@@ -5,7 +5,7 @@ import { createLogger, setNamespaceLevel } from '@almadar/logger';
|
|
|
5
5
|
import { createMinimalContext, resolveBinding, evaluate, evaluateGuard, SExpressionEvaluator } from '@almadar/evaluator';
|
|
6
6
|
export { createMinimalContext } from '@almadar/evaluator';
|
|
7
7
|
import { isKnownStdOperator } from '@almadar/std/registry';
|
|
8
|
-
import { OrbitalSchemaSchema, isInlineTrait, isEntityCall, isEntityReference, parseEntityRef, parseImportedTraitRef, isPageReference, isPageReferenceString, isPageReferenceObject, parsePageRef, isReferenceConfigType, configRefEventKnob, normalizeCallSiteConfigToValues, resolveConfigRefEventName } from '@almadar/core';
|
|
8
|
+
import { containsEntityBinding, containsPayloadBinding, RENDER_BINDING_MARKER, OrbitalSchemaSchema, isInlineTrait, isEntityCall, isEntityReference, parseEntityRef, parseImportedTraitRef, isPageReference, isPageReferenceString, isPageReferenceObject, parsePageRef, isReferenceConfigType, configRefEventKnob, normalizeCallSiteConfigToValues, resolveConfigRefEventName } from '@almadar/core';
|
|
9
9
|
export { normalizeCallSiteConfigToValues } from '@almadar/core';
|
|
10
10
|
import { sampleRowCount, sampleRow } from '@almadar/core/mock';
|
|
11
11
|
|
|
@@ -291,6 +291,7 @@ function isValidDurationString(interval) {
|
|
|
291
291
|
}
|
|
292
292
|
var bindLog = createLogger("almadar:runtime:bindings");
|
|
293
293
|
setNamespaceLevel("almadar:runtime:bindings", "WARN");
|
|
294
|
+
var deferLog = createLogger("almadar:runtime:defer");
|
|
294
295
|
var renderLog = createLogger("almadar:runtime:render-ui");
|
|
295
296
|
var CLIENT_ONLY_BINDING_ROOTS = /* @__PURE__ */ new Set(["trait"]);
|
|
296
297
|
var CALLSITE_PAYLOAD_PREFIX = "@callsitePayload.";
|
|
@@ -396,6 +397,45 @@ function interpolateValue(value, ctx) {
|
|
|
396
397
|
}
|
|
397
398
|
return value;
|
|
398
399
|
}
|
|
400
|
+
function deferEntityBindings(value, ctx, configHops = 0) {
|
|
401
|
+
if (typeof value === "string") {
|
|
402
|
+
if (containsEntityBinding(value) && !containsPayloadBinding(value)) {
|
|
403
|
+
return { [RENDER_BINDING_MARKER]: true, expression: value };
|
|
404
|
+
}
|
|
405
|
+
if (value.startsWith("@config.") && !value.includes(" ") && configHops < 8) {
|
|
406
|
+
const hop = ctx.config?.[value.slice("@config.".length)];
|
|
407
|
+
deferLog.debug("defer:config-hop", () => ({
|
|
408
|
+
forward: value,
|
|
409
|
+
hopType: typeof hop,
|
|
410
|
+
hopPreview: typeof hop === "string" ? hop : Array.isArray(hop) ? "array" : hop === void 0 ? "undefined" : "object"
|
|
411
|
+
}));
|
|
412
|
+
if (hop !== void 0 && hop !== value) {
|
|
413
|
+
return deferEntityBindings(hop, ctx, configHops + 1);
|
|
414
|
+
}
|
|
415
|
+
}
|
|
416
|
+
return interpolateValue(value, ctx);
|
|
417
|
+
}
|
|
418
|
+
if (Array.isArray(value)) {
|
|
419
|
+
if (value.length === 3 && value[0] === "fn" && typeof value[1] === "string") {
|
|
420
|
+
return value;
|
|
421
|
+
}
|
|
422
|
+
if (isSExpression(value)) {
|
|
423
|
+
if (containsEntityBinding(value) && !containsPayloadBinding(value)) {
|
|
424
|
+
return { [RENDER_BINDING_MARKER]: true, expression: value };
|
|
425
|
+
}
|
|
426
|
+
return interpolateValue(value, ctx);
|
|
427
|
+
}
|
|
428
|
+
return value.map((item) => deferEntityBindings(item, ctx));
|
|
429
|
+
}
|
|
430
|
+
if (value !== null && typeof value === "object") {
|
|
431
|
+
const out = {};
|
|
432
|
+
for (const [key, item] of Object.entries(value)) {
|
|
433
|
+
out[key] = deferEntityBindings(item, ctx);
|
|
434
|
+
}
|
|
435
|
+
return out;
|
|
436
|
+
}
|
|
437
|
+
return value;
|
|
438
|
+
}
|
|
399
439
|
var inFlightConfigRecursions = /* @__PURE__ */ new Set();
|
|
400
440
|
function interpolateString(value, ctx) {
|
|
401
441
|
if (value.startsWith("@") && isPureBinding(value)) {
|
|
@@ -1178,6 +1218,18 @@ function resolveArgs(args, bindings, strictBindings, contextExtensions) {
|
|
|
1178
1218
|
const ctx = createContextFromBindings(bindings, strictBindings, contextExtensions);
|
|
1179
1219
|
return args.map((arg) => interpolateValue(arg, ctx));
|
|
1180
1220
|
}
|
|
1221
|
+
function interpolateFilterTraitRefs(value, ctx) {
|
|
1222
|
+
if (typeof value === "string") {
|
|
1223
|
+
return value === "@entity" || value.startsWith("@entity.") ? interpolateValue(value, ctx) : value;
|
|
1224
|
+
}
|
|
1225
|
+
if (Array.isArray(value)) {
|
|
1226
|
+
if (value.length >= 2 && value[0] === "object/get" && value[1] === "@entity") {
|
|
1227
|
+
return value;
|
|
1228
|
+
}
|
|
1229
|
+
return value.map((v) => interpolateFilterTraitRefs(v, ctx));
|
|
1230
|
+
}
|
|
1231
|
+
return value;
|
|
1232
|
+
}
|
|
1181
1233
|
var EffectExecutor = class _EffectExecutor {
|
|
1182
1234
|
handlers;
|
|
1183
1235
|
bindings;
|
|
@@ -1186,6 +1238,7 @@ var EffectExecutor = class _EffectExecutor {
|
|
|
1186
1238
|
strictBindings;
|
|
1187
1239
|
contextExtensions;
|
|
1188
1240
|
evaluator;
|
|
1241
|
+
deferRenderBindings;
|
|
1189
1242
|
constructor(options) {
|
|
1190
1243
|
this.handlers = options.handlers;
|
|
1191
1244
|
this.bindings = options.bindings;
|
|
@@ -1194,6 +1247,7 @@ var EffectExecutor = class _EffectExecutor {
|
|
|
1194
1247
|
this.strictBindings = options.strictBindings ?? false;
|
|
1195
1248
|
this.contextExtensions = options.contextExtensions;
|
|
1196
1249
|
this.evaluator = options.evaluator;
|
|
1250
|
+
this.deferRenderBindings = options.deferRenderBindings ?? false;
|
|
1197
1251
|
}
|
|
1198
1252
|
_evaluator;
|
|
1199
1253
|
getEvaluator() {
|
|
@@ -1293,9 +1347,15 @@ var EffectExecutor = class _EffectExecutor {
|
|
|
1293
1347
|
const isCompound = operator === "do" || operator === "when" || operator === "let" || operator === "if";
|
|
1294
1348
|
const isSetPathForm = operator === "set" && args.length >= 2 && typeof args[0] === "string" && args[0].startsWith("@entity.");
|
|
1295
1349
|
const isFetchLike = (operator === "fetch" || operator === "ref" || operator === "deref" || operator === "os/watch-collection" || operator === "os/watch") && args.length >= 2 && args[1] !== null && typeof args[1] === "object" && !Array.isArray(args[1]);
|
|
1350
|
+
const isDeferringRenderUI = (operator === "render-ui" || operator === "render") && this.deferRenderBindings;
|
|
1296
1351
|
let resolvedArgs;
|
|
1297
1352
|
if (isCompound) {
|
|
1298
1353
|
resolvedArgs = args;
|
|
1354
|
+
} else if (isDeferringRenderUI) {
|
|
1355
|
+
const ctx = createContextFromBindings(this.bindings, this.strictBindings, this.contextExtensions);
|
|
1356
|
+
resolvedArgs = args.map(
|
|
1357
|
+
(arg, index) => index === 0 ? interpolateValue(arg, ctx) : deferEntityBindings(arg, ctx)
|
|
1358
|
+
);
|
|
1299
1359
|
} else if (isSetPathForm) {
|
|
1300
1360
|
const ctx = createContextFromBindings(this.bindings, this.strictBindings, this.contextExtensions);
|
|
1301
1361
|
const resolvedRest = [];
|
|
@@ -1316,7 +1376,7 @@ var EffectExecutor = class _EffectExecutor {
|
|
|
1316
1376
|
const opts = args[1];
|
|
1317
1377
|
const resolvedOpts = {
|
|
1318
1378
|
...opts.id !== void 0 && { id: interpolateValue(opts.id, ctx) },
|
|
1319
|
-
...opts.filter !== void 0 && { filter: opts.filter },
|
|
1379
|
+
...opts.filter !== void 0 && { filter: interpolateFilterTraitRefs(opts.filter, ctx) },
|
|
1320
1380
|
...opts.limit !== void 0 && { limit: interpolateValue(opts.limit, ctx) },
|
|
1321
1381
|
...opts.offset !== void 0 && { offset: interpolateValue(opts.offset, ctx) },
|
|
1322
1382
|
...opts.include !== void 0 && { include: interpolateValue(opts.include, ctx) },
|
|
@@ -1868,7 +1928,8 @@ var EffectExecutor = class _EffectExecutor {
|
|
|
1868
1928
|
context: this.context,
|
|
1869
1929
|
debug: this.debug,
|
|
1870
1930
|
strictBindings: this.strictBindings,
|
|
1871
|
-
contextExtensions: this.contextExtensions
|
|
1931
|
+
contextExtensions: this.contextExtensions,
|
|
1932
|
+
deferRenderBindings: this.deferRenderBindings
|
|
1872
1933
|
});
|
|
1873
1934
|
await bodyExecutor.execute(body);
|
|
1874
1935
|
break;
|
|
@@ -2346,6 +2407,22 @@ var MockPersistenceAdapter = class {
|
|
|
2346
2407
|
seedRandom(this.config.seed);
|
|
2347
2408
|
mockLog.debug("mock:adapter:init", { seed: this.config.seed });
|
|
2348
2409
|
}
|
|
2410
|
+
/**
|
|
2411
|
+
* Add owner columns discovered after construction.
|
|
2412
|
+
*
|
|
2413
|
+
* The adapter is built before any schema is registered, so schema-DERIVED
|
|
2414
|
+
* owner columns (relation fields pointing at the `[identity]` entity) can
|
|
2415
|
+
* only arrive later.
|
|
2416
|
+
*
|
|
2417
|
+
* ⚠️ Seeding is EAGER — `registerEntity()` seeds immediately — so callers must
|
|
2418
|
+
* supply these columns BEFORE registering any orbital. Calling this afterwards
|
|
2419
|
+
* silently stamps nothing.
|
|
2420
|
+
*/
|
|
2421
|
+
addOwnerFields(fields) {
|
|
2422
|
+
if (fields.length === 0) return;
|
|
2423
|
+
const merged = /* @__PURE__ */ new Set([...this.config.ownerFields ?? [], ...fields]);
|
|
2424
|
+
this.config.ownerFields = [...merged];
|
|
2425
|
+
}
|
|
2349
2426
|
/** Re-anchor the PRNG to the configured seed. Called before every
|
|
2350
2427
|
* re-seed loop so identical reseed sequences produce identical rows
|
|
2351
2428
|
* (timestamps + generated fields). Without this, the first
|
|
@@ -2422,6 +2499,9 @@ var MockPersistenceAdapter = class {
|
|
|
2422
2499
|
if (relationFields.length === 0) continue;
|
|
2423
2500
|
for (const row of store.values()) {
|
|
2424
2501
|
for (const field of relationFields) {
|
|
2502
|
+
if (this.config.ownerId !== void 0 && row[field.name] === this.config.ownerId) {
|
|
2503
|
+
continue;
|
|
2504
|
+
}
|
|
2425
2505
|
const targetNormalized = (field.relation.entityId && this.storeNameById.get(field.relation.entityId)) ?? field.relation.entity.toLowerCase();
|
|
2426
2506
|
const targetStore = this.stores.get(targetNormalized);
|
|
2427
2507
|
if (!targetStore || targetStore.size === 0) continue;
|
|
@@ -3642,6 +3722,96 @@ function renameEntityInEffect(effect, rename, props) {
|
|
|
3642
3722
|
}
|
|
3643
3723
|
return effect;
|
|
3644
3724
|
}
|
|
3725
|
+
var TRAIT_EMBED_PREFIX = "@trait.";
|
|
3726
|
+
function renameTraitEmbedsInValue(node, subs) {
|
|
3727
|
+
if (node === null || node === void 0) return node;
|
|
3728
|
+
if (typeof node === "string") {
|
|
3729
|
+
if (!node.startsWith(TRAIT_EMBED_PREFIX)) return node;
|
|
3730
|
+
const rest = node.slice(TRAIT_EMBED_PREFIX.length);
|
|
3731
|
+
const dot = rest.search(/[.[]/);
|
|
3732
|
+
const name = dot === -1 ? rest : rest.slice(0, dot);
|
|
3733
|
+
const suffix = dot === -1 ? "" : rest.slice(dot);
|
|
3734
|
+
const to = subs.get(name);
|
|
3735
|
+
return to === void 0 ? node : `${TRAIT_EMBED_PREFIX}${to}${suffix}`;
|
|
3736
|
+
}
|
|
3737
|
+
if (Array.isArray(node)) return node.map((item) => renameTraitEmbedsInValue(item, subs));
|
|
3738
|
+
if (typeof node !== "object") return node;
|
|
3739
|
+
const next = {};
|
|
3740
|
+
for (const [key, value] of Object.entries(node)) {
|
|
3741
|
+
next[key] = renameTraitEmbedsInValue(value, subs);
|
|
3742
|
+
}
|
|
3743
|
+
return next;
|
|
3744
|
+
}
|
|
3745
|
+
function renameTraitEmbeds(trait, subs) {
|
|
3746
|
+
if (subs.size === 0) return trait;
|
|
3747
|
+
const sm = trait.stateMachine;
|
|
3748
|
+
const next = { ...trait };
|
|
3749
|
+
if (sm) {
|
|
3750
|
+
next.stateMachine = {
|
|
3751
|
+
...sm,
|
|
3752
|
+
transitions: (sm.transitions ?? []).map(
|
|
3753
|
+
(t) => t.effects ? { ...t, effects: renameTraitEmbedsInValue(t.effects, subs) } : t
|
|
3754
|
+
)
|
|
3755
|
+
};
|
|
3756
|
+
}
|
|
3757
|
+
if (trait.ticks) {
|
|
3758
|
+
next.ticks = trait.ticks.map(
|
|
3759
|
+
(tick) => tick.effects ? { ...tick, effects: renameTraitEmbedsInValue(tick.effects, subs) } : tick
|
|
3760
|
+
);
|
|
3761
|
+
}
|
|
3762
|
+
if (trait.config) {
|
|
3763
|
+
const nextConfig = {};
|
|
3764
|
+
for (const [key, field] of Object.entries(trait.config)) {
|
|
3765
|
+
nextConfig[key] = field.default === void 0 ? field : {
|
|
3766
|
+
...field,
|
|
3767
|
+
default: renameTraitEmbedsInValue(
|
|
3768
|
+
field.default,
|
|
3769
|
+
subs
|
|
3770
|
+
)
|
|
3771
|
+
};
|
|
3772
|
+
}
|
|
3773
|
+
next.config = nextConfig;
|
|
3774
|
+
}
|
|
3775
|
+
return next;
|
|
3776
|
+
}
|
|
3777
|
+
function findTraitEntryInOrbital(orbital, localName) {
|
|
3778
|
+
for (const traitRef of orbital.traits ?? []) {
|
|
3779
|
+
if (typeof traitRef === "string") continue;
|
|
3780
|
+
if ("stateMachine" in traitRef) {
|
|
3781
|
+
if (traitRef.name === localName) return traitRef;
|
|
3782
|
+
continue;
|
|
3783
|
+
}
|
|
3784
|
+
if (!("ref" in traitRef)) continue;
|
|
3785
|
+
const refObj = traitRef;
|
|
3786
|
+
const declared = refObj.name ?? parseImportedTraitRef(refObj.ref)?.traitName;
|
|
3787
|
+
if (declared === localName) return traitRef;
|
|
3788
|
+
}
|
|
3789
|
+
return null;
|
|
3790
|
+
}
|
|
3791
|
+
function traitEmbedNamesOf(trait) {
|
|
3792
|
+
const found = /* @__PURE__ */ new Set();
|
|
3793
|
+
const walk = (node) => {
|
|
3794
|
+
if (node === null || node === void 0) return;
|
|
3795
|
+
if (typeof node === "string") {
|
|
3796
|
+
if (!node.startsWith(TRAIT_EMBED_PREFIX)) return;
|
|
3797
|
+
const rest = node.slice(TRAIT_EMBED_PREFIX.length);
|
|
3798
|
+
const dot = rest.search(/[.[]/);
|
|
3799
|
+
const name = dot === -1 ? rest : rest.slice(0, dot);
|
|
3800
|
+
if (name.length > 0) found.add(name);
|
|
3801
|
+
return;
|
|
3802
|
+
}
|
|
3803
|
+
if (Array.isArray(node)) {
|
|
3804
|
+
for (const item of node) walk(item);
|
|
3805
|
+
return;
|
|
3806
|
+
}
|
|
3807
|
+
if (typeof node !== "object") return;
|
|
3808
|
+
for (const value of Object.values(node)) walk(value);
|
|
3809
|
+
};
|
|
3810
|
+
for (const t of trait.stateMachine?.transitions ?? []) walk(t.effects);
|
|
3811
|
+
for (const tick of trait.ticks ?? []) walk(tick.effects);
|
|
3812
|
+
for (const field of Object.values(trait.config ?? {})) walk(field.default);
|
|
3813
|
+
return [...found];
|
|
3814
|
+
}
|
|
3645
3815
|
function applyLinkedEntityRename(trait, linkedEntity) {
|
|
3646
3816
|
const atomLinked = trait.linkedEntity;
|
|
3647
3817
|
if (!linkedEntity || !atomLinked || linkedEntity === atomLinked) return trait;
|
|
@@ -3813,6 +3983,8 @@ var ReferenceResolver = class {
|
|
|
3813
3983
|
localTraits;
|
|
3814
3984
|
/** id-keyed mirror of `localTraits`, populated wherever the trait carries an `id`. */
|
|
3815
3985
|
localTraitsById = /* @__PURE__ */ new Map();
|
|
3986
|
+
/** Import scope of each loaded source orbital, keyed by its source path. */
|
|
3987
|
+
sourceImportsCache = /* @__PURE__ */ new Map();
|
|
3816
3988
|
loaderInitialized = false;
|
|
3817
3989
|
constructor(options) {
|
|
3818
3990
|
this.options = options;
|
|
@@ -3869,6 +4041,10 @@ var ReferenceResolver = class {
|
|
|
3869
4041
|
if (!entityResult.success || !traitsResult.success || !pagesResult.success) {
|
|
3870
4042
|
return { success: false, errors: ["Internal error: unexpected failure state"] };
|
|
3871
4043
|
}
|
|
4044
|
+
const pullErrors = await this.pullSiblingTraits(traitsResult.data, imports, importChain);
|
|
4045
|
+
if (pullErrors.length > 0) {
|
|
4046
|
+
return { success: false, errors: pullErrors };
|
|
4047
|
+
}
|
|
3872
4048
|
for (const resolvedTrait of traitsResult.data) {
|
|
3873
4049
|
resolvedTrait.trait = resolveEntityTokensById(resolvedTrait.trait, imports.idIndex);
|
|
3874
4050
|
resolvedTrait.trait = resolveConfigRefsById(resolvedTrait.trait, imports.idIndex);
|
|
@@ -4042,6 +4218,191 @@ var ReferenceResolver = class {
|
|
|
4042
4218
|
}
|
|
4043
4219
|
return { success: true, data: resolved, warnings: [] };
|
|
4044
4220
|
}
|
|
4221
|
+
/**
|
|
4222
|
+
* The import scope of an already-loaded orbital, memoised per source path.
|
|
4223
|
+
* A sibling that is itself a ref names its target through the SOURCE atom's
|
|
4224
|
+
* aliases, so it can only be resolved against those.
|
|
4225
|
+
*/
|
|
4226
|
+
async importsOfSource(imported, chain) {
|
|
4227
|
+
const key = imported.sourcePath ?? `${imported.alias}:${imported.from}`;
|
|
4228
|
+
const cached = this.sourceImportsCache.get(key);
|
|
4229
|
+
if (cached) return cached;
|
|
4230
|
+
const result = await this.resolveImports(
|
|
4231
|
+
imported.orbital.uses ?? [],
|
|
4232
|
+
imported.sourcePath,
|
|
4233
|
+
chain
|
|
4234
|
+
);
|
|
4235
|
+
if (!result.success) return null;
|
|
4236
|
+
result.data.idIndex = buildIdIndex(imported.orbital, result.data.orbitals);
|
|
4237
|
+
this.sourceImportsCache.set(key, result.data);
|
|
4238
|
+
return result.data;
|
|
4239
|
+
}
|
|
4240
|
+
/**
|
|
4241
|
+
* Sibling-trait auto-pull — the JS twin of the compiler's
|
|
4242
|
+
* `phases/inline/trait.rs` pass, appending to `resolved` in place.
|
|
4243
|
+
*
|
|
4244
|
+
* An atom's main trait embeds its own sub-views as `@trait.<Sibling>` string
|
|
4245
|
+
* literals (`std-browse`'s `bodyContent: {children: [@trait.DataGrid1]}`).
|
|
4246
|
+
* A consumer that imports only the main trait never instantiates those
|
|
4247
|
+
* siblings, so the token dangles: no state machine, no fetch, an empty list
|
|
4248
|
+
* where the grid should be. The compiled path materialises them; without this
|
|
4249
|
+
* pass the interpreted path did not, so a raw `.orb` handed straight to
|
|
4250
|
+
* `OrbitalServerRuntime` rendered a different app than the same `.orb` run
|
|
4251
|
+
* through `orbital resolve`.
|
|
4252
|
+
*
|
|
4253
|
+
* Pulls are keyed per EMBEDDER (`owner` = the top-level consumer trait that
|
|
4254
|
+
* started the chain), not per atom. Two rebinds of one atom in one orbital
|
|
4255
|
+
* (`ChannelRail -> Channel` and `ChatThread -> ChatMessage`, both std-browse)
|
|
4256
|
+
* carry different entity rebinds and different hosts to listen to, so one
|
|
4257
|
+
* shared copy can only ever serve one of them. The first owner keeps the
|
|
4258
|
+
* source name; later owners pull under `<Owner><Sibling>` — unique by
|
|
4259
|
+
* construction, since owner names are unique within the orbital.
|
|
4260
|
+
*/
|
|
4261
|
+
async pullSiblingTraits(resolved, imports, chain) {
|
|
4262
|
+
const work = [];
|
|
4263
|
+
const ownerSubs = /* @__PURE__ */ new Map();
|
|
4264
|
+
const subsFor = (owner) => {
|
|
4265
|
+
let m = ownerSubs.get(owner);
|
|
4266
|
+
if (!m) {
|
|
4267
|
+
m = /* @__PURE__ */ new Map();
|
|
4268
|
+
ownerSubs.set(owner, m);
|
|
4269
|
+
}
|
|
4270
|
+
return m;
|
|
4271
|
+
};
|
|
4272
|
+
for (const rt of resolved) {
|
|
4273
|
+
if (rt.source.type !== "imported" || !rt.trait.name) continue;
|
|
4274
|
+
const owner = rt.trait.name;
|
|
4275
|
+
subsFor(owner).set(rt.source.traitName, owner);
|
|
4276
|
+
for (const sibling of traitEmbedNamesOf(rt.trait)) {
|
|
4277
|
+
work.push({ alias: rt.source.alias, sibling, linkedEntity: rt.linkedEntity, parent: owner, owner });
|
|
4278
|
+
}
|
|
4279
|
+
}
|
|
4280
|
+
if (work.length === 0) return [];
|
|
4281
|
+
const errors = [];
|
|
4282
|
+
const consumerDeclared = new Set(resolved.map((r) => r.trait.name).filter(Boolean));
|
|
4283
|
+
const seen = new Set(consumerDeclared);
|
|
4284
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4285
|
+
const pulledAs = /* @__PURE__ */ new Map();
|
|
4286
|
+
const ownerOf = /* @__PURE__ */ new Map();
|
|
4287
|
+
const parentRewrites = /* @__PURE__ */ new Map();
|
|
4288
|
+
const pulled = [];
|
|
4289
|
+
const noteRewrite = (parent, from, to) => {
|
|
4290
|
+
let m = parentRewrites.get(parent);
|
|
4291
|
+
if (!m) {
|
|
4292
|
+
m = /* @__PURE__ */ new Map();
|
|
4293
|
+
parentRewrites.set(parent, m);
|
|
4294
|
+
}
|
|
4295
|
+
m.set(from, to);
|
|
4296
|
+
};
|
|
4297
|
+
for (let item = work.pop(); item !== void 0; item = work.pop()) {
|
|
4298
|
+
const { alias, sibling, linkedEntity, parent, owner } = item;
|
|
4299
|
+
const pullKey = `${alias}\0${sibling}\0${owner}`;
|
|
4300
|
+
const existing = pulledAs.get(pullKey);
|
|
4301
|
+
if (existing !== void 0) {
|
|
4302
|
+
if (existing !== sibling) noteRewrite(parent, sibling, existing);
|
|
4303
|
+
continue;
|
|
4304
|
+
}
|
|
4305
|
+
let finalName = sibling;
|
|
4306
|
+
if (seen.has(sibling)) {
|
|
4307
|
+
if (consumerDeclared.has(sibling)) continue;
|
|
4308
|
+
finalName = `${owner}${sibling}`;
|
|
4309
|
+
if (seen.has(finalName)) continue;
|
|
4310
|
+
}
|
|
4311
|
+
if (visited.has(pullKey)) continue;
|
|
4312
|
+
visited.add(pullKey);
|
|
4313
|
+
const imported = imports.orbitals.get(alias);
|
|
4314
|
+
if (!imported) continue;
|
|
4315
|
+
const atomEntry = findTraitEntryInOrbital(imported.orbital, sibling);
|
|
4316
|
+
if (!atomEntry) continue;
|
|
4317
|
+
let atomTrait;
|
|
4318
|
+
if ("stateMachine" in atomEntry) {
|
|
4319
|
+
const { trait: cfgResolved, errors: cfgErrors } = resolveConfigRefEmitNames(
|
|
4320
|
+
atomEntry
|
|
4321
|
+
);
|
|
4322
|
+
if (cfgErrors.length > 0) {
|
|
4323
|
+
errors.push(...cfgErrors);
|
|
4324
|
+
continue;
|
|
4325
|
+
}
|
|
4326
|
+
atomTrait = cfgResolved;
|
|
4327
|
+
} else {
|
|
4328
|
+
const srcImports = await this.importsOfSource(imported, chain);
|
|
4329
|
+
if (!srcImports) continue;
|
|
4330
|
+
const refObj = atomEntry;
|
|
4331
|
+
const nested = this.resolveTraitRefString(
|
|
4332
|
+
refObj.ref,
|
|
4333
|
+
srcImports,
|
|
4334
|
+
refObj.config,
|
|
4335
|
+
refObj.linkedEntity,
|
|
4336
|
+
refObj.name ?? sibling,
|
|
4337
|
+
refObj.events,
|
|
4338
|
+
refObj.listens,
|
|
4339
|
+
refObj.refId
|
|
4340
|
+
);
|
|
4341
|
+
if (!nested.success) {
|
|
4342
|
+
errors.push(...nested.errors);
|
|
4343
|
+
continue;
|
|
4344
|
+
}
|
|
4345
|
+
atomTrait = nested.data.trait;
|
|
4346
|
+
}
|
|
4347
|
+
let copy = applyLinkedEntityRename(atomTrait, linkedEntity);
|
|
4348
|
+
if (finalName !== sibling) {
|
|
4349
|
+
copy = { ...copy, name: finalName };
|
|
4350
|
+
noteRewrite(parent, sibling, finalName);
|
|
4351
|
+
}
|
|
4352
|
+
for (const next of traitEmbedNamesOf(copy)) {
|
|
4353
|
+
work.push({ alias, sibling: next, linkedEntity, parent: finalName, owner });
|
|
4354
|
+
}
|
|
4355
|
+
pulledAs.set(pullKey, finalName);
|
|
4356
|
+
subsFor(owner).set(sibling, finalName);
|
|
4357
|
+
ownerOf.set(finalName, owner);
|
|
4358
|
+
seen.add(finalName);
|
|
4359
|
+
pulled.push({
|
|
4360
|
+
trait: copy,
|
|
4361
|
+
source: { type: "imported", alias, traitName: sibling },
|
|
4362
|
+
...linkedEntity !== void 0 ? { linkedEntity } : {}
|
|
4363
|
+
});
|
|
4364
|
+
}
|
|
4365
|
+
if (pulled.length === 0 && parentRewrites.size === 0) return errors;
|
|
4366
|
+
const applyRewrites = (rt) => {
|
|
4367
|
+
const subs = rt.trait.name ? parentRewrites.get(rt.trait.name) : void 0;
|
|
4368
|
+
if (subs) rt.trait = renameTraitEmbeds(rt.trait, subs);
|
|
4369
|
+
};
|
|
4370
|
+
for (const rt of resolved) applyRewrites(rt);
|
|
4371
|
+
for (const rt of pulled) applyRewrites(rt);
|
|
4372
|
+
const idByName = /* @__PURE__ */ new Map();
|
|
4373
|
+
for (const rt of [...resolved, ...pulled]) {
|
|
4374
|
+
if (rt.trait.name) idByName.set(rt.trait.name, rt.trait.id);
|
|
4375
|
+
}
|
|
4376
|
+
for (const rt of pulled) {
|
|
4377
|
+
const listens = rt.trait.listens;
|
|
4378
|
+
const owner = rt.trait.name ? ownerOf.get(rt.trait.name) : void 0;
|
|
4379
|
+
const subs = owner ? ownerSubs.get(owner) : void 0;
|
|
4380
|
+
if (!listens || listens.length === 0 || !subs) continue;
|
|
4381
|
+
let changed = false;
|
|
4382
|
+
const nextListens = listens.map((listen) => {
|
|
4383
|
+
const source = listen.source;
|
|
4384
|
+
if (!source || source.kind !== "trait") return listen;
|
|
4385
|
+
const target = subs.get(source.trait);
|
|
4386
|
+
if (target === void 0 || target === source.trait) return listen;
|
|
4387
|
+
changed = true;
|
|
4388
|
+
const traitId = idByName.get(target);
|
|
4389
|
+
return {
|
|
4390
|
+
...listen,
|
|
4391
|
+
source: { kind: "trait", trait: target, ...traitId ? { traitId } : {} }
|
|
4392
|
+
};
|
|
4393
|
+
});
|
|
4394
|
+
if (changed) rt.trait = { ...rt.trait, listens: nextListens };
|
|
4395
|
+
}
|
|
4396
|
+
refResolverLog.info("sibling-pull", {
|
|
4397
|
+
pulled: pulled.map((p) => ({
|
|
4398
|
+
trait: p.trait.name,
|
|
4399
|
+
owner: p.trait.name ? ownerOf.get(p.trait.name) : void 0,
|
|
4400
|
+
linkedEntity: p.linkedEntity ?? p.trait.linkedEntity
|
|
4401
|
+
}))
|
|
4402
|
+
});
|
|
4403
|
+
resolved.push(...pulled);
|
|
4404
|
+
return errors;
|
|
4405
|
+
}
|
|
4045
4406
|
/**
|
|
4046
4407
|
* Resolve a single trait reference.
|
|
4047
4408
|
*/
|
|
@@ -4582,4 +4943,4 @@ var InMemoryPersistence = class {
|
|
|
4582
4943
|
}
|
|
4583
4944
|
};
|
|
4584
4945
|
|
|
4585
|
-
export { CALLSITE_PAYLOAD_PREFIX, EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, MockPersistenceAdapter, StateMachineManager, TickScheduler, buildEmitsFromTraits, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, containsBindings, createContextFromBindings, createInitialTraitState, createMockPersistence, createTestExecutor, createTickScheduler, createUnifiedLoader, extractBindings, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isBrowser, isElectron, isNamespacedEvent, isNode, isValidDurationString, normalizeEventKey, parseDurationString, parseNamespacedEvent, preprocessSchema, processEvent, resolveCallSitePayloadCaptures, validateEventPayload, validatePayloadShapes };
|
|
4946
|
+
export { CALLSITE_PAYLOAD_PREFIX, EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, MockPersistenceAdapter, StateMachineManager, TickScheduler, buildEmitsFromTraits, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, containsBindings, createContextFromBindings, createInitialTraitState, createMockPersistence, createTestExecutor, createTickScheduler, createUnifiedLoader, deferEntityBindings, extractBindings, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isBrowser, isElectron, isNamespacedEvent, isNode, isValidDurationString, normalizeEventKey, parseDurationString, parseNamespacedEvent, preprocessSchema, processEvent, resolveCallSitePayloadCaptures, validateEventPayload, validatePayloadShapes };
|
package/dist/index.d.ts
CHANGED
|
@@ -1,10 +1,10 @@
|
|
|
1
|
-
import { B as BindingContext, f as EvaluationContextExtensions, P as PatternProps, E as EffectHandlers,
|
|
2
|
-
export {
|
|
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-
|
|
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-
|
|
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-CL03tjGU.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-CL03tjGU.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-A2h0EikK.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-A2h0EikK.js';
|
|
5
5
|
import { EvaluationContext, SExpressionEvaluator } from '@almadar/evaluator';
|
|
6
6
|
export { EvaluationContext, createMinimalContext } from '@almadar/evaluator';
|
|
7
|
-
import { TraitConfigObject, EventPayload, PatternConfig, EntityId, EntityField, EntityRow, EntityPersistence, ServiceParams, PayloadField, OrbitalDefinition, OrbitalSchema } from '@almadar/core';
|
|
7
|
+
import { RenderBindingMarker, SExpr, TraitConfigObject, EventPayload, PatternConfig, EntityId, EntityField, EntityRow, EntityPersistence, ServiceParams, PayloadField, OrbitalDefinition, OrbitalSchema } from '@almadar/core';
|
|
8
8
|
export { EntityField, normalizeCallSiteConfigToValues } from '@almadar/core';
|
|
9
9
|
export { ServerBridgeConfig, ServerBridgeState } from './ServerBridge.js';
|
|
10
10
|
export { OsHandlerContext, OsHandlerResult } from './createOsHandlers.js';
|
|
@@ -284,6 +284,28 @@ declare function interpolateProps(props: PatternProps, ctx: EvaluationContext):
|
|
|
284
284
|
* Interpolate a single value.
|
|
285
285
|
*/
|
|
286
286
|
declare function interpolateValue(value: unknown, ctx: EvaluationContext): unknown;
|
|
287
|
+
/**
|
|
288
|
+
* Value a deferred render-ui prop tree can carry: interpolated runtime
|
|
289
|
+
* values, raw pass-through S-expressions (`fn` lambdas), render-time
|
|
290
|
+
* binding markers, and nested arrays/records of the same. No `unknown`
|
|
291
|
+
* escape hatch.
|
|
292
|
+
*/
|
|
293
|
+
type DeferredPatternValue = RuntimePatternValue | RenderBindingMarker | SExpr | Date | readonly DeferredPatternValue[] | {
|
|
294
|
+
readonly [prop: string]: DeferredPatternValue;
|
|
295
|
+
};
|
|
296
|
+
/**
|
|
297
|
+
* Carry `@entity`-dependent prop leaves into slot content as
|
|
298
|
+
* `RenderBindingMarker`s instead of resolving them at flush time — the
|
|
299
|
+
* renderer (`@almadar/ui`'s SlotContentRenderer) evaluates each marker
|
|
300
|
+
* against the live entity store on every React render, the same model the
|
|
301
|
+
* compiled shell uses. Everything else resolves eagerly through the same
|
|
302
|
+
* `interpolateValue` path the non-deferring executor uses:
|
|
303
|
+
* - payload-referencing leaves stay eager (`@payload` is event-scoped and
|
|
304
|
+
* does not exist at render time);
|
|
305
|
+
* - `fn` render lambdas pass through raw (they are already render-time);
|
|
306
|
+
* - literal arrays (children lists) and plain objects recurse per item.
|
|
307
|
+
*/
|
|
308
|
+
declare function deferEntityBindings(value: SExpr, ctx: EvaluationContext, configHops?: number): DeferredPatternValue;
|
|
287
309
|
/**
|
|
288
310
|
* Check if a value contains any binding references.
|
|
289
311
|
*/
|
|
@@ -328,6 +350,14 @@ interface EffectExecutorOptions {
|
|
|
328
350
|
contextExtensions?: EvaluationContextExtensions;
|
|
329
351
|
/** Evaluator for resolving nested S-expression values in `set` (e.g., substrate operators) */
|
|
330
352
|
evaluator?: SExpressionEvaluator;
|
|
353
|
+
/**
|
|
354
|
+
* When true, render-ui args keep `@entity`-dependent prop leaves as
|
|
355
|
+
* `RenderBindingMarker`s for render-time evaluation instead of resolving
|
|
356
|
+
* them eagerly at flush time. Set by the client-side interpreter
|
|
357
|
+
* (`useTraitStateMachine`); server-side executors resolve eagerly so
|
|
358
|
+
* SSE-pushed props stay concrete.
|
|
359
|
+
*/
|
|
360
|
+
deferRenderBindings?: boolean;
|
|
331
361
|
}
|
|
332
362
|
/**
|
|
333
363
|
* EffectExecutor - Routes effects to handlers.
|
|
@@ -363,6 +393,7 @@ declare class EffectExecutor {
|
|
|
363
393
|
private strictBindings;
|
|
364
394
|
private contextExtensions?;
|
|
365
395
|
private evaluator?;
|
|
396
|
+
private deferRenderBindings;
|
|
366
397
|
constructor(options: EffectExecutorOptions);
|
|
367
398
|
private _evaluator?;
|
|
368
399
|
private getEvaluator;
|
|
@@ -585,6 +616,18 @@ declare class MockPersistenceAdapter implements PersistenceAdapter {
|
|
|
585
616
|
private storeNameById;
|
|
586
617
|
private config;
|
|
587
618
|
constructor(config?: MockPersistenceConfig);
|
|
619
|
+
/**
|
|
620
|
+
* Add owner columns discovered after construction.
|
|
621
|
+
*
|
|
622
|
+
* The adapter is built before any schema is registered, so schema-DERIVED
|
|
623
|
+
* owner columns (relation fields pointing at the `[identity]` entity) can
|
|
624
|
+
* only arrive later.
|
|
625
|
+
*
|
|
626
|
+
* ⚠️ Seeding is EAGER — `registerEntity()` seeds immediately — so callers must
|
|
627
|
+
* supply these columns BEFORE registering any orbital. Calling this afterwards
|
|
628
|
+
* silently stamps nothing.
|
|
629
|
+
*/
|
|
630
|
+
addOwnerFields(fields: readonly string[]): void;
|
|
588
631
|
/** Re-anchor the PRNG to the configured seed. Called before every
|
|
589
632
|
* re-seed loop so identical reseed sequences produce identical rows
|
|
590
633
|
* (timestamps + generated fields). Without this, the first
|
|
@@ -1033,4 +1076,4 @@ declare namespace index {
|
|
|
1033
1076
|
export { type index_ComposeBehaviorsInput as ComposeBehaviorsInput, type index_ComposeBehaviorsResult as ComposeBehaviorsResult, type index_EventWiringEntry as EventWiringEntry, type index_LayoutStrategy as LayoutStrategy, type index_PipeStep as PipeStep, index_applyEventWiring as applyEventWiring, index_composeBehaviors as composeBehaviors, index_detectLayoutStrategy as detectLayoutStrategy, index_pipeBehaviors as pipeBehaviors };
|
|
1034
1077
|
}
|
|
1035
1078
|
|
|
1036
|
-
export { BindingContext, CALLSITE_PAYLOAD_PREFIX, type ClientEventBus, type ComposeBehaviorsInput, type ComposeBehaviorsResult, type CreateClientEffectHandlersOptions, type CreateServerEffectHandlersOptions, type CronFields, EffectContext, EffectExecutor, type EffectExecutorOptions, EffectHandlers, EffectResult, type EntitySchema, type EventWiringEntry, ExecutionEnvironment, ImportChainLike, type LayoutStrategy, LoadResult, LoadedOrbital, LoadedSchema, MockPersistenceAdapter, type MockPersistenceConfig, type PayloadMismatch, type PayloadValidationFailure, PersistenceAdapter, type PipeStep, SchemaLoader, type ServerEffectResult, type SlotSetter, type TickHandle, TickScheduler, TraitDefinition, UnifiedLoaderOptions, applyEventWiring, buildEmitsFromTraits, composeBehaviors, index as composition, containsBindings, createClientEffectHandlers, createContextFromBindings, createMockPersistence, createServerEffectHandlers, createTestExecutor, createTickScheduler, createUnifiedLoader, cronMatches, cronMinuteKey, detectLayoutStrategy, extractBindings, formatPayloadValidationError, interpolateProps, interpolateValue, isValidCronExpression, isValidDurationString, parseCron, parseCronField, parseDurationString, pipeBehaviors, resolveCallSitePayloadCaptures, validateEventPayload, validatePayloadShapes };
|
|
1079
|
+
export { BindingContext, CALLSITE_PAYLOAD_PREFIX, type ClientEventBus, type ComposeBehaviorsInput, type ComposeBehaviorsResult, type CreateClientEffectHandlersOptions, type CreateServerEffectHandlersOptions, type CronFields, type DeferredPatternValue, EffectContext, EffectExecutor, type EffectExecutorOptions, EffectHandlers, EffectResult, type EntitySchema, type EventWiringEntry, ExecutionEnvironment, ImportChainLike, type LayoutStrategy, LoadResult, LoadedOrbital, LoadedSchema, MockPersistenceAdapter, type MockPersistenceConfig, type PayloadMismatch, type PayloadValidationFailure, PersistenceAdapter, type PipeStep, SchemaLoader, type ServerEffectResult, type SlotSetter, type TickHandle, TickScheduler, TraitDefinition, UnifiedLoaderOptions, applyEventWiring, buildEmitsFromTraits, composeBehaviors, index as composition, containsBindings, createClientEffectHandlers, createContextFromBindings, createMockPersistence, createServerEffectHandlers, createTestExecutor, createTickScheduler, createUnifiedLoader, cronMatches, cronMinuteKey, deferEntityBindings, detectLayoutStrategy, extractBindings, formatPayloadValidationError, interpolateProps, interpolateValue, isValidCronExpression, isValidDurationString, parseCron, parseCronField, parseDurationString, pipeBehaviors, resolveCallSitePayloadCaptures, validateEventPayload, validatePayloadShapes };
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { EffectExecutor, createContextFromBindings } from './chunk-
|
|
2
|
-
export { CALLSITE_PAYLOAD_PREFIX, EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, MockPersistenceAdapter, StateMachineManager, TickScheduler, buildEmitsFromTraits, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, containsBindings, createContextFromBindings, createInitialTraitState, createMinimalContext, createMockPersistence, createTestExecutor, createTickScheduler, createUnifiedLoader, extractBindings, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isBrowser, isElectron, isNamespacedEvent, isNode, isValidDurationString, normalizeCallSiteConfigToValues, normalizeEventKey, parseDurationString, parseNamespacedEvent, preprocessSchema, processEvent, resolveCallSitePayloadCaptures, validateEventPayload, validatePayloadShapes } from './chunk-
|
|
1
|
+
import { EffectExecutor, createContextFromBindings } from './chunk-FIBEYLME.js';
|
|
2
|
+
export { CALLSITE_PAYLOAD_PREFIX, EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, MockPersistenceAdapter, StateMachineManager, TickScheduler, buildEmitsFromTraits, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, containsBindings, createContextFromBindings, createInitialTraitState, createMinimalContext, createMockPersistence, createTestExecutor, createTickScheduler, createUnifiedLoader, deferEntityBindings, extractBindings, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isBrowser, isElectron, isNamespacedEvent, isNode, isValidDurationString, normalizeCallSiteConfigToValues, normalizeEventKey, parseDurationString, parseNamespacedEvent, preprocessSchema, processEvent, resolveCallSitePayloadCaptures, validateEventPayload, validatePayloadShapes } from './chunk-FIBEYLME.js';
|
|
3
3
|
export { cronMatches, cronMinuteKey, isValidCronExpression, parseCron, parseCronField } from './chunk-OU3ITB5S.js';
|
|
4
4
|
import './chunk-T4VDAB4C.js';
|
|
5
5
|
export { PERF_NAMESPACE, RendererContractViolationError, adjustSchemaForMockData, aggregateSlotContent, assertIsMultiSourceSlotManager, assertIsSlotManager, bindEventBus, bindTraitStateGetter, buildMockData, buildOrbitalsByTrait, clearPerf, createSlotSetter, ensureVerificationApi, getOrbitalVerification, perfEnd, perfStart, perfStore, perfTime, prepareSchemaForPreview, pushPerfEntry, validateSlotContent, wrapCallbackForEvent } from './chunk-FOFLEZRJ.js';
|
|
@@ -3,6 +3,25 @@ import { TraitId, EventId, SExpr, TraitEventListener, AgentContext, LlmContext,
|
|
|
3
3
|
|
|
4
4
|
/** Alias for ResolvedPatternProps to avoid breaking internal consumers */
|
|
5
5
|
type PatternProps = ResolvedPatternProps;
|
|
6
|
+
/**
|
|
7
|
+
* Value a render-ui pattern prop can carry AFTER interpolation. Mirrors
|
|
8
|
+
* `FieldValue` but extends with `RuntimeRenderPattern` so nested pattern
|
|
9
|
+
* configs (children, slot props that are themselves render-ui nodes)
|
|
10
|
+
* round-trip without an `unknown` escape hatch.
|
|
11
|
+
*/
|
|
12
|
+
type RuntimePatternValue = string | number | boolean | null | undefined | EntityRow | EntityRow[] | readonly RuntimePatternValue[] | RuntimeRenderPattern;
|
|
13
|
+
/**
|
|
14
|
+
* Shape of a render-ui pattern AFTER interpolation, as the runtime hands
|
|
15
|
+
* it to `EffectHandlers.renderUI`. Different from `ResolvedPatternProps`
|
|
16
|
+
* (`@almadar/core`) because the post-interpolation pattern carries
|
|
17
|
+
* resolved EntityRow values (e.g. `{ entity: <row> }` from `@payload.row`)
|
|
18
|
+
* not just primitives. Used by render-ui observability helpers to narrow
|
|
19
|
+
* safely without `unknown` casts.
|
|
20
|
+
*/
|
|
21
|
+
interface RuntimeRenderPattern {
|
|
22
|
+
readonly [prop: string]: RuntimePatternValue;
|
|
23
|
+
}
|
|
24
|
+
|
|
6
25
|
type ConfigContext = TraitConfig;
|
|
7
26
|
/**
|
|
8
27
|
* Event structure for cross-trait communication.
|
|
@@ -432,7 +451,7 @@ interface TransitionObserver {
|
|
|
432
451
|
guardResult?: boolean;
|
|
433
452
|
effects: Array<{
|
|
434
453
|
type: string;
|
|
435
|
-
args:
|
|
454
|
+
args: SExpr[];
|
|
436
455
|
status: "executed" | "failed" | "skipped";
|
|
437
456
|
error?: string;
|
|
438
457
|
durationMs?: number;
|
|
@@ -444,4 +463,4 @@ interface TransitionObserver {
|
|
|
444
463
|
*/
|
|
445
464
|
declare const HANDLER_MANIFEST: Record<ExecutionEnvironment, string[]>;
|
|
446
465
|
|
|
447
|
-
export { type BindingContext as B, type ConfigContext as C, type EffectHandlers as E, HANDLER_MANIFEST as H, type IEventBus as I, type PatternProps as P, type RuntimeEvent as R, type TraitDefinition as T, type Unsubscribe as U, type EventListener as a, type RuntimeConfig as b, type TransitionObserver as c, type TraitState as d, type TransitionResult as e, type EvaluationContextExtensions as f, type
|
|
466
|
+
export { type BindingContext as B, type ConfigContext as C, type EffectHandlers as E, HANDLER_MANIFEST as H, type IEventBus as I, type PatternProps as P, type RuntimeEvent as R, type TraitDefinition as T, type Unsubscribe as U, type EventListener as a, type RuntimeConfig as b, type TransitionObserver as c, type TraitState as d, type TransitionResult as e, type EvaluationContextExtensions as f, type RuntimePatternValue as g, type EffectContext as h, type ExecutionEnvironment as i, type EffectResult as j, type BrowserFileMeta as k, type BrowserFilePickerOptions as l, type BrowserGeolocationOptions as m, type BrowserGeolocationPosition as n, type Effect as o };
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@almadar/runtime",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.45.0",
|
|
4
4
|
"description": "Interpreted runtime for Almadar orbital applications (OrbitalServerRuntime)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -52,11 +52,11 @@
|
|
|
52
52
|
"access": "public"
|
|
53
53
|
},
|
|
54
54
|
"dependencies": {
|
|
55
|
-
"@almadar/core": "^10.
|
|
56
|
-
"@almadar/evaluator": "^2.
|
|
55
|
+
"@almadar/core": "^10.43.0",
|
|
56
|
+
"@almadar/evaluator": "^2.38.0",
|
|
57
57
|
"@almadar/logger": "^1.10.0",
|
|
58
58
|
"@almadar/server": "^2.29.0",
|
|
59
|
-
"@almadar/std": "^16.
|
|
59
|
+
"@almadar/std": "^16.153.0"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
62
|
"express": "^5.0.0"
|