@fabricorg/platform 0.12.1 → 1.1.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.
Files changed (110) hide show
  1. package/CHANGELOG.md +38 -0
  2. package/README.md +7 -8
  3. package/dist/actions/index.cjs +7 -27
  4. package/dist/actions/index.d.cts +9 -7
  5. package/dist/actions/index.d.ts +9 -7
  6. package/dist/actions/index.js +1 -1
  7. package/dist/chunk-4QOA3VU5.js +47 -0
  8. package/dist/chunk-4QOA3VU5.js.map +1 -0
  9. package/dist/{chunk-35SDMFCR.js → chunk-53YJK3LK.js} +93 -99
  10. package/dist/chunk-53YJK3LK.js.map +1 -0
  11. package/dist/{chunk-LAZL2GDT.cjs → chunk-6T6F3TNQ.cjs} +99 -104
  12. package/dist/chunk-6T6F3TNQ.cjs.map +1 -0
  13. package/dist/{chunk-ZZGSS65W.cjs → chunk-A2VTSATF.cjs} +6 -6
  14. package/dist/{chunk-ZZGSS65W.cjs.map → chunk-A2VTSATF.cjs.map} +1 -1
  15. package/dist/{chunk-X7WC4AYC.js → chunk-ATWWZTRC.js} +32 -74
  16. package/dist/chunk-ATWWZTRC.js.map +1 -0
  17. package/dist/chunk-BFQNKQJE.cjs +53 -0
  18. package/dist/{chunk-4RMKUYRX.js.map → chunk-BFQNKQJE.cjs.map} +1 -1
  19. package/dist/{chunk-OC4ZFJKD.cjs → chunk-CBY6GRJP.cjs} +16 -17
  20. package/dist/chunk-CBY6GRJP.cjs.map +1 -0
  21. package/dist/{chunk-HL77HWWP.js → chunk-ETONSTUW.js} +3 -3
  22. package/dist/{chunk-HL77HWWP.js.map → chunk-ETONSTUW.js.map} +1 -1
  23. package/dist/{chunk-FSUYD4F4.js → chunk-J5LS5BSI.js} +19 -17
  24. package/dist/chunk-J5LS5BSI.js.map +1 -0
  25. package/dist/{chunk-6ER62UUN.js → chunk-JFVEPAED.js} +31 -40
  26. package/dist/chunk-JFVEPAED.js.map +1 -0
  27. package/dist/chunk-LDPBQ72C.cjs +40 -0
  28. package/dist/chunk-LDPBQ72C.cjs.map +1 -0
  29. package/dist/{chunk-7SHNYYGI.cjs → chunk-M5FGWXT3.cjs} +19 -20
  30. package/dist/chunk-M5FGWXT3.cjs.map +1 -0
  31. package/dist/{chunk-4MMMXV4Q.js → chunk-NETLRKDS.js} +16 -15
  32. package/dist/chunk-NETLRKDS.js.map +1 -0
  33. package/dist/chunk-NHGBTPPE.js +38 -0
  34. package/dist/chunk-NHGBTPPE.js.map +1 -0
  35. package/dist/chunk-OWSSGFNY.js +45 -0
  36. package/dist/chunk-OWSSGFNY.js.map +1 -0
  37. package/dist/{chunk-NJL3US7H.cjs → chunk-VZ6C4LXC.cjs} +31 -43
  38. package/dist/chunk-VZ6C4LXC.cjs.map +1 -0
  39. package/dist/chunk-WAI4UNWQ.cjs +48 -0
  40. package/dist/chunk-WAI4UNWQ.cjs.map +1 -0
  41. package/dist/{chunk-YQEXO3IQ.cjs → chunk-X3GHYMAJ.cjs} +32 -74
  42. package/dist/chunk-X3GHYMAJ.cjs.map +1 -0
  43. package/dist/events/index.cjs +3 -27
  44. package/dist/events/index.d.cts +20 -13
  45. package/dist/events/index.d.ts +20 -13
  46. package/dist/events/index.js +1 -1
  47. package/dist/index.cjs +88 -193
  48. package/dist/index.d.cts +8 -9
  49. package/dist/index.d.ts +8 -9
  50. package/dist/index.js +10 -11
  51. package/dist/manifest/index.cjs +11 -15
  52. package/dist/manifest/index.d.cts +0 -1
  53. package/dist/manifest/index.d.ts +0 -1
  54. package/dist/manifest/index.js +5 -9
  55. package/dist/modules/index.cjs +15 -15
  56. package/dist/modules/index.d.cts +46 -23
  57. package/dist/modules/index.d.ts +46 -23
  58. package/dist/modules/index.js +4 -8
  59. package/dist/objects/index.cjs +5 -13
  60. package/dist/objects/index.d.cts +7 -4
  61. package/dist/objects/index.d.ts +7 -4
  62. package/dist/objects/index.js +1 -1
  63. package/dist/policies/index.cjs +12 -24
  64. package/dist/policies/index.d.cts +10 -5
  65. package/dist/policies/index.d.ts +10 -5
  66. package/dist/policies/index.js +1 -1
  67. package/dist/privacy/index.cjs +10 -10
  68. package/dist/privacy/index.d.cts +16 -5
  69. package/dist/privacy/index.d.ts +16 -5
  70. package/dist/privacy/index.js +1 -1
  71. package/dist/projections/index.cjs +6 -18
  72. package/dist/projections/index.d.cts +8 -5
  73. package/dist/projections/index.d.ts +8 -5
  74. package/dist/projections/index.js +1 -1
  75. package/dist/state-machines/index.cjs +5 -21
  76. package/dist/state-machines/index.d.cts +17 -31
  77. package/dist/state-machines/index.d.ts +17 -31
  78. package/dist/state-machines/index.js +1 -1
  79. package/package.json +1 -11
  80. package/dist/chunk-35SDMFCR.js.map +0 -1
  81. package/dist/chunk-3O4GMCCE.js +0 -55
  82. package/dist/chunk-3O4GMCCE.js.map +0 -1
  83. package/dist/chunk-4MMMXV4Q.js.map +0 -1
  84. package/dist/chunk-4RMKUYRX.js +0 -59
  85. package/dist/chunk-6ER62UUN.js.map +0 -1
  86. package/dist/chunk-7RV5REPT.cjs +0 -63
  87. package/dist/chunk-7RV5REPT.cjs.map +0 -1
  88. package/dist/chunk-7SHNYYGI.cjs.map +0 -1
  89. package/dist/chunk-EO4VSB2O.cjs +0 -99
  90. package/dist/chunk-EO4VSB2O.cjs.map +0 -1
  91. package/dist/chunk-FSUYD4F4.js.map +0 -1
  92. package/dist/chunk-JOATYJXQ.cjs +0 -70
  93. package/dist/chunk-JOATYJXQ.cjs.map +0 -1
  94. package/dist/chunk-LAZL2GDT.cjs.map +0 -1
  95. package/dist/chunk-NJL3US7H.cjs.map +0 -1
  96. package/dist/chunk-O5WVBQ7P.js +0 -89
  97. package/dist/chunk-O5WVBQ7P.js.map +0 -1
  98. package/dist/chunk-OC4ZFJKD.cjs.map +0 -1
  99. package/dist/chunk-T2JLSZN6.js +0 -67
  100. package/dist/chunk-T2JLSZN6.js.map +0 -1
  101. package/dist/chunk-UV252FLT.cjs +0 -74
  102. package/dist/chunk-UV252FLT.cjs.map +0 -1
  103. package/dist/chunk-X7WC4AYC.js.map +0 -1
  104. package/dist/chunk-YQEXO3IQ.cjs.map +0 -1
  105. package/dist/displays/index.cjs +0 -24
  106. package/dist/displays/index.cjs.map +0 -1
  107. package/dist/displays/index.d.cts +0 -34
  108. package/dist/displays/index.d.ts +0 -34
  109. package/dist/displays/index.js +0 -3
  110. package/dist/displays/index.js.map +0 -1
