@fabricorg/platform 0.10.0 → 0.11.1

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.
Files changed (61) hide show
  1. package/CHANGELOG.md +27 -0
  2. package/README.md +8 -1
  3. package/dist/actions/index.cjs +11 -11
  4. package/dist/actions/index.d.cts +2 -0
  5. package/dist/actions/index.d.ts +2 -0
  6. package/dist/actions/index.js +1 -1
  7. package/dist/{chunk-JSTGOT6P.js → chunk-3WEHM2P3.cjs} +75 -3
  8. package/dist/chunk-3WEHM2P3.cjs.map +1 -0
  9. package/dist/chunk-4MMMXV4Q.js +135 -0
  10. package/dist/chunk-4MMMXV4Q.js.map +1 -0
  11. package/dist/{chunk-Q3WYIWCN.cjs → chunk-FN6IYVBK.js} +67 -5
  12. package/dist/chunk-FN6IYVBK.js.map +1 -0
  13. package/dist/{chunk-BWNPGRRV.cjs → chunk-HLRIXNVG.cjs} +2 -2
  14. package/dist/chunk-HLRIXNVG.cjs.map +1 -0
  15. package/dist/{chunk-54EQTOH6.cjs → chunk-JIT3UR27.cjs} +77 -10
  16. package/dist/chunk-JIT3UR27.cjs.map +1 -0
  17. package/dist/{chunk-4SMPJPJ6.js → chunk-JM55UQWK.js} +2 -2
  18. package/dist/chunk-JM55UQWK.js.map +1 -0
  19. package/dist/chunk-K27DUWRY.cjs +377 -0
  20. package/dist/chunk-K27DUWRY.cjs.map +1 -0
  21. package/dist/{chunk-N72WJ4AU.js → chunk-N3OUWEYA.js} +73 -8
  22. package/dist/chunk-N3OUWEYA.js.map +1 -0
  23. package/dist/chunk-NFHS5NWD.js +369 -0
  24. package/dist/chunk-NFHS5NWD.js.map +1 -0
  25. package/dist/chunk-OC4ZFJKD.cjs +141 -0
  26. package/dist/chunk-OC4ZFJKD.cjs.map +1 -0
  27. package/dist/index.cjs +67 -31
  28. package/dist/index.d.cts +4 -4
  29. package/dist/index.d.ts +4 -4
  30. package/dist/index.js +5 -5
  31. package/dist/manifest/index.cjs +17 -8
  32. package/dist/manifest/index.d.cts +39 -3
  33. package/dist/manifest/index.d.ts +39 -3
  34. package/dist/manifest/index.js +5 -4
  35. package/dist/modules/index.cjs +11 -10
  36. package/dist/modules/index.d.cts +49 -1
  37. package/dist/modules/index.d.ts +49 -1
  38. package/dist/modules/index.js +4 -3
  39. package/dist/objects/index.cjs +9 -5
  40. package/dist/objects/index.d.cts +58 -1
  41. package/dist/objects/index.d.ts +58 -1
  42. package/dist/objects/index.js +1 -1
  43. package/dist/projections/index.cjs +26 -2
  44. package/dist/projections/index.d.cts +38 -2
  45. package/dist/projections/index.d.ts +38 -2
  46. package/dist/projections/index.js +1 -1
  47. package/package.json +1 -1
  48. package/dist/chunk-35DD3H55.js +0 -187
  49. package/dist/chunk-35DD3H55.js.map +0 -1
  50. package/dist/chunk-4SMPJPJ6.js.map +0 -1
  51. package/dist/chunk-54EQTOH6.cjs.map +0 -1
  52. package/dist/chunk-BWNPGRRV.cjs.map +0 -1
  53. package/dist/chunk-I35B576X.js +0 -30
  54. package/dist/chunk-I35B576X.js.map +0 -1
  55. package/dist/chunk-JSTGOT6P.js.map +0 -1
  56. package/dist/chunk-N72WJ4AU.js.map +0 -1
  57. package/dist/chunk-Q3WYIWCN.cjs.map +0 -1
  58. package/dist/chunk-QETQGAXJ.cjs +0 -35
  59. package/dist/chunk-QETQGAXJ.cjs.map +0 -1
  60. package/dist/chunk-SSYKDXR4.cjs +0 -195
  61. package/dist/chunk-SSYKDXR4.cjs.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,32 @@
1
1
  # @fabricorg/platform
2
2
 
3
+ ## 0.11.1
4
+
5
+ ### Patch Changes
6
+
7
+ - Close final uplift audit gaps: align Host 2.x documentation and migration evidence, surface every
8
+ compiler/generator API to LLM consumers, make memory outbox egress directly usable, sanitize relay
9
+ failures, validate complete archetype state maps, support recursive JSON Schema generation, reject
10
+ cross-platform path traversal, synchronize artifact version stamps, and include package licenses.
11
+ - Expand the portable Zod 4 JSON Schema profile, validate exportable schemas without coupling runtime
12
+ registration to non-exportable validators, pause view replay before unsupported versions, and require
13
+ declared dependencies for cross-module relations.
14
+ - Omit non-exportable parameter or result schemas from manifests instead of failing manifest export.
15
+ - Preserve every repeated duplicate-event warning while deduplicating only warnings produced by both
16
+ replay preprocessing and the scoped replay pass.
17
+
18
+ ## 0.11.0
19
+
20
+ ### Minor Changes
21
+
22
+ - **Breaking wire change:** advance `MODULE_MANIFEST_VERSION` from 1 to 2. Consumers must negotiate
23
+ the manifest version; v2 readers can accept v1 input through `normalizeModuleManifest` and
24
+ `normalizeModuleManifestBundle`, but no down-conversion is promised.
25
+ - Add versioned view contracts, manifest export, event-schema filtering, and snapshot compatibility
26
+ without prescribing a physical read-model store.
27
+ - Add manifest v2 typed entity contracts, v1 reader normalization, optional action result schemas, and
28
+ Host enforcement of result validation before events and adapters.
29
+
3
30
  ## 0.10.0
4
31
 
5
32
  ### Minor Changes
package/README.md CHANGED
@@ -58,6 +58,11 @@ That's what this package gives you. Nothing more.
58
58
  | `@fabricorg/platform/objects` | Shared object-type contracts |
59
59
  | `@fabricorg/platform/testing` | In-memory adapter registry, fake `ActionContext`, deterministic IDs |
60
60
 
61
+ Modules may publish versioned `ViewContract`s. `replayView` filters declared event schema versions and
62
+ requires an explicit upgrade function before resuming an older compatible snapshot; manifests serialize
63
+ the logical shape and metadata but never executable functions or initial state. Physical stores remain
64
+ adapter concerns.
65
+
61
66
  ## Composing a vertical
62
67
 
63
68
  Verticals declare a `FabricModule<TDb>` that registers their actions, policies, state machines, events, and adapters with the platform:
@@ -93,7 +98,9 @@ const manifest = exportModuleManifest(myModule);
93
98
  const json = JSON.stringify(manifest, null, 2);
