@almadar/runtime 6.49.0 → 6.51.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.
@@ -1344,6 +1344,13 @@ declare class OrbitalServerRuntime {
1344
1344
  * `OrbitalServerRuntimeConfig.defaultUser`. Pass `undefined` for an
1345
1345
  * unauthenticated viewer. Takes effect on the next event; an authenticated
1346
1346
  * request still overrides it.
1347
+ *
1348
+ * Mock mode seeded owner columns EAGERLY at construction, stamped with
1349
+ * whichever id was `defaultUser` then (see `MockPersistenceAdapter.seed`).
1350
+ * Switching to a different id here would otherwise leave those columns
1351
+ * pointing at the old viewer forever, so an ownership-scoped view for the
1352
+ * new one stays empty — `restampOwner` re-points the already-stamped cells
1353
+ * instead of re-seeding.
1347
1354
  */
1348
1355
  setDefaultUser(user: UserContext | undefined): void;
1349
1356
  /** The viewer a dev host is currently presenting the app as. */
@@ -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-e-5490xl.js';
2
+ export { F as ClientEffectTuple, G as ClientNavigateTuple, H as ClientNotifyTuple, J as ClientRenderUITuple, K as EffectResult, e as InMemoryPersistence, M as LiveBroadcastItem, N as LoaderConfig, O as OrbitalEventRequest, f as OrbitalEventResponse, Q as OrbitalServerRuntime, g as OrbitalServerRuntimeConfig, P as PersistenceAdapter, R as RegisteredOrbital, l as RuntimeOrbital, m as RuntimeOrbitalSchema, n as RuntimeTrait, T as RuntimeTraitTick, p as collectDeclaredConfigDefaults, V as createOrbitalServerRuntime } from './OrbitalServerRuntime-DD9FKDpN.js';
3
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, validateEventPayload, formatPayloadValidationError, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, EffectExecutor } from './chunk-ML75GCRO.js';
2
- export { InMemoryPersistence, collectDeclaredConfigDefaults } from './chunk-ML75GCRO.js';
1
+ import { createTickScheduler, EventBus, createUnifiedLoader, MockPersistenceAdapter, InMemoryPersistence, preprocessSchema, normalizeCallSiteConfigToValues, StateMachineManager, parseDurationString, validateEventPayload, formatPayloadValidationError, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, EffectExecutor } from './chunk-BNTXTICR.js';
2
+ export { InMemoryPersistence, collectDeclaredConfigDefaults } from './chunk-BNTXTICR.js';
3
3
  import { isValidCronExpression } from './chunk-OU3ITB5S.js';
4
4
  import { createContextFromBindings, resolveCallSitePayloadCaptures, applyRowAccess, checkMutationAccess, accessDeniedMessage } from './chunk-XLMDWRMB.js';
5
5
  import './chunk-T4VDAB4C.js';