package/CHANGELOG.md CHANGED
@@ -1,5 +1,43 @@
1
1
  # @fabricorg/platform
2
2
 
3
+ ## 1.1.0
4
+
5
+ ### Minor Changes
6
+
7
+ - c504d0a: Make durability a declared, diffable contract.
8
+
9
+ `CapabilityMetadata` gains `workflows`: each declares its task queue, the event that starts it, the
10
+ durable deadlines it carries (resolved from configuration keys, never literals), and which governed
11
+ action reverses each compensatable step. The field is additive, so `MODULE_MANIFEST_VERSION` stays
12
+ at 2.
13
+
14
+ `diffModuleManifests` classifies this plane instead of reporting one blanket capability change:
15
+ adding a workflow, timer or reversal is compatible; moving a task queue, changing a trigger, dropping
16
+ a deadline or repointing a reversal is potentially breaking; removing a workflow or reversal is
17
+ breaking.
18
+
19
+ The compiler validates serialized workflow declarations, which never pass through a registry, and
20
+ rejects an action declaring `completion: "immediate"` while `kind: "saga"` — a manifest contradiction
21
+ that now fails the build rather than a running host.
22
+
23
+ `platform-temporal` executes declared reversals. `runCompensatedSaga` unwinds newest-first, routes
24
+ every reversal through the governed Host under a distinct deterministic
25
+ `compensationInvocationIdentity`, and surfaces a reversal that itself failed on
26
+ `SagaCompensationError` rather than swallowing it. A step that _resolves_ with a non-successful
27
+ status — blocked, failed, parked for approval, sent to reconciliation — now triggers the unwind
28
+ instead of being recorded as completed. Step identities must be unique and may not use the reserved
29
+ `compensate:` prefix, and when a `workflow` declaration is supplied every reversal is checked against
30
+ it.
31
+
32
+ ## 1.0.0
33
+
34
+ ### Major Changes
35
+
36
+ - Make the capability runtime vertical-neutral and instance-scoped. Move experience and display
37
+ semantics into a namespaced companion package, require explicit host registries, replace privacy
38
+ field defaults with caller-owned policy, add PostgreSQL projection adapters, and generate executable
39
+ ProjectionHost read and PlatformHost mutation seams.
40
+
3
41
  ## 0.12.1
4
42
 
5
43
  ### Patch Changes
package/README.md CHANGED
@@ -48,10 +48,9 @@ That's what this package gives you. Nothing more.
48
48
  | `@fabricorg/platform/events` | `AssetEventEnvelope`, `EventTypeRegistry` |
49
49
  | `@fabricorg/platform/projections` | Replay/snapshot framework |
50
50
  | `@fabricorg/platform/adapters` | `AdapterRegistry`, retry + circuit-breaker |
51
- | `@fabricorg/platform/modules` | `FabricModule<TDb>`, `registerFabricModules` |
51
+ | `@fabricorg/platform/modules` | `FabricModule<TDb>`, `createModuleRegistry` |
52
52
  | `@fabricorg/platform/manifest` | `exportModuleManifest`, `exportModuleManifestBundle`, `ModuleManifest` |
53
53
  | `@fabricorg/platform/ids` | `createFabricId`, `FABRIC_ID_PREFIXES` |
54
- | `@fabricorg/platform/displays` | `DisplayRendererRegistration` |
55
54
  | `@fabricorg/platform/privacy` | Redaction + data classification |
56
55
  | `@fabricorg/platform/evidence` | Compliance evidence packets |
57
56
  | `@fabricorg/platform/governance` | External footprints, delegated principals, obligations, attestations, and reconciliation |
@@ -69,7 +68,7 @@ Verticals declare a `FabricModule<TDb>` that registers their actions, policies,
69
68
 
