@almadar/runtime 6.44.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-Dz0oubQ_.d.ts → OrbitalServerRuntime-A2h0EikK.d.ts} +21 -1
- package/dist/OrbitalServerRuntime.d.ts +2 -2
- package/dist/OrbitalServerRuntime.js +68 -10
- package/dist/ServerBridge.d.ts +1 -1
- package/dist/{chunk-EJHMWSUS.js → chunk-FIBEYLME.js} +65 -4
- package/dist/createOsHandlers.d.ts +1 -1
- package/dist/index.d.ts +37 -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
|
}
|
|
@@ -1341,6 +1348,19 @@ declare class OrbitalServerRuntime {
|
|
|
1341
1348
|
setDefaultUser(user: UserContext | undefined): void;
|
|
1342
1349
|
/** The viewer a dev host is currently presenting the app as. */
|
|
1343
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;
|
|
1344
1364
|
/**
|
|
1345
1365
|
* Process an event for an orbital
|
|
1346
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,7 @@ 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 { DEFAULT_VIEWER, buildResolvedTraitConfigs, isInlineTrait, isEntityCall, applyListenPayloadMapping, normalizeUserContext } from '@almadar/core';
|
|
10
|
+
import { DEFAULT_VIEWER, buildResolvedTraitConfigs, isInlineTrait, isEntityCall, applyListenPayloadMapping, normalizeUserContext, isRuntimeEntity } from '@almadar/core';
|
|
11
11
|
import { ownerFieldsFromSchema, identityEntityName } from '@almadar/core/mock';
|
|
12
12
|
|
|
13
13
|
// src/identity/routing.ts
|
|
@@ -650,6 +650,16 @@ var OrbitalServerRuntime = class {
|
|
|
650
650
|
const routeKey = eventRouteKey(bareEvent, listener.eventId);
|
|
651
651
|
const cleanup = this.eventBus.on(routeKey, async (event) => {
|
|
652
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
|
+
}
|
|
653
663
|
if (this.config.debug) {
|
|
654
664
|
xOrbitalLog.debug("listen:received", () => ({
|
|
655
665
|
receiverOrbital: orbitalName,
|
|
@@ -915,6 +925,34 @@ var OrbitalServerRuntime = class {
|
|
|
915
925
|
// ==========================================================================
|
|
916
926
|
// Event Processing
|
|
917
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
|
+
}
|
|
918
956
|
/**
|
|
919
957
|
* Process an event for an orbital
|
|
920
958
|
*
|
|
@@ -1010,9 +1048,10 @@ var OrbitalServerRuntime = class {
|
|
|
1010
1048
|
}
|
|
1011
1049
|
}
|
|
1012
1050
|
const entityByTrait = {};
|
|
1013
|
-
for (const
|
|
1051
|
+
for (const trait of registered.traits) {
|
|
1052
|
+
const fields = registered.traitFieldStates.get(this.sharedFieldKey(registered, trait.name));
|
|
1014
1053
|
if (fields && Object.keys(fields).length > 0) {
|
|
1015
|
-
entityByTrait[name] = fields;
|
|
1054
|
+
entityByTrait[trait.name] = fields;
|
|
1016
1055
|
}
|
|
1017
1056
|
}
|
|
1018
1057
|
const results = registered.manager.sendEvent(
|
|
@@ -1127,6 +1166,9 @@ var OrbitalServerRuntime = class {
|
|
|
1127
1166
|
if (stamp.eventId === void 0 && emitContract?.eventId !== void 0) {
|
|
1128
1167
|
stamp.eventId = emitContract.eventId;
|
|
1129
1168
|
}
|
|
1169
|
+
if (originClientId !== void 0 && stamp.originClientId === void 0) {
|
|
1170
|
+
stamp.originClientId = originClientId;
|
|
1171
|
+
}
|
|
1130
1172
|
this.eventBus.emit(event, eventPayload, stamp, eventRouteKey(event, stamp.eventId));
|
|
1131
1173
|
const emittedItem = { event, payload: eventPayload, source: stamp };
|
|
1132
1174
|
emittedEvents.push(emittedItem);
|
|
@@ -1155,10 +1197,11 @@ var OrbitalServerRuntime = class {
|
|
|
1155
1197
|
}
|
|
1156
1198
|
},
|
|
1157
1199
|
set: async (targetId, field, value) => {
|
|
1158
|
-
|
|
1200
|
+
const fieldKey = this.sharedFieldKey(registered, traitName);
|
|
1201
|
+
let fieldState = registered.traitFieldStates.get(fieldKey);
|
|
1159
1202
|
if (!fieldState) {
|
|
1160
1203
|
fieldState = {};
|
|
1161
|
-
registered.traitFieldStates.set(
|
|
1204
|
+
registered.traitFieldStates.set(fieldKey, fieldState);
|
|
1162
1205
|
}
|
|
1163
1206
|
fieldState[field] = value;
|
|
1164
1207
|
effectResults.push({
|
|
@@ -1531,7 +1574,10 @@ var OrbitalServerRuntime = class {
|
|
|
1531
1574
|
bindings: bindingsRef ?? {},
|
|
1532
1575
|
context: contextRef ?? { traitName, orbitalName: registered.schema.name, state: "unknown", transition: "unknown" },
|
|
1533
1576
|
debug: this.config.debug,
|
|
1534
|
-
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
|
|
1535
1581
|
});
|
|
1536
1582
|
for (const innerEffect of atomicEffects) {
|
|
1537
1583
|
if (atomicFailed) break;
|
|
@@ -1619,7 +1665,7 @@ var OrbitalServerRuntime = class {
|
|
|
1619
1665
|
};
|
|
1620
1666
|
}
|
|
1621
1667
|
const entityFieldDefaults = collectDeclaredEntityDefaults(registered.entity);
|
|
1622
|
-
const traitFieldState = registered.traitFieldStates.get(traitName);
|
|
1668
|
+
const traitFieldState = registered.traitFieldStates.get(this.sharedFieldKey(registered, traitName));
|
|
1623
1669
|
if (entityFieldDefaults || traitFieldState) {
|
|
1624
1670
|
bindings.entity = {
|
|
1625
1671
|
...entityFieldDefaults ?? {},
|
|
@@ -1644,7 +1690,19 @@ var OrbitalServerRuntime = class {
|
|
|
1644
1690
|
bindings,
|
|
1645
1691
|
context,
|
|
1646
1692
|
debug: this.config.debug,
|
|
1647
|
-
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
|
|
1648
1706
|
});
|
|
1649
1707
|
await executor.executeAll(effects);
|
|
1650
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;
|
|
@@ -4882,4 +4943,4 @@ var InMemoryPersistence = class {
|
|
|
4882
4943
|
}
|
|
4883
4944
|
};
|
|
4884
4945
|
|
|
4885
|
-
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;
|
|
@@ -1045,4 +1076,4 @@ declare namespace index {
|
|
|
1045
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 };
|
|
1046
1077
|
}
|
|
1047
1078
|
|
|
1048
|
-
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"
|