94
99
  ```
95
100
 
96
- `exportModuleManifest` is a pure function of the module object: it does not touch the registries and the module does not need to be registered first. Declaration order is preserved everywhere, so the same module always produces byte-identical JSON. Function fields (`handler`, policy `evaluate`, transition `guard`, dynamic `targetState`, adapter `getInput`) are never serialized — the manifest contains definitions only, never raw parameter values, secrets, or runtime data. Actions whose schema validator exposes `toJSONSchema()` (for example Zod 4) include a `parameterSchema` in JSON Schema format. Use `exportModuleManifestBundle(modules)` to export several modules at once.
101
+ `exportModuleManifest` is a pure function of the module object: it does not touch the registries and the module does not need to be registered first. Declaration order is preserved everywhere, so the same module always produces byte-identical JSON. Function fields (`handler`, policy `evaluate`, transition `guard`, dynamic `targetState`, adapter `getInput`) are never serialized — the manifest contains definitions only, never raw parameter values, secrets, or runtime data. Manifest v2 object registrations may include `PortableJsonSchema`, qualified relations, namespaced semantic annotations, and enforcement-owned invariants. Actions whose validators expose `toJSONSchema()` include `parameterSchema` and optional `resultSchema` definitions. `normalizeModuleManifest` and `normalizeModuleManifestBundle` let v2 readers accept v1 input without promising down-conversion.
102
+
103
+ An entity schema does not validate arbitrary writes through `TDb`. Persisted-record validation requires an explicit Host/database adapter. When an action declares `resultSchema`, Platform Host validates the public result after the handler and before events or adapters; failure rolls back domain writes only when the Host store has a transaction provider that includes them.
97
104
 
98
105
  ## The action lifecycle
99
106
 
@@ -1,48 +1,48 @@
1
1
  'use strict';
2
2
 
3
- var chunkBWNPGRRV_cjs = require('../chunk-BWNPGRRV.cjs');
3
+ var chunkHLRIXNVG_cjs = require('../chunk-HLRIXNVG.cjs');
4
4
 
5
5
 
6
6
 
7
7
  Object.defineProperty(exports, "ACTOR_TYPES", {
8
8
  enumerable: true,
9
- get: function () { return chunkBWNPGRRV_cjs.ACTOR_TYPES; }
9
+ get: function () { return chunkHLRIXNVG_cjs.ACTOR_TYPES; }
10
10
  });
11
11
  Object.defineProperty(exports, "assertActionId", {
12
12
  enumerable: true,
13
- get: function () { return chunkBWNPGRRV_cjs.assertActionId; }
13
+ get: function () { return chunkHLRIXNVG_cjs.assertActionId; }
14
14
  });
15
15
  Object.defineProperty(exports, "assertActorType", {
16
16
  enumerable: true,
17
- get: function () { return chunkBWNPGRRV_cjs.assertActorType; }
17
+ get: function () { return chunkHLRIXNVG_cjs.assertActorType; }
18
18
  });
19
19
  Object.defineProperty(exports, "getRegisteredActionIds", {
20
20
  enumerable: true,
21
- get: function () { return chunkBWNPGRRV_cjs.getRegisteredActionIds; }
21
+ get: function () { return chunkHLRIXNVG_cjs.getRegisteredActionIds; }
22
22
  });
23
23
  Object.defineProperty(exports, "isActorType", {
24
24
  enumerable: true,
25
- get: function () { return chunkBWNPGRRV_cjs.isActorType; }
25
+ get: function () { return chunkHLRIXNVG_cjs.isActorType; }
26
26
  });
27
27
  Object.defineProperty(exports, "isRegisteredActionId", {
28
28
  enumerable: true,
29
- get: function () { return chunkBWNPGRRV_cjs.isRegisteredActionId; }
29
+ get: function () { return chunkHLRIXNVG_cjs.isRegisteredActionId; }
30
30
  });
31
31
  Object.defineProperty(exports, "registerAction", {
32
32
  enumerable: true,
33
- get: function () { return chunkBWNPGRRV_cjs.registerAction; }
33
+ get: function () { return chunkHLRIXNVG_cjs.registerAction; }
34
34
  });
35
35
  Object.defineProperty(exports, "registerActionIfMissing", {
36
36
  enumerable: true,
37
- get: function () { return chunkBWNPGRRV_cjs.registerActionIfMissing; }
37
+ get: function () { return chunkHLRIXNVG_cjs.registerActionIfMissing; }
38
38
  });
39
39
  Object.defineProperty(exports, "resolveAction", {
40
40
  enumerable: true,
41
- get: function () { return chunkBWNPGRRV_cjs.resolveAction; }
41
+ get: function () { return chunkHLRIXNVG_cjs.resolveAction; }
42
42
  });
43
43
  Object.defineProperty(exports, "resolveRegisteredAction", {
44
44
  enumerable: true,
45
- get: function () { return chunkBWNPGRRV_cjs.resolveRegisteredAction; }
45
+ get: function () { return chunkHLRIXNVG_cjs.resolveRegisteredAction; }
46
46
  });
47
47
  //# sourceMappingURL=index.cjs.map
48
48
  //# sourceMappingURL=index.cjs.map
@@ -64,6 +64,8 @@ interface ActionDefinition<TDb = unknown> {
64
64
  namespace: string;
65
65
  version: number;
66
66
  schema: SchemaValidator;
67
+ /** Optional validation contract for the public handler result data. */
68
+ resultSchema?: SchemaValidator;
67
69
  handler?: ActionHandler<TDb>;
68
70
  requiredRoles?: string[];
69
71
  requiredPermissions?: string[];
@@ -64,6 +64,8 @@ interface ActionDefinition<TDb = unknown> {
64
64
  namespace: string;
65
65
  version: number;
66
66
  schema: SchemaValidator;
67
+ /** Optional validation contract for the public handler result data. */
68
+ resultSchema?: SchemaValidator;
67
69
  handler?: ActionHandler<TDb>;
68
70
  requiredRoles?: string[];
69
71
  requiredPermissions?: string[];
@@ -1,3 +1,3 @@
1
- export { ACTOR_TYPES, assertActionId, assertActorType, getRegisteredActionIds, isActorType, isRegisteredActionId, registerAction, registerActionIfMissing, resolveAction, resolveRegisteredAction } from '../chunk-4SMPJPJ6.js';
1
+ export { ACTOR_TYPES, assertActionId, assertActorType, getRegisteredActionIds, isActorType, isRegisteredActionId, registerAction, registerActionIfMissing, resolveAction, resolveRegisteredAction } from '../chunk-JM55UQWK.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -1,4 +1,70 @@
1
+ 'use strict';
2
+
1
3
  // projections/index.ts
4
+ var viewRegistry = /* @__PURE__ */ new Map();
5
+ function viewContractKey(view) {
6
+ return `${view.name}@${view.version}`;
7
+ }
8
+ function registerViewContract(view) {
9
+ const key = viewContractKey(view);
10
+ if (viewRegistry.has(key)) throw new Error(`View contract "${key}" is already registered.`);
11
+ viewRegistry.set(key, view);
12
+ }
13
+ function registerViewContractIfMissing(view) {
14
+ if (!viewRegistry.has(viewContractKey(view))) registerViewContract(view);
15
+ }
16
+ function resolveViewContract(name, version) {
17
+ return viewRegistry.get(`${name}@${version}`);
18
+ }
19
+ function getRegisteredViewContractKeys() {
20
+ return Array.from(viewRegistry.keys());
21
+ }
22
+ async function replayView({
23
+ view,
24
+ events,
25
+ scope,
26
+ snapshot
27
+ }) {
28
+ if (snapshot && snapshot.snapshotVersion !== view.snapshotVersion && !view.compatibleSnapshotVersions?.includes(snapshot.snapshotVersion)) {
29
+ throw new Error(
30
+ `View "${viewContractKey(view)}" cannot resume snapshot version ${snapshot.snapshotVersion}.`
31
+ );
32
+ }
33
+ if (snapshot && snapshot.snapshotVersion !== view.snapshotVersion && !view.upgradeSnapshot) {
34
+ throw new Error(
35
+ `View "${viewContractKey(view)}" must provide upgradeSnapshot for snapshot version ${snapshot.snapshotVersion}.`
36
+ );
37
+ }
38
+ const upgradedSnapshot = snapshot && snapshot.snapshotVersion !== view.snapshotVersion ? { ...snapshot, snapshotVersion: view.snapshotVersion, snapshotData: await view.upgradeSnapshot(snapshot.snapshotData, snapshot.snapshotVersion) } : snapshot;
39
+ const accepted = new Map(
40
+ view.consumes.map((consumption) => [consumption.eventType, new Set(consumption.schemaVersions)])
41
+ );
42
+ const sourceEvents = [];
43
+ for await (const event of events) sourceEvents.push(event);
44
+ const preprocessingWarnings = [];
45
+ const orderedScopedEvents = sortEvents(filterEventsByScope(sourceEvents, scope, preprocessingWarnings), Boolean(scope.subjectType && scope.subjectId));
46
+ const versionWarnings = [];
47
+ const replayable = async function* () {
48
+ for (const event of orderedScopedEvents) {
49
+ const versions = accepted.get(event.eventType);
50
+ if (versions && !versions.has(event.eventSchemaVersion ?? 1)) {
51
+ versionWarnings.push({ code: "unsupported_event_version", eventId: event.id, message: `View "${viewContractKey(view)}" does not consume ${event.eventType} schema version ${event.eventSchemaVersion ?? 1}; replay stopped before this event so a compatible view can resume it later.` });
52
+ return;
53
+ }
54
+ yield event;
55
+ }
56
+ };
57
+ const result = await replayEvents({
58
+ events: replayable(),
59
+ scope,
60
+ initialState: view.initialState,
61
+ snapshot: upgradedSnapshot,
62
+ applyEvent: (state, event) => accepted.has(event.eventType) ? view.applyEvent(state, event) : state
63
+ });
64
+ const preprocessingWarningKeys = new Set(preprocessingWarnings.map((warning) => JSON.stringify(warning)));
65
+ const resultWarnings = result.warnings.filter((warning) => !preprocessingWarningKeys.has(JSON.stringify(warning)));
66
+ return { ...result, warnings: [...preprocessingWarnings, ...versionWarnings, ...resultWarnings] };
67
+ }
2
68
  async function replayEvents({
3
69
  events,
4
70
  scope,
@@ -176,6 +242,12 @@ function toTimestamp(value) {
176
242
  return value instanceof Date ? value.getTime() : new Date(value).getTime();
177
243
  }
178
244
 
179
- export { replayEvents };
180
- //# sourceMappingURL=chunk-JSTGOT6P.js.map
181
- //# sourceMappingURL=chunk-JSTGOT6P.js.map
245
+ exports.getRegisteredViewContractKeys = getRegisteredViewContractKeys;
246
+ exports.registerViewContract = registerViewContract;
247
+ exports.registerViewContractIfMissing = registerViewContractIfMissing;
248
+ exports.replayEvents = replayEvents;
249
+ exports.replayView = replayView;
250
+ exports.resolveViewContract = resolveViewContract;
251
+ exports.viewContractKey = viewContractKey;
252
+ //# sourceMappingURL=chunk-3WEHM2P3.cjs.map
253
+ //# sourceMappingURL=chunk-3WEHM2P3.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../projections/index.ts"],"names":[],"mappings":"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","file":"chunk-3WEHM2P3.cjs","sourcesContent":["export interface ReplayableAssetEvent<Payload = unknown> {\n\tid: string;\n\ttenantId: string;\n\tspaceId: string;\n\teventType: string;\n\teventSchemaVersion?: number;\n\tsubjectType: string;\n\tsubjectId: string;\n\tpayload: Payload;\n\tsequence: number;\n\toccurredAt: Date | string;\n\trecordedAt: Date | string;\n\tactionInvocationId: string;\n\tcorrelationId: string;\n}\n\nimport type { PortableJsonSchema } from \"../objects\";\n\nexport interface ViewEventConsumption {\n\teventType: string;\n\tschemaVersions: number[];\n}\n\nexport interface ViewContract<State = unknown, Event extends ReplayableAssetEvent = ReplayableAssetEvent> {\n\t/** Stable module-qualified logical identity, for example `orders/summary`. */\n\tname: `${string}/${string}`;\n\tversion: string;\n\tshape: PortableJsonSchema;\n\tconsumes: ViewEventConsumption[];\n\tscope: \"tenant-space\";\n\tsnapshotVersion: number;\n\tcompatibleSnapshotVersions?: number[];\n\t/** Required to transform any older compatible snapshot into the current state shape. */\n\tupgradeSnapshot?: (data: unknown, fromVersion: number) => State | Promise<State>;\n\tinitialState: State;\n\tapplyEvent: (state: State, event: Event) => State | Promise<State>;\n}\n\nconst viewRegistry = new Map<string, ViewContract>();\n\nexport function viewContractKey(view: Pick<ViewContract, \"name\" | \"version\">): string {\n\treturn `${view.name}@${view.version}`;\n}\n\nexport function registerViewContract(view: ViewContract): void {\n\tconst key = viewContractKey(view);\n\tif (viewRegistry.has(key)) throw new Error(`View contract \"${key}\" is already registered.`);\n\tviewRegistry.set(key, view);\n}\n\nexport function registerViewContractIfMissing(view: ViewContract): void {\n\tif (!viewRegistry.has(viewContractKey(view))) registerViewContract(view);\n}\n\nexport function resolveViewContract(name: string, version: string): ViewContract | undefined {\n\treturn viewRegistry.get(`${name}@${version}`);\n}\n\nexport function getRegisteredViewContractKeys(): string[] {\n\treturn Array.from(viewRegistry.keys());\n}\n\nexport interface ReplayViewOptions<State, Event extends ReplayableAssetEvent = ReplayableAssetEvent> {\n\tview: ViewContract<State, Event>;\n\tevents: Iterable<Event> | AsyncIterable<Event>;\n\tscope: ReplayScope;\n\tsnapshot?: (ReplaySnapshot<State> & { snapshotVersion: number }) | null;\n}\n\nexport async function replayView<State, Event extends ReplayableAssetEvent = ReplayableAssetEvent>({\n\tview,\n\tevents,\n\tscope,\n\tsnapshot,\n}: ReplayViewOptions<State, Event>): Promise<ReplayEventsResult<State, Event>> {\n\tif (\n\t\tsnapshot &&\n\t\tsnapshot.snapshotVersion !== view.snapshotVersion &&\n\t\t!view.compatibleSnapshotVersions?.includes(snapshot.snapshotVersion)\n\t) {\n\t\tthrow new Error(\n\t\t\t`View \"${viewContractKey(view)}\" cannot resume snapshot version ${snapshot.snapshotVersion}.`,\n\t\t);\n\t}\n\tif (snapshot && snapshot.snapshotVersion !== view.snapshotVersion && !view.upgradeSnapshot) {\n\t\tthrow new Error(\n\t\t\t`View \"${viewContractKey(view)}\" must provide upgradeSnapshot for snapshot version ${snapshot.snapshotVersion}.`,\n\t\t);\n\t}\n\tconst upgradedSnapshot = snapshot && snapshot.snapshotVersion !== view.snapshotVersion\n\t\t? { ...snapshot, snapshotVersion: view.snapshotVersion, snapshotData: await view.upgradeSnapshot!(snapshot.snapshotData, snapshot.snapshotVersion) }\n\t\t: snapshot;\n\tconst accepted = new Map(\n\t\tview.consumes.map((consumption) => [consumption.eventType, new Set(consumption.schemaVersions)]),\n\t);\n\tconst sourceEvents: Event[] = [];\n\tfor await (const event of events) sourceEvents.push(event);\n\tconst preprocessingWarnings: ReplayWarning[] = [];\n\tconst orderedScopedEvents = sortEvents(filterEventsByScope(sourceEvents, scope, preprocessingWarnings), Boolean(scope.subjectType && scope.subjectId));\n\tconst versionWarnings: ReplayWarning[] = [];\n\tconst replayable = async function* (): AsyncIterable<Event> {\n\t\tfor (const event of orderedScopedEvents) {\n\t\t\tconst versions = accepted.get(event.eventType);\n\t\t\tif (versions && !versions.has(event.eventSchemaVersion ?? 1)) {\n\t\t\t\tversionWarnings.push({ code: \"unsupported_event_version\", eventId: event.id, message: `View \"${viewContractKey(view)}\" does not consume ${event.eventType} schema version ${event.eventSchemaVersion ?? 1}; replay stopped before this event so a compatible view can resume it later.` });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tyield event;\n\t\t}\n\t};\n\tconst result = await replayEvents({\n\t\tevents: replayable(),\n\t\tscope,\n\t\tinitialState: view.initialState,\n\t\tsnapshot: upgradedSnapshot,\n\t\tapplyEvent: (state, event) => accepted.has(event.eventType) ? view.applyEvent(state, event) : state,\n\t});\n\tconst preprocessingWarningKeys = new Set(preprocessingWarnings.map((warning) => JSON.stringify(warning)));\n\tconst resultWarnings = result.warnings.filter((warning) => !preprocessingWarningKeys.has(JSON.stringify(warning)));\n\treturn { ...result, warnings: [...preprocessingWarnings, ...versionWarnings, ...resultWarnings] };\n}\n\nexport interface ReplayScope {\n\ttenantId: string;\n\tspaceId: string;\n\tsubjectType?: string;\n\tsubjectId?: string;\n}\n\nexport interface ReplaySnapshot<State = unknown> {\n\tsnapshotData: State;\n\teventCursor?: string | null;\n\teventSequence?: number | null;\n}\n\nexport type ReplayWarningCode =\n\t| \"cursor_not_found\"\n\t| \"duplicate_event\"\n\t| \"missing_sequence\"\n\t| \"subject_scope_incomplete\"\n\t| \"unsupported_event_version\";\n\nexport interface ReplayWarning {\n\tcode: ReplayWarningCode;\n\tmessage: string;\n\teventId?: string;\n\tsubjectType?: string;\n\tsubjectId?: string;\n\texpectedSequence?: number;\n\tactualSequence?: number;\n}\n\nexport interface ReplayEventsOptions<State, Event extends ReplayableAssetEvent = ReplayableAssetEvent> {\n\tevents: Iterable<Event> | AsyncIterable<Event>;\n\tscope: ReplayScope;\n\tinitialState: State;\n\tsnapshot?: ReplaySnapshot<State> | null;\n\tapplyEvent: (state: State, event: Event) => State | Promise<State>;\n}\n\nexport interface ReplayEventsResult<State, Event extends ReplayableAssetEvent = ReplayableAssetEvent> {\n\tstate: State;\n\tappliedEvents: Event[];\n\twarnings: ReplayWarning[];\n\teventCursor: string | null;\n\teventSequence: number;\n}\n\nexport async function replayEvents<State, Event extends ReplayableAssetEvent = ReplayableAssetEvent>({\n\tevents,\n\tscope,\n\tinitialState,\n\tsnapshot,\n\tapplyEvent,\n}: ReplayEventsOptions<State, Event>): Promise<ReplayEventsResult<State, Event>> {\n\tconst warnings: ReplayWarning[] = [];\n\tconst scopedEvents = filterEventsByScope(await collectEvents(events), scope, warnings);\n\tconst orderedEvents = sortEvents(scopedEvents, isSubjectScoped(scope));\n\tconst uniqueEvents = removeDuplicateEvents(orderedEvents, warnings);\n\tconst resumableEvents = applyCursor(uniqueEvents, snapshot, isSubjectScoped(scope), warnings);\n\n\tlet state = snapshot?.snapshotData ?? initialState;\n\tconst appliedEvents: Event[] = [];\n\tlet eventCursor = snapshot?.eventCursor ?? null;\n\tlet eventSequence = snapshot?.eventSequence ?? 0;\n\n\tfor (const event of resumableEvents) {\n\t\tstate = await applyEvent(state, event);\n\t\tappliedEvents.push(event);\n\t\teventCursor = event.id;\n\t\teventSequence = event.sequence;\n\t}\n\n\treturn {\n\t\tstate,\n\t\tappliedEvents,\n\t\twarnings,\n\t\teventCursor,\n\t\teventSequence,\n\t};\n}\n\nasync function collectEvents<Event extends ReplayableAssetEvent>(\n\tevents: Iterable<Event> | AsyncIterable<Event>,\n): Promise<Event[]> {\n\tconst collected: Event[] = [];\n\n\tif (Symbol.asyncIterator in events) {\n\t\tfor await (const event of events) {\n\t\t\tcollected.push(event);\n\t\t}\n\n\t\treturn collected;\n\t}\n\n\tfor (const event of events) {\n\t\tcollected.push(event);\n\t}\n\n\treturn collected;\n}\n\nfunction filterEventsByScope<Event extends ReplayableAssetEvent>(\n\tevents: Event[],\n\tscope: ReplayScope,\n\twarnings: ReplayWarning[],\n): Event[] {\n\tif ((scope.subjectType && !scope.subjectId) || (!scope.subjectType && scope.subjectId)) {\n\t\twarnings.push({\n\t\t\tcode: \"subject_scope_incomplete\",\n\t\t\tmessage: \"Both subjectType and subjectId are required for subject-scoped replay.\",\n\t\t\tsubjectType: scope.subjectType,\n\t\t\tsubjectId: scope.subjectId,\n\t\t});\n\t}\n\n\treturn events.filter((event) => {\n\t\tif (event.tenantId !== scope.tenantId || event.spaceId !== scope.spaceId) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (scope.subjectType && event.subjectType !== scope.subjectType) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (scope.subjectId && event.subjectId !== scope.subjectId) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t});\n}\n\nfunction removeDuplicateEvents<Event extends ReplayableAssetEvent>(\n\tevents: Event[],\n\twarnings: ReplayWarning[],\n): Event[] {\n\tconst seenEventIds = new Set<string>();\n\tconst uniqueEvents: Event[] = [];\n\n\tfor (const event of events) {\n\t\tif (seenEventIds.has(event.id)) {\n\t\t\twarnings.push({\n\t\t\t\tcode: \"duplicate_event\",\n\t\t\t\tmessage: `Duplicate event ${event.id} ignored during replay.`,\n\t\t\t\teventId: event.id,\n\t\t\t\tsubjectType: event.subjectType,\n\t\t\t\tsubjectId: event.subjectId,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tseenEventIds.add(event.id);\n\t\tuniqueEvents.push(event);\n\t}\n\n\trecordMissingSequenceWarnings(uniqueEvents, warnings);\n\n\treturn uniqueEvents;\n}\n\nfunction recordMissingSequenceWarnings<Event extends ReplayableAssetEvent>(\n\tevents: Event[],\n\twarnings: ReplayWarning[],\n): void {\n\tconst lastSequenceBySubject = new Map<string, number>();\n\n\tfor (const event of events) {\n\t\tconst subjectKey = `${event.subjectType}:${event.subjectId}`;\n\t\tconst previousSequence = lastSequenceBySubject.get(subjectKey);\n\t\tconst expectedSequence = previousSequence === undefined ? event.sequence : previousSequence + 1;\n\n\t\tif (previousSequence !== undefined && event.sequence > expectedSequence) {\n\t\t\twarnings.push({\n\t\t\t\tcode: \"missing_sequence\",\n\t\t\t\tmessage: `Missing event sequence for ${subjectKey}: expected ${expectedSequence}, received ${event.sequence}.`,\n\t\t\t\teventId: event.id,\n\t\t\t\tsubjectType: event.subjectType,\n\t\t\t\tsubjectId: event.subjectId,\n\t\t\t\texpectedSequence,\n\t\t\t\tactualSequence: event.sequence,\n\t\t\t});\n\t\t}\n\n\t\tlastSequenceBySubject.set(subjectKey, Math.max(previousSequence ?? event.sequence, event.sequence));\n\t}\n}\n\nfunction applyCursor<Event extends ReplayableAssetEvent>(\n\tevents: Event[],\n\tsnapshot: ReplaySnapshot | null | undefined,\n\tsubjectScoped: boolean,\n\twarnings: ReplayWarning[],\n): Event[] {\n\tconst eventCursor = snapshot?.eventCursor;\n\n\tif (eventCursor) {\n\t\tconst cursorIndex = events.findIndex((event) => event.id === eventCursor);\n\n\t\tif (cursorIndex >= 0) {\n\t\t\treturn events.slice(cursorIndex + 1);\n\t\t}\n\n\t\twarnings.push({\n\t\t\tcode: \"cursor_not_found\",\n\t\t\tmessage: `Snapshot cursor ${eventCursor} was not found in the scoped event stream.`,\n\t\t\teventId: eventCursor,\n\t\t});\n\t}\n\n\tif (subjectScoped && snapshot?.eventSequence !== undefined && snapshot.eventSequence !== null) {\n\t\treturn events.filter((event) => event.sequence > snapshot.eventSequence!);\n\t}\n\n\treturn events;\n}\n\nfunction sortEvents<Event extends ReplayableAssetEvent>(events: Event[], subjectScoped: boolean): Event[] {\n\treturn [...events].sort((first, second) =>\n\t\tsubjectScoped ? compareSubjectEvents(first, second) : compareGlobalEvents(first, second),\n\t);\n}\n\nfunction compareSubjectEvents(first: ReplayableAssetEvent, second: ReplayableAssetEvent): number {\n\treturn compareValues(\n\t\t[first.sequence, toTimestamp(first.recordedAt), toTimestamp(first.occurredAt), first.id],\n\t\t[second.sequence, toTimestamp(second.recordedAt), toTimestamp(second.occurredAt), second.id],\n\t);\n}\n\nfunction compareGlobalEvents(first: ReplayableAssetEvent, second: ReplayableAssetEvent): number {\n\treturn compareValues(\n\t\t[\n\t\t\ttoTimestamp(first.recordedAt),\n\t\t\ttoTimestamp(first.occurredAt),\n\t\t\tfirst.actionInvocationId,\n\t\t\tfirst.correlationId,\n\t\t\tfirst.subjectType,\n\t\t\tfirst.subjectId,\n\t\t\tfirst.sequence,\n\t\t\tfirst.id,\n\t\t],\n\t\t[\n\t\t\ttoTimestamp(second.recordedAt),\n\t\t\ttoTimestamp(second.occurredAt),\n\t\t\tsecond.actionInvocationId,\n\t\t\tsecond.correlationId,\n\t\t\tsecond.subjectType,\n\t\t\tsecond.subjectId,\n\t\t\tsecond.sequence,\n\t\t\tsecond.id,\n\t\t],\n\t);\n}\n\nfunction compareValues(firstValues: Array<number | string>, secondValues: Array<number | string>): number {\n\tfor (const [index, firstValue] of firstValues.entries()) {\n\t\tconst secondValue = secondValues[index];\n\n\t\tif (firstValue < secondValue) {\n\t\t\treturn -1;\n\t\t}\n\n\t\tif (firstValue > secondValue) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nfunction isSubjectScoped(scope: ReplayScope): boolean {\n\treturn Boolean(scope.subjectType && scope.subjectId);\n}\n\nfunction toTimestamp(value: Date | string): number {\n\treturn value instanceof Date ? value.getTime() : new Date(value).getTime();\n}\n"]}
@@ -0,0 +1,135 @@
1
+ // objects/index.ts
2
+ var objectTypeRegistry = /* @__PURE__ */ new Set([
3
+ "AssetEvent",
4
+ "ActionInvocation",
5
+ "PolicyEvaluation",
6
+ "ApprovalRequest",
7
+ "ConsentRecord",
8
+ "AgentRun"
9
+ ]);
10
+ var supportedSchemaKeywords = /* @__PURE__ */ new Set([
11
+ "$schema",
12
+ "$id",
13
+ "$ref",
14
+ "$defs",
15
+ "title",
16
+ "description",
17
+ "type",
18
+ "enum",
19
+ "const",
20
+ "properties",
21
+ "required",
22
+ "additionalProperties",
23
+ "items",
24
+ "prefixItems",
25
+ "propertyNames",
26
+ "patternProperties",
27
+ "dependentRequired",
28
+ "allOf",
29
+ "anyOf",
30
+ "oneOf",
31
+ "not",
32
+ "minimum",
33
+ "maximum",
34
+ "exclusiveMinimum",
35
+ "exclusiveMaximum",
36
+ "minLength",
37
+ "maxLength",
38
+ "pattern",
39
+ "format",
40
+ "minItems",
41
+ "maxItems",
42
+ "uniqueItems",
43
+ "default",
44
+ "readOnly",
45
+ "writeOnly",
46
+ "deprecated",
47
+ "contentEncoding",
48
+ "contentMediaType",
49
+ "multipleOf",
50
+ "if",
51
+ "then",
52
+ "else",
53
+ "examples",
54
+ "$comment"
55
+ ]);
56
+ function assertPortableJsonSchema(schema, path = "schema") {
57
+ if (!schema || typeof schema !== "object" || Array.isArray(schema)) {
58
+ throw new Error(`${path} must be a JSON Schema object.`);
59
+ }
60
+ const value = schema;
61
+ for (const keyword of Object.keys(value)) {
62
+ if (!supportedSchemaKeywords.has(keyword) && !keyword.startsWith("x-")) {
63
+ throw new Error(`${path} uses unsupported JSON Schema keyword "${keyword}".`);
64
+ }
65
+ }
66
+ if (value.properties !== void 0) {
67
+ if (!value.properties || typeof value.properties !== "object" || Array.isArray(value.properties)) {
68
+ throw new Error(`${path}.properties must be an object.`);
69
+ }
70
+ for (const [name, child] of Object.entries(value.properties)) {
71
+ assertPortableJsonSchema(child, `${path}.properties.${name}`);
72
+ }
73
+ }
74
+ if (value.$defs !== void 0) {
75
+ if (!value.$defs || typeof value.$defs !== "object" || Array.isArray(value.$defs)) {
76
+ throw new Error(`${path}.$defs must be an object.`);
77
+ }
78
+ for (const [name, child] of Object.entries(value.$defs)) {
79
+ assertPortableJsonSchema(child, `${path}.$defs.${name}`);
80
+ }
81
+ }
82
+ if (value.patternProperties !== void 0) {
83
+ if (!value.patternProperties || typeof value.patternProperties !== "object" || Array.isArray(value.patternProperties)) throw new Error(`${path}.patternProperties must be an object.`);
84
+ for (const [name, child] of Object.entries(value.patternProperties)) assertPortableJsonSchema(child, `${path}.patternProperties.${name}`);
85
+ }
86
+ for (const keyword of ["allOf", "anyOf", "oneOf"]) {
87
+ if (value[keyword] !== void 0) {
88
+ if (!Array.isArray(value[keyword])) throw new Error(`${path}.${keyword} must be an array.`);
89
+ value[keyword].forEach((child, index) => assertPortableJsonSchema(child, `${path}.${keyword}[${index}]`));
90
+ }
91
+ }
92
+ if (value.not !== void 0) assertPortableJsonSchema(value.not, `${path}.not`);
93
+ for (const keyword of ["propertyNames", "if", "then", "else"]) if (value[keyword] !== void 0) assertPortableJsonSchema(value[keyword], `${path}.${keyword}`);
94
+ if (value.additionalProperties !== void 0 && typeof value.additionalProperties !== "boolean") {
95
+ assertPortableJsonSchema(value.additionalProperties, `${path}.additionalProperties`);
96
+ }
97
+ if (value.items !== void 0) {
98
+ if (Array.isArray(value.items)) {
99
+ value.items.forEach((child, index) => assertPortableJsonSchema(child, `${path}.items[${index}]`));
100
+ } else {
101
+ assertPortableJsonSchema(value.items, `${path}.items`);
102
+ }
103
+ }
104
+ if (value.prefixItems !== void 0) {
105
+ if (!Array.isArray(value.prefixItems)) throw new Error(`${path}.prefixItems must be an array.`);
106
+ value.prefixItems.forEach((child, index) => assertPortableJsonSchema(child, `${path}.prefixItems[${index}]`));
107
+ }
108
+ if (value.dependentRequired !== void 0) {
109
+ if (!value.dependentRequired || typeof value.dependentRequired !== "object" || Array.isArray(value.dependentRequired) || Object.values(value.dependentRequired).some((items) => !Array.isArray(items) || items.some((item) => typeof item !== "string"))) throw new Error(`${path}.dependentRequired must map property names to arrays of property names.`);
110
+ }
111
+ if (value.required !== void 0 && (!Array.isArray(value.required) || value.required.some((item) => typeof item !== "string"))) {
112
+ throw new Error(`${path}.required must be an array of property names.`);
113
+ }
114
+ }
115
+ function assertObjectType(type) {
116
+ if (!/^[A-Z][a-zA-Z0-9]*$/.test(type)) {
117
+ throw new Error(
118
+ `Invalid object type: "${type}". Object types must be PascalCase alphanumeric.`
119
+ );
120
+ }
121
+ }
122
+ function registerObjectType(type) {
123
+ assertObjectType(type);
124
+ objectTypeRegistry.add(type);
125
+ }
126
+ function isValidObjectType(type) {
127
+ return objectTypeRegistry.has(type);
128
+ }
129
+ function getRegisteredObjectTypes() {
130
+ return Array.from(objectTypeRegistry);
131
+ }
132
+
133
+ export { assertObjectType, assertPortableJsonSchema, getRegisteredObjectTypes, isValidObjectType, registerObjectType };
134
+ //# sourceMappingURL=chunk-4MMMXV4Q.js.map
135
+ //# sourceMappingURL=chunk-4MMMXV4Q.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../objects/index.ts"],"names":[],"mappings":"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","file":"chunk-4MMMXV4Q.js","sourcesContent":["const objectTypeRegistry = new Set<string>([\n\t\"AssetEvent\",\n\t\"ActionInvocation\",\n\t\"PolicyEvaluation\",\n\t\"ApprovalRequest\",\n\t\"ConsentRecord\",\n\t\"AgentRun\",\n]);\n\nexport type FabricObjectType = string;\n\nexport type JsonPrimitive = string | number | boolean | null;\nexport type JsonValue = JsonPrimitive | JsonValue[] | { [key: string]: JsonValue };\n\n/**\n * Dependency-free JSON Schema profile accepted in portable module manifests.\n * Unknown extension keywords must use an `x-` prefix. Runtime validators may\n * support more vocabulary, but exported entity contracts stay in this profile.\n */\nexport interface PortableJsonSchema {\n\t$schema?: string;\n\t$id?: string;\n\t$ref?: string;\n\t$defs?: Record<string, PortableJsonSchema>;\n\ttitle?: string;\n\tdescription?: string;\n\ttype?: \"null\" | \"boolean\" | \"object\" | \"array\" | \"number\" | \"integer\" | \"string\" | Array<\"null\" | \"boolean\" | \"object\" | \"array\" | \"number\" | \"integer\" | \"string\">;\n\tenum?: JsonValue[];\n\tconst?: JsonValue;\n\tproperties?: Record<string, PortableJsonSchema>;\n\trequired?: string[];\n\tadditionalProperties?: boolean | PortableJsonSchema;\n\titems?: PortableJsonSchema | PortableJsonSchema[];\n\tprefixItems?: PortableJsonSchema[];\n\tpropertyNames?: PortableJsonSchema;\n\tpatternProperties?: Record<string, PortableJsonSchema>;\n\tdependentRequired?: Record<string, string[]>;\n\tallOf?: PortableJsonSchema[];\n\tanyOf?: PortableJsonSchema[];\n\toneOf?: PortableJsonSchema[];\n\tnot?: PortableJsonSchema;\n\tif?: PortableJsonSchema;\n\tthen?: PortableJsonSchema;\n\telse?: PortableJsonSchema;\n\tminimum?: number;\n\tmaximum?: number;\n\texclusiveMinimum?: number;\n\texclusiveMaximum?: number;\n\tmultipleOf?: number;\n\tminLength?: number;\n\tmaxLength?: number;\n\tpattern?: string;\n\tformat?: string;\n\tminItems?: number;\n\tmaxItems?: number;\n\tuniqueItems?: boolean;\n\tdefault?: JsonValue;\n\treadOnly?: boolean;\n\twriteOnly?: boolean;\n\tdeprecated?: boolean;\n\tcontentEncoding?: string;\n\tcontentMediaType?: string;\n\texamples?: JsonValue[];\n\t$comment?: string;\n\t[key: `x-${string}`]: JsonValue | undefined;\n}\n\nconst supportedSchemaKeywords = new Set([\n\t\"$schema\", \"$id\", \"$ref\", \"$defs\", \"title\", \"description\", \"type\", \"enum\", \"const\",\n\t\"properties\", \"required\", \"additionalProperties\", \"items\", \"prefixItems\", \"propertyNames\", \"patternProperties\", \"dependentRequired\", \"allOf\", \"anyOf\", \"oneOf\",\n\t\"not\", \"minimum\", \"maximum\", \"exclusiveMinimum\", \"exclusiveMaximum\", \"minLength\",\n\t\"maxLength\", \"pattern\", \"format\", \"minItems\", \"maxItems\", \"uniqueItems\", \"default\",\n\t\"readOnly\", \"writeOnly\", \"deprecated\", \"contentEncoding\", \"contentMediaType\", \"multipleOf\", \"if\", \"then\", \"else\", \"examples\", \"$comment\",\n]);\n\nexport function assertPortableJsonSchema(\n\tschema: unknown,\n\tpath = \"schema\",\n): asserts schema is PortableJsonSchema {\n\tif (!schema || typeof schema !== \"object\" || Array.isArray(schema)) {\n\t\tthrow new Error(`${path} must be a JSON Schema object.`);\n\t}\n\tconst value = schema as Record<string, unknown>;\n\tfor (const keyword of Object.keys(value)) {\n\t\tif (!supportedSchemaKeywords.has(keyword) && !keyword.startsWith(\"x-\")) {\n\t\t\tthrow new Error(`${path} uses unsupported JSON Schema keyword \"${keyword}\".`);\n\t\t}\n\t}\n\tif (value.properties !== undefined) {\n\t\tif (!value.properties || typeof value.properties !== \"object\" || Array.isArray(value.properties)) {\n\t\t\tthrow new Error(`${path}.properties must be an object.`);\n\t\t}\n\t\tfor (const [name, child] of Object.entries(value.properties)) {\n\t\t\tassertPortableJsonSchema(child, `${path}.properties.${name}`);\n\t\t}\n\t}\n\tif (value.$defs !== undefined) {\n\t\tif (!value.$defs || typeof value.$defs !== \"object\" || Array.isArray(value.$defs)) {\n\t\t\tthrow new Error(`${path}.$defs must be an object.`);\n\t\t}\n\t\tfor (const [name, child] of Object.entries(value.$defs)) {\n\t\t\tassertPortableJsonSchema(child, `${path}.$defs.${name}`);\n\t\t}\n\t}\n\tif (value.patternProperties !== undefined) {\n\t\tif (!value.patternProperties || typeof value.patternProperties !== \"object\" || Array.isArray(value.patternProperties)) throw new Error(`${path}.patternProperties must be an object.`);\n\t\tfor (const [name, child] of Object.entries(value.patternProperties)) assertPortableJsonSchema(child, `${path}.patternProperties.${name}`);\n\t}\n\tfor (const keyword of [\"allOf\", \"anyOf\", \"oneOf\"] as const) {\n\t\tif (value[keyword] !== undefined) {\n\t\t\tif (!Array.isArray(value[keyword])) throw new Error(`${path}.${keyword} must be an array.`);\n\t\t\tvalue[keyword].forEach((child, index) => assertPortableJsonSchema(child, `${path}.${keyword}[${index}]`));\n\t\t}\n\t}\n\tif (value.not !== undefined) assertPortableJsonSchema(value.not, `${path}.not`);\n\tfor (const keyword of [\"propertyNames\", \"if\", \"then\", \"else\"] as const) if (value[keyword] !== undefined) assertPortableJsonSchema(value[keyword], `${path}.${keyword}`);\n\tif (value.additionalProperties !== undefined && typeof value.additionalProperties !== \"boolean\") {\n\t\tassertPortableJsonSchema(value.additionalProperties, `${path}.additionalProperties`);\n\t}\n\tif (value.items !== undefined) {\n\t\tif (Array.isArray(value.items)) {\n\t\t\tvalue.items.forEach((child, index) => assertPortableJsonSchema(child, `${path}.items[${index}]`));\n\t\t} else {\n\t\t\tassertPortableJsonSchema(value.items, `${path}.items`);\n\t\t}\n\t}\n\tif (value.prefixItems !== undefined) {\n\t\tif (!Array.isArray(value.prefixItems)) throw new Error(`${path}.prefixItems must be an array.`);\n\t\tvalue.prefixItems.forEach((child, index) => assertPortableJsonSchema(child, `${path}.prefixItems[${index}]`));\n\t}\n\tif (value.dependentRequired !== undefined) {\n\t\tif (!value.dependentRequired || typeof value.dependentRequired !== \"object\" || Array.isArray(value.dependentRequired) || Object.values(value.dependentRequired).some((items) => !Array.isArray(items) || items.some((item) => typeof item !== \"string\"))) throw new Error(`${path}.dependentRequired must map property names to arrays of property names.`);\n\t}\n\tif (value.required !== undefined && (!Array.isArray(value.required) || value.required.some((item) => typeof item !== \"string\"))) {\n\t\tthrow new Error(`${path}.required must be an array of property names.`);\n\t}\n}\n\nexport function assertObjectType(type: string): asserts type is FabricObjectType {\n\tif (!/^[A-Z][a-zA-Z0-9]*$/.test(type)) {\n\t\tthrow new Error(\n\t\t\t`Invalid object type: \"${type}\". Object types must be PascalCase alphanumeric.`,\n\t\t);\n\t}\n}\n\nexport function registerObjectType(type: string): void {\n\tassertObjectType(type);\n\tobjectTypeRegistry.add(type);\n}\n\nexport function isValidObjectType(type: string): boolean {\n\treturn objectTypeRegistry.has(type);\n}\n\nexport function getRegisteredObjectTypes(): string[] {\n\treturn Array.from(objectTypeRegistry);\n}\n"]}
@@ -1,6 +1,68 @@
1
- 'use strict';
2
-
3
1
  // projections/index.ts