70
69
  ```ts
71
70
  import type { FabricModule } from "@fabricorg/platform/modules";
72
- import { registerFabricModules } from "@fabricorg/platform/modules";
71
+ import { createModuleRegistry } from "@fabricorg/platform/modules";
73
72
 
74
73
  const myModule: FabricModule<MyDbClient> = {
75
74
  namespace: "demo",
@@ -78,14 +77,13 @@ const myModule: FabricModule<MyDbClient> = {
78
77
  actions: [greet, /* ... */],
79
78
  policies: [/* ... */],
80
79
  stateMachines: [/* ... */],
81
- displayRenderers: [],
82
80
  };
83
81
 
84
82
  // At app startup:
85
- registerFabricModules([myModule]);
83
+ const registry = createModuleRegistry([myModule]);
86
84
  ```
87
85
 
88
- The platform never auto-loads a module. The host app composes them explicitly — no implicit defaults, no globals, no surprises.
86
+ The platform never auto-loads a module. The host app composes an instance-scoped registry and injects it into its hosts. Experience roles, slots, action intents, and display rendering live in `@fabricorg/experience-contracts`, carried through the namespaced `fabric.experience/v1` extension.
89
87
 
90
88
  ## Exporting a module manifest
91
89
 
@@ -140,11 +138,12 @@ Your worker maps action IDs to implementations. The platform dispatches generica
140
138
 
141
139
  ## Portability boundary
142
140
 
143
- The `boundary.test.ts` in this package fails CI if any of these leak in:
141
+ The repository Boundary Guard scans source and packed artifacts and fails CI if any of these leak in:
144
142
 
145
143
  - Concrete database/ORM imports — the literal `Prisma`, the field name `prisma:`, or the type default `TDb = any`
146
- - Vertical vocabulary (`lending.`, `borrower`, `lender`, `Vehicle`, `Party`, `Obligation`, `Offer`, etc.)
144
+ - Vertical vocabulary from the governed denylist
147
145
  - "Register default" hooks (`registerDefaultPolicies`, etc.) — the platform never auto-loads anything
146
+ - Module-scope mutable registries, import-time environment reads, or unapproved infrastructure imports
148
147
 
149
148
  This is what keeps the platform portable across verticals and consumers. If you fork or add new patterns specific to your domain, extend the list in `boundary.test.ts`.
150
149
 
@@ -1,48 +1,28 @@
1
1
  'use strict';
2
2
 
3
- var chunkJOATYJXQ_cjs = require('../chunk-JOATYJXQ.cjs');
3
+ var chunkBFQNKQJE_cjs = require('../chunk-BFQNKQJE.cjs');
4
4
 
5
5
 
6
6
 
7
7
  Object.defineProperty(exports, "ACTOR_TYPES", {
8
8
  enumerable: true,
9
- get: function () { return chunkJOATYJXQ_cjs.ACTOR_TYPES; }
9
+ get: function () { return chunkBFQNKQJE_cjs.ACTOR_TYPES; }
10
10
  });
11
11
  Object.defineProperty(exports, "assertActionId", {
12
12
  enumerable: true,
13
- get: function () { return chunkJOATYJXQ_cjs.assertActionId; }
13
+ get: function () { return chunkBFQNKQJE_cjs.assertActionId; }
14
14
  });
15
15
  Object.defineProperty(exports, "assertActorType", {
16
16
  enumerable: true,
17
- get: function () { return chunkJOATYJXQ_cjs.assertActorType; }
17
+ get: function () { return chunkBFQNKQJE_cjs.assertActorType; }
18
18
  });
