@fabricorg/platform 0.9.0 → 0.11.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 (61) hide show
  1. package/CHANGELOG.md +48 -2
  2. package/README.md +21 -0
  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-3JQI3OFC.js +347 -0
  8. package/dist/chunk-3JQI3OFC.js.map +1 -0
  9. package/dist/chunk-3S6UTP4X.js +110 -0
  10. package/dist/chunk-3S6UTP4X.js.map +1 -0
  11. package/dist/{chunk-JSTGOT6P.js → chunk-7WASIL46.js} +58 -3
  12. package/dist/chunk-7WASIL46.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-4SMPJPJ6.js → chunk-JM55UQWK.js} +2 -2
  16. package/dist/chunk-JM55UQWK.js.map +1 -0
  17. package/dist/chunk-NFP5DJBT.js +219 -0
  18. package/dist/chunk-NFP5DJBT.js.map +1 -0
  19. package/dist/{chunk-Q3WYIWCN.cjs → chunk-O7IHZ53Y.cjs} +63 -2
  20. package/dist/chunk-O7IHZ53Y.cjs.map +1 -0
  21. package/dist/chunk-ODP3DO6P.cjs +355 -0
  22. package/dist/chunk-ODP3DO6P.cjs.map +1 -0
  23. package/dist/chunk-RYCHDNHZ.cjs +226 -0
  24. package/dist/chunk-RYCHDNHZ.cjs.map +1 -0
  25. package/dist/chunk-XCL2HBMB.cjs +116 -0
  26. package/dist/chunk-XCL2HBMB.cjs.map +1 -0
  27. package/dist/index.cjs +92 -39
  28. package/dist/index.d.cts +4 -3
  29. package/dist/index.d.ts +4 -3
  30. package/dist/index.js +6 -5
  31. package/dist/manifest/index.cjs +40 -0
  32. package/dist/manifest/index.cjs.map +1 -0
  33. package/dist/manifest/index.d.cts +181 -0
  34. package/dist/manifest/index.d.ts +181 -0
  35. package/dist/manifest/index.js +11 -0
  36. package/dist/manifest/index.js.map +1 -0
  37. package/dist/modules/index.cjs +11 -10
  38. package/dist/modules/index.d.cts +49 -1
  39. package/dist/modules/index.d.ts +49 -1
  40. package/dist/modules/index.js +4 -3
  41. package/dist/objects/index.cjs +9 -5
  42. package/dist/objects/index.d.cts +45 -1
  43. package/dist/objects/index.d.ts +45 -1
  44. package/dist/objects/index.js +1 -1
  45. package/dist/projections/index.cjs +26 -2
  46. package/dist/projections/index.d.cts +38 -2
  47. package/dist/projections/index.d.ts +38 -2
  48. package/dist/projections/index.js +1 -1
  49. package/package.json +11 -1
  50. package/dist/chunk-35DD3H55.js +0 -187
  51. package/dist/chunk-35DD3H55.js.map +0 -1
  52. package/dist/chunk-4SMPJPJ6.js.map +0 -1
  53. package/dist/chunk-BWNPGRRV.cjs.map +0 -1
  54. package/dist/chunk-I35B576X.js +0 -30
  55. package/dist/chunk-I35B576X.js.map +0 -1
  56. package/dist/chunk-JSTGOT6P.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
@@ -1,5 +1,7 @@
1
1
  import { ActionDefinition } from '../actions/index.js';
2
2
  import { DisplayRenderer } from '../displays/index.js';
3
+ import { PortableJsonSchema, JsonValue } from '../objects/index.js';
4
+ import { ViewContract } from '../projections/index.js';
3
5
 