@@ -915,9 +915,20 @@ var OrbitalServerRuntime = class {
915
915
  * `OrbitalServerRuntimeConfig.defaultUser`. Pass `undefined` for an
916
916
  * unauthenticated viewer. Takes effect on the next event; an authenticated
917
917
  * request still overrides it.
918
+ *
919
+ * Mock mode seeded owner columns EAGERLY at construction, stamped with
920
+ * whichever id was `defaultUser` then (see `MockPersistenceAdapter.seed`).
921
+ * Switching to a different id here would otherwise leave those columns
922
+ * pointing at the old viewer forever, so an ownership-scoped view for the
923
+ * new one stays empty — `restampOwner` re-points the already-stamped cells
924
+ * instead of re-seeding.
918
925
  */
919
926
  setDefaultUser(user) {
927
+ const previousId = this.config.defaultUser?.id;
920
928
  this.config.defaultUser = user;
929
+ if (this.persistence instanceof MockPersistenceAdapter && user?.id !== void 0 && user.id !== previousId) {
930
+ this.persistence.restampOwner(user.id);
931
+ }
921
932
  }
922
933
  /** The viewer a dev host is currently presenting the app as. */
923
934
  getDefaultUser() {
@@ -2108,6 +2108,13 @@ var MockPersistenceAdapter = class {
2108
2108
  /** entityId -> normalized store name, so relation lookups can prefer the id sibling over `relation.entity` name-matching. */
2109
2109
  storeNameById = /* @__PURE__ */ new Map();
2110
2110
  config;
2111
+ /**
2112
+ * Every (entity, row id, column) cell `seed()` stamped with `config.ownerId`.
2113
+ * Seeding is eager and runs once at registration, before a dev host's
2114
+ * viewer is known to have changed — see `restampOwner`, which walks this
2115
+ * list to re-point the stamp when the default user changes later.
2116
+ */
2117
+ ownerStampedCells = [];
2111
2118
  constructor(config = {}) {
2112
2119
  this.config = {
2113
2120
  defaultSeedCount: 6,
@@ -2136,6 +2143,36 @@ var MockPersistenceAdapter = class {
2136
2143
  const merged = /* @__PURE__ */ new Set([...this.config.ownerFields ?? [], ...fields]);
2137
2144
  this.config.ownerFields = [...merged];
2138
2145
  }
2146
+ /**
2147
+ * Re-point every owner-stamped cell from the current `ownerId` to
2148
+ * `newOwnerId`, and remember `newOwnerId` for any future seed.
2149
+ *
2150
+ * Seeding is eager (`registerEntity()` seeds immediately, at construction
2151
+ * time), so the columns above are frozen to whichever id was the default
2152
+ * user THEN — a dev host switching viewers later (`setDefaultUser` /
2153
+ * `POST /persona`) left the stamp pointing at the old id forever, so an
2154
+ * ownership-scoped view for the NEW viewer stayed empty. This does not
2155
+ * re-seed (eager seeding is intentional, see the class doc); it only
2156
+ * re-labels the cells `seed()` already marked as viewer-owned.
2157
+ *
2158
+ * No-op when there is no new id, or it matches the current one — an
2159
+ * anonymous switch (`newOwnerId === undefined`) leaves existing stamps as
2160
+ * they are rather than clearing a non-nullable owner column.
2161
+ */
2162
+ restampOwner(newOwnerId) {
2163
+ const oldOwnerId = this.config.ownerId;
2164
+ this.config.ownerId = newOwnerId;
2165
+ if (!newOwnerId || newOwnerId === oldOwnerId) return;
2166
+ for (const cell of this.ownerStampedCells) {
2167
+ const row = this.stores.get(cell.entity)?.get(cell.id);
2168
+ if (row) row[cell.column] = newOwnerId;
2169
+ }
2170
+ mockLog.debug("mock:owner-restamped", {
2171
+ from: oldOwnerId,
2172
+ to: newOwnerId,
2173
+ cells: this.ownerStampedCells.length
2174
+ });
2175
+ }
2139
2176
  /** Re-anchor the PRNG to the configured seed. Called before every
2140
2177
  * re-seed loop so identical reseed sequences produce identical rows
2141
2178
  * (timestamps + generated fields). Without this, the first
@@ -2271,7 +2308,10 @@ var MockPersistenceAdapter = class {
2271
2308
  for (let i = 0; i < count; i++) {
2272
2309
  const item = this.generateMockItem(entityName, fields, i + 1, persistence);
2273
2310
  if (ownerId && ownerCols.length > 0 && i % 2 === 0) {
2274
- for (const col of ownerCols) item[col] = ownerId;
2311
+ for (const col of ownerCols) {
2312
+ item[col] = ownerId;
2313
+ this.ownerStampedCells.push({ entity: normalized, id: item.id, column: col });
2314
+ }
2275
2315
  }
2276
2316
  store.set(item.id, item);
2277
2317
  generated.push({
@@ -2387,6 +2427,7 @@ var MockPersistenceAdapter = class {
2387
2427
  clearAll() {
2388
2428
  this.stores.clear();
2389
2429
  this.idCounters.clear();
2430
+ this.ownerStampedCells = [];
2390
2431
  this.resetFakerSeed();
2391
2432
  mockLog.debug("mock:adapter:clearAll", { reanchored: this.config.seed });
2392
2433
  }
@@ -4538,12 +4579,13 @@ async function preprocessSchema(schema, options) {
4538
4579
  design: resolvedOrbital.original.design,
4539
4580
  // Gap #22: pass through auxiliary entities so OrbitalServerRuntime's
4540
4581
  // mock-seed branch registers SearchResult / FilterTarget / PagedItem
4541
- // alongside the molecule's primary entity. Without this, an inlined
4542
- // .orb that has `auxiliaryEntities` populated by the Rust inline
4543
- // phase still loses them here, and `(set @entity.searchTerm ...)` /
4544
- // `(fetch SearchResult ...)` from no-rebind imports hit unregistered
4545
- // persistence and silently no-op.
4546
- auxiliaryEntities: resolvedOrbital.original.auxiliaryEntities
4582
+ // alongside the molecule's primary entity and DERIVE them for
4583
+ // no-rebind imported traits. L1-emitted registry .orbs carry no
4584
+ // auxiliaryEntities (only the Rust inline phase adds them, and the
4585
+ // runtime path never runs it), so a trait imported without `-> Entity`
4586
+ // stays bound to its atom's own entity while that entity was never
4587
+ // registered or seeded here — hard zero rows.
4588
+ auxiliaryEntities: deriveAuxiliaryEntities(resolvedOrbital)
4547
4589
  };
4548
4590
  preprocessedOrbitals.push(preprocessedOrbital);
4549
4591
  }
@@ -4561,6 +4603,25 @@ async function preprocessSchema(schema, options) {
4561
4603
  }
4562
4604
  };
4563
4605
  }
4606
+ function deriveAuxiliaryEntities(resolvedOrbital) {
4607
+ const combined = [...resolvedOrbital.original.auxiliaryEntities ?? []];
4608
+ const seen = /* @__PURE__ */ new Set([resolvedOrbital.entity.name]);
4609
+ for (const aux of combined) {
4610
+ if (typeof aux !== "string" && "name" in aux && typeof aux.name === "string") {
4611
+ seen.add(aux.name);
4612
+ }
4613
+ }
4614
+ for (const rt of resolvedOrbital.traits) {
4615
+ if (rt.source.type !== "imported" || rt.linkedEntity) continue;
4616
+ const imported = resolvedOrbital.imports.orbitals.get(rt.source.alias);
4617
+ const entity = imported?.orbital?.entity;
4618
+ if (!entity || typeof entity === "string" || !("fields" in entity) || !entity.name) continue;
4619
+ if (seen.has(entity.name)) continue;
4620
+ seen.add(entity.name);
4621
+ combined.push(entity);
4622
+ }
4623
+ return combined.length > 0 ? combined : void 0;
4624
+ }
4564
4625
  function getIsolatedCollectionName(orbitalName, entitySharing) {
4565
4626
  const info = entitySharing[orbitalName];
4566
4627
  if (!info) {
package/dist/index.d.ts CHANGED
@@ -1,7 +1,7 @@
1
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
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-e-5490xl.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-e-5490xl.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-DD9FKDpN.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-DD9FKDpN.js';
5
5
  import { EvaluationContext, SExpressionEvaluator } from '@almadar/evaluator';
6
6
  export { EvaluationContext, createMinimalContext } from '@almadar/evaluator';
7
7
  import { RenderBindingMarker, SExpr, TraitConfigObject, EventPayload, PatternConfig, EntityId, EntityField, EntityRow, EntityPersistence, ServiceParams, EntityAccessPolicies, PayloadField, OrbitalDefinition, OrbitalSchema } from '@almadar/core';
@@ -616,6 +616,13 @@ declare class MockPersistenceAdapter implements PersistenceAdapter {
616
616
  /** entityId -> normalized store name, so relation lookups can prefer the id sibling over `relation.entity` name-matching. */
617
617
  private storeNameById;
618
618
  private config;
619
+ /**
620
+ * Every (entity, row id, column) cell `seed()` stamped with `config.ownerId`.
621
+ * Seeding is eager and runs once at registration, before a dev host's
622
+ * viewer is known to have changed — see `restampOwner`, which walks this
623
+ * list to re-point the stamp when the default user changes later.
624
+ */
625
+ private ownerStampedCells;
619
626
  constructor(config?: MockPersistenceConfig);
620
627
  /**
621
628
  * Add owner columns discovered after construction.
@@ -629,6 +636,23 @@ declare class MockPersistenceAdapter implements PersistenceAdapter {
629
636
  * silently stamps nothing.
630
637
  */
631
638
  addOwnerFields(fields: readonly string[]): void;
639
+ /**
640
+ * Re-point every owner-stamped cell from the current `ownerId` to
641
+ * `newOwnerId`, and remember `newOwnerId` for any future seed.
642
+ *
643
+ * Seeding is eager (`registerEntity()` seeds immediately, at construction
644
+ * time), so the columns above are frozen to whichever id was the default
645
+ * user THEN — a dev host switching viewers later (`setDefaultUser` /
646
+ * `POST /persona`) left the stamp pointing at the old id forever, so an
647
+ * ownership-scoped view for the NEW viewer stayed empty. This does not
648
+ * re-seed (eager seeding is intentional, see the class doc); it only
649
+ * re-labels the cells `seed()` already marked as viewer-owned.
650
+ *
651
+ * No-op when there is no new id, or it matches the current one — an
652
+ * anonymous switch (`newOwnerId === undefined`) leaves existing stamps as
653
+ * they are rather than clearing a non-nullable owner column.
654
+ */
655
+ restampOwner(newOwnerId: string | undefined): void;
632
656
  /** Re-anchor the PRNG to the configured seed. Called before every
633
657
  * re-seed loop so identical reseed sequences produce identical rows
634
658
  * (timestamps + generated fields). Without this, the first
package/dist/index.js CHANGED
@@ -1,5 +1,5 @@
1
- import { EffectExecutor } from './chunk-ML75GCRO.js';
2
- export { EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, MockPersistenceAdapter, StateMachineManager, TickScheduler, buildEmitsFromTraits, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, createInitialTraitState, createMockPersistence, createTestExecutor, createTickScheduler, createUnifiedLoader, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, isBrowser, isElectron, isNamespacedEvent, isNode, isValidDurationString, normalizeCallSiteConfigToValues, normalizeEventKey, parseDurationString, parseNamespacedEvent, preprocessSchema, processEvent, validateEventPayload, validatePayloadShapes } from './chunk-ML75GCRO.js';
1
+ import { EffectExecutor } from './chunk-BNTXTICR.js';
2
+ export { EffectExecutor, EventBus, HANDLER_MANIFEST, InMemoryPersistence, MockPersistenceAdapter, StateMachineManager, TickScheduler, buildEmitsFromTraits, collectDeclaredConfigDefaults, collectDeclaredEntityDefaults, createInitialTraitState, createMockPersistence, createTestExecutor, createTickScheduler, createUnifiedLoader, findInitialState, findTransition, formatPayloadValidationError, getIsolatedCollectionName, getNamespacedEvent, isBrowser, isElectron, isNamespacedEvent, isNode, isValidDurationString, normalizeCallSiteConfigToValues, normalizeEventKey, parseDurationString, parseNamespacedEvent, preprocessSchema, processEvent, validateEventPayload, validatePayloadShapes } from './chunk-BNTXTICR.js';
3
3
  export { cronMatches, cronMinuteKey, isValidCronExpression, parseCron, parseCronField } from './chunk-OU3ITB5S.js';
4
4
  import { createContextFromBindings, applyRowAccess, checkMutationAccess, accessDeniedMessage } from './chunk-XLMDWRMB.js';
5
5
  export { CALLSITE_PAYLOAD_PREFIX, applyRowAccess, checkMutationAccess, containsBindings, createContextFromBindings, createMinimalContext, deferEntityBindings, extractBindings, interpolateProps, interpolateValue, resolveCallSitePayloadCaptures } from './chunk-XLMDWRMB.js';
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@almadar/runtime",
3
- "version": "6.49.0",
3
+ "version": "6.51.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.49.0",
60
+ "@almadar/core": "^10.52.0",
61
61
  "@almadar/evaluator": "^2.39.0",
62
62
  "@almadar/logger": "^1.11.0",
63
- "@almadar/server": "^2.33.0",
64
- "@almadar/std": "^16.160.0"
63
+ "@almadar/server": "^2.34.0",
64
+ "@almadar/std": "^16.163.0"
65
65
  },
66
66
  "peerDependencies": {
67
67
  "express": "^5.0.0"