19
- Object.defineProperty(exports, "getRegisteredActionIds", {
19
+ Object.defineProperty(exports, "createActionRegistry", {
20
20
  enumerable: true,
21
- get: function () { return chunkJOATYJXQ_cjs.getRegisteredActionIds; }
21
+ get: function () { return chunkBFQNKQJE_cjs.createActionRegistry; }
22
22
  });
23
23
  Object.defineProperty(exports, "isActorType", {
24
24
  enumerable: true,
25
- get: function () { return chunkJOATYJXQ_cjs.isActorType; }
26
- });
27
- Object.defineProperty(exports, "isRegisteredActionId", {
28
- enumerable: true,
29
- get: function () { return chunkJOATYJXQ_cjs.isRegisteredActionId; }
30
- });
31
- Object.defineProperty(exports, "registerAction", {
32
- enumerable: true,
33
- get: function () { return chunkJOATYJXQ_cjs.registerAction; }
34
- });
35
- Object.defineProperty(exports, "registerActionIfMissing", {
36
- enumerable: true,
37
- get: function () { return chunkJOATYJXQ_cjs.registerActionIfMissing; }
38
- });
39
- Object.defineProperty(exports, "resolveAction", {
40
- enumerable: true,
41
- get: function () { return chunkJOATYJXQ_cjs.resolveAction; }
42
- });
43
- Object.defineProperty(exports, "resolveRegisteredAction", {
44
- enumerable: true,
45
- get: function () { return chunkJOATYJXQ_cjs.resolveRegisteredAction; }
25
+ get: function () { return chunkBFQNKQJE_cjs.isActorType; }
46
26
  });
47
27
  //# sourceMappingURL=index.cjs.map
48
28
  //# sourceMappingURL=index.cjs.map
@@ -159,11 +159,13 @@ interface SagaCompletion {
159
159
  }
160
160
  type SagaImplementation = (ctx: SagaContext, runChild: SagaRunChild) => Promise<SagaCompletion>;
161
161
  declare function assertActionId(actionId: string): asserts actionId is ActionId;
162
- declare function registerAction(definition: ActionDefinition): void;
163
- declare function resolveAction(actionId: ActionId): ActionDefinition | undefined;
164
- declare function isRegisteredActionId(actionId: string): actionId is ActionId;
165
- declare function resolveRegisteredAction(actionId: string): ActionDefinition | undefined;
166
- declare function getRegisteredActionIds(): ActionId[];
167
- declare function registerActionIfMissing(definition: ActionDefinition): void;
162
+ interface ActionRegistry<TDb = unknown> {
163
+ register(definition: ActionDefinition<TDb>): void;
164
+ registerIfMissing(definition: ActionDefinition<TDb>): void;
165
+ resolve(actionId: ActionId): ActionDefinition<TDb> | undefined;
166
+ has(actionId: string): actionId is ActionId;
167
+ ids(): ActionId[];
168
+ }
169
+ declare function createActionRegistry<TDb = unknown>(definitions?: readonly ActionDefinition<TDb>[]): ActionRegistry<TDb>;
168
170
 
169
- export { ACTOR_TYPES, type ActionCompletionMode, type ActionConnectivity, type ActionConsistency, type ActionContext, type ActionDataSensitivity, type ActionDefinition, type ActionExecutionContract, type ActionHandler, type ActionId, type ActionIdempotencyStance, type ActionResult, type ActionStateMachineBinding, type ActionStatus, type ActorType, type AdapterStep, type AdapterStepRetryPolicy, type AuthorityMoment, type FabricRuntimeServices, type SagaChildActionInput, type SagaCompletion, type SagaCompletionEvent, type SagaContext, type SagaImplementation, type SagaRunChild, type SchemaParseIssue, type SchemaParseResult, type SchemaValidator, assertActionId, assertActorType, getRegisteredActionIds, isActorType, isRegisteredActionId, registerAction, registerActionIfMissing, resolveAction, resolveRegisteredAction };
171
+ export { ACTOR_TYPES, type ActionCompletionMode, type ActionConnectivity, type ActionConsistency, type ActionContext, type ActionDataSensitivity, type ActionDefinition, type ActionExecutionContract, type ActionHandler, type ActionId, type ActionIdempotencyStance, type ActionRegistry, type ActionResult, type ActionStateMachineBinding, type ActionStatus, type ActorType, type AdapterStep, type AdapterStepRetryPolicy, type AuthorityMoment, type FabricRuntimeServices, type SagaChildActionInput, type SagaCompletion, type SagaCompletionEvent, type SagaContext, type SagaImplementation, type SagaRunChild, type SchemaParseIssue, type SchemaParseResult, type SchemaValidator, assertActionId, assertActorType, createActionRegistry, isActorType };
@@ -159,11 +159,13 @@ interface SagaCompletion {
159
159
  }
160
160
  type SagaImplementation = (ctx: SagaContext, runChild: SagaRunChild) => Promise<SagaCompletion>;
161
161
  declare function assertActionId(actionId: string): asserts actionId is ActionId;
162
- declare function registerAction(definition: ActionDefinition): void;
163
- declare function resolveAction(actionId: ActionId): ActionDefinition | undefined;
164
- declare function isRegisteredActionId(actionId: string): actionId is ActionId;
165
- declare function resolveRegisteredAction(actionId: string): ActionDefinition | undefined;
166
- declare function getRegisteredActionIds(): ActionId[];
167
- declare function registerActionIfMissing(definition: ActionDefinition): void;
162
+ interface ActionRegistry<TDb = unknown> {
163
+ register(definition: ActionDefinition<TDb>): void;
164
+ registerIfMissing(definition: ActionDefinition<TDb>): void;
165
+ resolve(actionId: ActionId): ActionDefinition<TDb> | undefined;
166
+ has(actionId: string): actionId is ActionId;
167
+ ids(): ActionId[];
168
+ }
169
+ declare function createActionRegistry<TDb = unknown>(definitions?: readonly ActionDefinition<TDb>[]): ActionRegistry<TDb>;
168
170
 
169
- export { ACTOR_TYPES, type ActionCompletionMode, type ActionConnectivity, type ActionConsistency, type ActionContext, type ActionDataSensitivity, type ActionDefinition, type ActionExecutionContract, type ActionHandler, type ActionId, type ActionIdempotencyStance, type ActionResult, type ActionStateMachineBinding, type ActionStatus, type ActorType, type AdapterStep, type AdapterStepRetryPolicy, type AuthorityMoment, type FabricRuntimeServices, type SagaChildActionInput, type SagaCompletion, type SagaCompletionEvent, type SagaContext, type SagaImplementation, type SagaRunChild, type SchemaParseIssue, type SchemaParseResult, type SchemaValidator, assertActionId, assertActorType, getRegisteredActionIds, isActorType, isRegisteredActionId, registerAction, registerActionIfMissing, resolveAction, resolveRegisteredAction };
171
+ export { ACTOR_TYPES, type ActionCompletionMode, type ActionConnectivity, type ActionConsistency, type ActionContext, type ActionDataSensitivity, type ActionDefinition, type ActionExecutionContract, type ActionHandler, type ActionId, type ActionIdempotencyStance, type ActionRegistry, type ActionResult, type ActionStateMachineBinding, type ActionStatus, type ActorType, type AdapterStep, type AdapterStepRetryPolicy, type AuthorityMoment, type FabricRuntimeServices, type SagaChildActionInput, type SagaCompletion, type SagaCompletionEvent, type SagaContext, type SagaImplementation, type SagaRunChild, type SchemaParseIssue, type SchemaParseResult, type SchemaValidator, assertActionId, assertActorType, createActionRegistry, isActorType };
@@ -1,3 +1,3 @@
1
- export { ACTOR_TYPES, assertActionId, assertActorType, getRegisteredActionIds, isActorType, isRegisteredActionId, registerAction, registerActionIfMissing, resolveAction, resolveRegisteredAction } from '../chunk-4RMKUYRX.js';
1
+ export { ACTOR_TYPES, assertActionId, assertActorType, createActionRegistry, isActorType } from '../chunk-4QOA3VU5.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -0,0 +1,47 @@
1
+ // actions/index.ts
2
+ var ACTOR_TYPES = [
3
+ "natural_person",
4
+ "agent",
5
+ "system",
6
+ "service_account",
7
+ "external_system",
8
+ "integration"
9
+ ];
10
+ function isActorType(value) {
11
+ return ACTOR_TYPES.includes(value);
12
+ }
13
+ function assertActorType(value) {
14
+ if (!isActorType(value)) {
15
+ throw new Error(`Invalid actorType: ${value}`);
16
+ }
17
+ }
18
+ function assertActionId(actionId) {
19
+ if (!/^[a-z][a-z0-9-]*\.[a-z][a-z0-9_]*$/.test(actionId)) {
20
+ throw new Error(`Invalid action ID: ${actionId}`);
21
+ }
22
+ }
23
+ function createActionRegistry(definitions = []) {
24
+ const actions = /* @__PURE__ */ new Map();
25
+ const register = (definition) => {
26
+ assertActionId(definition.actionId);
27
+ if (actions.has(definition.actionId)) throw new Error(`Action "${definition.actionId}" is already registered`);
28
+ if (definition.mutatesDomain && definition.emitsEvents.length === 0) {
29
+ throw new Error(`Action "${definition.actionId}" mutates domain but emits no events. Every mutating action must emit at least one AssetEvent.`);
30
+ }
31
+ actions.set(definition.actionId, definition);
32
+ };
33
+ for (const definition of definitions) register(definition);
34
+ return {
35
+ register,
36
+ registerIfMissing(definition) {
37
+ if (!actions.has(definition.actionId)) register(definition);
38
+ },
39
+ resolve: (actionId) => actions.get(actionId),
40
+ has: (actionId) => actions.has(actionId),
41
+ ids: () => Array.from(actions.keys())
42
+ };
43
+ }
44
+
45
+ export { ACTOR_TYPES, assertActionId, assertActorType, createActionRegistry, isActorType };
46
+ //# sourceMappingURL=chunk-4QOA3VU5.js.map
47
+ //# sourceMappingURL=chunk-4QOA3VU5.js.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;AA2KO,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;AAUO,SAAS,oBAAA,CAAoC,WAAA,GAAgD,EAAC,EAAwB;AAC5H,EAAA,MAAM,OAAA,uBAAc,GAAA,EAAqC;AACzD,EAAA,MAAM,QAAA,GAAW,CAAC,UAAA,KAA4C;AAC7D,IAAA,cAAA,CAAe,WAAW,QAAQ,CAAA;AAClC,IAAA,IAAI,OAAA,CAAQ,GAAA,CAAI,UAAA,CAAW,QAAQ,CAAA,EAAG,MAAM,IAAI,KAAA,CAAM,CAAA,QAAA,EAAW,UAAA,CAAW,QAAQ,CAAA,uBAAA,CAAyB,CAAA;AAC7G,IAAA,IAAI,UAAA,CAAW,aAAA,IAAiB,UAAA,CAAW,WAAA,CAAY,WAAW,CAAA,EAAG;AACpE,MAAA,MAAM,IAAI,KAAA,CAAM,CAAA,QAAA,EAAW,UAAA,CAAW,QAAQ,CAAA,8FAAA,CAAgG,CAAA;AAAA,IAC/I;AACA,IAAA,OAAA,CAAQ,GAAA,CAAI,UAAA,CAAW,QAAA,EAAU,UAAU,CAAA;AAAA,EAC5C,CAAA;AACA,EAAA,KAAA,MAAW,UAAA,IAAc,WAAA,EAAa,QAAA,CAAS,UAAU,CAAA;AACzD,EAAA,OAAO;AAAA,IACN,QAAA;AAAA,IACA,kBAAkB,UAAA,EAAY;AAC7B,MAAA,IAAI,CAAC,OAAA,CAAQ,GAAA,CAAI,WAAW,QAAQ,CAAA,WAAY,UAAU,CAAA;AAAA,IAC3D,CAAA;AAAA,IACA,OAAA,EAAS,CAAC,QAAA,KAAa,OAAA,CAAQ,IAAI,QAAQ,CAAA;AAAA,IAC3C,GAAA,EAAK,CAAC,QAAA,KAAmC,OAAA,CAAQ,IAAI,QAAoB,CAAA;AAAA,IACzE,KAAK,MAAM,KAAA,CAAM,IAAA,CAAK,OAAA,CAAQ,MAAM;AAAA,GACrC;AACD","file":"chunk-4QOA3VU5.js","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| \"reconciliation_required\"\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\tprovenance?: { source: string; auditAttributes?: Record<string, 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\t/** Portable execution semantics used by hosts, gateways, and generated capability contracts. */\n\texecution?: ActionExecutionContract;\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 type ActionConnectivity = \"online-required\" | \"offline-capturable\";\nexport type AuthorityMoment = \"capture\" | \"execution\" | \"both\";\nexport type ActionIdempotencyStance = \"required\" | \"supported\" | \"prohibited\";\nexport type ActionCompletionMode = \"immediate\" | \"accepted\" | \"long-running\";\nexport type ActionConsistency = \"authoritative-now\" | \"provisional-until-reconciled\";\nexport type ActionDataSensitivity = \"public\" | \"internal\" | \"confidential\" | \"restricted\";\n\nexport interface ActionExecutionContract {\n\tconnectivity: ActionConnectivity;\n\tauthorityMoment: AuthorityMoment;\n\tidempotency: ActionIdempotencyStance;\n\tcompletion: ActionCompletionMode;\n\tconsistency: ActionConsistency;\n\tsensitivity?: ActionDataSensitivity;\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\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 interface ActionRegistry<TDb = unknown> {\n\tregister(definition: ActionDefinition<TDb>): void;\n\tregisterIfMissing(definition: ActionDefinition<TDb>): void;\n\tresolve(actionId: ActionId): ActionDefinition<TDb> | undefined;\n\thas(actionId: string): actionId is ActionId;\n\tids(): ActionId[];\n}\n\nexport function createActionRegistry<TDb = unknown>(definitions: readonly ActionDefinition<TDb>[] = []): ActionRegistry<TDb> {\n\tconst actions = new Map<ActionId, ActionDefinition<TDb>>();\n\tconst register = (definition: ActionDefinition<TDb>): void => {\n\t\tassertActionId(definition.actionId);\n\t\tif (actions.has(definition.actionId)) throw new Error(`Action \"${definition.actionId}\" is already registered`);\n\t\tif (definition.mutatesDomain && definition.emitsEvents.length === 0) {\n\t\t\tthrow new Error(`Action \"${definition.actionId}\" mutates domain but emits no events. Every mutating action must emit at least one AssetEvent.`);\n\t\t}\n\t\tactions.set(definition.actionId, definition);\n\t};\n\tfor (const definition of definitions) register(definition);\n\treturn {\n\t\tregister,\n\t\tregisterIfMissing(definition) {\n\t\t\tif (!actions.has(definition.actionId)) register(definition);\n\t\t},\n\t\tresolve: (actionId) => actions.get(actionId),\n\t\thas: (actionId): actionId is ActionId => actions.has(actionId as ActionId),\n\t\tids: () => Array.from(actions.keys()),\n\t};\n}\n"]}
@@ -1,15 +1,8 @@
1
- import { assertPortableJsonSchema, registerObjectType } from './chunk-4MMMXV4Q.js';
2
- import { registerPolicyIfMissing } from './chunk-6ER62UUN.js';
3
- import { registerViewContractIfMissing } from './chunk-FSUYD4F4.js';
4
- import { registerStateMachineIfMissing } from './chunk-T2JLSZN6.js';
5
- import { registerActionIfMissing } from './chunk-4RMKUYRX.js';
6
- import { registerDisplayRenderer } from './chunk-O5WVBQ7P.js';
7
- import { isValidEventType, registerSubjectType, registerEventType } from './chunk-3O4GMCCE.js';
1
+ import { assertPortableJsonSchema } from './chunk-NETLRKDS.js';
2
+ import { viewContractKey } from './chunk-J5LS5BSI.js';
3
+ import { createEventContractRegistry } from './chunk-NHGBTPPE.js';
8
4
 
9
5
  // modules/index.ts
10
- var registeredModuleNamespaces = /* @__PURE__ */ new Set();
11
- var registeredQualifiedObjectTypes = /* @__PURE__ */ new Set();
12
- var registeredObjectDefinitions = /* @__PURE__ */ new Map();
13
6
  function getModuleDependencyNamespace(dependency) {
14
7
  return typeof dependency === "string" ? dependency : dependency.namespace;
15
8
  }
@@ -30,15 +23,26 @@ function validateModuleNamespace(namespace) {
30
23
  }
31
24
  }
32
25
  function createModuleRegistry(modules = []) {
33
- const registered = /* @__PURE__ */ new Map();
34
- for (const module of modules) {
35
- validateModuleNamespace(module.namespace);
36
- if (registered.has(module.namespace)) {
37
- throw new Error(`Duplicate FabricModule namespace "${module.namespace}".`);
38
- }
39
- registered.set(module.namespace, module);
40
- }
41
- return { modules: registered };
26
+ const orderedModules = validateAndOrderFabricModules(modules);
27
+ const registered = new Map(orderedModules.map((module) => [module.namespace, module]));
28
+ const actions = new Map(orderedModules.flatMap((module) => (module.actions ?? []).map((action) => [action.actionId, action])));
29
+ const policies = new Map(orderedModules.flatMap((module) => (module.policies ?? []).map((policy) => {
30
+ const evaluator = policy;
31
+ return [evaluator.policyId, evaluator];
32
+ })));
33
+ const machines = new Map(orderedModules.flatMap((module) => (module.stateMachines ?? []).map((machine) => {
34
+ const definition = machine;
35
+ return [definition.entityType, definition];
36
+ })));
37
+ const views = new Map(orderedModules.flatMap((module) => (module.views ?? []).map((view) => [viewContractKey(view), view])));
38
+ return {
39
+ modules: registered,
40
+ orderedModules,
41
+ resolveAction: (actionId) => actions.get(actionId),
42
+ resolvePolicy: (policyId) => policies.get(policyId),
43
+ resolveStateMachine: (entityType) => machines.get(entityType),
44
+ resolveView: (name, version) => views.get(`${name}@${version}`)
45
+ };
42
46
  }
43
47
  function validateIdentifierList(values, label, namespace) {
44
48
  for (const value of values ?? []) {
@@ -106,6 +110,56 @@ function validateObjectDefinition(objectType, namespace, context) {
106
110
  }
107
111
  }
108
112
  }
113
+ function validateCapabilityWorkflows(module, context) {
114
+ const workflows = module.capability?.workflows ?? [];
115
+ const actionsById = new Map((module.actions ?? []).map((action) => [action.actionId, action]));
116
+ const names = /* @__PURE__ */ new Set();
117
+ for (const workflow of workflows) {
118
+ if (!/^[A-Za-z][A-Za-z0-9_-]*$/.test(workflow.name)) {
119
+ throw new Error(`Module "${module.namespace}" declares invalid workflow name "${workflow.name}".`);
120
+ }
121
+ if (names.has(workflow.name)) {
122
+ throw new Error(`Module "${module.namespace}" declares duplicate workflow "${workflow.name}".`);
123
+ }
124
+ names.add(workflow.name);
125
+ if (!/^[a-z][a-z0-9-]*(\.[a-z][a-z0-9-]*)*$/.test(workflow.taskQueue)) {
126
+ throw new Error(`Module "${module.namespace}" workflow "${workflow.name}" declares invalid task queue "${workflow.taskQueue}".`);
127
+ }
128
+ if (workflow.startedBy !== void 0) {
129
+ const known = context.plannedEventTypes?.has(workflow.startedBy) ?? (module.eventTypes ?? []).some((eventType) => getEventTypeName(eventType) === workflow.startedBy);
130
+ if (!known) {
131
+ throw new Error(`Module "${module.namespace}" workflow "${workflow.name}" is started by unknown event type "${workflow.startedBy}".`);
132
+ }
133
+ }
134
+ const timerNames = /* @__PURE__ */ new Set();
135
+ for (const timer of workflow.timers ?? []) {
136
+ if (!timer.name.trim() || !timer.configKey.trim()) {
137
+ throw new Error(`Module "${module.namespace}" workflow "${workflow.name}" has a timer without a name or configKey.`);
138
+ }
139
+ if (timerNames.has(timer.name)) {
140
+ throw new Error(`Module "${module.namespace}" workflow "${workflow.name}" declares duplicate timer "${timer.name}".`);
141
+ }
142
+ timerNames.add(timer.name);
143
+ }
144
+ const steps = /* @__PURE__ */ new Set();
145
+ for (const compensation of workflow.compensations ?? []) {
146
+ if (!compensation.step.trim()) {
147
+ throw new Error(`Module "${module.namespace}" workflow "${workflow.name}" has a compensation without a step.`);
148
+ }
149
+ if (steps.has(compensation.step)) {
150
+ throw new Error(`Module "${module.namespace}" workflow "${workflow.name}" declares duplicate compensation for step "${compensation.step}".`);
151
+ }
152
+ steps.add(compensation.step);
153
+ const compensatingAction = actionsById.get(compensation.actionId);
154
+ if (!compensatingAction) {
155
+ throw new Error(`Module "${module.namespace}" workflow "${workflow.name}" compensates step "${compensation.step}" with unknown action "${compensation.actionId}".`);
156
+ }
157
+ if (!compensatingAction.idempotent || compensatingAction.execution?.idempotency === "prohibited") {
158
+ throw new Error(`Module "${module.namespace}" workflow "${workflow.name}" compensates step "${compensation.step}" with non-idempotent action "${compensation.actionId}"; a reversal must be safely repeatable.`);
159
+ }
160
+ }
161
+ }
162
+ }
109
163
  function validateManifest(module, context = {}) {
110
164
  validateModuleNamespace(module.namespace);
111
165
  const dependencies = (module.dependencies ?? []).map(getModuleDependencyNamespace);
@@ -115,25 +169,15 @@ function validateManifest(module, context = {}) {
115
169
  if (!module.capability.displayName.trim() || !module.capability.description.trim()) {
116
170
  throw new Error(`Module "${module.namespace}" capability requires displayName and description.`);
117
171
  }
118
- if (new Set(module.capability.roles ?? []).size !== (module.capability.roles ?? []).length || (module.capability.roles ?? []).some((role) => !/^[a-z][a-z0-9-]*$/.test(role))) {
119
- throw new Error(`Module "${module.namespace}" capability has invalid or duplicate roles.`);
120
- }
121
- const slots = /* @__PURE__ */ new Set();
122
- for (const slot of module.capability.slots ?? []) {
123
- if (!/^[a-z][a-z0-9-]*$/.test(slot.name) || slots.has(slot.name)) {
124
- throw new Error(`Module "${module.namespace}" capability has invalid or duplicate slot "${slot.name}".`);
172
+ for (const namespace of Object.keys(module.capability.extensions ?? {})) {
173
+ if (!/^[a-z][a-z0-9.-]*\.[a-z0-9.-]+\/v[1-9][0-9]*$/.test(namespace)) {
174
+ throw new Error(`Module "${module.namespace}" capability has invalid extension namespace "${namespace}".`);
125
175
  }
126
- slots.add(slot.name);
127
- if (slot.shape) assertPortableJsonSchema(slot.shape, `Capability slot "${slot.name}" shape`);
128
- }
129
- const intents = /* @__PURE__ */ new Set();
130
- for (const intent of module.capability.actionIntents ?? []) {
131
- if (!/^[a-z][a-z0-9-]*(?:\.[a-z][a-z0-9-]*)+$/.test(intent.name) || intents.has(intent.name)) throw new Error(`Module "${module.namespace}" capability has invalid or duplicate action intent "${intent.name}".`);
132
- intents.add(intent.name);
133
176
  }
134
177
  for (const port of module.capability.requirements?.ports ?? []) {
135
178
  if (!/^[a-z][a-z0-9-]*$/.test(port.name)) throw new Error(`Module "${module.namespace}" capability has invalid port requirement "${port.name}".`);
136
179
  }
180
+ validateCapabilityWorkflows(module, context);
137
181
  }
138
182
  for (const eventType of module.eventTypes ?? []) if (typeof eventType !== "string" && eventType.schema) assertPortableJsonSchema(eventType.schema, `Event "${eventType.eventType}" schema`);
139
183
  for (const action of module.actions ?? []) {
@@ -205,15 +249,6 @@ function validateManifest(module, context = {}) {
205
249
  );
206
250
  }
207
251
  }
208
- for (const descriptor of module.displayRenderers ?? []) {
209
- const isPlannedEventType = context.plannedEventTypes?.has(descriptor.eventType) ?? false;
210
- const isModuleEventType = eventTypes.includes(descriptor.eventType);
211
- if (!isValidEventType(descriptor.eventType) && !isModuleEventType && !isPlannedEventType) {
212
- throw new Error(
213
- `Display renderer registered for unknown event type "${descriptor.eventType}". Register the event type before adding a display renderer.`
214
- );
215
- }
216
- }
217
252
  const viewKeys = /* @__PURE__ */ new Set();
218
253
  for (const view of module.views ?? []) {
219
254
  if (!view.name.startsWith(`${module.namespace}/`) || !/^[a-z][a-z0-9-]*\/[a-z][a-z0-9/_-]*$/.test(view.name)) {
@@ -233,7 +268,7 @@ function validateManifest(module, context = {}) {
233
268
  for (const consumption of view.consumes) {
234
269
  const isPlanned = context.plannedEventTypes?.has(consumption.eventType) ?? false;
235
270
  const isModuleEvent = eventTypes.includes(consumption.eventType);
236
- if (!isValidEventType(consumption.eventType) && !isPlanned && !isModuleEvent) {
271
+ if (!isPlanned && !isModuleEvent) {
237
272
  throw new Error(`View "${key}" consumes unknown event type "${consumption.eventType}".`);
238
273
  }
239
274
  if (consumption.schemaVersions.length === 0 || consumption.schemaVersions.some((version) => !Number.isInteger(version) || version < 1)) {
@@ -242,12 +277,12 @@ function validateManifest(module, context = {}) {
242
277
  }
243
278
  }
244
279
  }
245
- function sortModulesByDependency(modules, registeredNamespaces = registeredModuleNamespaces) {
280
+ function sortModulesByDependency(modules, registeredNamespaces = /* @__PURE__ */ new Set()) {
246
281
  const modulesByNamespace = /* @__PURE__ */ new Map();
247
282
  for (const module of modules) {
248
283
  validateModuleNamespace(module.namespace);
249
284
  if (modulesByNamespace.has(module.namespace)) {
250
- throw new Error(`Duplicate Fabric module namespace "${module.namespace}".`);
285
+ throw new Error(`Duplicate FabricModule namespace "${module.namespace}".`);
251
286
  }
252
287
  modulesByNamespace.set(module.namespace, module);
253
288
  }
@@ -291,9 +326,6 @@ function assertAcyclicRelations(modules) {
291
326
  ];
292
327
  for (const kind of relationKinds) {
293
328
  const edges = /* @__PURE__ */ new Map();
294
- for (const [source, objectType] of registeredObjectDefinitions) {
295
- edges.set(source, (objectType.relations ?? []).filter(kind.include).map((relation) => relation.target));
296
- }
297
329
  for (const module of modules) {
298
330
  for (const objectType of module.objectTypes ?? []) {
299
331
  if (typeof objectType === "string") continue;
@@ -316,53 +348,13 @@ function assertAcyclicRelations(modules) {
316
348
  for (const node of edges.keys()) visit(node, []);
317
349
  }
318
350
  }
319
- function registerValidatedFabricModule(module) {
320
- for (const objectType of module.objectTypes ?? []) {
321
- registerObjectType(getObjectTypeName(objectType));
322
- const qualified = qualifiedObjectType(module.namespace, getObjectTypeName(objectType));
323
- registeredQualifiedObjectTypes.add(qualified);
324
- if (typeof objectType !== "string") registeredObjectDefinitions.set(qualified, objectType);
325
- }
326
- for (const subjectType of module.subjectTypes ?? []) {
327
- registerSubjectType(subjectType);
328
- }
329
- for (const eventType of module.eventTypes ?? []) {
330
- registerEventType(getEventTypeName(eventType));
331
- }
332
- for (const policy of module.policies ?? []) {
333
- registerPolicyIfMissing(policy);
334
- }
335
- for (const machine of module.stateMachines ?? []) {
336
- registerStateMachineIfMissing(machine);
337
- }
338
- for (const action of module.actions ?? []) {
339
- registerActionIfMissing(action);
340
- }
341
- for (const descriptor of module.displayRenderers ?? []) {
342
- registerDisplayRenderer(descriptor.eventType, descriptor.renderer);
343
- }
344
- for (const view of module.views ?? []) registerViewContractIfMissing(view);
345
- registeredModuleNamespaces.add(module.namespace);
346
- }
347
- function registerFabricModule(module) {
348
- const availableObjectTypes = /* @__PURE__ */ new Set([
349
- ...registeredQualifiedObjectTypes,
350
- ...(module.objectTypes ?? []).map((objectType) => qualifiedObjectType(module.namespace, getObjectTypeName(objectType)))
351
- ]);
352
- validateManifest(module, { availableNamespaces: registeredModuleNamespaces, availableObjectTypes });
353
- assertAcyclicRelations([module]);
354
- registerValidatedFabricModule(module);
355
- }
356
- function registerFabricModules(modules) {
357
- const availableNamespaces = /* @__PURE__ */ new Set([
358
- ...registeredModuleNamespaces,
359
- ...modules.map((module) => module.namespace)
360
- ]);
351
+ function validateAndOrderFabricModules(modules) {
352
+ const availableNamespaces = new Set(modules.map((module) => module.namespace));
361
353
  const plannedEventTypes = new Set(
362
354
  modules.flatMap((module) => (module.eventTypes ?? []).map(getEventTypeName))
363
355
  );
356
+ for (const eventType of createEventContractRegistry().eventTypes()) plannedEventTypes.add(eventType);
364
357
  const availableObjectTypes = /* @__PURE__ */ new Set([
365
- ...registeredQualifiedObjectTypes,
366
358
  ...modules.flatMap(
367
359
  (module) => (module.objectTypes ?? []).map((objectType) => qualifiedObjectType(module.namespace, getObjectTypeName(objectType)))
368
360
  )
@@ -371,13 +363,15 @@ function registerFabricModules(modules) {
371
363
  validateManifest(module, { availableNamespaces, plannedEventTypes, availableObjectTypes });
372
364
  }
373
365
  assertAcyclicRelations(modules);
374
- const sortedModules = sortModulesByDependency(modules);
375
- for (const module of sortedModules) {
376
- registerValidatedFabricModule(module);
377
- }
378
- return sortedModules;
366
+ return sortModulesByDependency(modules);
367
+ }
368
+ function registerFabricModules(modules) {
369
+ return validateAndOrderFabricModules(modules);
370
+ }
371
+ function registerFabricModule(module) {
372
+ validateAndOrderFabricModules([module]);
379
373
  }
380
374
 
381
- export { createModuleRegistry, getEventTypeName, getModuleDependencyNamespace, getObjectTypeName, registerFabricModule, registerFabricModules, validateModuleNamespace };
382
- //# sourceMappingURL=chunk-35SDMFCR.js.map
383
- //# sourceMappingURL=chunk-35SDMFCR.js.map
375
+ export { createModuleRegistry, getEventTypeName, getModuleDependencyNamespace, getObjectTypeName, registerFabricModule, registerFabricModules, validateAndOrderFabricModules, validateModuleNamespace };
376
+ //# sourceMappingURL=chunk-53YJK3LK.js.map
377
+ //# sourceMappingURL=chunk-53YJK3LK.js.map