@almadar/runtime 6.43.0 → 6.44.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-Dz0oubQ_.d.ts} +8 -0
- package/dist/OrbitalServerRuntime.d.ts +1 -1
- package/dist/OrbitalServerRuntime.js +33 -5
- package/dist/{chunk-2SM626PK.js → chunk-EJHMWSUS.js} +300 -0
- package/dist/index.d.ts +14 -2
- package/dist/index.js +2 -2
- package/package.json +3 -3
|
@@ -1199,6 +1199,14 @@ declare class OrbitalServerRuntime {
|
|
|
1199
1199
|
* std registry on disk.
|
|
1200
1200
|
*/
|
|
1201
1201
|
register(schema: OrbitalSchema): Promise<void>;
|
|
1202
|
+
/**
|
|
1203
|
+
* Teach the mock seeder which columns hold the viewer's id, derived from the
|
|
1204
|
+
* schema's `[identity]` entity. No-op for a program that declares none, so
|
|
1205
|
+
* unmigrated apps seed exactly as before. Mirrors
|
|
1206
|
+
* `orbital-core/src/runtime/seed.rs::owner_fields_from_schema` — a feature
|
|
1207
|
+
* that lives on only one execution path is not a feature.
|
|
1208
|
+
*/
|
|
1209
|
+
private applyIdentityOwnerFields;
|
|
1202
1210
|
/**
|
|
1203
1211
|
* Register an OrbitalSchema synchronously (for backward compatibility).
|
|
1204
1212
|
* Note: This version doesn't wait for instance seeding to complete.
|
|
@@ -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-
|
|
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-Dz0oubQ_.js';
|
|
3
3
|
import './types-p_L8-Sk4.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-EJHMWSUS.js';
|
|
2
|
+
export { InMemoryPersistence, collectDeclaredConfigDefaults } from './chunk-EJHMWSUS.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 } 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-
|
|
@@ -2346,6 +2346,22 @@ var MockPersistenceAdapter = class {
|
|
|
2346
2346
|
seedRandom(this.config.seed);
|
|
2347
2347
|
mockLog.debug("mock:adapter:init", { seed: this.config.seed });
|
|
2348
2348
|
}
|
|
2349
|
+
/**
|
|
2350
|
+
* Add owner columns discovered after construction.
|
|
2351
|
+
*
|
|
2352
|
+
* The adapter is built before any schema is registered, so schema-DERIVED
|
|
2353
|
+
* owner columns (relation fields pointing at the `[identity]` entity) can
|
|
2354
|
+
* only arrive later.
|
|
2355
|
+
*
|
|
2356
|
+
* ⚠️ Seeding is EAGER — `registerEntity()` seeds immediately — so callers must
|
|
2357
|
+
* supply these columns BEFORE registering any orbital. Calling this afterwards
|
|
2358
|
+
* silently stamps nothing.
|
|
2359
|
+
*/
|
|
2360
|
+
addOwnerFields(fields) {
|
|
2361
|
+
if (fields.length === 0) return;
|
|
2362
|
+
const merged = /* @__PURE__ */ new Set([...this.config.ownerFields ?? [], ...fields]);
|
|
2363
|
+
this.config.ownerFields = [...merged];
|
|
2364
|
+
}
|
|
2349
2365
|
/** Re-anchor the PRNG to the configured seed. Called before every
|
|
2350
2366
|
* re-seed loop so identical reseed sequences produce identical rows
|
|
2351
2367
|
* (timestamps + generated fields). Without this, the first
|
|
@@ -2422,6 +2438,9 @@ var MockPersistenceAdapter = class {
|
|
|
2422
2438
|
if (relationFields.length === 0) continue;
|
|
2423
2439
|
for (const row of store.values()) {
|
|
2424
2440
|
for (const field of relationFields) {
|
|
2441
|
+
if (this.config.ownerId !== void 0 && row[field.name] === this.config.ownerId) {
|
|
2442
|
+
continue;
|
|
2443
|
+
}
|
|
2425
2444
|
const targetNormalized = (field.relation.entityId && this.storeNameById.get(field.relation.entityId)) ?? field.relation.entity.toLowerCase();
|
|
2426
2445
|
const targetStore = this.stores.get(targetNormalized);
|
|
2427
2446
|
if (!targetStore || targetStore.size === 0) continue;
|
|
@@ -3642,6 +3661,96 @@ function renameEntityInEffect(effect, rename, props) {
|
|
|
3642
3661
|
}
|
|
3643
3662
|
return effect;
|
|
3644
3663
|
}
|
|
3664
|
+
var TRAIT_EMBED_PREFIX = "@trait.";
|
|
3665
|
+
function renameTraitEmbedsInValue(node, subs) {
|
|
3666
|
+
if (node === null || node === void 0) return node;
|
|
3667
|
+
if (typeof node === "string") {
|
|
3668
|
+
if (!node.startsWith(TRAIT_EMBED_PREFIX)) return node;
|
|
3669
|
+
const rest = node.slice(TRAIT_EMBED_PREFIX.length);
|
|
3670
|
+
const dot = rest.search(/[.[]/);
|
|
3671
|
+
const name = dot === -1 ? rest : rest.slice(0, dot);
|
|
3672
|
+
const suffix = dot === -1 ? "" : rest.slice(dot);
|
|
3673
|
+
const to = subs.get(name);
|
|
3674
|
+
return to === void 0 ? node : `${TRAIT_EMBED_PREFIX}${to}${suffix}`;
|
|
3675
|
+
}
|
|
3676
|
+
if (Array.isArray(node)) return node.map((item) => renameTraitEmbedsInValue(item, subs));
|
|
3677
|
+
if (typeof node !== "object") return node;
|
|
3678
|
+
const next = {};
|
|
3679
|
+
for (const [key, value] of Object.entries(node)) {
|
|
3680
|
+
next[key] = renameTraitEmbedsInValue(value, subs);
|
|
3681
|
+
}
|
|
3682
|
+
return next;
|
|
3683
|
+
}
|
|
3684
|
+
function renameTraitEmbeds(trait, subs) {
|
|
3685
|
+
if (subs.size === 0) return trait;
|
|
3686
|
+
const sm = trait.stateMachine;
|
|
3687
|
+
const next = { ...trait };
|
|
3688
|
+
if (sm) {
|
|
3689
|
+
next.stateMachine = {
|
|
3690
|
+
...sm,
|
|
3691
|
+
transitions: (sm.transitions ?? []).map(
|
|
3692
|
+
(t) => t.effects ? { ...t, effects: renameTraitEmbedsInValue(t.effects, subs) } : t
|
|
3693
|
+
)
|
|
3694
|
+
};
|
|
3695
|
+
}
|
|
3696
|
+
if (trait.ticks) {
|
|
3697
|
+
next.ticks = trait.ticks.map(
|
|
3698
|
+
(tick) => tick.effects ? { ...tick, effects: renameTraitEmbedsInValue(tick.effects, subs) } : tick
|
|
3699
|
+
);
|
|
3700
|
+
}
|
|
3701
|
+
if (trait.config) {
|
|
3702
|
+
const nextConfig = {};
|
|
3703
|
+
for (const [key, field] of Object.entries(trait.config)) {
|
|
3704
|
+
nextConfig[key] = field.default === void 0 ? field : {
|
|
3705
|
+
...field,
|
|
3706
|
+
default: renameTraitEmbedsInValue(
|
|
3707
|
+
field.default,
|
|
3708
|
+
subs
|
|
3709
|
+
)
|
|
3710
|
+
};
|
|
3711
|
+
}
|
|
3712
|
+
next.config = nextConfig;
|
|
3713
|
+
}
|
|
3714
|
+
return next;
|
|
3715
|
+
}
|
|
3716
|
+
function findTraitEntryInOrbital(orbital, localName) {
|
|
3717
|
+
for (const traitRef of orbital.traits ?? []) {
|
|
3718
|
+
if (typeof traitRef === "string") continue;
|
|
3719
|
+
if ("stateMachine" in traitRef) {
|
|
3720
|
+
if (traitRef.name === localName) return traitRef;
|
|
3721
|
+
continue;
|
|
3722
|
+
}
|
|
3723
|
+
if (!("ref" in traitRef)) continue;
|
|
3724
|
+
const refObj = traitRef;
|
|
3725
|
+
const declared = refObj.name ?? parseImportedTraitRef(refObj.ref)?.traitName;
|
|
3726
|
+
if (declared === localName) return traitRef;
|
|
3727
|
+
}
|
|
3728
|
+
return null;
|
|
3729
|
+
}
|
|
3730
|
+
function traitEmbedNamesOf(trait) {
|
|
3731
|
+
const found = /* @__PURE__ */ new Set();
|
|
3732
|
+
const walk = (node) => {
|
|
3733
|
+
if (node === null || node === void 0) return;
|
|
3734
|
+
if (typeof node === "string") {
|
|
3735
|
+
if (!node.startsWith(TRAIT_EMBED_PREFIX)) return;
|
|
3736
|
+
const rest = node.slice(TRAIT_EMBED_PREFIX.length);
|
|
3737
|
+
const dot = rest.search(/[.[]/);
|
|
3738
|
+
const name = dot === -1 ? rest : rest.slice(0, dot);
|
|
3739
|
+
if (name.length > 0) found.add(name);
|
|
3740
|
+
return;
|
|
3741
|
+
}
|
|
3742
|
+
if (Array.isArray(node)) {
|
|
3743
|
+
for (const item of node) walk(item);
|
|
3744
|
+
return;
|
|
3745
|
+
}
|
|
3746
|
+
if (typeof node !== "object") return;
|
|
3747
|
+
for (const value of Object.values(node)) walk(value);
|
|
3748
|
+
};
|
|
3749
|
+
for (const t of trait.stateMachine?.transitions ?? []) walk(t.effects);
|
|
3750
|
+
for (const tick of trait.ticks ?? []) walk(tick.effects);
|
|
3751
|
+
for (const field of Object.values(trait.config ?? {})) walk(field.default);
|
|
3752
|
+
return [...found];
|
|
3753
|
+
}
|
|
3645
3754
|
function applyLinkedEntityRename(trait, linkedEntity) {
|
|
3646
3755
|
const atomLinked = trait.linkedEntity;
|
|
3647
3756
|
if (!linkedEntity || !atomLinked || linkedEntity === atomLinked) return trait;
|
|
@@ -3813,6 +3922,8 @@ var ReferenceResolver = class {
|
|
|
3813
3922
|
localTraits;
|
|
3814
3923
|
/** id-keyed mirror of `localTraits`, populated wherever the trait carries an `id`. */
|
|
3815
3924
|
localTraitsById = /* @__PURE__ */ new Map();
|
|
3925
|
+
/** Import scope of each loaded source orbital, keyed by its source path. */
|
|
3926
|
+
sourceImportsCache = /* @__PURE__ */ new Map();
|
|
3816
3927
|
loaderInitialized = false;
|
|
3817
3928
|
constructor(options) {
|
|
3818
3929
|
this.options = options;
|
|
@@ -3869,6 +3980,10 @@ var ReferenceResolver = class {
|
|
|
3869
3980
|
if (!entityResult.success || !traitsResult.success || !pagesResult.success) {
|
|
3870
3981
|
return { success: false, errors: ["Internal error: unexpected failure state"] };
|
|
3871
3982
|
}
|
|
3983
|
+
const pullErrors = await this.pullSiblingTraits(traitsResult.data, imports, importChain);
|
|
3984
|
+
if (pullErrors.length > 0) {
|
|
3985
|
+
return { success: false, errors: pullErrors };
|
|
3986
|
+
}
|
|
3872
3987
|
for (const resolvedTrait of traitsResult.data) {
|
|
3873
3988
|
resolvedTrait.trait = resolveEntityTokensById(resolvedTrait.trait, imports.idIndex);
|
|
3874
3989
|
resolvedTrait.trait = resolveConfigRefsById(resolvedTrait.trait, imports.idIndex);
|
|
@@ -4042,6 +4157,191 @@ var ReferenceResolver = class {
|
|
|
4042
4157
|
}
|
|
4043
4158
|
return { success: true, data: resolved, warnings: [] };
|
|
4044
4159
|
}
|
|
4160
|
+
/**
|
|
4161
|
+
* The import scope of an already-loaded orbital, memoised per source path.
|
|
4162
|
+
* A sibling that is itself a ref names its target through the SOURCE atom's
|
|
4163
|
+
* aliases, so it can only be resolved against those.
|
|
4164
|
+
*/
|
|
4165
|
+
async importsOfSource(imported, chain) {
|
|
4166
|
+
const key = imported.sourcePath ?? `${imported.alias}:${imported.from}`;
|
|
4167
|
+
const cached = this.sourceImportsCache.get(key);
|
|
4168
|
+
if (cached) return cached;
|
|
4169
|
+
const result = await this.resolveImports(
|
|
4170
|
+
imported.orbital.uses ?? [],
|
|
4171
|
+
imported.sourcePath,
|
|
4172
|
+
chain
|
|
4173
|
+
);
|
|
4174
|
+
if (!result.success) return null;
|
|
4175
|
+
result.data.idIndex = buildIdIndex(imported.orbital, result.data.orbitals);
|
|
4176
|
+
this.sourceImportsCache.set(key, result.data);
|
|
4177
|
+
return result.data;
|
|
4178
|
+
}
|
|
4179
|
+
/**
|
|
4180
|
+
* Sibling-trait auto-pull — the JS twin of the compiler's
|
|
4181
|
+
* `phases/inline/trait.rs` pass, appending to `resolved` in place.
|
|
4182
|
+
*
|
|
4183
|
+
* An atom's main trait embeds its own sub-views as `@trait.<Sibling>` string
|
|
4184
|
+
* literals (`std-browse`'s `bodyContent: {children: [@trait.DataGrid1]}`).
|
|
4185
|
+
* A consumer that imports only the main trait never instantiates those
|
|
4186
|
+
* siblings, so the token dangles: no state machine, no fetch, an empty list
|
|
4187
|
+
* where the grid should be. The compiled path materialises them; without this
|
|
4188
|
+
* pass the interpreted path did not, so a raw `.orb` handed straight to
|
|
4189
|
+
* `OrbitalServerRuntime` rendered a different app than the same `.orb` run
|
|
4190
|
+
* through `orbital resolve`.
|
|
4191
|
+
*
|
|
4192
|
+
* Pulls are keyed per EMBEDDER (`owner` = the top-level consumer trait that
|
|
4193
|
+
* started the chain), not per atom. Two rebinds of one atom in one orbital
|
|
4194
|
+
* (`ChannelRail -> Channel` and `ChatThread -> ChatMessage`, both std-browse)
|
|
4195
|
+
* carry different entity rebinds and different hosts to listen to, so one
|
|
4196
|
+
* shared copy can only ever serve one of them. The first owner keeps the
|
|
4197
|
+
* source name; later owners pull under `<Owner><Sibling>` — unique by
|
|
4198
|
+
* construction, since owner names are unique within the orbital.
|
|
4199
|
+
*/
|
|
4200
|
+
async pullSiblingTraits(resolved, imports, chain) {
|
|
4201
|
+
const work = [];
|
|
4202
|
+
const ownerSubs = /* @__PURE__ */ new Map();
|
|
4203
|
+
const subsFor = (owner) => {
|
|
4204
|
+
let m = ownerSubs.get(owner);
|
|
4205
|
+
if (!m) {
|
|
4206
|
+
m = /* @__PURE__ */ new Map();
|
|
4207
|
+
ownerSubs.set(owner, m);
|
|
4208
|
+
}
|
|
4209
|
+
return m;
|
|
4210
|
+
};
|
|
4211
|
+
for (const rt of resolved) {
|
|
4212
|
+
if (rt.source.type !== "imported" || !rt.trait.name) continue;
|
|
4213
|
+
const owner = rt.trait.name;
|
|
4214
|
+
subsFor(owner).set(rt.source.traitName, owner);
|
|
4215
|
+
for (const sibling of traitEmbedNamesOf(rt.trait)) {
|
|
4216
|
+
work.push({ alias: rt.source.alias, sibling, linkedEntity: rt.linkedEntity, parent: owner, owner });
|
|
4217
|
+
}
|
|
4218
|
+
}
|
|
4219
|
+
if (work.length === 0) return [];
|
|
4220
|
+
const errors = [];
|
|
4221
|
+
const consumerDeclared = new Set(resolved.map((r) => r.trait.name).filter(Boolean));
|
|
4222
|
+
const seen = new Set(consumerDeclared);
|
|
4223
|
+
const visited = /* @__PURE__ */ new Set();
|
|
4224
|
+
const pulledAs = /* @__PURE__ */ new Map();
|
|
4225
|
+
const ownerOf = /* @__PURE__ */ new Map();
|
|
4226
|
+
const parentRewrites = /* @__PURE__ */ new Map();
|
|
4227
|
+
const pulled = [];
|
|
4228
|
+
const noteRewrite = (parent, from, to) => {
|
|
4229
|
+
let m = parentRewrites.get(parent);
|
|
4230
|
+
if (!m) {
|
|
4231
|
+
m = /* @__PURE__ */ new Map();
|
|
4232
|
+
parentRewrites.set(parent, m);
|
|
4233
|
+
}
|
|
4234
|
+
m.set(from, to);
|
|
4235
|
+
};
|
|
4236
|
+
for (let item = work.pop(); item !== void 0; item = work.pop()) {
|
|
4237
|
+
const { alias, sibling, linkedEntity, parent, owner } = item;
|
|
4238
|
+
const pullKey = `${alias}\0${sibling}\0${owner}`;
|
|
4239
|
+
const existing = pulledAs.get(pullKey);
|
|
4240
|
+
if (existing !== void 0) {
|
|
4241
|
+
if (existing !== sibling) noteRewrite(parent, sibling, existing);
|
|
4242
|
+
continue;
|
|
4243
|
+
}
|
|
4244
|
+
let finalName = sibling;
|
|
4245
|
+
if (seen.has(sibling)) {
|
|
4246
|
+
if (consumerDeclared.has(sibling)) continue;
|
|
4247
|
+
finalName = `${owner}${sibling}`;
|
|
4248
|
+
if (seen.has(finalName)) continue;
|
|
4249
|
+
}
|
|
4250
|
+
if (visited.has(pullKey)) continue;
|
|
4251
|
+
visited.add(pullKey);
|
|
4252
|
+
const imported = imports.orbitals.get(alias);
|
|
4253
|
+
if (!imported) continue;
|
|
4254
|
+
const atomEntry = findTraitEntryInOrbital(imported.orbital, sibling);
|
|
4255
|
+
if (!atomEntry) continue;
|
|
4256
|
+
let atomTrait;
|
|
4257
|
+
if ("stateMachine" in atomEntry) {
|
|
4258
|
+
const { trait: cfgResolved, errors: cfgErrors } = resolveConfigRefEmitNames(
|
|
4259
|
+
atomEntry
|
|
4260
|
+
);
|
|
4261
|
+
if (cfgErrors.length > 0) {
|
|
4262
|
+
errors.push(...cfgErrors);
|
|
4263
|
+
continue;
|
|
4264
|
+
}
|
|
4265
|
+
atomTrait = cfgResolved;
|
|
4266
|
+
} else {
|
|
4267
|
+
const srcImports = await this.importsOfSource(imported, chain);
|
|
4268
|
+
if (!srcImports) continue;
|
|
4269
|
+
const refObj = atomEntry;
|
|
4270
|
+
const nested = this.resolveTraitRefString(
|
|
4271
|
+
refObj.ref,
|
|
4272
|
+
srcImports,
|
|
4273
|
+
refObj.config,
|
|
4274
|
+
refObj.linkedEntity,
|
|
4275
|
+
refObj.name ?? sibling,
|
|
4276
|
+
refObj.events,
|
|
4277
|
+
refObj.listens,
|
|
4278
|
+
refObj.refId
|
|
4279
|
+
);
|
|
4280
|
+
if (!nested.success) {
|
|
4281
|
+
errors.push(...nested.errors);
|
|
4282
|
+
continue;
|
|
4283
|
+
}
|
|
4284
|
+
atomTrait = nested.data.trait;
|
|
4285
|
+
}
|
|
4286
|
+
let copy = applyLinkedEntityRename(atomTrait, linkedEntity);
|
|
4287
|
+
if (finalName !== sibling) {
|
|
4288
|
+
copy = { ...copy, name: finalName };
|
|
4289
|
+
noteRewrite(parent, sibling, finalName);
|
|
4290
|
+
}
|
|
4291
|
+
for (const next of traitEmbedNamesOf(copy)) {
|
|
4292
|
+
work.push({ alias, sibling: next, linkedEntity, parent: finalName, owner });
|
|
4293
|
+
}
|
|
4294
|
+
pulledAs.set(pullKey, finalName);
|
|
4295
|
+
subsFor(owner).set(sibling, finalName);
|
|
4296
|
+
ownerOf.set(finalName, owner);
|
|
4297
|
+
seen.add(finalName);
|
|
4298
|
+
pulled.push({
|
|
4299
|
+
trait: copy,
|
|
4300
|
+
source: { type: "imported", alias, traitName: sibling },
|
|
4301
|
+
...linkedEntity !== void 0 ? { linkedEntity } : {}
|
|
4302
|
+
});
|
|
4303
|
+
}
|
|
4304
|
+
if (pulled.length === 0 && parentRewrites.size === 0) return errors;
|
|
4305
|
+
const applyRewrites = (rt) => {
|
|
4306
|
+
const subs = rt.trait.name ? parentRewrites.get(rt.trait.name) : void 0;
|
|
4307
|
+
if (subs) rt.trait = renameTraitEmbeds(rt.trait, subs);
|
|
4308
|
+
};
|
|
4309
|
+
for (const rt of resolved) applyRewrites(rt);
|
|
4310
|
+
for (const rt of pulled) applyRewrites(rt);
|
|
4311
|
+
const idByName = /* @__PURE__ */ new Map();
|
|
4312
|
+
for (const rt of [...resolved, ...pulled]) {
|
|
4313
|
+
if (rt.trait.name) idByName.set(rt.trait.name, rt.trait.id);
|
|
4314
|
+
}
|
|
4315
|
+
for (const rt of pulled) {
|
|
4316
|
+
const listens = rt.trait.listens;
|
|
4317
|
+
const owner = rt.trait.name ? ownerOf.get(rt.trait.name) : void 0;
|
|
4318
|
+
const subs = owner ? ownerSubs.get(owner) : void 0;
|
|
4319
|
+
if (!listens || listens.length === 0 || !subs) continue;
|
|
4320
|
+
let changed = false;
|
|
4321
|
+
const nextListens = listens.map((listen) => {
|
|
4322
|
+
const source = listen.source;
|
|
4323
|
+
if (!source || source.kind !== "trait") return listen;
|
|
4324
|
+
const target = subs.get(source.trait);
|
|
4325
|
+
if (target === void 0 || target === source.trait) return listen;
|
|
4326
|
+
changed = true;
|
|
4327
|
+
const traitId = idByName.get(target);
|
|
4328
|
+
return {
|
|
4329
|
+
...listen,
|
|
4330
|
+
source: { kind: "trait", trait: target, ...traitId ? { traitId } : {} }
|
|
4331
|
+
};
|
|
4332
|
+
});
|
|
4333
|
+
if (changed) rt.trait = { ...rt.trait, listens: nextListens };
|
|
4334
|
+
}
|
|
4335
|
+
refResolverLog.info("sibling-pull", {
|
|
4336
|
+
pulled: pulled.map((p) => ({
|
|
4337
|
+
trait: p.trait.name,
|
|
4338
|
+
owner: p.trait.name ? ownerOf.get(p.trait.name) : void 0,
|
|
4339
|
+
linkedEntity: p.linkedEntity ?? p.trait.linkedEntity
|
|
4340
|
+
}))
|
|
4341
|
+
});
|
|
4342
|
+
resolved.push(...pulled);
|
|
4343
|
+
return errors;
|
|
4344
|
+
}
|
|
4045
4345
|
/**
|
|
4046
4346
|
* Resolve a single trait reference.
|
|
4047
4347
|
*/
|
package/dist/index.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { B as BindingContext, f as EvaluationContextExtensions, P as PatternProps, E as EffectHandlers, g as EffectContext, h as ExecutionEnvironment, i as EffectResult, T as TraitDefinition } from './types-p_L8-Sk4.js';
|
|
2
2
|
export { j as BrowserFileMeta, k as BrowserFilePickerOptions, l as BrowserGeolocationOptions, m as BrowserGeolocationPosition, C as ConfigContext, n 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-p_L8-Sk4.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-
|
|
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-
|
|
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-Dz0oubQ_.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-Dz0oubQ_.js';
|
|
5
5
|
import { EvaluationContext, SExpressionEvaluator } from '@almadar/evaluator';
|
|
6
6
|
export { EvaluationContext, createMinimalContext } from '@almadar/evaluator';
|
|
7
7
|
import { TraitConfigObject, EventPayload, PatternConfig, EntityId, EntityField, EntityRow, EntityPersistence, ServiceParams, PayloadField, OrbitalDefinition, OrbitalSchema } from '@almadar/core';
|
|
@@ -585,6 +585,18 @@ declare class MockPersistenceAdapter implements PersistenceAdapter {
|
|
|
585
585
|
private storeNameById;
|
|
586
586
|
private config;
|
|
587
587
|
constructor(config?: MockPersistenceConfig);
|
|
588
|
+
/**
|
|
589
|
+
* Add owner columns discovered after construction.
|
|
590
|
+
*
|
|
591
|
+
* The adapter is built before any schema is registered, so schema-DERIVED
|
|
592
|
+
* owner columns (relation fields pointing at the `[identity]` entity) can
|
|
593
|
+
* only arrive later.
|
|
594
|
+
*
|
|
595
|
+
* ⚠️ Seeding is EAGER — `registerEntity()` seeds immediately — so callers must
|
|
596
|
+
* supply these columns BEFORE registering any orbital. Calling this afterwards
|
|
597
|
+
* silently stamps nothing.
|
|
598
|
+
*/
|
|
599
|
+
addOwnerFields(fields: readonly string[]): void;
|
|
588
600
|
/** Re-anchor the PRNG to the configured seed. Called before every
|
|
589
601
|
* re-seed loop so identical reseed sequences produce identical rows
|
|
590
602
|
* (timestamps + generated fields). Without this, the first
|
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-EJHMWSUS.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, extractBindings, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, interpolateProps, interpolateValue, isBrowser, isElectron, isNamespacedEvent, isNode, isValidDurationString, normalizeCallSiteConfigToValues, normalizeEventKey, parseDurationString, parseNamespacedEvent, preprocessSchema, processEvent, resolveCallSitePayloadCaptures, validateEventPayload, validatePayloadShapes } from './chunk-EJHMWSUS.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';
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@almadar/runtime",
|
|
3
|
-
"version": "6.
|
|
3
|
+
"version": "6.44.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.
|
|
55
|
+
"@almadar/core": "^10.42.0",
|
|
56
56
|
"@almadar/evaluator": "^2.37.0",
|
|
57
57
|
"@almadar/logger": "^1.10.0",
|
|
58
58
|
"@almadar/server": "^2.29.0",
|
|
59
|
-
"@almadar/std": "^16.
|
|
59
|
+
"@almadar/std": "^16.152.0"
|
|
60
60
|
},
|
|
61
61
|
"peerDependencies": {
|
|
62
62
|
"express": "^5.0.0"
|