@almadar/runtime 6.73.0 → 6.75.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-BiEntWd-.d.ts → OrbitalServerRuntime-Buvz7dd7.d.ts} +21 -18
- package/dist/OrbitalServerRuntime.d.ts +2 -2
- package/dist/OrbitalServerRuntime.js +40 -15
- package/dist/ServerBridge.d.ts +1 -1
- package/dist/{chunk-H7HQQVQJ.js → chunk-CEYC3Z2O.js} +93 -51
- package/dist/createOsHandlers.d.ts +1 -1
- package/dist/index.d.ts +39 -16
- package/dist/index.js +3 -6
- package/dist/{types-CWaIuEQn.d.ts → types-BO4tbEPp.d.ts} +0 -2
- package/package.json +4 -4
|
@@ -1,6 +1,6 @@
|
|
|
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, B as BindingContext, g as EffectContext, S as ServiceCallContext, E as EffectHandlers } from './types-
|
|
3
|
-
import { EventPayload, EventId, EntityRow, UserContext, ServiceParams, EntityAccessPolicies, Orbital, ServiceCallResult, TraitConfig, DeclaredTraitConfig, Entity, OrbitalSchema, Trait, PatternConfig, ResolvedPatternProps,
|
|
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, B as BindingContext, g as EffectContext, S as ServiceCallContext, E as EffectHandlers } from './types-BO4tbEPp.js';
|
|
3
|
+
import { EventPayload, EventId, EntityRow, UserContext, ServiceParams, EntityAccessPolicies, Orbital, ServiceCallResult, TraitConfig, DeclaredTraitConfig, Entity, OrbitalSchema, Trait, PatternConfig, ResolvedPatternProps, BusEventSource, RawUserClaims, OrbitalDefinition, TraitTick } from '@almadar/core';
|
|
4
4
|
|
|
5
5
|
/**
|
|
6
6
|
* EventBus - Platform-Agnostic Pub/Sub Implementation
|
|
@@ -538,7 +538,7 @@ interface CreateServerEffectHandlersOptions {
|
|
|
538
538
|
* transition, call this factory again.
|
|
539
539
|
*
|
|
540
540
|
* Intentionally does NOT implement:
|
|
541
|
-
* - `renderUI` / `
|
|
541
|
+
* - `renderUI` / `navigate` — these are client-side, provided
|
|
542
542
|
* by `createClientEffectHandlers`. A mock runtime merges both handler
|
|
543
543
|
* sets.
|
|
544
544
|
* - `os/watch-*` observers — these are a no-op outside the server.
|
|
@@ -1030,19 +1030,19 @@ declare function parseNamespacedEvent(eventName: string): {
|
|
|
1030
1030
|
|
|
1031
1031
|
/**
|
|
1032
1032
|
* Client-side effect tuple shipped in `OrbitalEventResponse.clientEffects`.
|
|
1033
|
-
* Restricted to the
|
|
1034
|
-
* UI: render-ui (slot mutation
|
|
1033
|
+
* Restricted to the effect kinds the client knows how to apply to the
|
|
1034
|
+
* UI: render-ui (slot mutation, including the `toast` slot that carries
|
|
1035
|
+
* what used to be the separate notify effect) and navigate (route change).
|
|
1035
1036
|
* Server-only effects (persist, set, fetch, ...) execute on the server and
|
|
1036
1037
|
* surface their results via `effectResults` and `emittedEvents`, not here.
|
|
1037
1038
|
*
|
|
1038
1039
|
* Shape note: the wire form is broader than `RenderUIEffect` /
|
|
1039
|
-
* `NavigateEffect`
|
|
1040
|
-
*
|
|
1041
|
-
*
|
|
1042
|
-
*
|
|
1043
|
-
*
|
|
1044
|
-
*
|
|
1045
|
-
* instead of `unknown[]`.
|
|
1040
|
+
* `NavigateEffect` from `@almadar/core/types/effect.ts` in two places — the
|
|
1041
|
+
* runtime appends an interpolated `props` object plus an optional `priority`
|
|
1042
|
+
* slot to render-ui (slot 4 + 5), and `navigate`'s optional argument may
|
|
1043
|
+
* surface as `undefined` rather than absent. The local union spells those
|
|
1044
|
+
* variants out explicitly so consumers (ServerBridge.tsx parser, debugger
|
|
1045
|
+
* inspector) get accurate completions instead of `unknown[]`.
|
|
1046
1046
|
*
|
|
1047
1047
|
* `slot` is a plain `string` in this wire shape (not `UISlot`'s literal
|
|
1048
1048
|
* union) because the runtime forwards the raw string from the trait's
|
|
@@ -1054,10 +1054,7 @@ type ClientNavigateTuple = ['navigate', string] | ['navigate', string, Record<st
|
|
|
1054
1054
|
crumb?: string;
|
|
1055
1055
|
}];
|
|
1056
1056
|
type ClientNavigateBackTuple = ['navigate-back'];
|
|
1057
|
-
type
|
|
1058
|
-
type?: string;
|
|
1059
|
-
}];
|
|
1060
|
-
type ClientEffectTuple = ClientRenderUITuple | ClientNavigateTuple | ClientNavigateBackTuple | ClientNotifyTuple;
|
|
1057
|
+
type ClientEffectTuple = ClientRenderUITuple | ClientNavigateTuple | ClientNavigateBackTuple;
|
|
1061
1058
|
|
|
1062
1059
|
/** @deprecated Use OrbitalSchema from @almadar/core */
|
|
1063
1060
|
type RuntimeOrbitalSchema = OrbitalSchema;
|
|
@@ -1174,7 +1171,7 @@ interface OrbitalEventResponse {
|
|
|
1174
1171
|
payload?: EventPayload;
|
|
1175
1172
|
source?: BusEventSource;
|
|
1176
1173
|
}>;
|
|
1177
|
-
/** Client-side effects to execute (render-ui, navigate
|
|
1174
|
+
/** Client-side effects to execute (render-ui, navigate) */
|
|
1178
1175
|
clientEffects?: ClientEffectTuple[];
|
|
1179
1176
|
/**
|
|
1180
1177
|
* Same effects as `clientEffects`, paired with the producing trait name.
|
|
@@ -1638,6 +1635,12 @@ declare class OrbitalServerRuntime {
|
|
|
1638
1635
|
* entity, its auxiliary entities, then other registered orbitals' primary
|
|
1639
1636
|
* entities (cross-orbital binds like a membership rail in the chat page). */
|
|
1640
1637
|
private isSharedEntity;
|
|
1638
|
+
/** Names of an entity's `@intrinsic` fields — trait-owned view state
|
|
1639
|
+
* (`ChatMessage.activeChannel`, `ChannelMember.pendingChannelId`, …) that
|
|
1640
|
+
* is NEVER a persisted column. Resolves the entity by name the same way
|
|
1641
|
+
* `isSharedEntity` does: the orbital's own entity, its auxiliary
|
|
1642
|
+
* entities, then other registered orbitals' primary entities. */
|
|
1643
|
+
private intrinsicFieldNames;
|
|
1641
1644
|
/**
|
|
1642
1645
|
* Process an event for an orbital
|
|
1643
1646
|
*
|
|
@@ -1763,4 +1766,4 @@ declare class OrbitalServerRuntime {
|
|
|
1763
1766
|
*/
|
|
1764
1767
|
declare function createOrbitalServerRuntime(config?: OrbitalServerRuntimeConfig): OrbitalServerRuntime;
|
|
1765
1768
|
|
|
1766
|
-
export { isElectron as A, isNamespacedEvent as B, type CreateServerEffectHandlersOptions as C, isNode as D, type EntitySharingMap as E, normalizeEventKey as F, parseNamespacedEvent as G, preprocessSchema as H, type ImportChainLike as I, processEvent as J, type ClientEffectTuple as K, type LoadResult as L, type ClientNavigateBackTuple as M, type ClientNavigateTuple as N, type OrbitalEventRequest as O, type PersistenceAdapter as P, type
|
|
1769
|
+
export { isElectron as A, isNamespacedEvent as B, type CreateServerEffectHandlersOptions as C, isNode as D, type EntitySharingMap as E, normalizeEventKey as F, parseNamespacedEvent as G, preprocessSchema as H, type ImportChainLike as I, processEvent as J, type ClientEffectTuple as K, type LoadResult as L, type ClientNavigateBackTuple as M, type ClientNavigateTuple as N, type OrbitalEventRequest as O, type PersistenceAdapter as P, type ClientRenderUITuple as Q, type RegisteredOrbital as R, type SchemaLoader as S, type LiveBroadcastItem as T, type UnifiedLoaderOptions as U, type LoaderConfig as V, OrbitalServerRuntime as W, type RuntimeTraitTick as X, createOrbitalServerRuntime as Y, type LoadedSchema as a, type LoadedOrbital as b, EventBus as c, type EventNamespaceMap as d, InMemoryPersistence as e, LIFECYCLE_EVENTS as f, type OrbitalEventResponse as g, type OrbitalServerRuntimeConfig as h, type PreprocessOptions as i, type PreprocessResult as j, type PreprocessedSchema as k, type ProcessEventOptions as l, type RuntimeOrbital as m, type RuntimeOrbitalSchema as n, type RuntimeTrait as o, type ServerEffectResult as p, StateMachineManager as q, collectDeclaredConfigDefaults as r, collectDeclaredEntityDefaults as s, createInitialTraitState as t, createServerEffectHandlers as u, findInitialState as v, findTransition as w, getIsolatedCollectionName as x, getNamespacedEvent as y, isBrowser as z };
|
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
import 'express';
|
|
2
|
-
export { K as ClientEffectTuple, M as ClientNavigateBackTuple, N as ClientNavigateTuple, Q as
|
|
3
|
-
import './types-
|
|
2
|
+
export { K as ClientEffectTuple, M as ClientNavigateBackTuple, N as ClientNavigateTuple, Q as ClientRenderUITuple, e as InMemoryPersistence, T as LiveBroadcastItem, V as LoaderConfig, O as OrbitalEventRequest, g as OrbitalEventResponse, W as OrbitalServerRuntime, h as OrbitalServerRuntimeConfig, P as PersistenceAdapter, R as RegisteredOrbital, m as RuntimeOrbital, n as RuntimeOrbitalSchema, o as RuntimeTrait, X as RuntimeTraitTick, r as collectDeclaredConfigDefaults, Y as createOrbitalServerRuntime } from './OrbitalServerRuntime-Buvz7dd7.js';
|
|
3
|
+
import './types-BO4tbEPp.js';
|
|
4
4
|
import '@almadar/core';
|
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { createTickScheduler, EventBus, createUnifiedLoader, MockPersistenceAdapter, InMemoryPersistence, preprocessSchema, normalizeCallSiteConfigToValues, StateMachineManager, parseDurationString, validateEventPayload, formatPayloadValidationError, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, EffectExecutor, LIFECYCLE_EVENTS } from './chunk-
|
|
2
|
-
export { InMemoryPersistence, collectDeclaredConfigDefaults } from './chunk-
|
|
1
|
+
import { createTickScheduler, EventBus, createUnifiedLoader, MockPersistenceAdapter, InMemoryPersistence, preprocessSchema, normalizeCallSiteConfigToValues, StateMachineManager, parseDurationString, validateEventPayload, formatPayloadValidationError, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, EffectExecutor, LIFECYCLE_EVENTS } from './chunk-CEYC3Z2O.js';
|
|
2
|
+
export { InMemoryPersistence, collectDeclaredConfigDefaults } from './chunk-CEYC3Z2O.js';
|
|
3
3
|
import { isValidCronExpression } from './chunk-OU3ITB5S.js';
|
|
4
4
|
import { createContextFromBindings, checkMutationAccess, applyRowAccess, accessDeniedMessage } from './chunk-ZWAOJT6R.js';
|
|
5
5
|
import './chunk-T4VDAB4C.js';
|
|
@@ -8,7 +8,7 @@ import './chunk-MLKGABMK.js';
|
|
|
8
8
|
import { createLogger } from '@almadar/logger';
|
|
9
9
|
import * as nodeModule from 'module';
|
|
10
10
|
import { evaluateListenPayloadExpr, evaluateGuard, evaluate } from '@almadar/evaluator';
|
|
11
|
-
import { DEFAULT_VIEWER, buildResolvedTraitConfigs, collectCallsiteCaptureChildren, isInlineTrait, isEntityCall, applyListenPayloadMapping, personaFromIdentityRow, normalizeUserContext, isRuntimeEntity, isPageReference } from '@almadar/core';
|
|
11
|
+
import { DEFAULT_VIEWER, buildResolvedTraitConfigs, collectCallsiteCaptureChildren, isInlineTrait, isEntityCall, applyListenPayloadMapping, personaFromIdentityRow, normalizeUserContext, isRuntimeEntity, omitFrameFields, isPageReference } from '@almadar/core';
|
|
12
12
|
import { ownerFieldsFromSchema, identityEntityName, entityAccessPoliciesByStoreKey, entityAccessPolicies } from '@almadar/core/mock';
|
|
13
13
|
import { getPatternFieldsContract } from '@almadar/core/patterns';
|
|
14
14
|
|
|
@@ -1266,6 +1266,24 @@ var OrbitalServerRuntime = class {
|
|
|
1266
1266
|
}
|
|
1267
1267
|
return false;
|
|
1268
1268
|
}
|
|
1269
|
+
/** Names of an entity's `@intrinsic` fields — trait-owned view state
|
|
1270
|
+
* (`ChatMessage.activeChannel`, `ChannelMember.pendingChannelId`, …) that
|
|
1271
|
+
* is NEVER a persisted column. Resolves the entity by name the same way
|
|
1272
|
+
* `isSharedEntity` does: the orbital's own entity, its auxiliary
|
|
1273
|
+
* entities, then other registered orbitals' primary entities. */
|
|
1274
|
+
intrinsicFieldNames(registered, entityName) {
|
|
1275
|
+
const namesOf = (entity) => entity.fields.filter((field) => field.intrinsic === true && typeof field.name === "string").map((field) => field.name);
|
|
1276
|
+
if (registered.entity.name === entityName) return namesOf(registered.entity);
|
|
1277
|
+
for (const aux of registered.schema.auxiliaryEntities ?? []) {
|
|
1278
|
+
if (typeof aux === "object" && !isEntityCall(aux) && aux.name === entityName) {
|
|
1279
|
+
return namesOf(aux);
|
|
1280
|
+
}
|
|
1281
|
+
}
|
|
1282
|
+
for (const other of this.orbitals.values()) {
|
|
1283
|
+
if (other.entity.name === entityName) return namesOf(other.entity);
|
|
1284
|
+
}
|
|
1285
|
+
return [];
|
|
1286
|
+
}
|
|
1269
1287
|
/**
|
|
1270
1288
|
* Process an event for an orbital
|
|
1271
1289
|
*
|
|
@@ -1321,8 +1339,14 @@ var OrbitalServerRuntime = class {
|
|
|
1321
1339
|
const { event, eventId, payload, entityId, user: requestUser, clientId } = request;
|
|
1322
1340
|
const viewer = normalizeUserContext(requestUser) ?? this.config.defaultUser;
|
|
1323
1341
|
const targetTrait = request.targetTrait ?? payload?.["_targetTrait"];
|
|
1342
|
+
const activeTraits = payload?._activeTraits;
|
|
1343
|
+
const dispatchTargetTraits = registered.traits.filter((trait) => {
|
|
1344
|
+
if (targetTrait !== void 0) return trait.name === targetTrait;
|
|
1345
|
+
if (activeTraits && activeTraits.length > 0 && !activeTraits.includes(trait.name)) return false;
|
|
1346
|
+
return registered.manager.canHandleEvent(trait.name, event, entityId, eventId);
|
|
1347
|
+
});
|
|
1324
1348
|
const validationFailures = [];
|
|
1325
|
-
for (const trait of
|
|
1349
|
+
for (const trait of dispatchTargetTraits) {
|
|
1326
1350
|
const eventSchema = trait.stateMachine?.events?.find((e) => e.key === event);
|
|
1327
1351
|
if (eventSchema?.payloadSchema && eventSchema.payloadSchema.length > 0) {
|
|
1328
1352
|
validationFailures.push(
|
|
@@ -1344,7 +1368,6 @@ var OrbitalServerRuntime = class {
|
|
|
1344
1368
|
const clientEffects = [];
|
|
1345
1369
|
const clientEffectsByTrait = [];
|
|
1346
1370
|
const effectResults = [];
|
|
1347
|
-
const activeTraits = payload?._activeTraits;
|
|
1348
1371
|
const cleanPayload = payload ? { ...payload } : void 0;
|
|
1349
1372
|
if (cleanPayload) {
|
|
1350
1373
|
delete cleanPayload._activeTraits;
|
|
@@ -1577,7 +1600,8 @@ var OrbitalServerRuntime = class {
|
|
|
1577
1600
|
try {
|
|
1578
1601
|
switch (opAction) {
|
|
1579
1602
|
case "create": {
|
|
1580
|
-
const
|
|
1603
|
+
const createIntrinsicFields = this.intrinsicFieldNames(registered, opEntityType);
|
|
1604
|
+
const createData = createIntrinsicFields.length > 0 ? omitFrameFields(opRest[0] || {}, createIntrinsicFields) : opRest[0] || {};
|
|
1581
1605
|
const { id: newId } = await this.persistence.create(opEntityType, createData);
|
|
1582
1606
|
batchResults.push({ ...createData, action: "create", entityType: opEntityType, id: newId });
|
|
1583
1607
|
completed.push({ action: "create", entityType: opEntityType, id: newId });
|
|
@@ -1585,7 +1609,8 @@ var OrbitalServerRuntime = class {
|
|
|
1585
1609
|
}
|
|
1586
1610
|
case "update": {
|
|
1587
1611
|
const updateId = opRest[0];
|
|
1588
|
-
const
|
|
1612
|
+
const updateIntrinsicFields = this.intrinsicFieldNames(registered, opEntityType);
|
|
1613
|
+
const updateData = updateIntrinsicFields.length > 0 ? omitFrameFields(opRest[1] || {}, updateIntrinsicFields) : opRest[1] || {};
|
|
1589
1614
|
await this.persistence.update(opEntityType, updateId, updateData);
|
|
1590
1615
|
const updated = await this.persistence.getById(opEntityType, updateId);
|
|
1591
1616
|
batchResults.push({ ...updated || updateData, action: "update", entityType: opEntityType, id: updateId });
|
|
@@ -1625,6 +1650,10 @@ var OrbitalServerRuntime = class {
|
|
|
1625
1650
|
return;
|
|
1626
1651
|
}
|
|
1627
1652
|
const type = targetEntityType || entityType;
|
|
1653
|
+
if ((action === "create" || action === "update") && data !== void 0) {
|
|
1654
|
+
const intrinsicFields = this.intrinsicFieldNames(registered, type);
|
|
1655
|
+
if (intrinsicFields.length > 0) data = omitFrameFields(data, intrinsicFields);
|
|
1656
|
+
}
|
|
1628
1657
|
let resultData;
|
|
1629
1658
|
const sizeBefore = (await this.persistence.list(type)).length;
|
|
1630
1659
|
let deniedReason;
|
|
@@ -1952,7 +1981,8 @@ var OrbitalServerRuntime = class {
|
|
|
1952
1981
|
contextExtensions: this.config.contextExtensions,
|
|
1953
1982
|
// Same render-time marker boundary as the outer executor
|
|
1954
1983
|
// (including the [shared]-defers-regardless-of-persistence rule).
|
|
1955
|
-
deferRenderBindings: registered.entity === void 0 || isRuntimeEntity(registered.entity) || registered.entity.shared === true
|
|
1984
|
+
deferRenderBindings: registered.entity === void 0 || isRuntimeEntity(registered.entity) || registered.entity.shared === true,
|
|
1985
|
+
resolveIntrinsicFields: (type) => this.intrinsicFieldNames(registered, type)
|
|
1956
1986
|
});
|
|
1957
1987
|
for (const innerEffect of atomicEffects) {
|
|
1958
1988
|
if (atomicFailed) break;
|
|
@@ -2003,12 +2033,6 @@ var OrbitalServerRuntime = class {
|
|
|
2003
2033
|
navigateBack: () => {
|
|
2004
2034
|
pushClientEffect(["navigate-back"]);
|
|
2005
2035
|
},
|
|
2006
|
-
notify: (message, type) => {
|
|
2007
|
-
if (this.config.debug) {
|
|
2008
|
-
effectLog.info("notify", { type, message });
|
|
2009
|
-
}
|
|
2010
|
-
pushClientEffect(["notify", message, { type }]);
|
|
2011
|
-
},
|
|
2012
2036
|
log: (message, level) => {
|
|
2013
2037
|
if (level === "error") {
|
|
2014
2038
|
dynamicLog.error(message);
|
|
@@ -2117,7 +2141,8 @@ var OrbitalServerRuntime = class {
|
|
|
2117
2141
|
// client-held by contract (one live frame across bound traits), and
|
|
2118
2142
|
// the eager clobber pinned the chat composer's controlled input to
|
|
2119
2143
|
// the server's flush-time "" on every keystroke round-trip.
|
|
2120
|
-
deferRenderBindings: registered.entity === void 0 || isRuntimeEntity(registered.entity) || registered.entity.shared === true
|
|
2144
|
+
deferRenderBindings: registered.entity === void 0 || isRuntimeEntity(registered.entity) || registered.entity.shared === true,
|
|
2145
|
+
resolveIntrinsicFields: (type) => this.intrinsicFieldNames(registered, type)
|
|
2121
2146
|
});
|
|
2122
2147
|
await executor.executeAll(effects);
|
|
2123
2148
|
}
|
package/dist/ServerBridge.d.ts
CHANGED
|
@@ -4,9 +4,9 @@ import { seedRandom, randomArrayElement, randomInt, shuffleArray, randomPastDate
|
|
|
4
4
|
import { collectTraitRefsFromValue, collectTraitRefsFromEffects } from './chunk-SCRAHWOC.js';
|
|
5
5
|
import { createLogger, setNamespaceLevel } from '@almadar/logger';
|
|
6
6
|
import { evaluateGuard, SExpressionEvaluator } from '@almadar/evaluator';
|
|
7
|
-
import { OrbitalSchemaSchema, isInlineTrait, isEntityCall, isEntityReference, parseEntityRef, parseImportedTraitRef, isPageReference, isPageReferenceString, isPageReferenceObject, parsePageRef, parseOrbitalRef, overrideDeclaredKnobs, asTraitId, asEntityId, asPageId, asOrbitalId, deriveId, isReferenceConfigType, configRefEventKnob, normalizeCallSiteConfigToValues, resolveConfigRefEventName, isCallSiteConfigDeclaration, asEventId, ledgerRename, idPrefix, eventListPropsOf } from '@almadar/core';
|
|
7
|
+
import { omitFrameFields, OrbitalSchemaSchema, isInlineTrait, isEntityCall, isEntityReference, parseEntityRef, parseImportedTraitRef, isPageReference, isPageReferenceString, isPageReferenceObject, parsePageRef, parseOrbitalRef, overrideDeclaredKnobs, asTraitId, asEntityId, asPageId, asOrbitalId, deriveId, isReferenceConfigType, configRefEventKnob, normalizeCallSiteConfigToValues, resolveConfigRefEventName, isCallSiteConfigDeclaration, asEventId, ledgerRename, idPrefix, eventListPropsOf } from '@almadar/core';
|
|
8
8
|
export { normalizeCallSiteConfigToValues } from '@almadar/core';
|
|
9
|
-
import { sampleRowCount, sampleRow, identityEntitiesOf, roleVocabularyOf } from '@almadar/core/mock';
|
|
9
|
+
import { sampleRowCount, linkSelfRelationField, sampleRow, identityEntitiesOf, roleVocabularyOf } from '@almadar/core/mock';
|
|
10
10
|
|
|
11
11
|
var log = createLogger("almadar:runtime:eventbus");
|
|
12
12
|
var EventBus = class {
|
|
@@ -922,14 +922,13 @@ var StateMachineManager = class {
|
|
|
922
922
|
|
|
923
923
|
// src/types.ts
|
|
924
924
|
var HANDLER_MANIFEST = {
|
|
925
|
-
client: ["render-ui", "render", "navigate", "navigate-back", "
|
|
925
|
+
client: ["render-ui", "render", "navigate", "navigate-back", "emit", "set", "log", "ref", "deref", "watch", "send-server", "browser/open-file-picker", "browser/clipboard-read", "browser/clipboard-write", "browser/geolocation-current"],
|
|
926
926
|
server: ["persist", "fetch", "fetch-stream", "call-service", "emit", "set", "spawn", "despawn", "log", "ref", "deref", "swap!", "atomic", "os/watch-files", "os/watch-process", "os/watch-port", "os/watch-http", "os/watch-cron", "os/watch-signal", "os/watch-env", "os/debounce"],
|
|
927
927
|
test: [
|
|
928
928
|
"render-ui",
|
|
929
929
|
"render",
|
|
930
930
|
"navigate",
|
|
931
931
|
"navigate-back",
|
|
932
|
-
"notify",
|
|
933
932
|
"emit",
|
|
934
933
|
"set",
|
|
935
934
|
"persist",
|
|
@@ -989,6 +988,7 @@ var EffectExecutor = class _EffectExecutor {
|
|
|
989
988
|
contextExtensions;
|
|
990
989
|
evaluator;
|
|
991
990
|
deferRenderBindings;
|
|
991
|
+
resolveIntrinsicFields;
|
|
992
992
|
constructor(options) {
|
|
993
993
|
this.handlers = options.handlers;
|
|
994
994
|
this.bindings = options.bindings;
|
|
@@ -998,6 +998,22 @@ var EffectExecutor = class _EffectExecutor {
|
|
|
998
998
|
this.contextExtensions = options.contextExtensions;
|
|
999
999
|
this.evaluator = options.evaluator;
|
|
1000
1000
|
this.deferRenderBindings = options.deferRenderBindings ?? false;
|
|
1001
|
+
this.resolveIntrinsicFields = options.resolveIntrinsicFields;
|
|
1002
|
+
}
|
|
1003
|
+
/**
|
|
1004
|
+
* `@intrinsic` fields are NEVER a persisted column — strips them from
|
|
1005
|
+
* `data` before a `persist create`/`persist update` write, regardless of
|
|
1006
|
+
* what expression produced `data` (bare `@entity`, an explicit literal
|
|
1007
|
+
* that names one, an `object/merge` result, …). Deterministic on the
|
|
1008
|
+
* entity's declared schema, not on how the value was constructed. A
|
|
1009
|
+
* no-op when no schema was supplied (`resolveIntrinsicFields` absent,
|
|
1010
|
+
* e.g. a browser/offline-preview handler set) or the entity declares no
|
|
1011
|
+
* intrinsic fields.
|
|
1012
|
+
*/
|
|
1013
|
+
stripFrameFields(entityType, data) {
|
|
1014
|
+
if (data === void 0 || !this.resolveIntrinsicFields) return data;
|
|
1015
|
+
const intrinsicFields = this.resolveIntrinsicFields(entityType);
|
|
1016
|
+
return intrinsicFields.length > 0 ? omitFrameFields(data, intrinsicFields) : data;
|
|
1001
1017
|
}
|
|
1002
1018
|
_evaluator;
|
|
1003
1019
|
getEvaluator() {
|
|
@@ -1063,7 +1079,6 @@ var EffectExecutor = class _EffectExecutor {
|
|
|
1063
1079
|
"render": this.handlers.renderUI,
|
|
1064
1080
|
"navigate": this.handlers.navigate,
|
|
1065
1081
|
"navigate-back": this.handlers.navigateBack,
|
|
1066
|
-
"notify": this.handlers.notify,
|
|
1067
1082
|
"log": this.handlers.log,
|
|
1068
1083
|
"ref": this.handlers.ref,
|
|
1069
1084
|
"deref": this.handlers.deref,
|
|
@@ -1413,7 +1428,19 @@ var EffectExecutor = class _EffectExecutor {
|
|
|
1413
1428
|
}
|
|
1414
1429
|
try {
|
|
1415
1430
|
if (action === "batch") {
|
|
1416
|
-
const operations = args[1]
|
|
1431
|
+
const operations = args[1].map((op) => {
|
|
1432
|
+
if (!Array.isArray(op) || op.length < 2) return op;
|
|
1433
|
+
const [opAction, opEntityType, ...opRest] = op;
|
|
1434
|
+
if (opAction === "create") {
|
|
1435
|
+
const stripped = this.stripFrameFields(opEntityType, opRest[0]);
|
|
1436
|
+
return [opAction, opEntityType, stripped, ...opRest.slice(1)];
|
|
1437
|
+
}
|
|
1438
|
+
if (opAction === "update") {
|
|
1439
|
+
const stripped = this.stripFrameFields(opEntityType, opRest[1]);
|
|
1440
|
+
return [opAction, opEntityType, opRest[0], stripped, ...opRest.slice(2)];
|
|
1441
|
+
}
|
|
1442
|
+
return op;
|
|
1443
|
+
});
|
|
1417
1444
|
const batchSummary = await this.handlers.persist("batch", "", {
|
|
1418
1445
|
operations
|
|
1419
1446
|
});
|
|
@@ -1432,7 +1459,7 @@ var EffectExecutor = class _EffectExecutor {
|
|
|
1432
1459
|
persistLog.debug("persist:emit-fired", { action, eventName: emitCfg?.success });
|
|
1433
1460
|
} else {
|
|
1434
1461
|
const entityType = args[1];
|
|
1435
|
-
const data = args[2];
|
|
1462
|
+
const data = action === "create" || action === "update" ? this.stripFrameFields(entityType, args[2]) : args[2];
|
|
1436
1463
|
const persisted = await this.handlers.persist(action, entityType, data);
|
|
1437
1464
|
if (persisted === void 0) {
|
|
1438
1465
|
const attemptedId = typeof data === "string" ? data : data && typeof data === "object" ? data.id : void 0;
|
|
@@ -1697,15 +1724,7 @@ var EffectExecutor = class _EffectExecutor {
|
|
|
1697
1724
|
break;
|
|
1698
1725
|
}
|
|
1699
1726
|
case "notify": {
|
|
1700
|
-
|
|
1701
|
-
const message = args[0];
|
|
1702
|
-
const type = args[1] || "info";
|
|
1703
|
-
this.handlers.notify(message, type);
|
|
1704
|
-
} else {
|
|
1705
|
-
const category = typeof args[1] === "string" ? args[1] : "info";
|
|
1706
|
-
const message = typeof args[0] === "string" ? args[0] : JSON.stringify(args[0] ?? null);
|
|
1707
|
-
effectLog.info("notify", { category, message });
|
|
1708
|
-
}
|
|
1727
|
+
this.logUnsupported("notify");
|
|
1709
1728
|
break;
|
|
1710
1729
|
}
|
|
1711
1730
|
// === Compound Effects ===
|
|
@@ -2476,14 +2495,18 @@ var MockPersistenceAdapter = class _MockPersistenceAdapter {
|
|
|
2476
2495
|
* of nested-tree atoms (e.g. std-thread-comments-linear with ThreadPost.
|
|
2477
2496
|
* replies → [ThreadPost]) render empty reply cards.
|
|
2478
2497
|
*
|
|
2479
|
-
* Cross-entity relations pick random IDs from the target store.
|
|
2480
|
-
*
|
|
2481
|
-
*
|
|
2482
|
-
* root (
|
|
2483
|
-
* real roots
|
|
2484
|
-
*
|
|
2485
|
-
*
|
|
2486
|
-
* `
|
|
2498
|
+
* Cross-entity relations pick random IDs from the target store. EVERY
|
|
2499
|
+
* self-referential relation, any cardinality, is linked deterministically
|
|
2500
|
+
* instead via `@almadar/core/mock`'s `linkSelfRelationField`: row 0 stays a
|
|
2501
|
+
* root (never referenced), row *i* parents to row ⌊(i−1)/2⌋ — one shared
|
|
2502
|
+
* forest, real roots, no cycles. `one`/`many-to-one` self-relations (a
|
|
2503
|
+
* parent column like `Tag.parentId : Tag`) store the scalar parent id;
|
|
2504
|
+
* `many`/`one-to-many`/`many-to-many` self-relations (a children list like
|
|
2505
|
+
* `ChatMessage.replies : [ChatMessage]`) store the forest's children-id
|
|
2506
|
+
* list — no more random cross-linking, so the root row is never referenced
|
|
2507
|
+
* and stays deletable under `onDelete: restrict`. The runtime caps
|
|
2508
|
+
* recursion at depth=2 in `populateRelations`, so deep chains render two
|
|
2509
|
+
* levels then stop.
|
|
2487
2510
|
*
|
|
2488
2511
|
* Entities sharing a collection are linked once per STORE, over the union
|
|
2489
2512
|
* of their declared relation fields (first declarer of a field name wins).
|
|
@@ -2525,13 +2548,12 @@ var MockPersistenceAdapter = class _MockPersistenceAdapter {
|
|
|
2525
2548
|
if (!targetStore || targetStore.size === 0) continue;
|
|
2526
2549
|
const sameStore = targetStore === store;
|
|
2527
2550
|
const cardinality = field.relation.cardinality ?? "many";
|
|
2528
|
-
if (sameStore
|
|
2529
|
-
|
|
2530
|
-
|
|
2531
|
-
|
|
2532
|
-
|
|
2533
|
-
|
|
2534
|
-
});
|
|
2551
|
+
if (sameStore) {
|
|
2552
|
+
linkSelfRelationField(
|
|
2553
|
+
rows,
|
|
2554
|
+
{ name: field.name, cardinality },
|
|
2555
|
+
(row, i) => this.config.ownerId !== void 0 && row[field.name] === this.config.ownerId || stampedCellKeys.has(stampedCellKey(storeKey, row["id"], field.name))
|
|
2556
|
+
);
|
|
2535
2557
|
continue;
|
|
2536
2558
|
}
|
|
2537
2559
|
for (const row of rows) {
|
|
@@ -2539,11 +2561,7 @@ var MockPersistenceAdapter = class _MockPersistenceAdapter {
|
|
|
2539
2561
|
if (this.config.ownerId !== void 0 && row[field.name] === this.config.ownerId || stampedCellKeys.has(stampedCellKey(storeKey, selfId, field.name))) {
|
|
2540
2562
|
continue;
|
|
2541
2563
|
}
|
|
2542
|
-
let eligible = [];
|
|
2543
|
-
for (const id of targetStore.keys()) {
|
|
2544
|
-
if (sameStore && id === selfId) continue;
|
|
2545
|
-
eligible.push(id);
|
|
2546
|
-
}
|
|
2564
|
+
let eligible = [...targetStore.keys()];
|
|
2547
2565
|
if (isOwnerColumn && this.ownerCandidateGate) {
|
|
2548
2566
|
const gate = this.ownerCandidateGate;
|
|
2549
2567
|
eligible = eligible.filter(
|
|
@@ -4326,10 +4344,18 @@ function traitEmbedNamesOf(trait) {
|
|
|
4326
4344
|
for (const field of Object.values(trait.config ?? {})) walk(field.default);
|
|
4327
4345
|
return [...found].sort();
|
|
4328
4346
|
}
|
|
4329
|
-
function resolveForwardedSiblingConfigFrom(trait, parentChain, orbitalConfig, schemaConfig) {
|
|
4347
|
+
function resolveForwardedSiblingConfigFrom(trait, parentChain, orbitalConfig, schemaConfig, schemaOnlyKeys) {
|
|
4330
4348
|
const declared = trait.config;
|
|
4331
4349
|
if (!declared) return trait;
|
|
4332
|
-
const next = resolveConfigForwards(
|
|
4350
|
+
const next = resolveConfigForwards(
|
|
4351
|
+
declared,
|
|
4352
|
+
parentChain,
|
|
4353
|
+
orbitalConfig,
|
|
4354
|
+
void 0,
|
|
4355
|
+
void 0,
|
|
4356
|
+
schemaConfig,
|
|
4357
|
+
schemaOnlyKeys
|
|
4358
|
+
);
|
|
4333
4359
|
return next ? { ...trait, config: next } : trait;
|
|
4334
4360
|
}
|
|
4335
4361
|
function callSiteRungValue(rungConfig, knob) {
|
|
@@ -4338,8 +4364,9 @@ function callSiteRungValue(rungConfig, knob) {
|
|
|
4338
4364
|
return isCallSiteConfigDeclaration(entry) ? entry.default : entry;
|
|
4339
4365
|
}
|
|
4340
4366
|
function walkConfigForwardChain(forward, parentChain, orbitalConfig, upstreamOrbitalConfig, upstreamSchemaConfig, schemaConfig) {
|
|
4367
|
+
const unresolved = { value: void 0, reachedSchemaConfigOnly: false };
|
|
4341
4368
|
let knob = forward.slice("@config.".length);
|
|
4342
|
-
if (knob.length === 0 || knob.includes(".")) return
|
|
4369
|
+
if (knob.length === 0 || knob.includes(".")) return unresolved;
|
|
4343
4370
|
let value;
|
|
4344
4371
|
let currentForward = forward;
|
|
4345
4372
|
for (const rungConfig of parentChain) {
|
|
@@ -4358,16 +4385,17 @@ function walkConfigForwardChain(forward, parentChain, orbitalConfig, upstreamOrb
|
|
|
4358
4385
|
if (value === void 0 || value === currentForward) value = orbitalConfig?.[knob]?.default;
|
|
4359
4386
|
if (value === void 0 || value === currentForward) value = upstreamOrbitalConfig?.[knob]?.default;
|
|
4360
4387
|
if (value === void 0 || value === currentForward) value = upstreamSchemaConfig?.[knob]?.default;
|
|
4361
|
-
|
|
4362
|
-
if (
|
|
4363
|
-
return
|
|
4388
|
+
const reachesSchemaConfigRung = value === void 0 || value === currentForward;
|
|
4389
|
+
if (reachesSchemaConfigRung) value = schemaConfig?.[knob]?.default;
|
|
4390
|
+
if (value === void 0 || value === currentForward) return unresolved;
|
|
4391
|
+
return { value, reachedSchemaConfigOnly: reachesSchemaConfigRung };
|
|
4364
4392
|
}
|
|
4365
|
-
function resolveConfigForwards(declared, parentChain, orbitalConfig, upstreamOrbitalConfig, upstreamSchemaConfig, schemaConfig) {
|
|
4393
|
+
function resolveConfigForwards(declared, parentChain, orbitalConfig, upstreamOrbitalConfig, upstreamSchemaConfig, schemaConfig, schemaOnlyKeys) {
|
|
4366
4394
|
let next;
|
|
4367
4395
|
for (const [key, field] of Object.entries(declared)) {
|
|
4368
4396
|
const forward = field.default;
|
|
4369
4397
|
if (typeof forward !== "string" || !forward.startsWith("@config.")) continue;
|
|
4370
|
-
const value = walkConfigForwardChain(
|
|
4398
|
+
const { value, reachedSchemaConfigOnly } = walkConfigForwardChain(
|
|
4371
4399
|
forward,
|
|
4372
4400
|
parentChain,
|
|
4373
4401
|
orbitalConfig,
|
|
@@ -4376,6 +4404,7 @@ function resolveConfigForwards(declared, parentChain, orbitalConfig, upstreamOrb
|
|
|
4376
4404
|
schemaConfig
|
|
4377
4405
|
);
|
|
4378
4406
|
if (value === void 0) continue;
|
|
4407
|
+
if (reachedSchemaConfigOnly) schemaOnlyKeys?.add(key);
|
|
4379
4408
|
next ??= { ...declared };
|
|
4380
4409
|
next[key] = { ...field, default: value, forwardedFrom: forward };
|
|
4381
4410
|
}
|
|
@@ -4386,7 +4415,7 @@ function resolveCallSiteConfigForwards(config, parentChain, orbitalConfig, schem
|
|
|
4386
4415
|
for (const [key, entry] of Object.entries(config)) {
|
|
4387
4416
|
const forward = isCallSiteConfigDeclaration(entry) ? entry.default : entry;
|
|
4388
4417
|
if (typeof forward !== "string" || !forward.startsWith("@config.")) continue;
|
|
4389
|
-
const value = walkConfigForwardChain(forward, parentChain, orbitalConfig, void 0, void 0, schemaConfig);
|
|
4418
|
+
const { value } = walkConfigForwardChain(forward, parentChain, orbitalConfig, void 0, void 0, schemaConfig);
|
|
4390
4419
|
if (value === void 0) continue;
|
|
4391
4420
|
next ??= { ...config };
|
|
4392
4421
|
next[key] = isCallSiteConfigDeclaration(entry) ? { ...entry, default: value, forwardedFrom: forward } : value;
|
|
@@ -5584,11 +5613,11 @@ function rewriteConfigPagePaths(node, pathMap) {
|
|
|
5584
5613
|
}
|
|
5585
5614
|
return node;
|
|
5586
5615
|
}
|
|
5587
|
-
function rewriteTraitConfigPagePaths(trait, pathMap) {
|
|
5616
|
+
function rewriteTraitConfigPagePaths(trait, pathMap, schemaOnlyKeys) {
|
|
5588
5617
|
if (pathMap.size === 0 || !trait.config) return trait;
|
|
5589
5618
|
const nextConfig = {};
|
|
5590
5619
|
for (const [key, field] of Object.entries(trait.config)) {
|
|
5591
|
-
nextConfig[key] = field.default === void 0 ? field : { ...field, default: rewriteConfigPagePaths(field.default, pathMap) };
|
|
5620
|
+
nextConfig[key] = field.default === void 0 || schemaOnlyKeys.has(key) ? field : { ...field, default: rewriteConfigPagePaths(field.default, pathMap) };
|
|
5592
5621
|
}
|
|
5593
5622
|
return { ...trait, config: nextConfig };
|
|
5594
5623
|
}
|
|
@@ -7479,17 +7508,30 @@ var ReferenceResolver = class _ReferenceResolver {
|
|
|
7479
7508
|
if (pathMap.size > 0) {
|
|
7480
7509
|
next = rewriteTraitNavigateTargets(next, pathMap);
|
|
7481
7510
|
}
|
|
7511
|
+
const schemaOnlyKeys = /* @__PURE__ */ new Set();
|
|
7482
7512
|
for (const embedderName of embeddersOf.get(trait.name) ?? []) {
|
|
7483
7513
|
const embedderConfig = parentConfigs.get(embedderName);
|
|
7484
|
-
next = resolveForwardedSiblingConfigFrom(
|
|
7514
|
+
next = resolveForwardedSiblingConfigFrom(
|
|
7515
|
+
next,
|
|
7516
|
+
embedderConfig ? [embedderConfig] : [],
|
|
7517
|
+
void 0,
|
|
7518
|
+
void 0,
|
|
7519
|
+
schemaOnlyKeys
|
|
7520
|
+
);
|
|
7485
7521
|
}
|
|
7486
|
-
next = resolveForwardedSiblingConfigFrom(
|
|
7487
|
-
|
|
7522
|
+
next = resolveForwardedSiblingConfigFrom(
|
|
7523
|
+
next,
|
|
7524
|
+
transitiveEmbedderChain(trait.name),
|
|
7525
|
+
void 0,
|
|
7526
|
+
void 0,
|
|
7527
|
+
schemaOnlyKeys
|
|
7528
|
+
);
|
|
7529
|
+
next = resolveForwardedSiblingConfigFrom(next, [], foldedConfig, importedSchemaConfig, schemaOnlyKeys);
|
|
7488
7530
|
if (fieldSubs.size > 0 && next.config) {
|
|
7489
7531
|
next = { ...next, config: rewriteEntityFieldsInConfig(next.config, fieldSubs) };
|
|
7490
7532
|
}
|
|
7491
7533
|
if (pathMap.size > 0) {
|
|
7492
|
-
next = rewriteTraitConfigPagePaths(next, pathMap);
|
|
7534
|
+
next = rewriteTraitConfigPagePaths(next, pathMap, schemaOnlyKeys);
|
|
7493
7535
|
}
|
|
7494
7536
|
next = applyEventRenames(next, ref.events, keptFinalNames);
|
|
7495
7537
|
return next;
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { h as RuntimePatternValue, B as BindingContext, f as EvaluationContextExtensions, P as PatternProps, E as EffectHandlers, g as EffectContext, i as ExecutionEnvironment, j as EffectResult, T as TraitDefinition } from './types-
|
|
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-
|
|
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 { C as CreateServerEffectHandlersOptions, E as EntitySharingMap, c as EventBus, d as EventNamespaceMap, e as InMemoryPersistence, f as LIFECYCLE_EVENTS, O as OrbitalEventRequest, g as OrbitalEventResponse, h as OrbitalServerRuntimeConfig, i as PreprocessOptions, j as PreprocessResult, k as PreprocessedSchema, l as ProcessEventOptions, R as RegisteredOrbital, m as RuntimeOrbital, n as RuntimeOrbitalSchema, o as RuntimeTrait, p as ServerEffectResult, q as StateMachineManager, r as collectDeclaredConfigDefaults, s as collectDeclaredEntityDefaults, t as createInitialTraitState, u as createServerEffectHandlers, v as findInitialState, w as findTransition, x as getIsolatedCollectionName, y as getNamespacedEvent, z as isBrowser, A as isElectron, B as isNamespacedEvent, D as isNode, F as normalizeEventKey, G as parseNamespacedEvent, H as preprocessSchema, J as processEvent } from './OrbitalServerRuntime-
|
|
1
|
+
import { h as RuntimePatternValue, B as BindingContext, f as EvaluationContextExtensions, P as PatternProps, E as EffectHandlers, g as EffectContext, i as ExecutionEnvironment, j as EffectResult, T as TraitDefinition } from './types-BO4tbEPp.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-BO4tbEPp.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-Buvz7dd7.js';
|
|
4
|
+
export { C as CreateServerEffectHandlersOptions, E as EntitySharingMap, c as EventBus, d as EventNamespaceMap, e as InMemoryPersistence, f as LIFECYCLE_EVENTS, O as OrbitalEventRequest, g as OrbitalEventResponse, h as OrbitalServerRuntimeConfig, i as PreprocessOptions, j as PreprocessResult, k as PreprocessedSchema, l as ProcessEventOptions, R as RegisteredOrbital, m as RuntimeOrbital, n as RuntimeOrbitalSchema, o as RuntimeTrait, p as ServerEffectResult, q as StateMachineManager, r as collectDeclaredConfigDefaults, s as collectDeclaredEntityDefaults, t as createInitialTraitState, u as createServerEffectHandlers, v as findInitialState, w as findTransition, x as getIsolatedCollectionName, y as getNamespacedEvent, z as isBrowser, A as isElectron, B as isNamespacedEvent, D as isNode, F as normalizeEventKey, G as parseNamespacedEvent, H as preprocessSchema, J as processEvent } from './OrbitalServerRuntime-Buvz7dd7.js';
|
|
5
5
|
import { EvaluationContext, SExpressionEvaluator } from '@almadar/evaluator';
|
|
6
6
|
export { EvaluationContext, createMinimalContext } from '@almadar/evaluator';
|
|
7
7
|
import { RenderBindingMarker, SExpr, RuntimeValue, EventPayload, PatternConfig, EntityId, EntityField, EntityRow, EntityPersistence, PayloadField, OrbitalDefinition, OrbitalSchema } from '@almadar/core';
|
|
@@ -353,6 +353,16 @@ interface EffectExecutorOptions {
|
|
|
353
353
|
* SSE-pushed props stay concrete.
|
|
354
354
|
*/
|
|
355
355
|
deferRenderBindings?: boolean;
|
|
356
|
+
/**
|
|
357
|
+
* Names of an entity's `@intrinsic` fields — trait-owned view state
|
|
358
|
+
* (never a persisted column) — keyed by entity type. Supplied only by a
|
|
359
|
+
* caller holding the registered schema (`OrbitalServerRuntime`); the
|
|
360
|
+
* `persist` case uses it to strip those keys from a bare `@entity`
|
|
361
|
+
* binding before the write reaches the store. Absent means "no schema
|
|
362
|
+
* available" (e.g. a browser/offline-preview handler set), in which case
|
|
363
|
+
* persist writes verbatim exactly as before.
|
|
364
|
+
*/
|
|
365
|
+
resolveIntrinsicFields?: (entityType: string) => readonly string[];
|
|
356
366
|
}
|
|
357
367
|
/**
|
|
358
368
|
* EffectExecutor - Routes effects to handlers.
|
|
@@ -389,7 +399,19 @@ declare class EffectExecutor {
|
|
|
389
399
|
private contextExtensions?;
|
|
390
400
|
private evaluator?;
|
|
391
401
|
private deferRenderBindings;
|
|
402
|
+
private resolveIntrinsicFields?;
|
|
392
403
|
constructor(options: EffectExecutorOptions);
|
|
404
|
+
/**
|
|
405
|
+
* `@intrinsic` fields are NEVER a persisted column — strips them from
|
|
406
|
+
* `data` before a `persist create`/`persist update` write, regardless of
|
|
407
|
+
* what expression produced `data` (bare `@entity`, an explicit literal
|
|
408
|
+
* that names one, an `object/merge` result, …). Deterministic on the
|
|
409
|
+
* entity's declared schema, not on how the value was constructed. A
|
|
410
|
+
* no-op when no schema was supplied (`resolveIntrinsicFields` absent,
|
|
411
|
+
* e.g. a browser/offline-preview handler set) or the entity declares no
|
|
412
|
+
* intrinsic fields.
|
|
413
|
+
*/
|
|
414
|
+
private stripFrameFields;
|
|
393
415
|
private _evaluator?;
|
|
394
416
|
private getEvaluator;
|
|
395
417
|
/**
|
|
@@ -521,8 +543,6 @@ interface CreateClientEffectHandlersOptions {
|
|
|
521
543
|
}, crumb?: string) => void;
|
|
522
544
|
/** Navigate-back function: pop the orbital-scoped navigation stack. */
|
|
523
545
|
navigateBack?: () => void;
|
|
524
|
-
/** Notify function for notification effects */
|
|
525
|
-
notify?: (message: string, type: 'success' | 'error' | 'warning' | 'info') => void;
|
|
526
546
|
/**
|
|
527
547
|
* Send-server handler for `send-server` effects.
|
|
528
548
|
* When omitted, defaults to a lazy WebSocket transport connecting to the
|
|
@@ -542,7 +562,7 @@ interface CreateClientEffectHandlersOptions {
|
|
|
542
562
|
/**
|
|
543
563
|
* Create client-side effect handlers for trait state machine execution.
|
|
544
564
|
*
|
|
545
|
-
* Client handles: emit, renderUI, navigate,
|
|
565
|
+
* Client handles: emit, renderUI, navigate, sendServer
|
|
546
566
|
* Server handles: persist, set, callService (logged as warnings on client)
|
|
547
567
|
*
|
|
548
568
|
* @example
|
|
@@ -554,7 +574,6 @@ interface CreateClientEffectHandlersOptions {
|
|
|
554
574
|
* clearSlot: (slot) => pendingSlots.set(slot, []),
|
|
555
575
|
* },
|
|
556
576
|
* navigate: (path) => router.push(path),
|
|
557
|
-
* notify: (msg, type) => toast[type](msg),
|
|
558
577
|
* });
|
|
559
578
|
* ```
|
|
560
579
|
*/
|
|
@@ -747,14 +766,18 @@ declare class MockPersistenceAdapter implements PersistenceAdapter {
|
|
|
747
766
|
* of nested-tree atoms (e.g. std-thread-comments-linear with ThreadPost.
|
|
748
767
|
* replies → [ThreadPost]) render empty reply cards.
|
|
749
768
|
*
|
|
750
|
-
* Cross-entity relations pick random IDs from the target store.
|
|
751
|
-
*
|
|
752
|
-
*
|
|
753
|
-
* root (
|
|
754
|
-
* real roots
|
|
755
|
-
*
|
|
756
|
-
*
|
|
757
|
-
* `
|
|
769
|
+
* Cross-entity relations pick random IDs from the target store. EVERY
|
|
770
|
+
* self-referential relation, any cardinality, is linked deterministically
|
|
771
|
+
* instead via `@almadar/core/mock`'s `linkSelfRelationField`: row 0 stays a
|
|
772
|
+
* root (never referenced), row *i* parents to row ⌊(i−1)/2⌋ — one shared
|
|
773
|
+
* forest, real roots, no cycles. `one`/`many-to-one` self-relations (a
|
|
774
|
+
* parent column like `Tag.parentId : Tag`) store the scalar parent id;
|
|
775
|
+
* `many`/`one-to-many`/`many-to-many` self-relations (a children list like
|
|
776
|
+
* `ChatMessage.replies : [ChatMessage]`) store the forest's children-id
|
|
777
|
+
* list — no more random cross-linking, so the root row is never referenced
|
|
778
|
+
* and stays deletable under `onDelete: restrict`. The runtime caps
|
|
779
|
+
* recursion at depth=2 in `populateRelations`, so deep chains render two
|
|
780
|
+
* levels then stop.
|
|
758
781
|
*
|
|
759
782
|
* Entities sharing a collection are linked once per STORE, over the union
|
|
760
783
|
* of their declared relation fields (first declarer of a field name wins).
|
package/dist/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { EffectExecutor } from './chunk-
|
|
2
|
-
export { EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, LIFECYCLE_EVENTS, MockPersistenceAdapter, StateMachineManager, TickScheduler, buildEmitsFromTraits, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, createInitialTraitState, createMockPersistence, createTestExecutor, createTickScheduler, createUnifiedLoader, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, isBrowser, isElectron, isNamespacedEvent, isNode, isValidDurationString, normalizeCallSiteConfigToValues, normalizeEventKey, parseDurationString, parseNamespacedEvent, preprocessSchema, processEvent, validateEventPayload, validatePayloadShapes } from './chunk-
|
|
1
|
+
import { EffectExecutor } from './chunk-CEYC3Z2O.js';
|
|
2
|
+
export { EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, LIFECYCLE_EVENTS, MockPersistenceAdapter, StateMachineManager, TickScheduler, buildEmitsFromTraits, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, createInitialTraitState, createMockPersistence, createTestExecutor, createTickScheduler, createUnifiedLoader, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, isBrowser, isElectron, isNamespacedEvent, isNode, isValidDurationString, normalizeCallSiteConfigToValues, normalizeEventKey, parseDurationString, parseNamespacedEvent, preprocessSchema, processEvent, validateEventPayload, validatePayloadShapes } from './chunk-CEYC3Z2O.js';
|
|
3
3
|
export { cronMatches, cronMinuteKey, isValidCronExpression, parseCron, parseCronField } from './chunk-OU3ITB5S.js';
|
|
4
4
|
import { createContextFromBindings, applyRowAccess, checkMutationAccess, accessDeniedMessage } from './chunk-ZWAOJT6R.js';
|
|
5
5
|
export { applyRowAccess, checkMutationAccess, containsBindings, createContextFromBindings, createMinimalContext, deferEntityBindings, extractBindings, interpolateProps, interpolateValue } from './chunk-ZWAOJT6R.js';
|
|
@@ -68,7 +68,7 @@ function sendServerEvent(orbital, event, payload) {
|
|
|
68
68
|
}
|
|
69
69
|
}
|
|
70
70
|
function createClientEffectHandlers(options) {
|
|
71
|
-
const { eventBus, slotSetter, navigate, navigateBack,
|
|
71
|
+
const { eventBus, slotSetter, navigate, navigateBack, sendServer, orbitalName = "" } = options;
|
|
72
72
|
return {
|
|
73
73
|
emit: (event, payload) => {
|
|
74
74
|
const prefixedEvent = event.startsWith("UI:") ? event : `UI:${event}`;
|
|
@@ -101,9 +101,6 @@ function createClientEffectHandlers(options) {
|
|
|
101
101
|
navigateBack: navigateBack ?? (() => {
|
|
102
102
|
log.warn("navigate-back-no-handler");
|
|
103
103
|
}),
|
|
104
|
-
notify: notify ?? ((msg, type) => {
|
|
105
|
-
log.debug("notify", { type: type ?? null, message: msg });
|
|
106
|
-
}),
|
|
107
104
|
sendServer: sendServer ?? ((event, payload) => {
|
|
108
105
|
sendServerEvent(orbitalName, event, payload);
|
|
109
106
|
}),
|
|
@@ -240,8 +240,6 @@ interface EffectHandlers {
|
|
|
240
240
|
/** Pop the orbital-scoped navigation stack and return to the previous
|
|
241
241
|
* entry (client only). */
|
|
242
242
|
navigateBack?: () => void;
|
|
243
|
-
/** Show a notification (client: toast, server: log) */
|
|
244
|
-
notify?: (message: string, type: 'success' | 'error' | 'warning' | 'info') => void;
|
|
245
243
|
/** Log a message */
|
|
246
244
|
log?: (message: string, level?: 'log' | 'warn' | 'error', data?: unknown) => void;
|
|
247
245
|
/** Ref: declarative data subscription (server: same as fetch) */
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@almadar/runtime",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.75.0",
|
|
4
4
|
"description": "Interpreted runtime for Almadar orbital applications (OrbitalServerRuntime)",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "./dist/index.js",
|
|
@@ -57,11 +57,11 @@
|
|
|
57
57
|
"access": "public"
|
|
58
58
|
},
|
|
59
59
|
"dependencies": {
|
|
60
|
-
"@almadar/core": "^10.
|
|
60
|
+
"@almadar/core": "^10.90.0",
|
|
61
61
|
"@almadar/evaluator": "^2.45.0",
|
|
62
62
|
"@almadar/logger": "^1.12.0",
|
|
63
|
-
"@almadar/server": "^2.
|
|
64
|
-
"@almadar/std": "^16.
|
|
63
|
+
"@almadar/server": "^2.41.0",
|
|
64
|
+
"@almadar/std": "^16.211.0"
|
|
65
65
|
},
|
|
66
66
|
"peerDependencies": {
|
|
67
67
|
"express": "^5.0.0"
|