4
6
  interface ModuleDependency {
5
7
  namespace: string;
@@ -23,6 +25,29 @@ interface ObjectTypeRegistration {
23
25
  displayName?: string;
24
26
  idPrefix?: string;
25
27
  isCoreModuleType?: boolean;
28
+ schema?: PortableJsonSchema;
29
+ semantics?: Record<string, JsonValue>;
30
+ relations?: ObjectRelationDefinition[];
31
+ invariants?: DeclarativeInvariant[];
32
+ }
33
+ type ObjectRelationCardinality = "one" | "many";
34
+ type ObjectRelationSemantics = "reference" | "owned";
35
+ type ObjectRelationDeleteBehavior = "restrict" | "cascade" | "set-null";
36
+ interface ObjectRelationDefinition {
37
+ name: string;
38
+ target: `${string}.${string}`;
39
+ cardinality: ObjectRelationCardinality;
40
+ required?: boolean;
41
+ semantics: ObjectRelationSemantics;
42
+ onTargetDelete: ObjectRelationDeleteBehavior;
43
+ }
44
+ type InvariantEnforcement = "json-schema" | "state-machine" | "policy" | "host-adapter" | "application";
45
+ interface DeclarativeInvariant {
46
+ id: string;
47
+ description: string;
48
+ required?: boolean;
49
+ enforcement: InvariantEnforcement;
50
+ enforcementRef?: string;
26
51
  }
27
52
  type ObjectTypeRegistrationInput = string | ObjectTypeRegistration;
28
53
  interface ModuleDisplayRendererRegistration {
@@ -38,11 +63,33 @@ interface StateMachineRegistration {
38
63
  entityType: string;
39
64
  states: string[];
40
65
  }
66
+ interface CapabilitySlotDefinition {
67
+ name: string;
68
+ description: string;
69
+ shape?: PortableJsonSchema;
70
+ }
71
+ interface CapabilityMetadata {
72
+ displayName: string;
73
+ description: string;
74
+ roles?: string[];
75
+ stability: "experimental" | "beta" | "stable" | "deprecated";
76
+ deprecated?: {
77
+ since: string;
78
+ replacement?: string;
79
+ message: string;
80
+ };
81
+ slots?: CapabilitySlotDefinition[];
82
+ certification?: {
83
+ profile: string;
84
+ required: boolean;
85
+ };
86
+ }
41
87
  interface FabricModule<TDb = unknown> {
42
88
  namespace: string;
43
89
  version?: string;
44
90
  displayName?: string;
45
91
  description?: string;
92
+ capability?: CapabilityMetadata;
46
93
  dependencies?: ModuleDependencyInput[];
47
94
  objectTypes?: ObjectTypeRegistrationInput[];
48
95
  subjectTypes?: string[];
@@ -59,6 +106,7 @@ interface FabricModule<TDb = unknown> {
59
106
  dataClassifications?: unknown[];
60
107
  retentionRules?: unknown[];
61
108
  evidenceRenderers?: unknown[];
109
+ views?: ViewContract[];
62
110
  }
63
111
  interface ModuleRegistry<TDb = unknown> {
64
112
  modules: ReadonlyMap<string, FabricModule<TDb>>;
@@ -71,4 +119,4 @@ declare function createModuleRegistry<TDb = unknown>(modules?: FabricModule<TDb>
71
119
  declare function registerFabricModule(module: FabricModule<unknown>): void;
72
120
  declare function registerFabricModules(modules: FabricModule<unknown>[]): FabricModule<unknown>[];
73
121
 
74
- export { type EventTypeRegistration, type EventTypeRegistrationInput, type FabricModule, type IdPrefixRegistration, type ModuleDependency, type ModuleDependencyInput, type ModuleDisplayRendererRegistration, type ModuleRegistry, type ObjectTypeRegistration, type ObjectTypeRegistrationInput, type PolicyRegistration, type StateMachineRegistration, createModuleRegistry, getEventTypeName, getModuleDependencyNamespace, getObjectTypeName, registerFabricModule, registerFabricModules, validateModuleNamespace };
122
+ export { type CapabilityMetadata, type CapabilitySlotDefinition, type DeclarativeInvariant, type EventTypeRegistration, type EventTypeRegistrationInput, type FabricModule, type IdPrefixRegistration, type InvariantEnforcement, type ModuleDependency, type ModuleDependencyInput, type ModuleDisplayRendererRegistration, type ModuleRegistry, type ObjectRelationCardinality, type ObjectRelationDefinition, type ObjectRelationDeleteBehavior, type ObjectRelationSemantics, type ObjectTypeRegistration, type ObjectTypeRegistrationInput, type PolicyRegistration, type StateMachineRegistration, createModuleRegistry, getEventTypeName, getModuleDependencyNamespace, getObjectTypeName, registerFabricModule, registerFabricModules, validateModuleNamespace };
@@ -1,8 +1,9 @@
1
- export { createModuleRegistry, getEventTypeName, getModuleDependencyNamespace, getObjectTypeName, registerFabricModule, registerFabricModules, validateModuleNamespace } from '../chunk-35DD3H55.js';
2
- import '../chunk-I35B576X.js';
1
+ export { createModuleRegistry, getEventTypeName, getModuleDependencyNamespace, getObjectTypeName, registerFabricModule, registerFabricModules, validateModuleNamespace } from '../chunk-3JQI3OFC.js';
2
+ import '../chunk-3S6UTP4X.js';
3
3
  import '../chunk-6ER62UUN.js';
4
+ import '../chunk-7WASIL46.js';
4
5
  import '../chunk-T2JLSZN6.js';
5
- import '../chunk-4SMPJPJ6.js';
6
+ import '../chunk-JM55UQWK.js';
6
7
  import '../chunk-O5WVBQ7P.js';
7
8
  import '../chunk-4YQOGV7H.js';
8
9
  //# sourceMappingURL=index.js.map
@@ -1,24 +1,28 @@
1
1
  'use strict';
2
2
 
3
- var chunkQETQGAXJ_cjs = require('../chunk-QETQGAXJ.cjs');
3
+ var chunkXCL2HBMB_cjs = require('../chunk-XCL2HBMB.cjs');
4
4
 
5
5
 
6
6
 
7
7
  Object.defineProperty(exports, "assertObjectType", {
8
8
  enumerable: true,
9
- get: function () { return chunkQETQGAXJ_cjs.assertObjectType; }
9
+ get: function () { return chunkXCL2HBMB_cjs.assertObjectType; }
10
+ });
11
+ Object.defineProperty(exports, "assertPortableJsonSchema", {
12
+ enumerable: true,
13
+ get: function () { return chunkXCL2HBMB_cjs.assertPortableJsonSchema; }
10
14
  });
11
15
  Object.defineProperty(exports, "getRegisteredObjectTypes", {
12
16
  enumerable: true,
13
- get: function () { return chunkQETQGAXJ_cjs.getRegisteredObjectTypes; }
17
+ get: function () { return chunkXCL2HBMB_cjs.getRegisteredObjectTypes; }
14
18
  });
15
19
  Object.defineProperty(exports, "isValidObjectType", {
16
20
  enumerable: true,
17
- get: function () { return chunkQETQGAXJ_cjs.isValidObjectType; }
21
+ get: function () { return chunkXCL2HBMB_cjs.isValidObjectType; }
18
22
  });
19
23
  Object.defineProperty(exports, "registerObjectType", {
20
24
  enumerable: true,
21
- get: function () { return chunkQETQGAXJ_cjs.registerObjectType; }
25
+ get: function () { return chunkXCL2HBMB_cjs.registerObjectType; }
22
26
  });
23
27
  //# sourceMappingURL=index.cjs.map
24
28
  //# sourceMappingURL=index.cjs.map
@@ -1,7 +1,51 @@
1
1
  type FabricObjectType = string;
2
+ type JsonPrimitive = string | number | boolean | null;
3
+ type JsonValue = JsonPrimitive | JsonValue[] | {
4
+ [key: string]: JsonValue;
5
+ };
6
+ /**
7
+ * Dependency-free JSON Schema profile accepted in portable module manifests.
8
+ * Unknown extension keywords must use an `x-` prefix. Runtime validators may
9
+ * support more vocabulary, but exported entity contracts stay in this profile.
10
+ */
11
+ interface PortableJsonSchema {
12
+ $schema?: string;
13
+ $id?: string;
14
+ $ref?: string;
15
+ $defs?: Record<string, PortableJsonSchema>;
16
+ title?: string;
17
+ description?: string;
18
+ type?: "null" | "boolean" | "object" | "array" | "number" | "integer" | "string" | Array<"null" | "boolean" | "object" | "array" | "number" | "integer" | "string">;
19
+ enum?: JsonValue[];
20
+ const?: JsonValue;
21
+ properties?: Record<string, PortableJsonSchema>;
22
+ required?: string[];
23
+ additionalProperties?: boolean | PortableJsonSchema;
24
+ items?: PortableJsonSchema | PortableJsonSchema[];
25
+ allOf?: PortableJsonSchema[];
26
+ anyOf?: PortableJsonSchema[];
27
+ oneOf?: PortableJsonSchema[];
28
+ not?: PortableJsonSchema;
29
+ minimum?: number;
30
+ maximum?: number;
31
+ exclusiveMinimum?: number;
32
+ exclusiveMaximum?: number;
33
+ minLength?: number;
34
+ maxLength?: number;
35
+ pattern?: string;
36
+ format?: string;
37
+ minItems?: number;
38
+ maxItems?: number;
39
+ uniqueItems?: boolean;
40
+ default?: JsonValue;
41
+ readOnly?: boolean;
42
+ writeOnly?: boolean;
43
+ [key: `x-${string}`]: JsonValue | undefined;
44
+ }
45
+ declare function assertPortableJsonSchema(schema: unknown, path?: string): asserts schema is PortableJsonSchema;
2
46
  declare function assertObjectType(type: string): asserts type is FabricObjectType;
3
47
  declare function registerObjectType(type: string): void;
4
48
  declare function isValidObjectType(type: string): boolean;
5
49
  declare function getRegisteredObjectTypes(): string[];
6
50
 
7
- export { type FabricObjectType, assertObjectType, getRegisteredObjectTypes, isValidObjectType, registerObjectType };
51
+ export { type FabricObjectType, type JsonPrimitive, type JsonValue, type PortableJsonSchema, assertObjectType, assertPortableJsonSchema, getRegisteredObjectTypes, isValidObjectType, registerObjectType };
@@ -1,7 +1,51 @@
1
1
  type FabricObjectType = string;
2
+ type JsonPrimitive = string | number | boolean | null;
3
+ type JsonValue = JsonPrimitive | JsonValue[] | {
4
+ [key: string]: JsonValue;
5
+ };
6
+ /**
7
+ * Dependency-free JSON Schema profile accepted in portable module manifests.
8
+ * Unknown extension keywords must use an `x-` prefix. Runtime validators may
9
+ * support more vocabulary, but exported entity contracts stay in this profile.
10
+ */
11
+ interface PortableJsonSchema {
12
+ $schema?: string;
13
+ $id?: string;
14
+ $ref?: string;
15
+ $defs?: Record<string, PortableJsonSchema>;
16
+ title?: string;
17
+ description?: string;
18
+ type?: "null" | "boolean" | "object" | "array" | "number" | "integer" | "string" | Array<"null" | "boolean" | "object" | "array" | "number" | "integer" | "string">;
19
+ enum?: JsonValue[];
20
+ const?: JsonValue;
21
+ properties?: Record<string, PortableJsonSchema>;
22
+ required?: string[];
23
+ additionalProperties?: boolean | PortableJsonSchema;
24
+ items?: PortableJsonSchema | PortableJsonSchema[];
25
+ allOf?: PortableJsonSchema[];
26
+ anyOf?: PortableJsonSchema[];
27
+ oneOf?: PortableJsonSchema[];
28
+ not?: PortableJsonSchema;
29
+ minimum?: number;
30
+ maximum?: number;
31
+ exclusiveMinimum?: number;
32
+ exclusiveMaximum?: number;
33
+ minLength?: number;
34
+ maxLength?: number;
35
+ pattern?: string;
36
+ format?: string;
37
+ minItems?: number;
38
+ maxItems?: number;
39
+ uniqueItems?: boolean;
40
+ default?: JsonValue;
41
+ readOnly?: boolean;
42
+ writeOnly?: boolean;
43
+ [key: `x-${string}`]: JsonValue | undefined;
44
+ }
45
+ declare function assertPortableJsonSchema(schema: unknown, path?: string): asserts schema is PortableJsonSchema;
2
46
  declare function assertObjectType(type: string): asserts type is FabricObjectType;
3
47
  declare function registerObjectType(type: string): void;
4
48
  declare function isValidObjectType(type: string): boolean;
5
49
  declare function getRegisteredObjectTypes(): string[];
6
50
 
7
- export { type FabricObjectType, assertObjectType, getRegisteredObjectTypes, isValidObjectType, registerObjectType };
51
+ export { type FabricObjectType, type JsonPrimitive, type JsonValue, type PortableJsonSchema, assertObjectType, assertPortableJsonSchema, getRegisteredObjectTypes, isValidObjectType, registerObjectType };
@@ -1,3 +1,3 @@
1
- export { assertObjectType, getRegisteredObjectTypes, isValidObjectType, registerObjectType } from '../chunk-I35B576X.js';
1
+ export { assertObjectType, assertPortableJsonSchema, getRegisteredObjectTypes, isValidObjectType, registerObjectType } from '../chunk-3S6UTP4X.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
@@ -1,12 +1,36 @@
1
1
  'use strict';
2
2
 
3
- var chunkQ3WYIWCN_cjs = require('../chunk-Q3WYIWCN.cjs');
3
+ var chunkO7IHZ53Y_cjs = require('../chunk-O7IHZ53Y.cjs');
4
4
 
5
5
 
6
6
 
7
+ Object.defineProperty(exports, "getRegisteredViewContractKeys", {
8
+ enumerable: true,
9
+ get: function () { return chunkO7IHZ53Y_cjs.getRegisteredViewContractKeys; }
10
+ });
11
+ Object.defineProperty(exports, "registerViewContract", {
12
+ enumerable: true,
13
+ get: function () { return chunkO7IHZ53Y_cjs.registerViewContract; }
14
+ });
15
+ Object.defineProperty(exports, "registerViewContractIfMissing", {
16
+ enumerable: true,
17
+ get: function () { return chunkO7IHZ53Y_cjs.registerViewContractIfMissing; }
18
+ });
7
19
  Object.defineProperty(exports, "replayEvents", {
8
20
  enumerable: true,
9
- get: function () { return chunkQ3WYIWCN_cjs.replayEvents; }
21
+ get: function () { return chunkO7IHZ53Y_cjs.replayEvents; }
22
+ });
23
+ Object.defineProperty(exports, "replayView", {
24
+ enumerable: true,
25
+ get: function () { return chunkO7IHZ53Y_cjs.replayView; }
26
+ });
27
+ Object.defineProperty(exports, "resolveViewContract", {
28
+ enumerable: true,
29
+ get: function () { return chunkO7IHZ53Y_cjs.resolveViewContract; }
30
+ });
31
+ Object.defineProperty(exports, "viewContractKey", {
32
+ enumerable: true,
33
+ get: function () { return chunkO7IHZ53Y_cjs.viewContractKey; }
10
34
  });
11
35
  //# sourceMappingURL=index.cjs.map
12
36
  //# sourceMappingURL=index.cjs.map
@@ -1,8 +1,11 @@
1
+ import { PortableJsonSchema } from '../objects/index.cjs';
2
+
1
3
  interface ReplayableAssetEvent<Payload = unknown> {
2
4
  id: string;
3
5
  tenantId: string;
4
6
  spaceId: string;
5
7
  eventType: string;
8
+ eventSchemaVersion?: number;
6
9
  subjectType: string;
7
10
  subjectId: string;
8
11
  payload: Payload;
@@ -12,6 +15,39 @@ interface ReplayableAssetEvent<Payload = unknown> {
12
15
  actionInvocationId: string;
13
16
  correlationId: string;
14
17
  }
18
+
19
+ interface ViewEventConsumption {
20
+ eventType: string;
21
+ schemaVersions: number[];
22
+ }
23
+ interface ViewContract<State = unknown, Event extends ReplayableAssetEvent = ReplayableAssetEvent> {
24
+ /** Stable module-qualified logical identity, for example `orders/summary`. */
25
+ name: `${string}/${string}`;
26
+ version: string;
27
+ shape: PortableJsonSchema;
28
+ consumes: ViewEventConsumption[];
29
+ scope: "tenant-space";
30
+ snapshotVersion: number;
31
+ compatibleSnapshotVersions?: number[];
32
+ /** Required to transform any older compatible snapshot into the current state shape. */
33
+ upgradeSnapshot?: (data: unknown, fromVersion: number) => State | Promise<State>;
34
+ initialState: State;
35
+ applyEvent: (state: State, event: Event) => State | Promise<State>;
36
+ }
37
+ declare function viewContractKey(view: Pick<ViewContract, "name" | "version">): string;
38
+ declare function registerViewContract(view: ViewContract): void;
39
+ declare function registerViewContractIfMissing(view: ViewContract): void;
40
+ declare function resolveViewContract(name: string, version: string): ViewContract | undefined;
41
+ declare function getRegisteredViewContractKeys(): string[];
42
+ interface ReplayViewOptions<State, Event extends ReplayableAssetEvent = ReplayableAssetEvent> {
43
+ view: ViewContract<State, Event>;
44
+ events: Iterable<Event> | AsyncIterable<Event>;
45
+ scope: ReplayScope;
46
+ snapshot?: (ReplaySnapshot<State> & {
47
+ snapshotVersion: number;
48
+ }) | null;
49
+ }
50
+ declare function replayView<State, Event extends ReplayableAssetEvent = ReplayableAssetEvent>({ view, events, scope, snapshot, }: ReplayViewOptions<State, Event>): Promise<ReplayEventsResult<State, Event>>;
15
51
  interface ReplayScope {
16
52
  tenantId: string;
17
53
  spaceId: string;
@@ -23,7 +59,7 @@ interface ReplaySnapshot<State = unknown> {
23
59
  eventCursor?: string | null;
24
60
  eventSequence?: number | null;
25
61
  }
26
- type ReplayWarningCode = "cursor_not_found" | "duplicate_event" | "missing_sequence" | "subject_scope_incomplete";
62
+ type ReplayWarningCode = "cursor_not_found" | "duplicate_event" | "missing_sequence" | "subject_scope_incomplete" | "unsupported_event_version";
27
63
  interface ReplayWarning {
28
64
  code: ReplayWarningCode;
29
65
  message: string;
@@ -49,4 +85,4 @@ interface ReplayEventsResult<State, Event extends ReplayableAssetEvent = Replaya
49
85
  }
50
86
  declare function replayEvents<State, Event extends ReplayableAssetEvent = ReplayableAssetEvent>({ events, scope, initialState, snapshot, applyEvent, }: ReplayEventsOptions<State, Event>): Promise<ReplayEventsResult<State, Event>>;
51
87
 
52
- export { type ReplayEventsOptions, type ReplayEventsResult, type ReplayScope, type ReplaySnapshot, type ReplayWarning, type ReplayWarningCode, type ReplayableAssetEvent, replayEvents };
88
+ export { type ReplayEventsOptions, type ReplayEventsResult, type ReplayScope, type ReplaySnapshot, type ReplayViewOptions, type ReplayWarning, type ReplayWarningCode, type ReplayableAssetEvent, type ViewContract, type ViewEventConsumption, getRegisteredViewContractKeys, registerViewContract, registerViewContractIfMissing, replayEvents, replayView, resolveViewContract, viewContractKey };
@@ -1,8 +1,11 @@
1
+ import { PortableJsonSchema } from '../objects/index.js';
2
+
1
3
  interface ReplayableAssetEvent<Payload = unknown> {
2
4
  id: string;
3
5
  tenantId: string;
4
6
  spaceId: string;
5
7
  eventType: string;
8
+ eventSchemaVersion?: number;
6
9
  subjectType: string;
7
10
  subjectId: string;
8
11
  payload: Payload;
@@ -12,6 +15,39 @@ interface ReplayableAssetEvent<Payload = unknown> {
12
15
  actionInvocationId: string;
13
16
  correlationId: string;
14
17
  }
18
+
19
+ interface ViewEventConsumption {
20
+ eventType: string;
21
+ schemaVersions: number[];
22
+ }
23
+ interface ViewContract<State = unknown, Event extends ReplayableAssetEvent = ReplayableAssetEvent> {
24
+ /** Stable module-qualified logical identity, for example `orders/summary`. */
25
+ name: `${string}/${string}`;
26
+ version: string;
27
+ shape: PortableJsonSchema;
28
+ consumes: ViewEventConsumption[];
29
+ scope: "tenant-space";
30
+ snapshotVersion: number;
31
+ compatibleSnapshotVersions?: number[];
32
+ /** Required to transform any older compatible snapshot into the current state shape. */
33
+ upgradeSnapshot?: (data: unknown, fromVersion: number) => State | Promise<State>;
34
+ initialState: State;
35
+ applyEvent: (state: State, event: Event) => State | Promise<State>;
36
+ }
37
+ declare function viewContractKey(view: Pick<ViewContract, "name" | "version">): string;
38
+ declare function registerViewContract(view: ViewContract): void;
39
+ declare function registerViewContractIfMissing(view: ViewContract): void;
40
+ declare function resolveViewContract(name: string, version: string): ViewContract | undefined;
41
+ declare function getRegisteredViewContractKeys(): string[];
42
+ interface ReplayViewOptions<State, Event extends ReplayableAssetEvent = ReplayableAssetEvent> {
43
+ view: ViewContract<State, Event>;
44
+ events: Iterable<Event> | AsyncIterable<Event>;
45
+ scope: ReplayScope;
46
+ snapshot?: (ReplaySnapshot<State> & {
47
+ snapshotVersion: number;
48
+ }) | null;
49
+ }
50
+ declare function replayView<State, Event extends ReplayableAssetEvent = ReplayableAssetEvent>({ view, events, scope, snapshot, }: ReplayViewOptions<State, Event>): Promise<ReplayEventsResult<State, Event>>;
15
51
  interface ReplayScope {
16
52
  tenantId: string;
17
53
  spaceId: string;
@@ -23,7 +59,7 @@ interface ReplaySnapshot<State = unknown> {
23
59
  eventCursor?: string | null;
24
60
  eventSequence?: number | null;
25
61
  }
26
- type ReplayWarningCode = "cursor_not_found" | "duplicate_event" | "missing_sequence" | "subject_scope_incomplete";
62
+ type ReplayWarningCode = "cursor_not_found" | "duplicate_event" | "missing_sequence" | "subject_scope_incomplete" | "unsupported_event_version";
27
63
  interface ReplayWarning {
28
64
  code: ReplayWarningCode;
29
65
  message: string;
@@ -49,4 +85,4 @@ interface ReplayEventsResult<State, Event extends ReplayableAssetEvent = Replaya
49
85
  }
50
86
  declare function replayEvents<State, Event extends ReplayableAssetEvent = ReplayableAssetEvent>({ events, scope, initialState, snapshot, applyEvent, }: ReplayEventsOptions<State, Event>): Promise<ReplayEventsResult<State, Event>>;
51
87
 
52
- export { type ReplayEventsOptions, type ReplayEventsResult, type ReplayScope, type ReplaySnapshot, type ReplayWarning, type ReplayWarningCode, type ReplayableAssetEvent, replayEvents };
88
+ export { type ReplayEventsOptions, type ReplayEventsResult, type ReplayScope, type ReplaySnapshot, type ReplayViewOptions, type ReplayWarning, type ReplayWarningCode, type ReplayableAssetEvent, type ViewContract, type ViewEventConsumption, getRegisteredViewContractKeys, registerViewContract, registerViewContractIfMissing, replayEvents, replayView, resolveViewContract, viewContractKey };
@@ -1,3 +1,3 @@
1
- export { replayEvents } from '../chunk-JSTGOT6P.js';
1
+ export { getRegisteredViewContractKeys, registerViewContract, registerViewContractIfMissing, replayEvents, replayView, resolveViewContract, viewContractKey } from '../chunk-7WASIL46.js';
2
2
  //# sourceMappingURL=index.js.map
3
3
  //# sourceMappingURL=index.js.map
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@fabricorg/platform",
3
- "version": "0.9.0",
3
+ "version": "0.11.0",
4
4
  "description": "Generic, vertical-agnostic runtime for ontology-based business applications. Provides actions, modules, events, policies, state machines, adapters, displays, projections, privacy, and evidence contracts. Zero runtime dependencies; portable across any database client and any vertical (lending, insurance, healthcare, legal, etc.).",
5
5
  "keywords": [
6
6
  "fabric",
@@ -118,6 +118,16 @@
118
118
  "default": "./dist/ids/index.cjs"
119
119
  }
120
120
  },
121
+ "./manifest": {
122
+ "import": {
123
+ "types": "./dist/manifest/index.d.ts",
124
+ "default": "./dist/manifest/index.js"
125
+ },
126
+ "require": {
127
+ "types": "./dist/manifest/index.d.cts",
128
+ "default": "./dist/manifest/index.cjs"
129
+ }
130
+ },
121
131
  "./modules": {
122
132
  "import": {
123
133
  "types": "./dist/modules/index.d.ts",
@@ -1,187 +0,0 @@
1
- import { registerObjectType } from './chunk-I35B576X.js';
2
- import { registerPolicyIfMissing } from './chunk-6ER62UUN.js';
3
- import { registerStateMachineIfMissing } from './chunk-T2JLSZN6.js';
4
- import { registerActionIfMissing } from './chunk-4SMPJPJ6.js';
5
- import { registerDisplayRenderer } from './chunk-O5WVBQ7P.js';
6
- import { registerSubjectType, registerEventType, isValidEventType } from './chunk-4YQOGV7H.js';
7
-
8
- // modules/index.ts
9
- var registeredModuleNamespaces = /* @__PURE__ */ new Set();
10
- function getModuleDependencyNamespace(dependency) {
11
- return typeof dependency === "string" ? dependency : dependency.namespace;
12
- }
13
- function getObjectTypeName(objectType) {
14
- return typeof objectType === "string" ? objectType : objectType.type;
15
- }
16
- function getEventTypeName(eventType) {
17
- return typeof eventType === "string" ? eventType : eventType.eventType;
18
- }
19
- function validateModuleNamespace(namespace) {
20
- if (!namespace) {
21
- throw new Error("Module namespace cannot be empty");
22
- }
23
- if (!/^[a-z][a-z0-9-]*$/.test(namespace)) {
24
- throw new Error(
25
- `Invalid module namespace: "${namespace}". Must be lowercase letters, numbers, and hyphens only.`
26
- );
27
- }
28
- }
29
- function createModuleRegistry(modules = []) {
30
- const registered = /* @__PURE__ */ new Map();
31
- for (const module of modules) {
32
- validateModuleNamespace(module.namespace);
33
- if (registered.has(module.namespace)) {
34
- throw new Error(`Duplicate FabricModule namespace "${module.namespace}".`);
35
- }
36
- registered.set(module.namespace, module);
37
- }
38
- return { modules: registered };
39
- }
40
- function validateIdentifierList(values, label, namespace) {
41
- for (const value of values ?? []) {
42
- if (!value) {
43
- throw new Error(`Module "${namespace}" has an empty ${label} entry.`);
44
- }
45
- }
46
- }
47
- function validateManifest(module, context = {}) {
48
- validateModuleNamespace(module.namespace);
49
- const dependencies = (module.dependencies ?? []).map(getModuleDependencyNamespace);
50
- const objectTypes = (module.objectTypes ?? []).map(getObjectTypeName);
51
- const eventTypes = (module.eventTypes ?? []).map(getEventTypeName);
52
- for (const dependency of dependencies) {
53
- validateModuleNamespace(dependency);
54
- if (dependency === module.namespace) {
55
- throw new Error(`Module "${module.namespace}" cannot depend on itself.`);
56
- }
57
- if (context.availableNamespaces && !context.availableNamespaces.has(dependency)) {
58
- throw new Error(`Module "${module.namespace}" depends on missing module "${dependency}".`);
59
- }
60
- }
61
- validateIdentifierList(objectTypes, "objectTypes", module.namespace);
62
- validateIdentifierList(module.subjectTypes, "subjectTypes", module.namespace);
63
- validateIdentifierList(eventTypes, "eventTypes", module.namespace);
64
- for (const objectType of objectTypes) {
65
- if (!/^[A-Z][a-zA-Z0-9]*$/.test(objectType)) {
66
- throw new Error(
67
- `Invalid object type: "${objectType}". Object types must be PascalCase alphanumeric.`
68
- );
69
- }
70
- }
71
- for (const action of module.actions ?? []) {
72
- if (!/^[a-z][a-z0-9-]*\.[a-z][a-z0-9_]*$/.test(action.actionId)) {
73
- throw new Error(`Invalid action ID: ${action.actionId}`);
74
- }
75
- if (action.namespace !== module.namespace) {
76
- throw new Error(
77
- `Action "${action.actionId}" declares namespace "${action.namespace}" but is registered by module "${module.namespace}".`
78
- );
79
- }
80
- if (!action.actionId.startsWith(`${module.namespace}.`)) {
81
- throw new Error(
82
- `Action "${action.actionId}" must start with module namespace "${module.namespace}."`
83
- );
84
- }
85
- if (action.mutatesDomain && action.emitsEvents.length === 0) {
86
- throw new Error(
87
- `Action "${action.actionId}" mutates domain but emits no events. Every mutating action must emit at least one AssetEvent.`
88
- );
89
- }
90
- }
91
- for (const descriptor of module.displayRenderers ?? []) {
92
- const isPlannedEventType = context.plannedEventTypes?.has(descriptor.eventType) ?? false;
93
- const isModuleEventType = eventTypes.includes(descriptor.eventType);
94
- if (!isValidEventType(descriptor.eventType) && !isModuleEventType && !isPlannedEventType) {
95
- throw new Error(
96
- `Display renderer registered for unknown event type "${descriptor.eventType}". Register the event type before adding a display renderer.`
97
- );
98
- }
99
- }
100
- }
101
- function sortModulesByDependency(modules, registeredNamespaces = registeredModuleNamespaces) {
102
- const modulesByNamespace = /* @__PURE__ */ new Map();
103
- for (const module of modules) {
104
- validateModuleNamespace(module.namespace);
105
- if (modulesByNamespace.has(module.namespace)) {
106
- throw new Error(`Duplicate Fabric module namespace "${module.namespace}".`);
107
- }
108
- modulesByNamespace.set(module.namespace, module);
109
- }
110
- const sorted = [];
111
- const visiting = /* @__PURE__ */ new Set();
112
- const visited = /* @__PURE__ */ new Set();
113
- function visit(module, path) {
114
- if (visited.has(module.namespace)) {
115
- return;
116
- }
117
- if (visiting.has(module.namespace)) {
118
- throw new Error(
119
- `Cyclic Fabric module dependency detected: ${[...path, module.namespace].join(" -> ")}`
120
- );
121
- }
122
- visiting.add(module.namespace);
123
- for (const dependency of (module.dependencies ?? []).map(getModuleDependencyNamespace)) {
124
- const dependencyModule = modulesByNamespace.get(dependency);
125
- if (!dependencyModule) {
126
- if (registeredNamespaces.has(dependency)) {
127
- continue;
128
- }
129
- throw new Error(`Module "${module.namespace}" depends on missing module "${dependency}".`);
130
- }
131
- visit(dependencyModule, [...path, module.namespace]);
132
- }
133
- visiting.delete(module.namespace);
134
- visited.add(module.namespace);
135
- sorted.push(module);
136
- }
137
- for (const module of modules) {
138
- visit(module, []);
139
- }
140
- return sorted;
141
- }
142
- function registerFabricModule(module) {
143
- validateManifest(module, { availableNamespaces: registeredModuleNamespaces });
144
- for (const objectType of module.objectTypes ?? []) {
145
- registerObjectType(getObjectTypeName(objectType));
146
- }
147
- for (const subjectType of module.subjectTypes ?? []) {
148
- registerSubjectType(subjectType);
149
- }
150
- for (const eventType of module.eventTypes ?? []) {
151
- registerEventType(getEventTypeName(eventType));
152
- }
153
- for (const policy of module.policies ?? []) {
154
- registerPolicyIfMissing(policy);
155
- }
156
- for (const machine of module.stateMachines ?? []) {
157
- registerStateMachineIfMissing(machine);
158
- }
159
- for (const action of module.actions ?? []) {
160
- registerActionIfMissing(action);
161
- }
162
- for (const descriptor of module.displayRenderers ?? []) {
163
- registerDisplayRenderer(descriptor.eventType, descriptor.renderer);
164
- }
165
- registeredModuleNamespaces.add(module.namespace);
166
- }
167
- function registerFabricModules(modules) {
168
- const availableNamespaces = /* @__PURE__ */ new Set([
169
- ...registeredModuleNamespaces,
170
- ...modules.map((module) => module.namespace)
171
- ]);
172
- const plannedEventTypes = new Set(
173
- modules.flatMap((module) => (module.eventTypes ?? []).map(getEventTypeName))
174
- );
175
- for (const module of modules) {
176
- validateManifest(module, { availableNamespaces, plannedEventTypes });
177
- }
178
- const sortedModules = sortModulesByDependency(modules);
179
- for (const module of sortedModules) {
180
- registerFabricModule(module);
181
- }
182
- return sortedModules;
183
- }
184
-
185
- export { createModuleRegistry, getEventTypeName, getModuleDependencyNamespace, getObjectTypeName, registerFabricModule, registerFabricModules, validateModuleNamespace };
186
- //# sourceMappingURL=chunk-35DD3H55.js.map
187
- //# sourceMappingURL=chunk-35DD3H55.js.map