2
+ var viewRegistry = /* @__PURE__ */ new Map();
3
+ function viewContractKey(view) {
4
+ return `${view.name}@${view.version}`;
5
+ }
6
+ function registerViewContract(view) {
7
+ const key = viewContractKey(view);
8
+ if (viewRegistry.has(key)) throw new Error(`View contract "${key}" is already registered.`);
9
+ viewRegistry.set(key, view);
10
+ }
11
+ function registerViewContractIfMissing(view) {
12
+ if (!viewRegistry.has(viewContractKey(view))) registerViewContract(view);
13
+ }
14
+ function resolveViewContract(name, version) {
15
+ return viewRegistry.get(`${name}@${version}`);
16
+ }
17
+ function getRegisteredViewContractKeys() {
18
+ return Array.from(viewRegistry.keys());
19
+ }
20
+ async function replayView({
21
+ view,
22
+ events,
23
+ scope,
24
+ snapshot
25
+ }) {
26
+ if (snapshot && snapshot.snapshotVersion !== view.snapshotVersion && !view.compatibleSnapshotVersions?.includes(snapshot.snapshotVersion)) {
27
+ throw new Error(
28
+ `View "${viewContractKey(view)}" cannot resume snapshot version ${snapshot.snapshotVersion}.`
29
+ );
30
+ }
31
+ if (snapshot && snapshot.snapshotVersion !== view.snapshotVersion && !view.upgradeSnapshot) {
32
+ throw new Error(
33
+ `View "${viewContractKey(view)}" must provide upgradeSnapshot for snapshot version ${snapshot.snapshotVersion}.`
34
+ );
35
+ }
36
+ const upgradedSnapshot = snapshot && snapshot.snapshotVersion !== view.snapshotVersion ? { ...snapshot, snapshotVersion: view.snapshotVersion, snapshotData: await view.upgradeSnapshot(snapshot.snapshotData, snapshot.snapshotVersion) } : snapshot;
37
+ const accepted = new Map(
38
+ view.consumes.map((consumption) => [consumption.eventType, new Set(consumption.schemaVersions)])
39
+ );
40
+ const sourceEvents = [];
41
+ for await (const event of events) sourceEvents.push(event);
42
+ const preprocessingWarnings = [];
43
+ const orderedScopedEvents = sortEvents(filterEventsByScope(sourceEvents, scope, preprocessingWarnings), Boolean(scope.subjectType && scope.subjectId));
44
+ const versionWarnings = [];
45
+ const replayable = async function* () {
46
+ for (const event of orderedScopedEvents) {
47
+ const versions = accepted.get(event.eventType);
48
+ if (versions && !versions.has(event.eventSchemaVersion ?? 1)) {
49
+ versionWarnings.push({ code: "unsupported_event_version", eventId: event.id, message: `View "${viewContractKey(view)}" does not consume ${event.eventType} schema version ${event.eventSchemaVersion ?? 1}; replay stopped before this event so a compatible view can resume it later.` });
50
+ return;
51
+ }
52
+ yield event;
53
+ }
54
+ };
55
+ const result = await replayEvents({
56
+ events: replayable(),
57
+ scope,
58
+ initialState: view.initialState,
59
+ snapshot: upgradedSnapshot,
60
+ applyEvent: (state, event) => accepted.has(event.eventType) ? view.applyEvent(state, event) : state
61
+ });
62
+ const preprocessingWarningKeys = new Set(preprocessingWarnings.map((warning) => JSON.stringify(warning)));
63
+ const resultWarnings = result.warnings.filter((warning) => !preprocessingWarningKeys.has(JSON.stringify(warning)));
64
+ return { ...result, warnings: [...preprocessingWarnings, ...versionWarnings, ...resultWarnings] };
65
+ }
4
66
  async function replayEvents({
5
67
  events,
6
68
  scope,
@@ -178,6 +240,6 @@ function toTimestamp(value) {
178
240
  return value instanceof Date ? value.getTime() : new Date(value).getTime();
179
241
  }
180
242
 
181
- exports.replayEvents = replayEvents;
182
- //# sourceMappingURL=chunk-Q3WYIWCN.cjs.map
183
- //# sourceMappingURL=chunk-Q3WYIWCN.cjs.map
243
+ export { getRegisteredViewContractKeys, registerViewContract, registerViewContractIfMissing, replayEvents, replayView, resolveViewContract, viewContractKey };
244
+ //# sourceMappingURL=chunk-FN6IYVBK.js.map
245
+ //# sourceMappingURL=chunk-FN6IYVBK.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../projections/index.ts"],"names":[],"mappings":"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","file":"chunk-FN6IYVBK.js","sourcesContent":["export interface ReplayableAssetEvent<Payload = unknown> {\n\tid: string;\n\ttenantId: string;\n\tspaceId: string;\n\teventType: string;\n\teventSchemaVersion?: number;\n\tsubjectType: string;\n\tsubjectId: string;\n\tpayload: Payload;\n\tsequence: number;\n\toccurredAt: Date | string;\n\trecordedAt: Date | string;\n\tactionInvocationId: string;\n\tcorrelationId: string;\n}\n\nimport type { PortableJsonSchema } from \"../objects\";\n\nexport interface ViewEventConsumption {\n\teventType: string;\n\tschemaVersions: number[];\n}\n\nexport interface ViewContract<State = unknown, Event extends ReplayableAssetEvent = ReplayableAssetEvent> {\n\t/** Stable module-qualified logical identity, for example `orders/summary`. */\n\tname: `${string}/${string}`;\n\tversion: string;\n\tshape: PortableJsonSchema;\n\tconsumes: ViewEventConsumption[];\n\tscope: \"tenant-space\";\n\tsnapshotVersion: number;\n\tcompatibleSnapshotVersions?: number[];\n\t/** Required to transform any older compatible snapshot into the current state shape. */\n\tupgradeSnapshot?: (data: unknown, fromVersion: number) => State | Promise<State>;\n\tinitialState: State;\n\tapplyEvent: (state: State, event: Event) => State | Promise<State>;\n}\n\nconst viewRegistry = new Map<string, ViewContract>();\n\nexport function viewContractKey(view: Pick<ViewContract, \"name\" | \"version\">): string {\n\treturn `${view.name}@${view.version}`;\n}\n\nexport function registerViewContract(view: ViewContract): void {\n\tconst key = viewContractKey(view);\n\tif (viewRegistry.has(key)) throw new Error(`View contract \"${key}\" is already registered.`);\n\tviewRegistry.set(key, view);\n}\n\nexport function registerViewContractIfMissing(view: ViewContract): void {\n\tif (!viewRegistry.has(viewContractKey(view))) registerViewContract(view);\n}\n\nexport function resolveViewContract(name: string, version: string): ViewContract | undefined {\n\treturn viewRegistry.get(`${name}@${version}`);\n}\n\nexport function getRegisteredViewContractKeys(): string[] {\n\treturn Array.from(viewRegistry.keys());\n}\n\nexport interface ReplayViewOptions<State, Event extends ReplayableAssetEvent = ReplayableAssetEvent> {\n\tview: ViewContract<State, Event>;\n\tevents: Iterable<Event> | AsyncIterable<Event>;\n\tscope: ReplayScope;\n\tsnapshot?: (ReplaySnapshot<State> & { snapshotVersion: number }) | null;\n}\n\nexport async function replayView<State, Event extends ReplayableAssetEvent = ReplayableAssetEvent>({\n\tview,\n\tevents,\n\tscope,\n\tsnapshot,\n}: ReplayViewOptions<State, Event>): Promise<ReplayEventsResult<State, Event>> {\n\tif (\n\t\tsnapshot &&\n\t\tsnapshot.snapshotVersion !== view.snapshotVersion &&\n\t\t!view.compatibleSnapshotVersions?.includes(snapshot.snapshotVersion)\n\t) {\n\t\tthrow new Error(\n\t\t\t`View \"${viewContractKey(view)}\" cannot resume snapshot version ${snapshot.snapshotVersion}.`,\n\t\t);\n\t}\n\tif (snapshot && snapshot.snapshotVersion !== view.snapshotVersion && !view.upgradeSnapshot) {\n\t\tthrow new Error(\n\t\t\t`View \"${viewContractKey(view)}\" must provide upgradeSnapshot for snapshot version ${snapshot.snapshotVersion}.`,\n\t\t);\n\t}\n\tconst upgradedSnapshot = snapshot && snapshot.snapshotVersion !== view.snapshotVersion\n\t\t? { ...snapshot, snapshotVersion: view.snapshotVersion, snapshotData: await view.upgradeSnapshot!(snapshot.snapshotData, snapshot.snapshotVersion) }\n\t\t: snapshot;\n\tconst accepted = new Map(\n\t\tview.consumes.map((consumption) => [consumption.eventType, new Set(consumption.schemaVersions)]),\n\t);\n\tconst sourceEvents: Event[] = [];\n\tfor await (const event of events) sourceEvents.push(event);\n\tconst preprocessingWarnings: ReplayWarning[] = [];\n\tconst orderedScopedEvents = sortEvents(filterEventsByScope(sourceEvents, scope, preprocessingWarnings), Boolean(scope.subjectType && scope.subjectId));\n\tconst versionWarnings: ReplayWarning[] = [];\n\tconst replayable = async function* (): AsyncIterable<Event> {\n\t\tfor (const event of orderedScopedEvents) {\n\t\t\tconst versions = accepted.get(event.eventType);\n\t\t\tif (versions && !versions.has(event.eventSchemaVersion ?? 1)) {\n\t\t\t\tversionWarnings.push({ code: \"unsupported_event_version\", eventId: event.id, message: `View \"${viewContractKey(view)}\" does not consume ${event.eventType} schema version ${event.eventSchemaVersion ?? 1}; replay stopped before this event so a compatible view can resume it later.` });\n\t\t\t\treturn;\n\t\t\t}\n\t\t\tyield event;\n\t\t}\n\t};\n\tconst result = await replayEvents({\n\t\tevents: replayable(),\n\t\tscope,\n\t\tinitialState: view.initialState,\n\t\tsnapshot: upgradedSnapshot,\n\t\tapplyEvent: (state, event) => accepted.has(event.eventType) ? view.applyEvent(state, event) : state,\n\t});\n\tconst preprocessingWarningKeys = new Set(preprocessingWarnings.map((warning) => JSON.stringify(warning)));\n\tconst resultWarnings = result.warnings.filter((warning) => !preprocessingWarningKeys.has(JSON.stringify(warning)));\n\treturn { ...result, warnings: [...preprocessingWarnings, ...versionWarnings, ...resultWarnings] };\n}\n\nexport interface ReplayScope {\n\ttenantId: string;\n\tspaceId: string;\n\tsubjectType?: string;\n\tsubjectId?: string;\n}\n\nexport interface ReplaySnapshot<State = unknown> {\n\tsnapshotData: State;\n\teventCursor?: string | null;\n\teventSequence?: number | null;\n}\n\nexport type ReplayWarningCode =\n\t| \"cursor_not_found\"\n\t| \"duplicate_event\"\n\t| \"missing_sequence\"\n\t| \"subject_scope_incomplete\"\n\t| \"unsupported_event_version\";\n\nexport interface ReplayWarning {\n\tcode: ReplayWarningCode;\n\tmessage: string;\n\teventId?: string;\n\tsubjectType?: string;\n\tsubjectId?: string;\n\texpectedSequence?: number;\n\tactualSequence?: number;\n}\n\nexport interface ReplayEventsOptions<State, Event extends ReplayableAssetEvent = ReplayableAssetEvent> {\n\tevents: Iterable<Event> | AsyncIterable<Event>;\n\tscope: ReplayScope;\n\tinitialState: State;\n\tsnapshot?: ReplaySnapshot<State> | null;\n\tapplyEvent: (state: State, event: Event) => State | Promise<State>;\n}\n\nexport interface ReplayEventsResult<State, Event extends ReplayableAssetEvent = ReplayableAssetEvent> {\n\tstate: State;\n\tappliedEvents: Event[];\n\twarnings: ReplayWarning[];\n\teventCursor: string | null;\n\teventSequence: number;\n}\n\nexport async function replayEvents<State, Event extends ReplayableAssetEvent = ReplayableAssetEvent>({\n\tevents,\n\tscope,\n\tinitialState,\n\tsnapshot,\n\tapplyEvent,\n}: ReplayEventsOptions<State, Event>): Promise<ReplayEventsResult<State, Event>> {\n\tconst warnings: ReplayWarning[] = [];\n\tconst scopedEvents = filterEventsByScope(await collectEvents(events), scope, warnings);\n\tconst orderedEvents = sortEvents(scopedEvents, isSubjectScoped(scope));\n\tconst uniqueEvents = removeDuplicateEvents(orderedEvents, warnings);\n\tconst resumableEvents = applyCursor(uniqueEvents, snapshot, isSubjectScoped(scope), warnings);\n\n\tlet state = snapshot?.snapshotData ?? initialState;\n\tconst appliedEvents: Event[] = [];\n\tlet eventCursor = snapshot?.eventCursor ?? null;\n\tlet eventSequence = snapshot?.eventSequence ?? 0;\n\n\tfor (const event of resumableEvents) {\n\t\tstate = await applyEvent(state, event);\n\t\tappliedEvents.push(event);\n\t\teventCursor = event.id;\n\t\teventSequence = event.sequence;\n\t}\n\n\treturn {\n\t\tstate,\n\t\tappliedEvents,\n\t\twarnings,\n\t\teventCursor,\n\t\teventSequence,\n\t};\n}\n\nasync function collectEvents<Event extends ReplayableAssetEvent>(\n\tevents: Iterable<Event> | AsyncIterable<Event>,\n): Promise<Event[]> {\n\tconst collected: Event[] = [];\n\n\tif (Symbol.asyncIterator in events) {\n\t\tfor await (const event of events) {\n\t\t\tcollected.push(event);\n\t\t}\n\n\t\treturn collected;\n\t}\n\n\tfor (const event of events) {\n\t\tcollected.push(event);\n\t}\n\n\treturn collected;\n}\n\nfunction filterEventsByScope<Event extends ReplayableAssetEvent>(\n\tevents: Event[],\n\tscope: ReplayScope,\n\twarnings: ReplayWarning[],\n): Event[] {\n\tif ((scope.subjectType && !scope.subjectId) || (!scope.subjectType && scope.subjectId)) {\n\t\twarnings.push({\n\t\t\tcode: \"subject_scope_incomplete\",\n\t\t\tmessage: \"Both subjectType and subjectId are required for subject-scoped replay.\",\n\t\t\tsubjectType: scope.subjectType,\n\t\t\tsubjectId: scope.subjectId,\n\t\t});\n\t}\n\n\treturn events.filter((event) => {\n\t\tif (event.tenantId !== scope.tenantId || event.spaceId !== scope.spaceId) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (scope.subjectType && event.subjectType !== scope.subjectType) {\n\t\t\treturn false;\n\t\t}\n\n\t\tif (scope.subjectId && event.subjectId !== scope.subjectId) {\n\t\t\treturn false;\n\t\t}\n\n\t\treturn true;\n\t});\n}\n\nfunction removeDuplicateEvents<Event extends ReplayableAssetEvent>(\n\tevents: Event[],\n\twarnings: ReplayWarning[],\n): Event[] {\n\tconst seenEventIds = new Set<string>();\n\tconst uniqueEvents: Event[] = [];\n\n\tfor (const event of events) {\n\t\tif (seenEventIds.has(event.id)) {\n\t\t\twarnings.push({\n\t\t\t\tcode: \"duplicate_event\",\n\t\t\t\tmessage: `Duplicate event ${event.id} ignored during replay.`,\n\t\t\t\teventId: event.id,\n\t\t\t\tsubjectType: event.subjectType,\n\t\t\t\tsubjectId: event.subjectId,\n\t\t\t});\n\t\t\tcontinue;\n\t\t}\n\n\t\tseenEventIds.add(event.id);\n\t\tuniqueEvents.push(event);\n\t}\n\n\trecordMissingSequenceWarnings(uniqueEvents, warnings);\n\n\treturn uniqueEvents;\n}\n\nfunction recordMissingSequenceWarnings<Event extends ReplayableAssetEvent>(\n\tevents: Event[],\n\twarnings: ReplayWarning[],\n): void {\n\tconst lastSequenceBySubject = new Map<string, number>();\n\n\tfor (const event of events) {\n\t\tconst subjectKey = `${event.subjectType}:${event.subjectId}`;\n\t\tconst previousSequence = lastSequenceBySubject.get(subjectKey);\n\t\tconst expectedSequence = previousSequence === undefined ? event.sequence : previousSequence + 1;\n\n\t\tif (previousSequence !== undefined && event.sequence > expectedSequence) {\n\t\t\twarnings.push({\n\t\t\t\tcode: \"missing_sequence\",\n\t\t\t\tmessage: `Missing event sequence for ${subjectKey}: expected ${expectedSequence}, received ${event.sequence}.`,\n\t\t\t\teventId: event.id,\n\t\t\t\tsubjectType: event.subjectType,\n\t\t\t\tsubjectId: event.subjectId,\n\t\t\t\texpectedSequence,\n\t\t\t\tactualSequence: event.sequence,\n\t\t\t});\n\t\t}\n\n\t\tlastSequenceBySubject.set(subjectKey, Math.max(previousSequence ?? event.sequence, event.sequence));\n\t}\n}\n\nfunction applyCursor<Event extends ReplayableAssetEvent>(\n\tevents: Event[],\n\tsnapshot: ReplaySnapshot | null | undefined,\n\tsubjectScoped: boolean,\n\twarnings: ReplayWarning[],\n): Event[] {\n\tconst eventCursor = snapshot?.eventCursor;\n\n\tif (eventCursor) {\n\t\tconst cursorIndex = events.findIndex((event) => event.id === eventCursor);\n\n\t\tif (cursorIndex >= 0) {\n\t\t\treturn events.slice(cursorIndex + 1);\n\t\t}\n\n\t\twarnings.push({\n\t\t\tcode: \"cursor_not_found\",\n\t\t\tmessage: `Snapshot cursor ${eventCursor} was not found in the scoped event stream.`,\n\t\t\teventId: eventCursor,\n\t\t});\n\t}\n\n\tif (subjectScoped && snapshot?.eventSequence !== undefined && snapshot.eventSequence !== null) {\n\t\treturn events.filter((event) => event.sequence > snapshot.eventSequence!);\n\t}\n\n\treturn events;\n}\n\nfunction sortEvents<Event extends ReplayableAssetEvent>(events: Event[], subjectScoped: boolean): Event[] {\n\treturn [...events].sort((first, second) =>\n\t\tsubjectScoped ? compareSubjectEvents(first, second) : compareGlobalEvents(first, second),\n\t);\n}\n\nfunction compareSubjectEvents(first: ReplayableAssetEvent, second: ReplayableAssetEvent): number {\n\treturn compareValues(\n\t\t[first.sequence, toTimestamp(first.recordedAt), toTimestamp(first.occurredAt), first.id],\n\t\t[second.sequence, toTimestamp(second.recordedAt), toTimestamp(second.occurredAt), second.id],\n\t);\n}\n\nfunction compareGlobalEvents(first: ReplayableAssetEvent, second: ReplayableAssetEvent): number {\n\treturn compareValues(\n\t\t[\n\t\t\ttoTimestamp(first.recordedAt),\n\t\t\ttoTimestamp(first.occurredAt),\n\t\t\tfirst.actionInvocationId,\n\t\t\tfirst.correlationId,\n\t\t\tfirst.subjectType,\n\t\t\tfirst.subjectId,\n\t\t\tfirst.sequence,\n\t\t\tfirst.id,\n\t\t],\n\t\t[\n\t\t\ttoTimestamp(second.recordedAt),\n\t\t\ttoTimestamp(second.occurredAt),\n\t\t\tsecond.actionInvocationId,\n\t\t\tsecond.correlationId,\n\t\t\tsecond.subjectType,\n\t\t\tsecond.subjectId,\n\t\t\tsecond.sequence,\n\t\t\tsecond.id,\n\t\t],\n\t);\n}\n\nfunction compareValues(firstValues: Array<number | string>, secondValues: Array<number | string>): number {\n\tfor (const [index, firstValue] of firstValues.entries()) {\n\t\tconst secondValue = secondValues[index];\n\n\t\tif (firstValue < secondValue) {\n\t\t\treturn -1;\n\t\t}\n\n\t\tif (firstValue > secondValue) {\n\t\t\treturn 1;\n\t\t}\n\t}\n\n\treturn 0;\n}\n\nfunction isSubjectScoped(scope: ReplayScope): boolean {\n\treturn Boolean(scope.subjectType && scope.subjectId);\n}\n\nfunction toTimestamp(value: Date | string): number {\n\treturn value instanceof Date ? value.getTime() : new Date(value).getTime();\n}\n"]}
@@ -66,5 +66,5 @@ exports.registerAction = registerAction;
66
66
  exports.registerActionIfMissing = registerActionIfMissing;
67
67
  exports.resolveAction = resolveAction;
68
68
  exports.resolveRegisteredAction = resolveRegisteredAction;
69
- //# sourceMappingURL=chunk-BWNPGRRV.cjs.map
70
- //# sourceMappingURL=chunk-BWNPGRRV.cjs.map
69
+ //# sourceMappingURL=chunk-HLRIXNVG.cjs.map
70
+ //# sourceMappingURL=chunk-HLRIXNVG.cjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../actions/index.ts"],"names":[],"mappings":";;;AAwBO,IAAM,WAAA,GAAoC;AAAA,EAChD,gBAAA;AAAA,EACA,OAAA;AAAA,EACA,QAAA;AAAA,EACA,iBAAA;AAAA,EACA,iBAAA;AAAA,EACA;AACD;AAEO,SAAS,YAAY,KAAA,EAAmC;AAC9D,EAAA,OAAQ,WAAA,CAAkC,SAAS,KAAK,CAAA;AACzD;AAEO,SAAS,gBAAgB,KAAA,EAA2C;AAC1E,EAAA,IAAI,CAAC,WAAA,CAAY,KAAK,CAAA,EAAG;AACxB,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,KAAK,CAAA,CAAE,CAAA;AAAA,EAC9C;AACD;AAuJA,IAAM,QAAA,uBAAe,GAAA,EAAgC;AAE9C,SAAS,eAAe,QAAA,EAAgD;AAC9E,EAAA,IAAI,CAAC,oCAAA,CAAqC,IAAA,CAAK,QAAQ,CAAA,EAAG;AACzD,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,mBAAA,EAAsB,QAAQ,CAAA,CAAE,CAAA;AAAA,EACjD;AACD;AAEO,SAAS,eAAe,UAAA,EAAoC;AAClE,EAAA,cAAA,CAAe,WAAW,QAAQ,CAAA;AAElC,EAAA,IAAI,QAAA,CAAS,GAAA,CAAI,UAAA,CAAW,QAAQ,CAAA,EAAG;AACtC,IAAA,MAAM,IAAI,KAAA,CAAM,CAAA,QAAA,EAAW,UAAA,CAAW,QAAQ,CAAA,uBAAA,CAAyB,CAAA;AAAA,EACxE;AAEA,EAAA,IAAI,UAAA,CAAW,aAAA,IAAiB,UAAA,CAAW,WAAA,CAAY,WAAW,CAAA,EAAG;AACpE,IAAA,MAAM,IAAI,KAAA;AAAA,MACT,CAAA,QAAA,EAAW,WAAW,QAAQ,CAAA,8FAAA;AAAA,KAE/B;AAAA,EACD;AAEA,EAAA,QAAA,CAAS,GAAA,CAAI,UAAA,CAAW,QAAA,EAAU,UAAU,CAAA;AAC7C;AAEO,SAAS,cAAc,QAAA,EAAkD;AAC/E,EAAA,OAAO,QAAA,CAAS,IAAI,QAAQ,CAAA;AAC7B;AAEO,SAAS,qBAAqB,QAAA,EAAwC;AAC5E,EAAA,OAAO,QAAA,CAAS,IAAI,QAAoB,CAAA;AACzC;AAEO,SAAS,wBAAwB,QAAA,EAAgD;AACvF,EAAA,IAAI,CAAC,oBAAA,CAAqB,QAAQ,CAAA,EAAG;AACpC,IAAA,OAAO,MAAA;AAAA,EACR;AAEA,EAAA,OAAO,cAAc,QAAQ,CAAA;AAC9B;AAEO,SAAS,sBAAA,GAAqC;AACpD,EAAA,OAAO,KAAA,CAAM,IAAA,CAAK,QAAA,CAAS,IAAA,EAAM,CAAA;AAClC;AAEO,SAAS,wBAAwB,UAAA,EAAoC;AAC3E,EAAA,IAAI,CAAC,QAAA,CAAS,GAAA,CAAI,UAAA,CAAW,QAAQ,CAAA,EAAG;AACvC,IAAA,cAAA,CAAe,UAAU,CAAA;AAAA,EAC1B;AACD","file":"chunk-HLRIXNVG.cjs","sourcesContent":["export type ActionId = `${string}.${string}`;\n\nexport interface SchemaParseIssue {\n\tpath: PropertyKey[];\n\tmessage: string;\n}\n\nexport type SchemaParseResult<T = unknown> =\n\t| { success: true; data: T }\n\t| { success: false; error: { issues: SchemaParseIssue[] } };\n\nexport interface SchemaValidator<T = unknown> {\n\tparse(input: unknown): T;\n\tsafeParse(input: unknown): SchemaParseResult<T>;\n}\n\nexport type ActorType =\n\t| \"natural_person\"\n\t| \"agent\"\n\t| \"system\"\n\t| \"service_account\"\n\t| \"external_system\"\n\t| \"integration\";\n\nexport const ACTOR_TYPES: readonly ActorType[] = [\n\t\"natural_person\",\n\t\"agent\",\n\t\"system\",\n\t\"service_account\",\n\t\"external_system\",\n\t\"integration\",\n] as const;\n\nexport function isActorType(value: string): value is ActorType {\n\treturn (ACTOR_TYPES as readonly string[]).includes(value);\n}\n\nexport function assertActorType(value: string): asserts value is ActorType {\n\tif (!isActorType(value)) {\n\t\tthrow new Error(`Invalid actorType: ${value}`);\n\t}\n}\n\nexport type ActionStatus =\n\t| \"pending\"\n\t| \"running\"\n\t| \"completed\"\n\t| \"failed\"\n\t| \"blocked_by_policy\"\n\t| \"waiting_for_approval\"\n\t| \"validation_failed\";\n\nexport interface FabricRuntimeServices {\n\treadonly [serviceName: string]: unknown;\n}\n\nexport interface ActionContext<TDb = unknown> {\n\tactionInvocationId: string;\n\ttenantId: string;\n\tspaceId: string;\n\tactorId: string;\n\tactorType: ActorType;\n\tcorrelationId: string;\n\tcausationId?: string;\n\tdb: TDb;\n\tservices?: FabricRuntimeServices;\n}\n\nexport interface ActionResult {\n\tsuccess: boolean;\n\tdata?: Record<string, unknown>;\n\terror?: string;\n}\n\nexport type ActionHandler<TDb = unknown> = (\n\tctx: ActionContext<TDb>,\n\tparams: unknown,\n) => Promise<ActionResult>;\n\nexport interface AdapterStepRetryPolicy {\n\tidempotent: boolean;\n\tmaxAttempts?: number;\n\tinitialDelayMs?: number;\n\tbackoffMultiplier?: number;\n\tmaxDelayMs?: number;\n}\n\nexport interface AdapterStep {\n\tadapterType: string;\n\toperation: string;\n\tretryPolicy?: AdapterStepRetryPolicy;\n\tgetInput: (\n\t\tparams: unknown,\n\t\thandlerResult: Record<string, unknown>,\n\t) => Record<string, unknown> | undefined;\n}\n\nexport interface ActionStateMachineBinding {\n\tentityType: string;\n\ttargetState: string | ((params: unknown) => string);\n\tgetEntityId: (params: unknown) => string | undefined;\n}\n\nexport interface ActionDefinition<TDb = unknown> {\n\tactionId: ActionId;\n\tnamespace: string;\n\tversion: number;\n\tschema: SchemaValidator;\n\t/** Optional validation contract for the public handler result data. */\n\tresultSchema?: SchemaValidator;\n\thandler?: ActionHandler<TDb>;\n\trequiredRoles?: string[];\n\trequiredPermissions?: string[];\n\tpolicies?: `${string}.v${number}`[];\n\temitsEvents: string[];\n\tidempotent: boolean;\n\tmutatesDomain: boolean;\n\tstateMachine?: ActionStateMachineBinding;\n\tadapterSteps?: AdapterStep[];\n\t/** Completion actions can attest only after all external adapter work succeeds. */\n\teventPhase?: \"before_adapters\" | \"after_adapters\";\n\t/**\n\t * If \"saga\", the action is a multi-step orchestration. The worker dispatches\n\t * to a registered saga implementation instead of running `handler` directly.\n\t */\n\tkind?: \"atomic\" | \"saga\";\n}\n\nexport interface SagaContext {\n\tactionInvocationId: string;\n\ttenantId: string;\n\tspaceId: string;\n\tparameters: unknown;\n\tsleep?: (delayMs: number) => Promise<void>;\n\tquery?: <T = unknown>(model: string, operation: string, args: unknown) => Promise<T>;\n\t/**\n\t * Wait for a named external signal carrying a payload of `T`, with a timeout.\n\t *\n\t * Resolves with the payload of the first signal received, or `null` if the timeout\n\t * fires first. Subsequent signals with the same name received before another\n\t * `awaitSignal` call are buffered (FIFO) so no signal is lost.\n\t *\n\t * Intended for agent-driven and webhook-driven coordination: replace polling loops\n\t * with push-based wakeups while preserving the saga's deterministic replay\n\t * semantics (the runtime is responsible for capturing signals into workflow history).\n\t *\n\t * Optional. Runtimes that cannot implement push-based signaling (e.g. an in-memory\n\t * test harness) may omit this; sagas should treat absence as a fallback condition\n\t * and use `sleep` + `query` polling instead.\n\t *\n\t * Signal *senders* are runtime-specific (e.g. a Temporal `WorkflowClient.signal()`\n\t * call from an action handler). Apps that need to send signals from action\n\t * handlers should expose a coordination service via `ActionContext.services`\n\t * — the platform does not prescribe the sender API.\n\t *\n\t * @example\n\t * const payload = await ctx.awaitSignal?.<{ result: Record<string, unknown> }>(\n\t * \"userInputProcessed\",\n\t * 5 * 60 * 1000,\n\t * );\n\t * if (payload) { /* handle pushed result *\\/ }\n\t * else { /* timeout — fall back to deterministic path *\\/ }\n\t */\n\tawaitSignal?: <T = unknown>(signalName: string, timeoutMs: number) => Promise<T | null>;\n}\n\nexport interface SagaChildActionInput {\n\tsuffix: string;\n\tactionId: string;\n\tparameters: Record<string, unknown>;\n}\n\nexport type SagaRunChild = (input: SagaChildActionInput) => Promise<Record<string, unknown>>;\n\nexport interface SagaCompletionEvent {\n\teventType: string;\n\tsubjectType: string;\n\tsubjectId: string;\n\tpayload: unknown;\n\teventSchemaVersion?: number;\n}\n\nexport interface SagaCompletion {\n\tresultData: Record<string, unknown>;\n\tevent?: SagaCompletionEvent;\n}\n\nexport type SagaImplementation = (\n\tctx: SagaContext,\n\trunChild: SagaRunChild,\n) => Promise<SagaCompletion>;\n\nconst registry = new Map<ActionId, ActionDefinition>();\n\nexport function assertActionId(actionId: string): asserts actionId is ActionId {\n\tif (!/^[a-z][a-z0-9-]*\\.[a-z][a-z0-9_]*$/.test(actionId)) {\n\t\tthrow new Error(`Invalid action ID: ${actionId}`);\n\t}\n}\n\nexport function registerAction(definition: ActionDefinition): void {\n\tassertActionId(definition.actionId);\n\n\tif (registry.has(definition.actionId)) {\n\t\tthrow new Error(`Action \"${definition.actionId}\" is already registered`);\n\t}\n\n\tif (definition.mutatesDomain && definition.emitsEvents.length === 0) {\n\t\tthrow new Error(\n\t\t\t`Action \"${definition.actionId}\" mutates domain but emits no events. ` +\n\t\t\t\t`Every mutating action must emit at least one AssetEvent.`,\n\t\t);\n\t}\n\n\tregistry.set(definition.actionId, definition);\n}\n\nexport function resolveAction(actionId: ActionId): ActionDefinition | undefined {\n\treturn registry.get(actionId);\n}\n\nexport function isRegisteredActionId(actionId: string): actionId is ActionId {\n\treturn registry.has(actionId as ActionId);\n}\n\nexport function resolveRegisteredAction(actionId: string): ActionDefinition | undefined {\n\tif (!isRegisteredActionId(actionId)) {\n\t\treturn undefined;\n\t}\n\n\treturn resolveAction(actionId);\n}\n\nexport function getRegisteredActionIds(): ActionId[] {\n\treturn Array.from(registry.keys());\n}\n\nexport function registerActionIfMissing(definition: ActionDefinition): void {\n\tif (!registry.has(definition.actionId)) {\n\t\tregisterAction(definition);\n\t}\n}\n"]}