@fabricorg/platform 1.13.0 → 1.15.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +34 -0
- package/README.md +29 -0
- package/dist/actions/index.cjs +3 -1
- package/dist/actions/index.cjs.map +1 -1
- package/dist/actions/index.d.cts +15 -1
- package/dist/actions/index.d.ts +15 -1
- package/dist/actions/index.js +3 -1
- package/dist/actions/index.js.map +1 -1
- package/dist/manifest/index.cjs +1 -0
- package/dist/manifest/index.cjs.map +1 -1
- package/dist/manifest/index.d.cts +1 -0
- package/dist/manifest/index.d.ts +1 -0
- package/dist/manifest/index.js +1 -0
- package/dist/manifest/index.js.map +1 -1
- package/dist/modules/index.cjs +6 -0
- package/dist/modules/index.cjs.map +1 -1
- package/dist/modules/index.js +6 -0
- package/dist/modules/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,39 @@
|
|
|
1
1
|
# @fabricorg/platform
|
|
2
2
|
|
|
3
|
+
## 1.15.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- a28154f: Add parent-action `stagedInvocationPrincipals` declarations, registration validation, and deterministic manifest export. This security-sensitive contract keeps staged actor selection out of handler-controlled requests when paired with `@fabricorg/platform-host` 8.7.0 or later. Earlier Host versions ignore the field and dispatch staged children as the parent's actor, so upgrade every process that runs the Host (executes staging parent actions, dispatches stages, or runs the Platform worker) before shipping a module that declares a principal mapping.
|
|
8
|
+
|
|
9
|
+
## 1.14.0
|
|
10
|
+
|
|
11
|
+
### Minor Changes
|
|
12
|
+
|
|
13
|
+
- 6002c61: Add the finalizing-action `ActionResult.adapterPreparation` channel and optional third
|
|
14
|
+
`AdapterStep.getInput` argument. The finalizing-action helper refuses returned preparation
|
|
15
|
+
without the Host's `adapterPreparationProtocol: "v1"` capability; actions returning none
|
|
16
|
+
retain their existing capability behavior. Non-finalizing actions returning preparation fail
|
|
17
|
+
before adapter delivery.
|
|
18
|
+
|
|
19
|
+
Preparation must be a strict-JSON plain-object record and counts toward the 256 KiB checkpoint
|
|
20
|
+
limit. It is persisted separately for crash replay, excluded from public results, handler data,
|
|
21
|
+
finalize input and event extraction, and removed with terminal settlement while retaining other
|
|
22
|
+
checkpoint evidence. Running and reconciliation-required invocations retain preparation.
|
|
23
|
+
Older checkpoints pass undefined to getInput. Derived adapter inputs remain subject to the
|
|
24
|
+
existing redactAdapterInput and adapter evidence retention contracts.
|
|
25
|
+
|
|
26
|
+
Preparation checkpoints use `atomic-after-adapters-v2`; checkpoints without preparation keep
|
|
27
|
+
`atomic-after-adapters-v1`. Replay accepts only the matching protocol/preparation shapes.
|
|
28
|
+
Settlement clears preparation and restores v1, including approval rejection. Handler capability
|
|
29
|
+
and manifest finalization protocols remain v1. Upgrade all workers before handlers return
|
|
30
|
+
preparation: older Hosts refuse in-flight v2 replay through interruption handling, requiring
|
|
31
|
+
reconciliation after recorded effects or settling failed without recorded effects. An older
|
|
32
|
+
Host does not clear preparation, so a row it settles keeps the v2 checkpoint and its
|
|
33
|
+
preparation; in PostgreSQL, find such rows by a terminal status with
|
|
34
|
+
`finalization_checkpoint->>'protocol' = 'atomic-after-adapters-v2'`. Reconcile in-flight v2
|
|
35
|
+
work before rolling workers back.
|
|
36
|
+
|
|
3
37
|
## 1.13.0
|
|
4
38
|
|
|
5
39
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -96,6 +96,18 @@ add requests through `ActionFinalizationResult.stagedInvocations`. Each request
|
|
|
96
96
|
stable key, an action ID, and parameters. Actor, tenant, space, correlation, causation,
|
|
97
97
|
authorization, provenance, and child identity remain Host-owned.
|
|
98
98
|
|
|
99
|
+
The parent action may map an allowlisted child action ID to a Host-owned principal name through
|
|
100
|
+
`stagedInvocationPrincipals`. `StagedInvocationRequest` has no principal, actor, or authorization
|
|
101
|
+
field, and the Host request-field allowlist rejects those extra fields from a handler or finalizer.
|
|
102
|
+
Module registration validates that every mapping key is in
|
|
103
|
+
`stagesInvocations` and that each principal name matches `[a-z][a-z0-9._:-]{0,127}`. The Host
|
|
104
|
+
composition registers each name with its actor ID and actor type, records the selected name when it
|
|
105
|
+
stages the child, and resolves that durable name at dispatch. `@fabricorg/platform-host` 8.7.0 and
|
|
106
|
+
later enforces these rules and refuses an unregistered name during staging or dispatch. Earlier Host
|
|
107
|
+
versions ignore `stagedInvocationPrincipals` and dispatch the child as the parent's actor. Upgrade
|
|
108
|
+
the Host rollout described in its staged-invocation documentation before shipping a module that
|
|
109
|
+
declares a principal mapping.
|
|
110
|
+
|
|
99
111
|
Module registration rejects unknown targets, self-targets, capture-authority targets, and targets
|
|
100
112
|
in another module unless that module is a declared dependency. A staged child is not delegated
|
|
101
113
|
under the parent's authorization decision: dispatch submits it through the current registered
|
|
@@ -167,6 +179,23 @@ Every `invokeAction(id, params)` call goes through:
|
|
|
167
179
|
of those saved inputs and ordered succeeded/skipped stored redacted adapter outputs, plus
|
|
168
180
|
transaction-bound `db` without services. Hook event schema versions default to
|
|
169
181
|
`action.version` when omitted.
|
|
182
|
+
A handler may return a strict-JSON plain-object `adapterPreparation` alongside `data`.
|
|
183
|
+
Finalizing `getInput(params, handlerResult, adapterPreparation?)` receives a copy as its
|
|
184
|
+
third argument, or `undefined` for absent preparation and older checkpoints. The channel
|
|
185
|
+
is excluded from public results, hook input and event extraction. Host saves it separately
|
|
186
|
+
within the 256 KiB checkpoint limit, retains it while running or reconciliation is required,
|
|
187
|
+
and removes only that key with terminal completion/failure or cancellation. Derived adapter
|
|
188
|
+
inputs still use `redactAdapterInput` and its existing durable evidence contract.
|
|
189
|
+
Non-finalizing handlers returning preparation fail before adapter delivery.
|
|
190
|
+
`defineFinalizingAction` checks `ctx.adapterPreparationProtocol === "v1"` after the handler
|
|
191
|
+
returns preparation and refuses unsupported hosts; no preparation needs no new capability.
|
|
192
|
+
Checkpoints use `atomic-after-adapters-v2` with preparation and `atomic-after-adapters-v1`
|
|
193
|
+
without it. Replay refuses mismatched shapes before adapter delivery; settlement clears
|
|
194
|
+
preparation and restores v1. Upgrade all workers before handlers return preparation.
|
|
195
|
+
Older Hosts refuse in-flight v2 checkpoints, requiring reconciliation after recorded effects
|
|
196
|
+
or settling failed without recorded effects. An older Host does not clear preparation, so a
|
|
197
|
+
row it settles keeps the v2 checkpoint and its preparation. Handler capability and manifest
|
|
198
|
+
protocols stay v1.
|
|
170
199
|
It returns declared events and/or a shallow result patch. The manifest exports only
|
|
171
200
|
`finalization: { protocol: "atomic-after-adapters-v1" }`, not the callback.
|
|
172
201
|
The helper refuses older hosts before handler code runs. See the
|
package/dist/actions/index.cjs
CHANGED
|
@@ -30,10 +30,12 @@ function defineFinalizingAction(action) {
|
|
|
30
30
|
...action,
|
|
31
31
|
handler: async (ctx, params) => {
|
|
32
32
|
if (ctx.finalizationProtocol !== "atomic-after-adapters-v1") throw new Error("Host does not support atomic-after-adapters-v1 finalization.");
|
|
33
|
-
|
|
33
|
+
const result = handler ? await handler(ctx, params) : {
|
|
34
34
|
success: true,
|
|
35
35
|
data: {}
|
|
36
36
|
};
|
|
37
|
+
if (result.adapterPreparation !== void 0 && ctx.adapterPreparationProtocol !== "v1") throw new Error("Host does not support adapter preparation protocol v1.");
|
|
38
|
+
return result;
|
|
37
39
|
}
|
|
38
40
|
};
|
|
39
41
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":[],"sources":["../../actions/index.ts"],"sourcesContent":["import type { SurfaceDeclaration } from \"../discovery\";\nexport 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\tfinalizationProtocol?: \"atomic-after-adapters-v1\";\n\t/**\n\t * When the host admitted this invocation's submission through the\n\t * action's `admitSubmission` check, read from the durable invocation\n\t * record. Absent when the action declares no check, or when the runtime\n\t * that built this context does not run declared admission checks (a host\n\t * older than the one that introduced them). A handler whose action\n\t * declares `admitSubmission` can refuse to run without it.\n\t */\n\tadmittedAt?: Date;\n}\n\n/**\n * Trusted facts a host gives an action's `admitSubmission` check. Scope and\n * actor come from the host's authenticated submission, never from the\n * parameters.\n */\nexport interface ActionAdmissionInput {\n\treadonly actionId: ActionId;\n\treadonly tenantId: string;\n\treadonly spaceId: string;\n\treadonly actorId: string;\n\treadonly actorType: ActorType;\n\t/**\n\t * The submitted parameters, unvalidated, as a copy made for this check.\n\t * `@fabricorg/platform-host` records its own copy of the same value, taken\n\t * before the check ran, and only if the check admits it; changing this\n\t * copy changes nothing the host records.\n\t */\n\treadonly parameters: Readonly<Record<string, unknown>>;\n\t/**\n\t * Aborted when the host's admission deadline passes. Hosts pass an\n\t * `AbortSignal`. `@fabricorg/platform-host` refuses an answer that settles\n\t * at or after the deadline, even one that settles before the abort.\n\t */\n\treadonly signal: ActionAdmissionSignal;\n}\n\n/**\n * The part of an `AbortSignal` an admission check can rely on. Declared\n * structurally so this module compiles without DOM or Node type libraries; a\n * host passes a real `AbortSignal`, which satisfies it.\n */\nexport interface ActionAdmissionSignal {\n\treadonly aborted: boolean;\n\taddEventListener(type: \"abort\", listener: () => void, options?: { once?: boolean }): void;\n\tremoveEventListener(type: \"abort\", listener: () => void): void;\n}\n\n/**\n * An admission check's answer. Only `{ admitted: true }` admits. A refusal's\n * `code` must be a fixed code chosen by the action (lower-case first letter,\n * then letters, digits, `_`, `.`, `:` or `-`, at most 128 characters), never\n * a submitted value: the host puts it in the error it throws.\n */\nexport type ActionAdmissionDecision =\n\t| { readonly admitted: true }\n\t| { readonly admitted: false; readonly code: string };\n\n/**\n * Decides whether a submission may be recorded at all. A host that supports\n * it runs the check after authorizing the submitter and before it writes\n * anything durable for the submission; a refusal, a throw, a timeout or any\n * answer other than `{ admitted: true }` refuses the submission.\n */\nexport type ActionAdmission = (input: ActionAdmissionInput) => Promise<ActionAdmissionDecision>;\n\n/** A descendant invocation the Host durably stages with its parent mutation. */\nexport interface StagedInvocationRequest {\n\t/** Stable identity within one parent invocation. */\n\treadonly key: string;\n\treadonly actionId: ActionId;\n\treadonly parameters: Record<string, unknown>;\n}\n\nexport interface ActionResult {\n\tsuccess: boolean;\n\tdata?: Record<string, unknown>;\n\terror?: string;\n\t/** Host-owned descendants released only after this invocation completes. */\n\tstagedInvocations?: readonly StagedInvocationRequest[];\n}\n\nexport type ActionHandler<TDb = unknown> = (\n\tctx: ActionContext<TDb>,\n\tparams: unknown,\n) => Promise<ActionResult>;\n\nexport type FinalizationJson = null | boolean | number | string | readonly FinalizationJson[] | { readonly [key: string]: FinalizationJson };\nexport type FinalizationRecord = { readonly [key: string]: FinalizationJson };\nexport type ActionFinalizationContext<TDb = unknown> = Pick<ActionContext<TDb>,\n\t\"actionInvocationId\" | \"tenantId\" | \"spaceId\" | \"actorId\" | \"actorType\" |\n\t\"correlationId\" | \"causationId\" | \"provenance\" | \"db\">;\nexport type ActionFinalizationStep = {\n\treadonly stepIndex: number;\n\treadonly adapterType: string;\n\treadonly operation: string;\n} & ({ readonly status: \"succeeded\"; readonly adapterInvocationId: string; readonly output: FinalizationRecord } |\n\t{ readonly status: \"skipped\" });\nexport interface ActionFinalizationInput {\n\treadonly params: FinalizationJson;\n\treadonly handlerData: FinalizationRecord;\n\treadonly adapterOutputs: readonly ActionFinalizationStep[];\n}\nexport interface ActionFinalizationEvent {\n\treadonly eventType: string;\n\treadonly subjectType: string;\n\treadonly subjectId: string;\n\treadonly payload: FinalizationJson;\n\treadonly eventSchemaVersion?: number;\n}\nexport interface ActionFinalizationResult {\n\treadonly events?: readonly ActionFinalizationEvent[];\n\treadonly resultPatch?: FinalizationRecord;\n\t/** Additional descendants staged atomically with finalization and completion. */\n\treadonly stagedInvocations?: readonly StagedInvocationRequest[];\n}\nexport type ActionFinalizer<TDb = unknown> = (\n\tctx: ActionFinalizationContext<TDb>, input: ActionFinalizationInput,\n) => Promise<ActionFinalizationResult>;\n\n/** Validate declarations at registration and at dynamically resolved execution boundaries. */\nexport function assertActionFinalization<TDb>(action: Pick<ActionDefinition<TDb>, \"actionId\" | \"finalize\" | \"eventPhase\" | \"kind\" | \"execution\">): void {\n\tif (action.finalize === undefined) return;\n\tif (typeof action.finalize !== \"function\") throw new Error(\"Action finalization hook must be a function.\");\n\tif (action.eventPhase !== \"after_adapters\") throw new Error(\"Action finalization requires eventPhase after_adapters.\");\n\tif (action.kind !== undefined && action.kind !== \"atomic\") throw new Error(\"Action finalization requires an atomic action.\");\n\tif (action.execution?.completion !== undefined && action.execution.completion !== \"immediate\") throw new Error(\"Action finalization requires immediate completion.\");\n}\n\n/** Refuse older hosts before application handler code executes. Use for distributed finalizing actions. */\nexport function defineFinalizingAction<TDb>(action: ActionDefinition<TDb> & { finalize: ActionFinalizer<TDb> }): ActionDefinition<TDb> {\n\tassertActionFinalization(action);\n\tconst handler = action.handler;\n\treturn { ...action, handler: async (ctx, params) => {\n\t\tif (ctx.finalizationProtocol !== \"atomic-after-adapters-v1\") throw new Error(\"Host does not support atomic-after-adapters-v1 finalization.\");\n\t\treturn handler ? handler(ctx, params) : { success: true, data: {} };\n\t} };\n}\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\t/** Positive finite integer duration in milliseconds; overrides Host adapterDeadlineMs for this step. */\n\tdeadlineMs?: number;\n\tgetInput: (\n\t\tparams: unknown,\n\t\thandlerResult: Record<string, unknown>,\n\t) => Record<string, unknown> | undefined;\n}\n\n/** Validate optional step execution budgets before accepting or executing an action. */\nexport function assertAdapterStepDeadlines(action: { actionId: string; adapterSteps?: readonly Pick<AdapterStep, \"deadlineMs\">[] }): void {\n\tfor (const step of action.adapterSteps ?? []) {\n\t\tif (step.deadlineMs !== undefined && (!Number.isInteger(step.deadlineMs) || step.deadlineMs <= 0)) {\n\t\t\tthrow new Error(`Action \"${action.actionId}\" adapter step deadlineMs must be a positive finite integer.`);\n\t\t}\n\t}\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> extends SurfaceDeclaration {\n\tactionId: ActionId;\n\tnamespace: string;\n\tversion: number;\n\tschema: SchemaValidator;\n\t/**\n\t * Optional check a host runs on every submission before it records\n\t * anything durable for it (invocation, idempotency key, events, errors).\n\t * Use it when parameters must be validated against trusted context, for\n\t * example a secret reference the tenant's secret store must hold, before\n\t * they may be persisted. `@fabricorg/platform-host` runs it from the\n\t * release that introduced it; an older host ignores it, so a handler that\n\t * relies on it should require `ActionContext.admittedAt`.\n\t */\n\tadmitSubmission?: ActionAdmission;\n\t/** Optional validation contract for the public handler result data. */\n\tresultSchema?: SchemaValidator;\n\thandler?: ActionHandler<TDb>;\n\tfinalize?: ActionFinalizer<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/** Child action IDs this action is permitted to stage for post-completion dispatch. */\n\tstagesInvocations?: readonly ActionId[];\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\t/**\n\t * `immediate`: the invocation settles within the host's execution.\n\t * `accepted` and `long-running`: an adapter may hand the work to an\n\t * external system and the invocation stays running until that system\n\t * completes it by reference through the host's completion ingress.\n\t * Declare `completionDeadlineMs` on a `long-running` action so a callback\n\t * that never comes is noticed rather than waited on forever.\n\t */\n\tcompletion: ActionCompletionMode;\n\t/**\n\t * How long an accepted handoff may wait for its completion before the host\n\t * moves the invocation to reconciliation. Without it, nothing sweeps the\n\t * handoff. Refused on `immediate`, since nothing external completes it.\n\t */\n\tcompletionDeadlineMs?: number;\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 distinct signals with the same name received before\n\t * another `awaitSignal` call are buffered in FIFO order so none is lost.\n\t *\n\t * A signal may carry a stable signal ID that the sender keeps the same on each redelivery\n\t * (for example a webhook delivery ID or an approval decision ID). A runtime drops\n\t * a signal whose ID it has already received for this saga, so a sender retrying\n\t * after a timeout does not wake the saga twice. Signals without an ID are not\n\t * deduplicated. `@fabricorg/platform-temporal` provides `createSagaSignalInbox()`\n\t * for Temporal runtimes.\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\tif (definition.admitSubmission !== undefined && typeof definition.admitSubmission !== \"function\") {\n\t\t\tthrow new Error(`Action \"${definition.actionId}\" declares admitSubmission that is not a function.`);\n\t\t}\n\t\tassertAdapterStepDeadlines(definition);\n\t\tassertActionFinalization(definition);\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"],"mappings":";;AAyBA,MAAa,cAAoC;CAChD;CACA;CACA;CACA;CACA;CACA;AACD;AAEA,SAAgB,YAAY,OAAmC;CAC9D,OAAQ,YAAkC,SAAS,KAAK;AACzD;AAEA,SAAgB,gBAAgB,OAA2C;CAC1E,IAAI,CAAC,YAAY,KAAK,GACrB,MAAM,IAAI,MAAM,sBAAsB,OAAO;AAE/C;;AAqJA,SAAgB,yBAA8B,QAA0G;CACvJ,IAAI,OAAO,aAAa,KAAA,GAAW;CACnC,IAAI,OAAO,OAAO,aAAa,YAAY,MAAM,IAAI,MAAM,8CAA8C;CACzG,IAAI,OAAO,eAAe,kBAAkB,MAAM,IAAI,MAAM,yDAAyD;CACrH,IAAI,OAAO,SAAS,KAAA,KAAa,OAAO,SAAS,UAAU,MAAM,IAAI,MAAM,gDAAgD;CAC3H,IAAI,OAAO,WAAW,eAAe,KAAA,KAAa,OAAO,UAAU,eAAe,aAAa,MAAM,IAAI,MAAM,oDAAoD;AACpK;;AAGA,SAAgB,uBAA4B,QAA2F;CACtI,yBAAyB,MAAM;CAC/B,MAAM,UAAU,OAAO;CACvB,OAAO;EAAE,GAAG;EAAQ,SAAS,OAAO,KAAK,WAAW;GACnD,IAAI,IAAI,yBAAyB,4BAA4B,MAAM,IAAI,MAAM,8DAA8D;GAC3I,OAAO,UAAU,QAAQ,KAAK,MAAM,IAAI;IAAE,SAAS;IAAM,MAAM,CAAC;GAAE;EACnE;CAAE;AACH;;AAuBA,SAAgB,2BAA2B,QAA+F;CACzI,KAAK,MAAM,QAAQ,OAAO,gBAAgB,CAAC,GAC1C,IAAI,KAAK,eAAe,KAAA,MAAc,CAAC,OAAO,UAAU,KAAK,UAAU,KAAK,KAAK,cAAc,IAC9F,MAAM,IAAI,MAAM,WAAW,OAAO,SAAS,6DAA6D;AAG3G;AAqJA,SAAgB,eAAe,UAAgD;CAC9E,IAAI,CAAC,qCAAqC,KAAK,QAAQ,GACtD,MAAM,IAAI,MAAM,sBAAsB,UAAU;AAElD;AAUA,SAAgB,qBAAoC,cAAgD,CAAC,GAAwB;CAC5H,MAAM,0BAAU,IAAI,IAAqC;CACzD,MAAM,YAAY,eAA4C;EAC7D,eAAe,WAAW,QAAQ;EAClC,IAAI,QAAQ,IAAI,WAAW,QAAQ,GAAG,MAAM,IAAI,MAAM,WAAW,WAAW,SAAS,wBAAwB;EAC7G,IAAI,WAAW,iBAAiB,WAAW,YAAY,WAAW,GACjE,MAAM,IAAI,MAAM,WAAW,WAAW,SAAS,+FAA+F;EAE/I,IAAI,WAAW,oBAAoB,KAAA,KAAa,OAAO,WAAW,oBAAoB,YACrF,MAAM,IAAI,MAAM,WAAW,WAAW,SAAS,mDAAmD;EAEnG,2BAA2B,UAAU;EACrC,yBAAyB,UAAU;EACnC,QAAQ,IAAI,WAAW,UAAU,UAAU;CAC5C;CACA,KAAK,MAAM,cAAc,aAAa,SAAS,UAAU;CACzD,OAAO;EACN;EACA,kBAAkB,YAAY;GAC7B,IAAI,CAAC,QAAQ,IAAI,WAAW,QAAQ,GAAG,SAAS,UAAU;EAC3D;EACA,UAAU,aAAa,QAAQ,IAAI,QAAQ;EAC3C,MAAM,aAAmC,QAAQ,IAAI,QAAoB;EACzE,WAAW,MAAM,KAAK,QAAQ,KAAK,CAAC;CACrC;AACD"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":[],"sources":["../../actions/index.ts"],"sourcesContent":["import type { SurfaceDeclaration } from \"../discovery\";\nexport 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\tfinalizationProtocol?: \"atomic-after-adapters-v1\";\n\t/** Host support for private, durable finalizing-action adapter preparation. */\n\tadapterPreparationProtocol?: \"v1\";\n\t/**\n\t * When the host admitted this invocation's submission through the\n\t * action's `admitSubmission` check, read from the durable invocation\n\t * record. Absent when the action declares no check, or when the runtime\n\t * that built this context does not run declared admission checks (a host\n\t * older than the one that introduced them). A handler whose action\n\t * declares `admitSubmission` can refuse to run without it.\n\t */\n\tadmittedAt?: Date;\n}\n\n/**\n * Trusted facts a host gives an action's `admitSubmission` check. Scope and\n * actor come from the host's authenticated submission, never from the\n * parameters.\n */\nexport interface ActionAdmissionInput {\n\treadonly actionId: ActionId;\n\treadonly tenantId: string;\n\treadonly spaceId: string;\n\treadonly actorId: string;\n\treadonly actorType: ActorType;\n\t/**\n\t * The submitted parameters, unvalidated, as a copy made for this check.\n\t * `@fabricorg/platform-host` records its own copy of the same value, taken\n\t * before the check ran, and only if the check admits it; changing this\n\t * copy changes nothing the host records.\n\t */\n\treadonly parameters: Readonly<Record<string, unknown>>;\n\t/**\n\t * Aborted when the host's admission deadline passes. Hosts pass an\n\t * `AbortSignal`. `@fabricorg/platform-host` refuses an answer that settles\n\t * at or after the deadline, even one that settles before the abort.\n\t */\n\treadonly signal: ActionAdmissionSignal;\n}\n\n/**\n * The part of an `AbortSignal` an admission check can rely on. Declared\n * structurally so this module compiles without DOM or Node type libraries; a\n * host passes a real `AbortSignal`, which satisfies it.\n */\nexport interface ActionAdmissionSignal {\n\treadonly aborted: boolean;\n\taddEventListener(type: \"abort\", listener: () => void, options?: { once?: boolean }): void;\n\tremoveEventListener(type: \"abort\", listener: () => void): void;\n}\n\n/**\n * An admission check's answer. Only `{ admitted: true }` admits. A refusal's\n * `code` must be a fixed code chosen by the action (lower-case first letter,\n * then letters, digits, `_`, `.`, `:` or `-`, at most 128 characters), never\n * a submitted value: the host puts it in the error it throws.\n */\nexport type ActionAdmissionDecision =\n\t| { readonly admitted: true }\n\t| { readonly admitted: false; readonly code: string };\n\n/**\n * Decides whether a submission may be recorded at all. A host that supports\n * it runs the check after authorizing the submitter and before it writes\n * anything durable for the submission; a refusal, a throw, a timeout or any\n * answer other than `{ admitted: true }` refuses the submission.\n */\nexport type ActionAdmission = (input: ActionAdmissionInput) => Promise<ActionAdmissionDecision>;\n\n/** A descendant invocation the Host durably stages with its parent mutation. */\nexport interface StagedInvocationRequest {\n\t/** Stable identity within one parent invocation. */\n\treadonly key: string;\n\treadonly actionId: ActionId;\n\treadonly parameters: Record<string, unknown>;\n}\n\nexport interface ActionResult {\n\tsuccess: boolean;\n\tdata?: Record<string, unknown>;\n\t/**\n\t * Private strict-JSON plain-object input for finalizing actions' adapter steps.\n\t * Passed as getInput's third argument; excluded from public results and finalize input.\n\t * The Host checkpoints it for recovery and removes it on terminal settlement,\n\t * retaining it while running or reconciliation_required. Requires Host capability v1.\n\t * Adapter inputs derived from it remain subject to the Host's redactAdapterInput option.\n\t */\n\tadapterPreparation?: Record<string, unknown>;\n\terror?: string;\n\t/** Host-owned descendants released only after this invocation completes. */\n\tstagedInvocations?: readonly StagedInvocationRequest[];\n}\n\nexport type ActionHandler<TDb = unknown> = (\n\tctx: ActionContext<TDb>,\n\tparams: unknown,\n) => Promise<ActionResult>;\n\nexport type FinalizationJson = null | boolean | number | string | readonly FinalizationJson[] | { readonly [key: string]: FinalizationJson };\nexport type FinalizationRecord = { readonly [key: string]: FinalizationJson };\nexport type ActionFinalizationContext<TDb = unknown> = Pick<ActionContext<TDb>,\n\t\"actionInvocationId\" | \"tenantId\" | \"spaceId\" | \"actorId\" | \"actorType\" |\n\t\"correlationId\" | \"causationId\" | \"provenance\" | \"db\">;\nexport type ActionFinalizationStep = {\n\treadonly stepIndex: number;\n\treadonly adapterType: string;\n\treadonly operation: string;\n} & ({ readonly status: \"succeeded\"; readonly adapterInvocationId: string; readonly output: FinalizationRecord } |\n\t{ readonly status: \"skipped\" });\nexport interface ActionFinalizationInput {\n\treadonly params: FinalizationJson;\n\treadonly handlerData: FinalizationRecord;\n\treadonly adapterOutputs: readonly ActionFinalizationStep[];\n}\nexport interface ActionFinalizationEvent {\n\treadonly eventType: string;\n\treadonly subjectType: string;\n\treadonly subjectId: string;\n\treadonly payload: FinalizationJson;\n\treadonly eventSchemaVersion?: number;\n}\nexport interface ActionFinalizationResult {\n\treadonly events?: readonly ActionFinalizationEvent[];\n\treadonly resultPatch?: FinalizationRecord;\n\t/** Additional descendants staged atomically with finalization and completion. */\n\treadonly stagedInvocations?: readonly StagedInvocationRequest[];\n}\nexport type ActionFinalizer<TDb = unknown> = (\n\tctx: ActionFinalizationContext<TDb>, input: ActionFinalizationInput,\n) => Promise<ActionFinalizationResult>;\n\n/** Validate declarations at registration and at dynamically resolved execution boundaries. */\nexport function assertActionFinalization<TDb>(action: Pick<ActionDefinition<TDb>, \"actionId\" | \"finalize\" | \"eventPhase\" | \"kind\" | \"execution\">): void {\n\tif (action.finalize === undefined) return;\n\tif (typeof action.finalize !== \"function\") throw new Error(\"Action finalization hook must be a function.\");\n\tif (action.eventPhase !== \"after_adapters\") throw new Error(\"Action finalization requires eventPhase after_adapters.\");\n\tif (action.kind !== undefined && action.kind !== \"atomic\") throw new Error(\"Action finalization requires an atomic action.\");\n\tif (action.execution?.completion !== undefined && action.execution.completion !== \"immediate\") throw new Error(\"Action finalization requires immediate completion.\");\n}\n\n/** Refuse older hosts before application handler code executes. Use for distributed finalizing actions. */\nexport function defineFinalizingAction<TDb>(action: ActionDefinition<TDb> & { finalize: ActionFinalizer<TDb> }): ActionDefinition<TDb> {\n\tassertActionFinalization(action);\n\tconst handler = action.handler;\n\treturn { ...action, handler: async (ctx, params) => {\n\t\tif (ctx.finalizationProtocol !== \"atomic-after-adapters-v1\") throw new Error(\"Host does not support atomic-after-adapters-v1 finalization.\");\n\t\tconst result = handler ? await handler(ctx, params) : { success: true, data: {} };\n\t\tif (result.adapterPreparation !== undefined && ctx.adapterPreparationProtocol !== \"v1\")\n\t\t\tthrow new Error(\"Host does not support adapter preparation protocol v1.\");\n\t\treturn result;\n\t} };\n}\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\t/** Positive finite integer duration in milliseconds; overrides Host adapterDeadlineMs for this step. */\n\tdeadlineMs?: number;\n\tgetInput: (\n\t\tparams: unknown,\n\t\thandlerResult: Record<string, unknown>,\n\t\t/** Private preparation from a finalizing handler, absent when none was supplied. */\n\t\tadapterPreparation?: Record<string, unknown>,\n\t) => Record<string, unknown> | undefined;\n}\n\n/** Validate optional step execution budgets before accepting or executing an action. */\nexport function assertAdapterStepDeadlines(action: { actionId: string; adapterSteps?: readonly Pick<AdapterStep, \"deadlineMs\">[] }): void {\n\tfor (const step of action.adapterSteps ?? []) {\n\t\tif (step.deadlineMs !== undefined && (!Number.isInteger(step.deadlineMs) || step.deadlineMs <= 0)) {\n\t\t\tthrow new Error(`Action \"${action.actionId}\" adapter step deadlineMs must be a positive finite integer.`);\n\t\t}\n\t}\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> extends SurfaceDeclaration {\n\tactionId: ActionId;\n\tnamespace: string;\n\tversion: number;\n\tschema: SchemaValidator;\n\t/**\n\t * Optional check a host runs on every submission before it records\n\t * anything durable for it (invocation, idempotency key, events, errors).\n\t * Use it when parameters must be validated against trusted context, for\n\t * example a secret reference the tenant's secret store must hold, before\n\t * they may be persisted. `@fabricorg/platform-host` runs it from the\n\t * release that introduced it; an older host ignores it, so a handler that\n\t * relies on it should require `ActionContext.admittedAt`.\n\t */\n\tadmitSubmission?: ActionAdmission;\n\t/** Optional validation contract for the public handler result data. */\n\tresultSchema?: SchemaValidator;\n\thandler?: ActionHandler<TDb>;\n\tfinalize?: ActionFinalizer<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/** Child action IDs this action is permitted to stage for post-completion dispatch. */\n\tstagesInvocations?: readonly ActionId[];\n\t/** Host-registered principal name used when dispatching each declared staged child. */\n\tstagedInvocationPrincipals?: Readonly<Record<ActionId, string>>;\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\t/**\n\t * `immediate`: the invocation settles within the host's execution.\n\t * `accepted` and `long-running`: an adapter may hand the work to an\n\t * external system and the invocation stays running until that system\n\t * completes it by reference through the host's completion ingress.\n\t * Declare `completionDeadlineMs` on a `long-running` action so a callback\n\t * that never comes is noticed rather than waited on forever.\n\t */\n\tcompletion: ActionCompletionMode;\n\t/**\n\t * How long an accepted handoff may wait for its completion before the host\n\t * moves the invocation to reconciliation. Without it, nothing sweeps the\n\t * handoff. Refused on `immediate`, since nothing external completes it.\n\t */\n\tcompletionDeadlineMs?: number;\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 distinct signals with the same name received before\n\t * another `awaitSignal` call are buffered in FIFO order so none is lost.\n\t *\n\t * A signal may carry a stable signal ID that the sender keeps the same on each redelivery\n\t * (for example a webhook delivery ID or an approval decision ID). A runtime drops\n\t * a signal whose ID it has already received for this saga, so a sender retrying\n\t * after a timeout does not wake the saga twice. Signals without an ID are not\n\t * deduplicated. `@fabricorg/platform-temporal` provides `createSagaSignalInbox()`\n\t * for Temporal runtimes.\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\tif (definition.admitSubmission !== undefined && typeof definition.admitSubmission !== \"function\") {\n\t\t\tthrow new Error(`Action \"${definition.actionId}\" declares admitSubmission that is not a function.`);\n\t\t}\n\t\tassertAdapterStepDeadlines(definition);\n\t\tassertActionFinalization(definition);\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"],"mappings":";;AAyBA,MAAa,cAAoC;CAChD;CACA;CACA;CACA;CACA;CACA;AACD;AAEA,SAAgB,YAAY,OAAmC;CAC9D,OAAQ,YAAkC,SAAS,KAAK;AACzD;AAEA,SAAgB,gBAAgB,OAA2C;CAC1E,IAAI,CAAC,YAAY,KAAK,GACrB,MAAM,IAAI,MAAM,sBAAsB,OAAO;AAE/C;;AA+JA,SAAgB,yBAA8B,QAA0G;CACvJ,IAAI,OAAO,aAAa,KAAA,GAAW;CACnC,IAAI,OAAO,OAAO,aAAa,YAAY,MAAM,IAAI,MAAM,8CAA8C;CACzG,IAAI,OAAO,eAAe,kBAAkB,MAAM,IAAI,MAAM,yDAAyD;CACrH,IAAI,OAAO,SAAS,KAAA,KAAa,OAAO,SAAS,UAAU,MAAM,IAAI,MAAM,gDAAgD;CAC3H,IAAI,OAAO,WAAW,eAAe,KAAA,KAAa,OAAO,UAAU,eAAe,aAAa,MAAM,IAAI,MAAM,oDAAoD;AACpK;;AAGA,SAAgB,uBAA4B,QAA2F;CACtI,yBAAyB,MAAM;CAC/B,MAAM,UAAU,OAAO;CACvB,OAAO;EAAE,GAAG;EAAQ,SAAS,OAAO,KAAK,WAAW;GACnD,IAAI,IAAI,yBAAyB,4BAA4B,MAAM,IAAI,MAAM,8DAA8D;GAC3I,MAAM,SAAS,UAAU,MAAM,QAAQ,KAAK,MAAM,IAAI;IAAE,SAAS;IAAM,MAAM,CAAC;GAAE;GAChF,IAAI,OAAO,uBAAuB,KAAA,KAAa,IAAI,+BAA+B,MACjF,MAAM,IAAI,MAAM,wDAAwD;GACzE,OAAO;EACR;CAAE;AACH;;AAyBA,SAAgB,2BAA2B,QAA+F;CACzI,KAAK,MAAM,QAAQ,OAAO,gBAAgB,CAAC,GAC1C,IAAI,KAAK,eAAe,KAAA,MAAc,CAAC,OAAO,UAAU,KAAK,UAAU,KAAK,KAAK,cAAc,IAC9F,MAAM,IAAI,MAAM,WAAW,OAAO,SAAS,6DAA6D;AAG3G;AAuJA,SAAgB,eAAe,UAAgD;CAC9E,IAAI,CAAC,qCAAqC,KAAK,QAAQ,GACtD,MAAM,IAAI,MAAM,sBAAsB,UAAU;AAElD;AAUA,SAAgB,qBAAoC,cAAgD,CAAC,GAAwB;CAC5H,MAAM,0BAAU,IAAI,IAAqC;CACzD,MAAM,YAAY,eAA4C;EAC7D,eAAe,WAAW,QAAQ;EAClC,IAAI,QAAQ,IAAI,WAAW,QAAQ,GAAG,MAAM,IAAI,MAAM,WAAW,WAAW,SAAS,wBAAwB;EAC7G,IAAI,WAAW,iBAAiB,WAAW,YAAY,WAAW,GACjE,MAAM,IAAI,MAAM,WAAW,WAAW,SAAS,+FAA+F;EAE/I,IAAI,WAAW,oBAAoB,KAAA,KAAa,OAAO,WAAW,oBAAoB,YACrF,MAAM,IAAI,MAAM,WAAW,WAAW,SAAS,mDAAmD;EAEnG,2BAA2B,UAAU;EACrC,yBAAyB,UAAU;EACnC,QAAQ,IAAI,WAAW,UAAU,UAAU;CAC5C;CACA,KAAK,MAAM,cAAc,aAAa,SAAS,UAAU;CACzD,OAAO;EACN;EACA,kBAAkB,YAAY;GAC7B,IAAI,CAAC,QAAQ,IAAI,WAAW,QAAQ,GAAG,SAAS,UAAU;EAC3D;EACA,UAAU,aAAa,QAAQ,IAAI,QAAQ;EAC3C,MAAM,aAAmC,QAAQ,IAAI,QAAoB;EACzE,WAAW,MAAM,KAAK,QAAQ,KAAK,CAAC;CACrC;AACD"}
|
package/dist/actions/index.d.cts
CHANGED
|
@@ -41,6 +41,8 @@ export interface ActionContext<TDb = unknown> {
|
|
|
41
41
|
db: TDb;
|
|
42
42
|
services?: FabricRuntimeServices;
|
|
43
43
|
finalizationProtocol?: "atomic-after-adapters-v1";
|
|
44
|
+
/** Host support for private, durable finalizing-action adapter preparation. */
|
|
45
|
+
adapterPreparationProtocol?: "v1";
|
|
44
46
|
/**
|
|
45
47
|
* When the host admitted this invocation's submission through the
|
|
46
48
|
* action's `admitSubmission` check, read from the durable invocation
|
|
@@ -117,6 +119,14 @@ export interface StagedInvocationRequest {
|
|
|
117
119
|
export interface ActionResult {
|
|
118
120
|
success: boolean;
|
|
119
121
|
data?: Record<string, unknown>;
|
|
122
|
+
/**
|
|
123
|
+
* Private strict-JSON plain-object input for finalizing actions' adapter steps.
|
|
124
|
+
* Passed as getInput's third argument; excluded from public results and finalize input.
|
|
125
|
+
* The Host checkpoints it for recovery and removes it on terminal settlement,
|
|
126
|
+
* retaining it while running or reconciliation_required. Requires Host capability v1.
|
|
127
|
+
* Adapter inputs derived from it remain subject to the Host's redactAdapterInput option.
|
|
128
|
+
*/
|
|
129
|
+
adapterPreparation?: Record<string, unknown>;
|
|
120
130
|
error?: string;
|
|
121
131
|
/** Host-owned descendants released only after this invocation completes. */
|
|
122
132
|
stagedInvocations?: readonly StagedInvocationRequest[];
|
|
@@ -178,7 +188,9 @@ export interface AdapterStep {
|
|
|
178
188
|
retryPolicy?: AdapterStepRetryPolicy;
|
|
179
189
|
/** Positive finite integer duration in milliseconds; overrides Host adapterDeadlineMs for this step. */
|
|
180
190
|
deadlineMs?: number;
|
|
181
|
-
getInput: (params: unknown, handlerResult: Record<string, unknown
|
|
191
|
+
getInput: (params: unknown, handlerResult: Record<string, unknown>,
|
|
192
|
+
/** Private preparation from a finalizing handler, absent when none was supplied. */
|
|
193
|
+
adapterPreparation?: Record<string, unknown>) => Record<string, unknown> | undefined;
|
|
182
194
|
}
|
|
183
195
|
/** Validate optional step execution budgets before accepting or executing an action. */
|
|
184
196
|
export declare function assertAdapterStepDeadlines(action: {
|
|
@@ -221,6 +233,8 @@ export interface ActionDefinition<TDb = unknown> extends SurfaceDeclaration {
|
|
|
221
233
|
adapterSteps?: AdapterStep[];
|
|
222
234
|
/** Child action IDs this action is permitted to stage for post-completion dispatch. */
|
|
223
235
|
stagesInvocations?: readonly ActionId[];
|
|
236
|
+
/** Host-registered principal name used when dispatching each declared staged child. */
|
|
237
|
+
stagedInvocationPrincipals?: Readonly<Record<ActionId, string>>;
|
|
224
238
|
/** Completion actions can attest only after all external adapter work succeeds. */
|
|
225
239
|
eventPhase?: "before_adapters" | "after_adapters";
|
|
226
240
|
/**
|
package/dist/actions/index.d.ts
CHANGED
|
@@ -41,6 +41,8 @@ export interface ActionContext<TDb = unknown> {
|
|
|
41
41
|
db: TDb;
|
|
42
42
|
services?: FabricRuntimeServices;
|
|
43
43
|
finalizationProtocol?: "atomic-after-adapters-v1";
|
|
44
|
+
/** Host support for private, durable finalizing-action adapter preparation. */
|
|
45
|
+
adapterPreparationProtocol?: "v1";
|
|
44
46
|
/**
|
|
45
47
|
* When the host admitted this invocation's submission through the
|
|
46
48
|
* action's `admitSubmission` check, read from the durable invocation
|
|
@@ -117,6 +119,14 @@ export interface StagedInvocationRequest {
|
|
|
117
119
|
export interface ActionResult {
|
|
118
120
|
success: boolean;
|
|
119
121
|
data?: Record<string, unknown>;
|
|
122
|
+
/**
|
|
123
|
+
* Private strict-JSON plain-object input for finalizing actions' adapter steps.
|
|
124
|
+
* Passed as getInput's third argument; excluded from public results and finalize input.
|
|
125
|
+
* The Host checkpoints it for recovery and removes it on terminal settlement,
|
|
126
|
+
* retaining it while running or reconciliation_required. Requires Host capability v1.
|
|
127
|
+
* Adapter inputs derived from it remain subject to the Host's redactAdapterInput option.
|
|
128
|
+
*/
|
|
129
|
+
adapterPreparation?: Record<string, unknown>;
|
|
120
130
|
error?: string;
|
|
121
131
|
/** Host-owned descendants released only after this invocation completes. */
|
|
122
132
|
stagedInvocations?: readonly StagedInvocationRequest[];
|
|
@@ -178,7 +188,9 @@ export interface AdapterStep {
|
|
|
178
188
|
retryPolicy?: AdapterStepRetryPolicy;
|
|
179
189
|
/** Positive finite integer duration in milliseconds; overrides Host adapterDeadlineMs for this step. */
|
|
180
190
|
deadlineMs?: number;
|
|
181
|
-
getInput: (params: unknown, handlerResult: Record<string, unknown
|
|
191
|
+
getInput: (params: unknown, handlerResult: Record<string, unknown>,
|
|
192
|
+
/** Private preparation from a finalizing handler, absent when none was supplied. */
|
|
193
|
+
adapterPreparation?: Record<string, unknown>) => Record<string, unknown> | undefined;
|
|
182
194
|
}
|
|
183
195
|
/** Validate optional step execution budgets before accepting or executing an action. */
|
|
184
196
|
export declare function assertAdapterStepDeadlines(action: {
|
|
@@ -221,6 +233,8 @@ export interface ActionDefinition<TDb = unknown> extends SurfaceDeclaration {
|
|
|
221
233
|
adapterSteps?: AdapterStep[];
|
|
222
234
|
/** Child action IDs this action is permitted to stage for post-completion dispatch. */
|
|
223
235
|
stagesInvocations?: readonly ActionId[];
|
|
236
|
+
/** Host-registered principal name used when dispatching each declared staged child. */
|
|
237
|
+
stagedInvocationPrincipals?: Readonly<Record<ActionId, string>>;
|
|
224
238
|
/** Completion actions can attest only after all external adapter work succeeds. */
|
|
225
239
|
eventPhase?: "before_adapters" | "after_adapters";
|
|
226
240
|
/**
|
package/dist/actions/index.js
CHANGED
|
@@ -29,10 +29,12 @@ function defineFinalizingAction(action) {
|
|
|
29
29
|
...action,
|
|
30
30
|
handler: async (ctx, params) => {
|
|
31
31
|
if (ctx.finalizationProtocol !== "atomic-after-adapters-v1") throw new Error("Host does not support atomic-after-adapters-v1 finalization.");
|
|
32
|
-
|
|
32
|
+
const result = handler ? await handler(ctx, params) : {
|
|
33
33
|
success: true,
|
|
34
34
|
data: {}
|
|
35
35
|
};
|
|
36
|
+
if (result.adapterPreparation !== void 0 && ctx.adapterPreparationProtocol !== "v1") throw new Error("Host does not support adapter preparation protocol v1.");
|
|
37
|
+
return result;
|
|
36
38
|
}
|
|
37
39
|
};
|
|
38
40
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../actions/index.ts"],"sourcesContent":["import type { SurfaceDeclaration } from \"../discovery\";\nexport 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\tfinalizationProtocol?: \"atomic-after-adapters-v1\";\n\t/**\n\t * When the host admitted this invocation's submission through the\n\t * action's `admitSubmission` check, read from the durable invocation\n\t * record. Absent when the action declares no check, or when the runtime\n\t * that built this context does not run declared admission checks (a host\n\t * older than the one that introduced them). A handler whose action\n\t * declares `admitSubmission` can refuse to run without it.\n\t */\n\tadmittedAt?: Date;\n}\n\n/**\n * Trusted facts a host gives an action's `admitSubmission` check. Scope and\n * actor come from the host's authenticated submission, never from the\n * parameters.\n */\nexport interface ActionAdmissionInput {\n\treadonly actionId: ActionId;\n\treadonly tenantId: string;\n\treadonly spaceId: string;\n\treadonly actorId: string;\n\treadonly actorType: ActorType;\n\t/**\n\t * The submitted parameters, unvalidated, as a copy made for this check.\n\t * `@fabricorg/platform-host` records its own copy of the same value, taken\n\t * before the check ran, and only if the check admits it; changing this\n\t * copy changes nothing the host records.\n\t */\n\treadonly parameters: Readonly<Record<string, unknown>>;\n\t/**\n\t * Aborted when the host's admission deadline passes. Hosts pass an\n\t * `AbortSignal`. `@fabricorg/platform-host` refuses an answer that settles\n\t * at or after the deadline, even one that settles before the abort.\n\t */\n\treadonly signal: ActionAdmissionSignal;\n}\n\n/**\n * The part of an `AbortSignal` an admission check can rely on. Declared\n * structurally so this module compiles without DOM or Node type libraries; a\n * host passes a real `AbortSignal`, which satisfies it.\n */\nexport interface ActionAdmissionSignal {\n\treadonly aborted: boolean;\n\taddEventListener(type: \"abort\", listener: () => void, options?: { once?: boolean }): void;\n\tremoveEventListener(type: \"abort\", listener: () => void): void;\n}\n\n/**\n * An admission check's answer. Only `{ admitted: true }` admits. A refusal's\n * `code` must be a fixed code chosen by the action (lower-case first letter,\n * then letters, digits, `_`, `.`, `:` or `-`, at most 128 characters), never\n * a submitted value: the host puts it in the error it throws.\n */\nexport type ActionAdmissionDecision =\n\t| { readonly admitted: true }\n\t| { readonly admitted: false; readonly code: string };\n\n/**\n * Decides whether a submission may be recorded at all. A host that supports\n * it runs the check after authorizing the submitter and before it writes\n * anything durable for the submission; a refusal, a throw, a timeout or any\n * answer other than `{ admitted: true }` refuses the submission.\n */\nexport type ActionAdmission = (input: ActionAdmissionInput) => Promise<ActionAdmissionDecision>;\n\n/** A descendant invocation the Host durably stages with its parent mutation. */\nexport interface StagedInvocationRequest {\n\t/** Stable identity within one parent invocation. */\n\treadonly key: string;\n\treadonly actionId: ActionId;\n\treadonly parameters: Record<string, unknown>;\n}\n\nexport interface ActionResult {\n\tsuccess: boolean;\n\tdata?: Record<string, unknown>;\n\terror?: string;\n\t/** Host-owned descendants released only after this invocation completes. */\n\tstagedInvocations?: readonly StagedInvocationRequest[];\n}\n\nexport type ActionHandler<TDb = unknown> = (\n\tctx: ActionContext<TDb>,\n\tparams: unknown,\n) => Promise<ActionResult>;\n\nexport type FinalizationJson = null | boolean | number | string | readonly FinalizationJson[] | { readonly [key: string]: FinalizationJson };\nexport type FinalizationRecord = { readonly [key: string]: FinalizationJson };\nexport type ActionFinalizationContext<TDb = unknown> = Pick<ActionContext<TDb>,\n\t\"actionInvocationId\" | \"tenantId\" | \"spaceId\" | \"actorId\" | \"actorType\" |\n\t\"correlationId\" | \"causationId\" | \"provenance\" | \"db\">;\nexport type ActionFinalizationStep = {\n\treadonly stepIndex: number;\n\treadonly adapterType: string;\n\treadonly operation: string;\n} & ({ readonly status: \"succeeded\"; readonly adapterInvocationId: string; readonly output: FinalizationRecord } |\n\t{ readonly status: \"skipped\" });\nexport interface ActionFinalizationInput {\n\treadonly params: FinalizationJson;\n\treadonly handlerData: FinalizationRecord;\n\treadonly adapterOutputs: readonly ActionFinalizationStep[];\n}\nexport interface ActionFinalizationEvent {\n\treadonly eventType: string;\n\treadonly subjectType: string;\n\treadonly subjectId: string;\n\treadonly payload: FinalizationJson;\n\treadonly eventSchemaVersion?: number;\n}\nexport interface ActionFinalizationResult {\n\treadonly events?: readonly ActionFinalizationEvent[];\n\treadonly resultPatch?: FinalizationRecord;\n\t/** Additional descendants staged atomically with finalization and completion. */\n\treadonly stagedInvocations?: readonly StagedInvocationRequest[];\n}\nexport type ActionFinalizer<TDb = unknown> = (\n\tctx: ActionFinalizationContext<TDb>, input: ActionFinalizationInput,\n) => Promise<ActionFinalizationResult>;\n\n/** Validate declarations at registration and at dynamically resolved execution boundaries. */\nexport function assertActionFinalization<TDb>(action: Pick<ActionDefinition<TDb>, \"actionId\" | \"finalize\" | \"eventPhase\" | \"kind\" | \"execution\">): void {\n\tif (action.finalize === undefined) return;\n\tif (typeof action.finalize !== \"function\") throw new Error(\"Action finalization hook must be a function.\");\n\tif (action.eventPhase !== \"after_adapters\") throw new Error(\"Action finalization requires eventPhase after_adapters.\");\n\tif (action.kind !== undefined && action.kind !== \"atomic\") throw new Error(\"Action finalization requires an atomic action.\");\n\tif (action.execution?.completion !== undefined && action.execution.completion !== \"immediate\") throw new Error(\"Action finalization requires immediate completion.\");\n}\n\n/** Refuse older hosts before application handler code executes. Use for distributed finalizing actions. */\nexport function defineFinalizingAction<TDb>(action: ActionDefinition<TDb> & { finalize: ActionFinalizer<TDb> }): ActionDefinition<TDb> {\n\tassertActionFinalization(action);\n\tconst handler = action.handler;\n\treturn { ...action, handler: async (ctx, params) => {\n\t\tif (ctx.finalizationProtocol !== \"atomic-after-adapters-v1\") throw new Error(\"Host does not support atomic-after-adapters-v1 finalization.\");\n\t\treturn handler ? handler(ctx, params) : { success: true, data: {} };\n\t} };\n}\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\t/** Positive finite integer duration in milliseconds; overrides Host adapterDeadlineMs for this step. */\n\tdeadlineMs?: number;\n\tgetInput: (\n\t\tparams: unknown,\n\t\thandlerResult: Record<string, unknown>,\n\t) => Record<string, unknown> | undefined;\n}\n\n/** Validate optional step execution budgets before accepting or executing an action. */\nexport function assertAdapterStepDeadlines(action: { actionId: string; adapterSteps?: readonly Pick<AdapterStep, \"deadlineMs\">[] }): void {\n\tfor (const step of action.adapterSteps ?? []) {\n\t\tif (step.deadlineMs !== undefined && (!Number.isInteger(step.deadlineMs) || step.deadlineMs <= 0)) {\n\t\t\tthrow new Error(`Action \"${action.actionId}\" adapter step deadlineMs must be a positive finite integer.`);\n\t\t}\n\t}\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> extends SurfaceDeclaration {\n\tactionId: ActionId;\n\tnamespace: string;\n\tversion: number;\n\tschema: SchemaValidator;\n\t/**\n\t * Optional check a host runs on every submission before it records\n\t * anything durable for it (invocation, idempotency key, events, errors).\n\t * Use it when parameters must be validated against trusted context, for\n\t * example a secret reference the tenant's secret store must hold, before\n\t * they may be persisted. `@fabricorg/platform-host` runs it from the\n\t * release that introduced it; an older host ignores it, so a handler that\n\t * relies on it should require `ActionContext.admittedAt`.\n\t */\n\tadmitSubmission?: ActionAdmission;\n\t/** Optional validation contract for the public handler result data. */\n\tresultSchema?: SchemaValidator;\n\thandler?: ActionHandler<TDb>;\n\tfinalize?: ActionFinalizer<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/** Child action IDs this action is permitted to stage for post-completion dispatch. */\n\tstagesInvocations?: readonly ActionId[];\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\t/**\n\t * `immediate`: the invocation settles within the host's execution.\n\t * `accepted` and `long-running`: an adapter may hand the work to an\n\t * external system and the invocation stays running until that system\n\t * completes it by reference through the host's completion ingress.\n\t * Declare `completionDeadlineMs` on a `long-running` action so a callback\n\t * that never comes is noticed rather than waited on forever.\n\t */\n\tcompletion: ActionCompletionMode;\n\t/**\n\t * How long an accepted handoff may wait for its completion before the host\n\t * moves the invocation to reconciliation. Without it, nothing sweeps the\n\t * handoff. Refused on `immediate`, since nothing external completes it.\n\t */\n\tcompletionDeadlineMs?: number;\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 distinct signals with the same name received before\n\t * another `awaitSignal` call are buffered in FIFO order so none is lost.\n\t *\n\t * A signal may carry a stable signal ID that the sender keeps the same on each redelivery\n\t * (for example a webhook delivery ID or an approval decision ID). A runtime drops\n\t * a signal whose ID it has already received for this saga, so a sender retrying\n\t * after a timeout does not wake the saga twice. Signals without an ID are not\n\t * deduplicated. `@fabricorg/platform-temporal` provides `createSagaSignalInbox()`\n\t * for Temporal runtimes.\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\tif (definition.admitSubmission !== undefined && typeof definition.admitSubmission !== \"function\") {\n\t\t\tthrow new Error(`Action \"${definition.actionId}\" declares admitSubmission that is not a function.`);\n\t\t}\n\t\tassertAdapterStepDeadlines(definition);\n\t\tassertActionFinalization(definition);\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"],"mappings":";AAyBA,MAAa,cAAoC;CAChD;CACA;CACA;CACA;CACA;CACA;AACD;AAEA,SAAgB,YAAY,OAAmC;CAC9D,OAAQ,YAAkC,SAAS,KAAK;AACzD;AAEA,SAAgB,gBAAgB,OAA2C;CAC1E,IAAI,CAAC,YAAY,KAAK,GACrB,MAAM,IAAI,MAAM,sBAAsB,OAAO;AAE/C;;AAqJA,SAAgB,yBAA8B,QAA0G;CACvJ,IAAI,OAAO,aAAa,KAAA,GAAW;CACnC,IAAI,OAAO,OAAO,aAAa,YAAY,MAAM,IAAI,MAAM,8CAA8C;CACzG,IAAI,OAAO,eAAe,kBAAkB,MAAM,IAAI,MAAM,yDAAyD;CACrH,IAAI,OAAO,SAAS,KAAA,KAAa,OAAO,SAAS,UAAU,MAAM,IAAI,MAAM,gDAAgD;CAC3H,IAAI,OAAO,WAAW,eAAe,KAAA,KAAa,OAAO,UAAU,eAAe,aAAa,MAAM,IAAI,MAAM,oDAAoD;AACpK;;AAGA,SAAgB,uBAA4B,QAA2F;CACtI,yBAAyB,MAAM;CAC/B,MAAM,UAAU,OAAO;CACvB,OAAO;EAAE,GAAG;EAAQ,SAAS,OAAO,KAAK,WAAW;GACnD,IAAI,IAAI,yBAAyB,4BAA4B,MAAM,IAAI,MAAM,8DAA8D;GAC3I,OAAO,UAAU,QAAQ,KAAK,MAAM,IAAI;IAAE,SAAS;IAAM,MAAM,CAAC;GAAE;EACnE;CAAE;AACH;;AAuBA,SAAgB,2BAA2B,QAA+F;CACzI,KAAK,MAAM,QAAQ,OAAO,gBAAgB,CAAC,GAC1C,IAAI,KAAK,eAAe,KAAA,MAAc,CAAC,OAAO,UAAU,KAAK,UAAU,KAAK,KAAK,cAAc,IAC9F,MAAM,IAAI,MAAM,WAAW,OAAO,SAAS,6DAA6D;AAG3G;AAqJA,SAAgB,eAAe,UAAgD;CAC9E,IAAI,CAAC,qCAAqC,KAAK,QAAQ,GACtD,MAAM,IAAI,MAAM,sBAAsB,UAAU;AAElD;AAUA,SAAgB,qBAAoC,cAAgD,CAAC,GAAwB;CAC5H,MAAM,0BAAU,IAAI,IAAqC;CACzD,MAAM,YAAY,eAA4C;EAC7D,eAAe,WAAW,QAAQ;EAClC,IAAI,QAAQ,IAAI,WAAW,QAAQ,GAAG,MAAM,IAAI,MAAM,WAAW,WAAW,SAAS,wBAAwB;EAC7G,IAAI,WAAW,iBAAiB,WAAW,YAAY,WAAW,GACjE,MAAM,IAAI,MAAM,WAAW,WAAW,SAAS,+FAA+F;EAE/I,IAAI,WAAW,oBAAoB,KAAA,KAAa,OAAO,WAAW,oBAAoB,YACrF,MAAM,IAAI,MAAM,WAAW,WAAW,SAAS,mDAAmD;EAEnG,2BAA2B,UAAU;EACrC,yBAAyB,UAAU;EACnC,QAAQ,IAAI,WAAW,UAAU,UAAU;CAC5C;CACA,KAAK,MAAM,cAAc,aAAa,SAAS,UAAU;CACzD,OAAO;EACN;EACA,kBAAkB,YAAY;GAC7B,IAAI,CAAC,QAAQ,IAAI,WAAW,QAAQ,GAAG,SAAS,UAAU;EAC3D;EACA,UAAU,aAAa,QAAQ,IAAI,QAAQ;EAC3C,MAAM,aAAmC,QAAQ,IAAI,QAAoB;EACzE,WAAW,MAAM,KAAK,QAAQ,KAAK,CAAC;CACrC;AACD"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../actions/index.ts"],"sourcesContent":["import type { SurfaceDeclaration } from \"../discovery\";\nexport 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\tfinalizationProtocol?: \"atomic-after-adapters-v1\";\n\t/** Host support for private, durable finalizing-action adapter preparation. */\n\tadapterPreparationProtocol?: \"v1\";\n\t/**\n\t * When the host admitted this invocation's submission through the\n\t * action's `admitSubmission` check, read from the durable invocation\n\t * record. Absent when the action declares no check, or when the runtime\n\t * that built this context does not run declared admission checks (a host\n\t * older than the one that introduced them). A handler whose action\n\t * declares `admitSubmission` can refuse to run without it.\n\t */\n\tadmittedAt?: Date;\n}\n\n/**\n * Trusted facts a host gives an action's `admitSubmission` check. Scope and\n * actor come from the host's authenticated submission, never from the\n * parameters.\n */\nexport interface ActionAdmissionInput {\n\treadonly actionId: ActionId;\n\treadonly tenantId: string;\n\treadonly spaceId: string;\n\treadonly actorId: string;\n\treadonly actorType: ActorType;\n\t/**\n\t * The submitted parameters, unvalidated, as a copy made for this check.\n\t * `@fabricorg/platform-host` records its own copy of the same value, taken\n\t * before the check ran, and only if the check admits it; changing this\n\t * copy changes nothing the host records.\n\t */\n\treadonly parameters: Readonly<Record<string, unknown>>;\n\t/**\n\t * Aborted when the host's admission deadline passes. Hosts pass an\n\t * `AbortSignal`. `@fabricorg/platform-host` refuses an answer that settles\n\t * at or after the deadline, even one that settles before the abort.\n\t */\n\treadonly signal: ActionAdmissionSignal;\n}\n\n/**\n * The part of an `AbortSignal` an admission check can rely on. Declared\n * structurally so this module compiles without DOM or Node type libraries; a\n * host passes a real `AbortSignal`, which satisfies it.\n */\nexport interface ActionAdmissionSignal {\n\treadonly aborted: boolean;\n\taddEventListener(type: \"abort\", listener: () => void, options?: { once?: boolean }): void;\n\tremoveEventListener(type: \"abort\", listener: () => void): void;\n}\n\n/**\n * An admission check's answer. Only `{ admitted: true }` admits. A refusal's\n * `code` must be a fixed code chosen by the action (lower-case first letter,\n * then letters, digits, `_`, `.`, `:` or `-`, at most 128 characters), never\n * a submitted value: the host puts it in the error it throws.\n */\nexport type ActionAdmissionDecision =\n\t| { readonly admitted: true }\n\t| { readonly admitted: false; readonly code: string };\n\n/**\n * Decides whether a submission may be recorded at all. A host that supports\n * it runs the check after authorizing the submitter and before it writes\n * anything durable for the submission; a refusal, a throw, a timeout or any\n * answer other than `{ admitted: true }` refuses the submission.\n */\nexport type ActionAdmission = (input: ActionAdmissionInput) => Promise<ActionAdmissionDecision>;\n\n/** A descendant invocation the Host durably stages with its parent mutation. */\nexport interface StagedInvocationRequest {\n\t/** Stable identity within one parent invocation. */\n\treadonly key: string;\n\treadonly actionId: ActionId;\n\treadonly parameters: Record<string, unknown>;\n}\n\nexport interface ActionResult {\n\tsuccess: boolean;\n\tdata?: Record<string, unknown>;\n\t/**\n\t * Private strict-JSON plain-object input for finalizing actions' adapter steps.\n\t * Passed as getInput's third argument; excluded from public results and finalize input.\n\t * The Host checkpoints it for recovery and removes it on terminal settlement,\n\t * retaining it while running or reconciliation_required. Requires Host capability v1.\n\t * Adapter inputs derived from it remain subject to the Host's redactAdapterInput option.\n\t */\n\tadapterPreparation?: Record<string, unknown>;\n\terror?: string;\n\t/** Host-owned descendants released only after this invocation completes. */\n\tstagedInvocations?: readonly StagedInvocationRequest[];\n}\n\nexport type ActionHandler<TDb = unknown> = (\n\tctx: ActionContext<TDb>,\n\tparams: unknown,\n) => Promise<ActionResult>;\n\nexport type FinalizationJson = null | boolean | number | string | readonly FinalizationJson[] | { readonly [key: string]: FinalizationJson };\nexport type FinalizationRecord = { readonly [key: string]: FinalizationJson };\nexport type ActionFinalizationContext<TDb = unknown> = Pick<ActionContext<TDb>,\n\t\"actionInvocationId\" | \"tenantId\" | \"spaceId\" | \"actorId\" | \"actorType\" |\n\t\"correlationId\" | \"causationId\" | \"provenance\" | \"db\">;\nexport type ActionFinalizationStep = {\n\treadonly stepIndex: number;\n\treadonly adapterType: string;\n\treadonly operation: string;\n} & ({ readonly status: \"succeeded\"; readonly adapterInvocationId: string; readonly output: FinalizationRecord } |\n\t{ readonly status: \"skipped\" });\nexport interface ActionFinalizationInput {\n\treadonly params: FinalizationJson;\n\treadonly handlerData: FinalizationRecord;\n\treadonly adapterOutputs: readonly ActionFinalizationStep[];\n}\nexport interface ActionFinalizationEvent {\n\treadonly eventType: string;\n\treadonly subjectType: string;\n\treadonly subjectId: string;\n\treadonly payload: FinalizationJson;\n\treadonly eventSchemaVersion?: number;\n}\nexport interface ActionFinalizationResult {\n\treadonly events?: readonly ActionFinalizationEvent[];\n\treadonly resultPatch?: FinalizationRecord;\n\t/** Additional descendants staged atomically with finalization and completion. */\n\treadonly stagedInvocations?: readonly StagedInvocationRequest[];\n}\nexport type ActionFinalizer<TDb = unknown> = (\n\tctx: ActionFinalizationContext<TDb>, input: ActionFinalizationInput,\n) => Promise<ActionFinalizationResult>;\n\n/** Validate declarations at registration and at dynamically resolved execution boundaries. */\nexport function assertActionFinalization<TDb>(action: Pick<ActionDefinition<TDb>, \"actionId\" | \"finalize\" | \"eventPhase\" | \"kind\" | \"execution\">): void {\n\tif (action.finalize === undefined) return;\n\tif (typeof action.finalize !== \"function\") throw new Error(\"Action finalization hook must be a function.\");\n\tif (action.eventPhase !== \"after_adapters\") throw new Error(\"Action finalization requires eventPhase after_adapters.\");\n\tif (action.kind !== undefined && action.kind !== \"atomic\") throw new Error(\"Action finalization requires an atomic action.\");\n\tif (action.execution?.completion !== undefined && action.execution.completion !== \"immediate\") throw new Error(\"Action finalization requires immediate completion.\");\n}\n\n/** Refuse older hosts before application handler code executes. Use for distributed finalizing actions. */\nexport function defineFinalizingAction<TDb>(action: ActionDefinition<TDb> & { finalize: ActionFinalizer<TDb> }): ActionDefinition<TDb> {\n\tassertActionFinalization(action);\n\tconst handler = action.handler;\n\treturn { ...action, handler: async (ctx, params) => {\n\t\tif (ctx.finalizationProtocol !== \"atomic-after-adapters-v1\") throw new Error(\"Host does not support atomic-after-adapters-v1 finalization.\");\n\t\tconst result = handler ? await handler(ctx, params) : { success: true, data: {} };\n\t\tif (result.adapterPreparation !== undefined && ctx.adapterPreparationProtocol !== \"v1\")\n\t\t\tthrow new Error(\"Host does not support adapter preparation protocol v1.\");\n\t\treturn result;\n\t} };\n}\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\t/** Positive finite integer duration in milliseconds; overrides Host adapterDeadlineMs for this step. */\n\tdeadlineMs?: number;\n\tgetInput: (\n\t\tparams: unknown,\n\t\thandlerResult: Record<string, unknown>,\n\t\t/** Private preparation from a finalizing handler, absent when none was supplied. */\n\t\tadapterPreparation?: Record<string, unknown>,\n\t) => Record<string, unknown> | undefined;\n}\n\n/** Validate optional step execution budgets before accepting or executing an action. */\nexport function assertAdapterStepDeadlines(action: { actionId: string; adapterSteps?: readonly Pick<AdapterStep, \"deadlineMs\">[] }): void {\n\tfor (const step of action.adapterSteps ?? []) {\n\t\tif (step.deadlineMs !== undefined && (!Number.isInteger(step.deadlineMs) || step.deadlineMs <= 0)) {\n\t\t\tthrow new Error(`Action \"${action.actionId}\" adapter step deadlineMs must be a positive finite integer.`);\n\t\t}\n\t}\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> extends SurfaceDeclaration {\n\tactionId: ActionId;\n\tnamespace: string;\n\tversion: number;\n\tschema: SchemaValidator;\n\t/**\n\t * Optional check a host runs on every submission before it records\n\t * anything durable for it (invocation, idempotency key, events, errors).\n\t * Use it when parameters must be validated against trusted context, for\n\t * example a secret reference the tenant's secret store must hold, before\n\t * they may be persisted. `@fabricorg/platform-host` runs it from the\n\t * release that introduced it; an older host ignores it, so a handler that\n\t * relies on it should require `ActionContext.admittedAt`.\n\t */\n\tadmitSubmission?: ActionAdmission;\n\t/** Optional validation contract for the public handler result data. */\n\tresultSchema?: SchemaValidator;\n\thandler?: ActionHandler<TDb>;\n\tfinalize?: ActionFinalizer<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/** Child action IDs this action is permitted to stage for post-completion dispatch. */\n\tstagesInvocations?: readonly ActionId[];\n\t/** Host-registered principal name used when dispatching each declared staged child. */\n\tstagedInvocationPrincipals?: Readonly<Record<ActionId, string>>;\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\t/**\n\t * `immediate`: the invocation settles within the host's execution.\n\t * `accepted` and `long-running`: an adapter may hand the work to an\n\t * external system and the invocation stays running until that system\n\t * completes it by reference through the host's completion ingress.\n\t * Declare `completionDeadlineMs` on a `long-running` action so a callback\n\t * that never comes is noticed rather than waited on forever.\n\t */\n\tcompletion: ActionCompletionMode;\n\t/**\n\t * How long an accepted handoff may wait for its completion before the host\n\t * moves the invocation to reconciliation. Without it, nothing sweeps the\n\t * handoff. Refused on `immediate`, since nothing external completes it.\n\t */\n\tcompletionDeadlineMs?: number;\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 distinct signals with the same name received before\n\t * another `awaitSignal` call are buffered in FIFO order so none is lost.\n\t *\n\t * A signal may carry a stable signal ID that the sender keeps the same on each redelivery\n\t * (for example a webhook delivery ID or an approval decision ID). A runtime drops\n\t * a signal whose ID it has already received for this saga, so a sender retrying\n\t * after a timeout does not wake the saga twice. Signals without an ID are not\n\t * deduplicated. `@fabricorg/platform-temporal` provides `createSagaSignalInbox()`\n\t * for Temporal runtimes.\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\tif (definition.admitSubmission !== undefined && typeof definition.admitSubmission !== \"function\") {\n\t\t\tthrow new Error(`Action \"${definition.actionId}\" declares admitSubmission that is not a function.`);\n\t\t}\n\t\tassertAdapterStepDeadlines(definition);\n\t\tassertActionFinalization(definition);\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"],"mappings":";AAyBA,MAAa,cAAoC;CAChD;CACA;CACA;CACA;CACA;CACA;AACD;AAEA,SAAgB,YAAY,OAAmC;CAC9D,OAAQ,YAAkC,SAAS,KAAK;AACzD;AAEA,SAAgB,gBAAgB,OAA2C;CAC1E,IAAI,CAAC,YAAY,KAAK,GACrB,MAAM,IAAI,MAAM,sBAAsB,OAAO;AAE/C;;AA+JA,SAAgB,yBAA8B,QAA0G;CACvJ,IAAI,OAAO,aAAa,KAAA,GAAW;CACnC,IAAI,OAAO,OAAO,aAAa,YAAY,MAAM,IAAI,MAAM,8CAA8C;CACzG,IAAI,OAAO,eAAe,kBAAkB,MAAM,IAAI,MAAM,yDAAyD;CACrH,IAAI,OAAO,SAAS,KAAA,KAAa,OAAO,SAAS,UAAU,MAAM,IAAI,MAAM,gDAAgD;CAC3H,IAAI,OAAO,WAAW,eAAe,KAAA,KAAa,OAAO,UAAU,eAAe,aAAa,MAAM,IAAI,MAAM,oDAAoD;AACpK;;AAGA,SAAgB,uBAA4B,QAA2F;CACtI,yBAAyB,MAAM;CAC/B,MAAM,UAAU,OAAO;CACvB,OAAO;EAAE,GAAG;EAAQ,SAAS,OAAO,KAAK,WAAW;GACnD,IAAI,IAAI,yBAAyB,4BAA4B,MAAM,IAAI,MAAM,8DAA8D;GAC3I,MAAM,SAAS,UAAU,MAAM,QAAQ,KAAK,MAAM,IAAI;IAAE,SAAS;IAAM,MAAM,CAAC;GAAE;GAChF,IAAI,OAAO,uBAAuB,KAAA,KAAa,IAAI,+BAA+B,MACjF,MAAM,IAAI,MAAM,wDAAwD;GACzE,OAAO;EACR;CAAE;AACH;;AAyBA,SAAgB,2BAA2B,QAA+F;CACzI,KAAK,MAAM,QAAQ,OAAO,gBAAgB,CAAC,GAC1C,IAAI,KAAK,eAAe,KAAA,MAAc,CAAC,OAAO,UAAU,KAAK,UAAU,KAAK,KAAK,cAAc,IAC9F,MAAM,IAAI,MAAM,WAAW,OAAO,SAAS,6DAA6D;AAG3G;AAuJA,SAAgB,eAAe,UAAgD;CAC9E,IAAI,CAAC,qCAAqC,KAAK,QAAQ,GACtD,MAAM,IAAI,MAAM,sBAAsB,UAAU;AAElD;AAUA,SAAgB,qBAAoC,cAAgD,CAAC,GAAwB;CAC5H,MAAM,0BAAU,IAAI,IAAqC;CACzD,MAAM,YAAY,eAA4C;EAC7D,eAAe,WAAW,QAAQ;EAClC,IAAI,QAAQ,IAAI,WAAW,QAAQ,GAAG,MAAM,IAAI,MAAM,WAAW,WAAW,SAAS,wBAAwB;EAC7G,IAAI,WAAW,iBAAiB,WAAW,YAAY,WAAW,GACjE,MAAM,IAAI,MAAM,WAAW,WAAW,SAAS,+FAA+F;EAE/I,IAAI,WAAW,oBAAoB,KAAA,KAAa,OAAO,WAAW,oBAAoB,YACrF,MAAM,IAAI,MAAM,WAAW,WAAW,SAAS,mDAAmD;EAEnG,2BAA2B,UAAU;EACrC,yBAAyB,UAAU;EACnC,QAAQ,IAAI,WAAW,UAAU,UAAU;CAC5C;CACA,KAAK,MAAM,cAAc,aAAa,SAAS,UAAU;CACzD,OAAO;EACN;EACA,kBAAkB,YAAY;GAC7B,IAAI,CAAC,QAAQ,IAAI,WAAW,QAAQ,GAAG,SAAS,UAAU;EAC3D;EACA,UAAU,aAAa,QAAQ,IAAI,QAAQ;EAC3C,MAAM,aAAmC,QAAQ,IAAI,QAAoB;EACzE,WAAW,MAAM,KAAK,QAAQ,KAAK,CAAC;CACrC;AACD"}
|
package/dist/manifest/index.cjs
CHANGED
|
@@ -96,6 +96,7 @@ function exportAction(action) {
|
|
|
96
96
|
if (action.requiredRoles !== void 0) manifest.requiredRoles = [...action.requiredRoles];
|
|
97
97
|
if (action.requiredPermissions !== void 0) manifest.requiredPermissions = [...action.requiredPermissions];
|
|
98
98
|
if (action.stagesInvocations !== void 0) manifest.stagesInvocations = [...action.stagesInvocations];
|
|
99
|
+
if (action.stagedInvocationPrincipals !== void 0) manifest.stagedInvocationPrincipals = Object.fromEntries(Object.entries(action.stagedInvocationPrincipals).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0));
|
|
99
100
|
if (action.eventPhase !== void 0) manifest.eventPhase = action.eventPhase;
|
|
100
101
|
if (action.finalize !== void 0) manifest.finalization = { protocol: "atomic-after-adapters-v1" };
|
|
101
102
|
if (action.execution !== void 0) manifest.execution = cloneJson(action.execution);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["getModuleDependencyNamespace","getObjectTypeName","getEventTypeName"],"sources":["../../manifest/index.ts"],"sourcesContent":["import { assertAdapterStepDeadlines } from \"../actions\";\nimport { assertSurfaceDeclaration, type SurfaceDeclaration } from \"../discovery\";\nimport type {\n\tActionExecutionContract,\n\tActionDefinition,\n\tAdapterStepRetryPolicy,\n\tSchemaValidator,\n} from \"../actions\";\nimport {\n\tgetEventTypeName,\n\tgetModuleDependencyNamespace,\n\tgetObjectTypeName,\n\ttype FabricModule,\n\ttype CapabilityMetadata,\n\ttype DeclarativeInvariant,\n\ttype ModuleDependency,\n\ttype ModuleDependencyInput,\n\ttype ObjectRelationDefinition,\n} from \"../modules\";\nimport type { JsonValue, PortableJsonSchema } from \"../objects\";\nimport type {\n\tDataPolicyDefinition,\n\tPolicyFallbackDefinition,\n\tPolicyKind,\n} from \"../policies\";\nimport type { StateDefinition, StateMachineDefinition } from \"../state-machines\";\nimport type { ViewContract } from \"../projections\";\n\n/**\n * Version of the module manifest contract. Bump when the serialized shape\n * changes in a way consumers must detect.\n */\nexport const MODULE_MANIFEST_VERSION = 2 as const;\n\nexport interface ModuleManifestObjectType {\n\ttype: string;\n\tdisplayName?: string;\n\tidPrefix?: string;\n\tschema?: PortableJsonSchema;\n\tsemantics?: Record<string, JsonValue>;\n\trelations?: ObjectRelationDefinition[];\n\tinvariants?: DeclarativeInvariant[];\n}\n\nexport interface ModuleManifestIdPrefix {\n\tprefix: string;\n\tname: string;\n}\n\nexport interface ModuleManifestEventType {\n\teventType: string;\n\tschemaVersion: number;\n\tdescription?: string;\n\tschema?: PortableJsonSchema;\n}\n\nexport interface ModuleManifestActionStateMachine {\n\tentityType: string;\n\t/** Present only when the binding declares a static target state. */\n\ttargetState?: string;\n}\n\nexport interface ModuleManifestAdapterStep {\n\tadapterType: string;\n\toperation: string;\n\tretryPolicy?: AdapterStepRetryPolicy;\n\t/** Positive finite integer duration in milliseconds; overrides Host adapterDeadlineMs for this step. */\n\tdeadlineMs?: number;\n}\n\nexport interface ModuleManifestAction extends SurfaceDeclaration {\n\tactionId: string;\n\tversion: number;\n\tkind: \"atomic\" | \"saga\";\n\tidempotent: boolean;\n\tmutatesDomain: boolean;\n\temitsEvents: string[];\n\tpolicies?: string[];\n\trequiredRoles?: string[];\n\trequiredPermissions?: string[];\n\tstagesInvocations?: string[];\n\teventPhase?: \"before_adapters\" | \"after_adapters\";\n\tfinalization?: { protocol: \"atomic-after-adapters-v1\" };\n\texecution?: ActionExecutionContract;\n\t/**\n\t * JSON Schema for the action parameters, present only when the action's\n\t * `schema` validator implements {@link JsonSchemaExportableValidator}.\n\t */\n\tparameterSchema?: unknown;\n\tparameterSchemaFormat?: \"json-schema\";\n\tresultSchema?: unknown;\n\tresultSchemaFormat?: \"json-schema\";\n\tstateMachine?: ModuleManifestActionStateMachine;\n\tadapterSteps?: ModuleManifestAdapterStep[];\n}\n\nexport interface ModuleManifestCodePolicy {\n\ttype: \"code\";\n\tpolicyId: string;\n\tversion: number;\n\tpreviewSafe?: boolean;\n}\n\nexport interface ModuleManifestDataPolicy {\n\ttype: \"data\";\n\tpolicyId: string;\n\tpolicyVersion: number;\n\tkind: PolicyKind;\n\tdataDefinition?: DataPolicyDefinition;\n\tcodeEvaluatorPolicyId?: string;\n\tfallback?: PolicyFallbackDefinition;\n}\n\nexport type ModuleManifestPolicy = ModuleManifestCodePolicy | ModuleManifestDataPolicy;\n\nexport interface ModuleManifestStateMachineTransition {\n\tfrom: string;\n\tto: string;\n\tcausedByAction: string;\n\t/** `true` when the transition declares a guard function. The guard itself is never serialized. */\n\thasGuard: boolean;\n}\n\nexport interface ModuleManifestStateMachine {\n\tentityType: string;\n\t/** States in declaration order (`Object.values` order of the definition record). */\n\tstates: StateDefinition[];\n\ttransitions: ModuleManifestStateMachineTransition[];\n}\n\nexport interface ModuleManifestView extends SurfaceDeclaration {\n\tname: string;\n\tversion: string;\n\tshape: PortableJsonSchema;\n\tparameterSchema?: PortableJsonSchema;\n\tconsumes: Array<{ eventType: string; schemaVersions: number[] }>;\n\tscope: \"tenant-space\";\n\tsnapshotVersion: number;\n\tcompatibleSnapshotVersions?: number[];\n\tusage?: ViewContract[\"usage\"];\n}\n\n/**\n * Stable, JSON-serializable description of a {@link FabricModule}'s ontology:\n * object types, subject types, id prefixes, event types, actions, policies,\n * and state machines. Intended for downstream tooling (semantics exporters,\n * docs generators, tool generators) that cannot consume live module code.\n *\n * The manifest contains definitions only — never raw parameter values,\n * secrets, or runtime data. Function fields (`handler`, `evaluate`, `guard`,\n * dynamic `targetState`, adapter `getInput`) are never serialized.\n */\nexport interface ModuleManifest {\n\tmanifestVersion: typeof MODULE_MANIFEST_VERSION;\n\tnamespace: string;\n\tversion?: string;\n\tdisplayName?: string;\n\tdescription?: string;\n\tcapability?: CapabilityMetadata;\n\tdependencies: ModuleDependency[];\n\tobjectTypes: ModuleManifestObjectType[];\n\tsubjectTypes: string[];\n\tidPrefixes: ModuleManifestIdPrefix[];\n\teventTypes: ModuleManifestEventType[];\n\tactions: ModuleManifestAction[];\n\tpolicies: ModuleManifestPolicy[];\n\tstateMachines: ModuleManifestStateMachine[];\n\tviews: ModuleManifestView[];\n}\n\nexport interface ModuleManifestBundle {\n\tmanifestVersion: typeof MODULE_MANIFEST_VERSION;\n\t/** Manifests in the input module order. */\n\tmodules: ModuleManifest[];\n}\n\n/** Manifest v1 remains accepted by v2 readers; missing v2 fields normalize to absence. */\nexport type ModuleManifestObjectTypeV1 = Omit<\n\tModuleManifestObjectType,\n\t\"schema\" | \"semantics\" | \"relations\" | \"invariants\"\n>;\nexport type ModuleManifestActionV1 = Omit<\n\tModuleManifestAction,\n\t\"resultSchema\" | \"resultSchemaFormat\"\n>;\nexport type ModuleManifestV1 = Omit<\n\tModuleManifest,\n\t\"manifestVersion\" | \"objectTypes\" | \"actions\" | \"views\"\n> & {\n\tmanifestVersion: 1;\n\tobjectTypes: ModuleManifestObjectTypeV1[];\n\tactions: ModuleManifestActionV1[];\n};\nexport type ModuleManifestBundleV1 = Omit<ModuleManifestBundle, \"manifestVersion\" | \"modules\"> & {\n\tmanifestVersion: 1;\n\tmodules: ModuleManifestV1[];\n};\n\nexport function normalizeModuleManifest(\n\tmanifest: ModuleManifest | ModuleManifestV1,\n): ModuleManifest {\n\tconst version: number = manifest.manifestVersion;\n\tif (version !== 1 && version !== MODULE_MANIFEST_VERSION) {\n\t\tthrow new Error(`Unsupported module manifest version: ${String(version)}`);\n\t}\n\tconst views = \"views\" in manifest && Array.isArray(manifest.views) ? manifest.views : [];\n\t// Preserve the normalizer's legacy tolerance for absent/non-array fields.\n\tif (Array.isArray(manifest.actions))\n\t\tfor (const [index, action] of manifest.actions.entries()) {\n\t\t\tassertSurfaceDeclaration(action, `Module \"${manifest.namespace}\" action[${index}] \"${action?.actionId ?? \"unknown\"}\"`);\n\t\t\tassertAdapterStepDeadlines(action);\n\t\t\tif (action.finalization !== undefined) {\n\t\t\t\tconst descriptor = action.finalization;\n\t\t\t\tif (!descriptor || typeof descriptor !== \"object\" || Array.isArray(descriptor) ||\n\t\t\t\t\tObject.keys(descriptor).some(key => key !== \"protocol\") || descriptor.protocol !== \"atomic-after-adapters-v1\")\n\t\t\t\t\tthrow new Error(\"Invalid action finalization protocol descriptor.\");\n\t\t\t\tif (action.eventPhase !== \"after_adapters\" || (action.kind !== undefined && action.kind !== \"atomic\") ||\n\t\t\t\t\t(action.execution?.completion !== undefined && action.execution.completion !== \"immediate\"))\n\t\t\t\t\tthrow new Error(\"Incompatible action finalization declaration.\");\n\t\t\t}\n\t\t}\n\tfor (const [index, view] of views.entries())\n\t\tassertSurfaceDeclaration(view, `Module \"${manifest.namespace}\" view[${index}] \"${view?.name ?? \"unknown\"}\"`);\n\treturn {\n\t\t...manifest,\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tviews,\n\t};\n}\n\nexport function normalizeModuleManifestBundle(\n\tbundle: ModuleManifestBundle | ModuleManifestBundleV1,\n): ModuleManifestBundle {\n\tconst version: number = bundle.manifestVersion;\n\tif (version !== 1 && version !== MODULE_MANIFEST_VERSION) {\n\t\tthrow new Error(`Unsupported module manifest bundle version: ${String(version)}`);\n\t}\n\treturn {\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tmodules: bundle.modules.map((manifest) => normalizeModuleManifest(manifest)),\n\t};\n}\n\n/**\n * A {@link SchemaValidator} that can also export its parameter schema as JSON\n * Schema (for example a Zod 4 schema via `z.toJSONSchema`). Keeps the platform\n * zero-dependency while letting schema-bearing actions flow into manifests.\n */\nexport interface JsonSchemaExportableValidator extends SchemaValidator {\n\ttoJSONSchema(): Record<string, unknown>;\n}\n\nexport function isJsonSchemaExportableValidator(\n\tschema: SchemaValidator,\n): schema is JsonSchemaExportableValidator {\n\treturn (\n\t\ttypeof (schema as Partial<JsonSchemaExportableValidator>).toJSONSchema === \"function\"\n\t);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction exportDependency(dependency: ModuleDependencyInput): ModuleDependency {\n\tconst namespace = getModuleDependencyNamespace(dependency);\n\tif (typeof dependency === \"string\") {\n\t\treturn { namespace };\n\t}\n\tconst normalized: ModuleDependency = { namespace };\n\tif (dependency.version !== undefined) normalized.version = dependency.version;\n\tif (dependency.optional !== undefined) normalized.optional = dependency.optional;\n\treturn normalized;\n}\n\nfunction exportObjectType(\n\tobjectType: NonNullable<FabricModule[\"objectTypes\"]>[number],\n): ModuleManifestObjectType {\n\tif (typeof objectType === \"string\") {\n\t\treturn { type: objectType };\n\t}\n\tconst normalized: ModuleManifestObjectType = { type: getObjectTypeName(objectType) };\n\tif (objectType.displayName !== undefined) normalized.displayName = objectType.displayName;\n\tif (objectType.idPrefix !== undefined) normalized.idPrefix = objectType.idPrefix;\n\tif (objectType.schema !== undefined) normalized.schema = cloneJson(objectType.schema);\n\tif (objectType.semantics !== undefined) normalized.semantics = cloneJson(objectType.semantics);\n\tif (objectType.relations !== undefined) {\n\t\tnormalized.relations = objectType.relations.map((relation) => ({ ...relation }));\n\t}\n\tif (objectType.invariants !== undefined) {\n\t\tnormalized.invariants = objectType.invariants.map((invariant) => ({ ...invariant }));\n\t}\n\treturn normalized;\n}\n\nfunction cloneJson<T>(value: T): T {\n\tif (Array.isArray(value)) return value.map((item) => cloneJson(item)) as T;\n\tif (value !== null && typeof value === \"object\") {\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(value as Record<string, unknown>).map(([key, child]) => [key, cloneJson(child)]),\n\t\t) as T;\n\t}\n\treturn value;\n}\n\nfunction exportEventType(\n\teventType: NonNullable<FabricModule[\"eventTypes\"]>[number],\n): ModuleManifestEventType {\n\tif (typeof eventType === \"string\") {\n\t\t// String registrations carry no explicit schema version; the events\n\t\t// registry treats the bare name as the initial version of the type.\n\t\treturn { eventType, schemaVersion: 1 };\n\t}\n\tconst normalized: ModuleManifestEventType = {\n\t\teventType: getEventTypeName(eventType),\n\t\tschemaVersion: eventType.schemaVersion,\n\t};\n\tif (eventType.description !== undefined) normalized.description = eventType.description;\n\tif (eventType.schema !== undefined) normalized.schema = cloneJson(eventType.schema);\n\treturn normalized;\n}\n\nfunction exportAction(action: ActionDefinition): ModuleManifestAction {\n\tassertSurfaceDeclaration(action, `Action \"${action?.actionId ?? \"unknown\"}\"`);\n\tassertAdapterStepDeadlines(action);\n\tconst manifest: ModuleManifestAction = {\n\t\tactionId: action.actionId,\n\t\tversion: action.version,\n\t\tkind: action.kind ?? \"atomic\",\n\t\tidempotent: action.idempotent,\n\t\tmutatesDomain: action.mutatesDomain,\n\t\temitsEvents: [...action.emitsEvents],\n\t};\n\n\tif (action.surface !== undefined) manifest.surface = action.surface;\n\tif (action.surfaceReason !== undefined) manifest.surfaceReason = action.surfaceReason;\n\tif (action.policies !== undefined) manifest.policies = [...action.policies];\n\tif (action.requiredRoles !== undefined) manifest.requiredRoles = [...action.requiredRoles];\n\tif (action.requiredPermissions !== undefined) {\n\t\tmanifest.requiredPermissions = [...action.requiredPermissions];\n\t}\n\tif (action.stagesInvocations !== undefined) manifest.stagesInvocations = [...action.stagesInvocations];\n\tif (action.eventPhase !== undefined) manifest.eventPhase = action.eventPhase;\n\tif (action.finalize !== undefined) manifest.finalization = { protocol: \"atomic-after-adapters-v1\" };\n\tif (action.execution !== undefined) manifest.execution = cloneJson(action.execution);\n\n\tif (isJsonSchemaExportableValidator(action.schema)) {\n\t\ttry {\n\t\t\tmanifest.parameterSchema = action.schema.toJSONSchema();\n\t\t\tmanifest.parameterSchemaFormat = \"json-schema\";\n\t\t} catch {\n\t\t\t// Runtime-valid schemas that cannot be represented portably remain executable;\n\t\t\t// build-time consumers see the schema as unavailable rather than crashing export.\n\t\t}\n\t}\n\tif (action.resultSchema && isJsonSchemaExportableValidator(action.resultSchema)) {\n\t\ttry {\n\t\t\tmanifest.resultSchema = action.resultSchema.toJSONSchema();\n\t\t\tmanifest.resultSchemaFormat = \"json-schema\";\n\t\t} catch {\n\t\t\t// See parameter-schema behavior above.\n\t\t}\n\t}\n\n\tif (action.stateMachine !== undefined) {\n\t\tconst binding: ModuleManifestActionStateMachine = {\n\t\t\tentityType: action.stateMachine.entityType,\n\t\t};\n\t\tif (typeof action.stateMachine.targetState === \"string\") {\n\t\t\tbinding.targetState = action.stateMachine.targetState;\n\t\t}\n\t\tmanifest.stateMachine = binding;\n\t}\n\n\tif (action.adapterSteps !== undefined) {\n\t\tmanifest.adapterSteps = action.adapterSteps.map((step) => {\n\t\t\tconst exported: ModuleManifestAdapterStep = {\n\t\t\t\tadapterType: step.adapterType,\n\t\t\t\toperation: step.operation,\n\t\t\t};\n\t\t\tif (step.retryPolicy !== undefined) exported.retryPolicy = { ...step.retryPolicy };\n\t\t\tif (step.deadlineMs !== undefined) exported.deadlineMs = step.deadlineMs;\n\t\t\treturn exported;\n\t\t});\n\t}\n\n\treturn manifest;\n}\n\nfunction exportPolicy(policy: unknown): ModuleManifestPolicy | undefined {\n\tif (!isRecord(policy) || typeof policy.policyId !== \"string\") {\n\t\treturn undefined;\n\t}\n\n\t// Code evaluator: identified by its `evaluate` function (never serialized).\n\tif (typeof policy.evaluate === \"function\") {\n\t\tconst exported: ModuleManifestCodePolicy = {\n\t\t\ttype: \"code\",\n\t\t\tpolicyId: policy.policyId,\n\t\t\tversion: typeof policy.version === \"number\" ? policy.version : 1,\n\t\t};\n\t\tif (typeof policy.previewSafe === \"boolean\") exported.previewSafe = policy.previewSafe;\n\t\treturn exported;\n\t}\n\n\t// Declarative runtime policy definition: pure data, serialized as-is.\n\tif (typeof policy.kind === \"string\" && typeof policy.policyVersion === \"number\") {\n\t\tconst exported: ModuleManifestDataPolicy = {\n\t\t\ttype: \"data\",\n\t\t\tpolicyId: policy.policyId,\n\t\t\tpolicyVersion: policy.policyVersion,\n\t\t\tkind: policy.kind as PolicyKind,\n\t\t};\n\t\tif (isRecord(policy.dataDefinition)) {\n\t\t\texported.dataDefinition = policy.dataDefinition as unknown as DataPolicyDefinition;\n\t\t}\n\t\tif (typeof policy.codeEvaluatorPolicyId === \"string\") {\n\t\t\texported.codeEvaluatorPolicyId = policy.codeEvaluatorPolicyId;\n\t\t}\n\t\tif (isRecord(policy.fallback)) {\n\t\t\texported.fallback = policy.fallback as unknown as PolicyFallbackDefinition;\n\t\t}\n\t\treturn exported;\n\t}\n\n\t// Unknown policy shape: omit rather than guess.\n\treturn undefined;\n}\n\nfunction exportStateMachine(machine: unknown): ModuleManifestStateMachine | undefined {\n\tif (\n\t\t!isRecord(machine) ||\n\t\ttypeof machine.entityType !== \"string\" ||\n\t\t!isRecord(machine.states) ||\n\t\t!Array.isArray(machine.transitions)\n\t) {\n\t\treturn undefined;\n\t}\n\n\tconst definition = machine as unknown as StateMachineDefinition;\n\treturn {\n\t\tentityType: definition.entityType,\n\t\tstates: Object.values(definition.states),\n\t\ttransitions: definition.transitions.map((transition) => ({\n\t\t\tfrom: transition.from,\n\t\t\tto: transition.to,\n\t\t\tcausedByAction: transition.causedByAction,\n\t\t\thasGuard: typeof transition.guard === \"function\",\n\t\t})),\n\t};\n}\n\nfunction exportView(view: ViewContract): ModuleManifestView {\n\tassertSurfaceDeclaration(view, `View \"${view?.name ?? \"unknown\"}\"`);\n\tconst output: ModuleManifestView = {\n\t\tname: view.name,\n\t\tversion: view.version,\n\t\tshape: cloneJson(view.shape),\n\t\tconsumes: view.consumes.map((consumption) => ({\n\t\t\teventType: consumption.eventType,\n\t\t\tschemaVersions: [...consumption.schemaVersions],\n\t\t})),\n\t\tscope: view.scope,\n\t\tsnapshotVersion: view.snapshotVersion,\n\t};\n\tif (view.surface !== undefined) output.surface = view.surface;\n\tif (view.surfaceReason !== undefined) output.surfaceReason = view.surfaceReason;\n\tif (view.parameterSchema !== undefined) output.parameterSchema = cloneJson(view.parameterSchema);\n\tif (view.compatibleSnapshotVersions) output.compatibleSnapshotVersions = [...view.compatibleSnapshotVersions];\n\tif (view.usage) output.usage = cloneJson(view.usage);\n\treturn output;\n}\n\n/**\n * Export a stable, JSON-serializable manifest of a module's ontology.\n *\n * This is a pure function of the module object: it does not read or mutate the\n * global module/action/policy/state-machine registries, and the module does\n * not need to be registered first. Declaration order is preserved everywhere\n * (nothing is sorted), so the same module object always produces a\n * byte-identical `JSON.stringify` result.\n *\n * The manifest contains definitions only — never raw parameter values,\n * secrets, or runtime data. Function fields are elided (`handler`,\n * policy `evaluate`, transition `guard` → `hasGuard`, dynamic `targetState`,\n * adapter `getInput`).\n */\nexport function exportModuleManifest(module: FabricModule<unknown>): ModuleManifest {\n\tconst manifest: ModuleManifest = {\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tnamespace: module.namespace,\n\t\tdependencies: (module.dependencies ?? []).map(exportDependency),\n\t\tobjectTypes: (module.objectTypes ?? []).map(exportObjectType),\n\t\tsubjectTypes: [...(module.subjectTypes ?? [])],\n\t\tidPrefixes: (module.idPrefixes ?? []).map((registration) => ({\n\t\t\tprefix: registration.prefix,\n\t\t\tname: registration.name,\n\t\t})),\n\t\teventTypes: (module.eventTypes ?? []).map(exportEventType),\n\t\tactions: (module.actions ?? []).map(exportAction),\n\t\tpolicies: (module.policies ?? [])\n\t\t\t.map(exportPolicy)\n\t\t\t.filter((policy): policy is ModuleManifestPolicy => policy !== undefined),\n\t\tstateMachines: (module.stateMachines ?? [])\n\t\t\t.map(exportStateMachine)\n\t\t\t.filter((machine): machine is ModuleManifestStateMachine => machine !== undefined),\n\t\tviews: (module.views ?? []).map(exportView),\n\t};\n\n\tif (module.version !== undefined) manifest.version = module.version;\n\tif (module.displayName !== undefined) manifest.displayName = module.displayName;\n\tif (module.description !== undefined) manifest.description = module.description;\n\tif (module.capability !== undefined) manifest.capability = cloneJson(module.capability);\n\n\treturn manifest;\n}\n\n/**\n * Export manifests for a set of modules, preserving the input order.\n * Like {@link exportModuleManifest}, this is pure and registry-free.\n */\nexport function exportModuleManifestBundle(\n\tmodules: FabricModule<unknown>[],\n): ModuleManifestBundle {\n\treturn {\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tmodules: modules.map(exportModuleManifest),\n\t};\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["getModuleDependencyNamespace","getObjectTypeName","getEventTypeName"],"sources":["../../manifest/index.ts"],"sourcesContent":["import { assertAdapterStepDeadlines } from \"../actions\";\nimport { assertSurfaceDeclaration, type SurfaceDeclaration } from \"../discovery\";\nimport type {\n\tActionExecutionContract,\n\tActionDefinition,\n\tAdapterStepRetryPolicy,\n\tSchemaValidator,\n} from \"../actions\";\nimport {\n\tgetEventTypeName,\n\tgetModuleDependencyNamespace,\n\tgetObjectTypeName,\n\ttype FabricModule,\n\ttype CapabilityMetadata,\n\ttype DeclarativeInvariant,\n\ttype ModuleDependency,\n\ttype ModuleDependencyInput,\n\ttype ObjectRelationDefinition,\n} from \"../modules\";\nimport type { JsonValue, PortableJsonSchema } from \"../objects\";\nimport type {\n\tDataPolicyDefinition,\n\tPolicyFallbackDefinition,\n\tPolicyKind,\n} from \"../policies\";\nimport type { StateDefinition, StateMachineDefinition } from \"../state-machines\";\nimport type { ViewContract } from \"../projections\";\n\n/**\n * Version of the module manifest contract. Bump when the serialized shape\n * changes in a way consumers must detect.\n */\nexport const MODULE_MANIFEST_VERSION = 2 as const;\n\nexport interface ModuleManifestObjectType {\n\ttype: string;\n\tdisplayName?: string;\n\tidPrefix?: string;\n\tschema?: PortableJsonSchema;\n\tsemantics?: Record<string, JsonValue>;\n\trelations?: ObjectRelationDefinition[];\n\tinvariants?: DeclarativeInvariant[];\n}\n\nexport interface ModuleManifestIdPrefix {\n\tprefix: string;\n\tname: string;\n}\n\nexport interface ModuleManifestEventType {\n\teventType: string;\n\tschemaVersion: number;\n\tdescription?: string;\n\tschema?: PortableJsonSchema;\n}\n\nexport interface ModuleManifestActionStateMachine {\n\tentityType: string;\n\t/** Present only when the binding declares a static target state. */\n\ttargetState?: string;\n}\n\nexport interface ModuleManifestAdapterStep {\n\tadapterType: string;\n\toperation: string;\n\tretryPolicy?: AdapterStepRetryPolicy;\n\t/** Positive finite integer duration in milliseconds; overrides Host adapterDeadlineMs for this step. */\n\tdeadlineMs?: number;\n}\n\nexport interface ModuleManifestAction extends SurfaceDeclaration {\n\tactionId: string;\n\tversion: number;\n\tkind: \"atomic\" | \"saga\";\n\tidempotent: boolean;\n\tmutatesDomain: boolean;\n\temitsEvents: string[];\n\tpolicies?: string[];\n\trequiredRoles?: string[];\n\trequiredPermissions?: string[];\n\tstagesInvocations?: string[];\n\tstagedInvocationPrincipals?: Record<string, string>;\n\teventPhase?: \"before_adapters\" | \"after_adapters\";\n\tfinalization?: { protocol: \"atomic-after-adapters-v1\" };\n\texecution?: ActionExecutionContract;\n\t/**\n\t * JSON Schema for the action parameters, present only when the action's\n\t * `schema` validator implements {@link JsonSchemaExportableValidator}.\n\t */\n\tparameterSchema?: unknown;\n\tparameterSchemaFormat?: \"json-schema\";\n\tresultSchema?: unknown;\n\tresultSchemaFormat?: \"json-schema\";\n\tstateMachine?: ModuleManifestActionStateMachine;\n\tadapterSteps?: ModuleManifestAdapterStep[];\n}\n\nexport interface ModuleManifestCodePolicy {\n\ttype: \"code\";\n\tpolicyId: string;\n\tversion: number;\n\tpreviewSafe?: boolean;\n}\n\nexport interface ModuleManifestDataPolicy {\n\ttype: \"data\";\n\tpolicyId: string;\n\tpolicyVersion: number;\n\tkind: PolicyKind;\n\tdataDefinition?: DataPolicyDefinition;\n\tcodeEvaluatorPolicyId?: string;\n\tfallback?: PolicyFallbackDefinition;\n}\n\nexport type ModuleManifestPolicy = ModuleManifestCodePolicy | ModuleManifestDataPolicy;\n\nexport interface ModuleManifestStateMachineTransition {\n\tfrom: string;\n\tto: string;\n\tcausedByAction: string;\n\t/** `true` when the transition declares a guard function. The guard itself is never serialized. */\n\thasGuard: boolean;\n}\n\nexport interface ModuleManifestStateMachine {\n\tentityType: string;\n\t/** States in declaration order (`Object.values` order of the definition record). */\n\tstates: StateDefinition[];\n\ttransitions: ModuleManifestStateMachineTransition[];\n}\n\nexport interface ModuleManifestView extends SurfaceDeclaration {\n\tname: string;\n\tversion: string;\n\tshape: PortableJsonSchema;\n\tparameterSchema?: PortableJsonSchema;\n\tconsumes: Array<{ eventType: string; schemaVersions: number[] }>;\n\tscope: \"tenant-space\";\n\tsnapshotVersion: number;\n\tcompatibleSnapshotVersions?: number[];\n\tusage?: ViewContract[\"usage\"];\n}\n\n/**\n * Stable, JSON-serializable description of a {@link FabricModule}'s ontology:\n * object types, subject types, id prefixes, event types, actions, policies,\n * and state machines. Intended for downstream tooling (semantics exporters,\n * docs generators, tool generators) that cannot consume live module code.\n *\n * The manifest contains definitions only — never raw parameter values,\n * secrets, or runtime data. Function fields (`handler`, `evaluate`, `guard`,\n * dynamic `targetState`, adapter `getInput`) are never serialized.\n */\nexport interface ModuleManifest {\n\tmanifestVersion: typeof MODULE_MANIFEST_VERSION;\n\tnamespace: string;\n\tversion?: string;\n\tdisplayName?: string;\n\tdescription?: string;\n\tcapability?: CapabilityMetadata;\n\tdependencies: ModuleDependency[];\n\tobjectTypes: ModuleManifestObjectType[];\n\tsubjectTypes: string[];\n\tidPrefixes: ModuleManifestIdPrefix[];\n\teventTypes: ModuleManifestEventType[];\n\tactions: ModuleManifestAction[];\n\tpolicies: ModuleManifestPolicy[];\n\tstateMachines: ModuleManifestStateMachine[];\n\tviews: ModuleManifestView[];\n}\n\nexport interface ModuleManifestBundle {\n\tmanifestVersion: typeof MODULE_MANIFEST_VERSION;\n\t/** Manifests in the input module order. */\n\tmodules: ModuleManifest[];\n}\n\n/** Manifest v1 remains accepted by v2 readers; missing v2 fields normalize to absence. */\nexport type ModuleManifestObjectTypeV1 = Omit<\n\tModuleManifestObjectType,\n\t\"schema\" | \"semantics\" | \"relations\" | \"invariants\"\n>;\nexport type ModuleManifestActionV1 = Omit<\n\tModuleManifestAction,\n\t\"resultSchema\" | \"resultSchemaFormat\"\n>;\nexport type ModuleManifestV1 = Omit<\n\tModuleManifest,\n\t\"manifestVersion\" | \"objectTypes\" | \"actions\" | \"views\"\n> & {\n\tmanifestVersion: 1;\n\tobjectTypes: ModuleManifestObjectTypeV1[];\n\tactions: ModuleManifestActionV1[];\n};\nexport type ModuleManifestBundleV1 = Omit<ModuleManifestBundle, \"manifestVersion\" | \"modules\"> & {\n\tmanifestVersion: 1;\n\tmodules: ModuleManifestV1[];\n};\n\nexport function normalizeModuleManifest(\n\tmanifest: ModuleManifest | ModuleManifestV1,\n): ModuleManifest {\n\tconst version: number = manifest.manifestVersion;\n\tif (version !== 1 && version !== MODULE_MANIFEST_VERSION) {\n\t\tthrow new Error(`Unsupported module manifest version: ${String(version)}`);\n\t}\n\tconst views = \"views\" in manifest && Array.isArray(manifest.views) ? manifest.views : [];\n\t// Preserve the normalizer's legacy tolerance for absent/non-array fields.\n\tif (Array.isArray(manifest.actions))\n\t\tfor (const [index, action] of manifest.actions.entries()) {\n\t\t\tassertSurfaceDeclaration(action, `Module \"${manifest.namespace}\" action[${index}] \"${action?.actionId ?? \"unknown\"}\"`);\n\t\t\tassertAdapterStepDeadlines(action);\n\t\t\tif (action.finalization !== undefined) {\n\t\t\t\tconst descriptor = action.finalization;\n\t\t\t\tif (!descriptor || typeof descriptor !== \"object\" || Array.isArray(descriptor) ||\n\t\t\t\t\tObject.keys(descriptor).some(key => key !== \"protocol\") || descriptor.protocol !== \"atomic-after-adapters-v1\")\n\t\t\t\t\tthrow new Error(\"Invalid action finalization protocol descriptor.\");\n\t\t\t\tif (action.eventPhase !== \"after_adapters\" || (action.kind !== undefined && action.kind !== \"atomic\") ||\n\t\t\t\t\t(action.execution?.completion !== undefined && action.execution.completion !== \"immediate\"))\n\t\t\t\t\tthrow new Error(\"Incompatible action finalization declaration.\");\n\t\t\t}\n\t\t}\n\tfor (const [index, view] of views.entries())\n\t\tassertSurfaceDeclaration(view, `Module \"${manifest.namespace}\" view[${index}] \"${view?.name ?? \"unknown\"}\"`);\n\treturn {\n\t\t...manifest,\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tviews,\n\t};\n}\n\nexport function normalizeModuleManifestBundle(\n\tbundle: ModuleManifestBundle | ModuleManifestBundleV1,\n): ModuleManifestBundle {\n\tconst version: number = bundle.manifestVersion;\n\tif (version !== 1 && version !== MODULE_MANIFEST_VERSION) {\n\t\tthrow new Error(`Unsupported module manifest bundle version: ${String(version)}`);\n\t}\n\treturn {\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tmodules: bundle.modules.map((manifest) => normalizeModuleManifest(manifest)),\n\t};\n}\n\n/**\n * A {@link SchemaValidator} that can also export its parameter schema as JSON\n * Schema (for example a Zod 4 schema via `z.toJSONSchema`). Keeps the platform\n * zero-dependency while letting schema-bearing actions flow into manifests.\n */\nexport interface JsonSchemaExportableValidator extends SchemaValidator {\n\ttoJSONSchema(): Record<string, unknown>;\n}\n\nexport function isJsonSchemaExportableValidator(\n\tschema: SchemaValidator,\n): schema is JsonSchemaExportableValidator {\n\treturn (\n\t\ttypeof (schema as Partial<JsonSchemaExportableValidator>).toJSONSchema === \"function\"\n\t);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction exportDependency(dependency: ModuleDependencyInput): ModuleDependency {\n\tconst namespace = getModuleDependencyNamespace(dependency);\n\tif (typeof dependency === \"string\") {\n\t\treturn { namespace };\n\t}\n\tconst normalized: ModuleDependency = { namespace };\n\tif (dependency.version !== undefined) normalized.version = dependency.version;\n\tif (dependency.optional !== undefined) normalized.optional = dependency.optional;\n\treturn normalized;\n}\n\nfunction exportObjectType(\n\tobjectType: NonNullable<FabricModule[\"objectTypes\"]>[number],\n): ModuleManifestObjectType {\n\tif (typeof objectType === \"string\") {\n\t\treturn { type: objectType };\n\t}\n\tconst normalized: ModuleManifestObjectType = { type: getObjectTypeName(objectType) };\n\tif (objectType.displayName !== undefined) normalized.displayName = objectType.displayName;\n\tif (objectType.idPrefix !== undefined) normalized.idPrefix = objectType.idPrefix;\n\tif (objectType.schema !== undefined) normalized.schema = cloneJson(objectType.schema);\n\tif (objectType.semantics !== undefined) normalized.semantics = cloneJson(objectType.semantics);\n\tif (objectType.relations !== undefined) {\n\t\tnormalized.relations = objectType.relations.map((relation) => ({ ...relation }));\n\t}\n\tif (objectType.invariants !== undefined) {\n\t\tnormalized.invariants = objectType.invariants.map((invariant) => ({ ...invariant }));\n\t}\n\treturn normalized;\n}\n\nfunction cloneJson<T>(value: T): T {\n\tif (Array.isArray(value)) return value.map((item) => cloneJson(item)) as T;\n\tif (value !== null && typeof value === \"object\") {\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(value as Record<string, unknown>).map(([key, child]) => [key, cloneJson(child)]),\n\t\t) as T;\n\t}\n\treturn value;\n}\n\nfunction exportEventType(\n\teventType: NonNullable<FabricModule[\"eventTypes\"]>[number],\n): ModuleManifestEventType {\n\tif (typeof eventType === \"string\") {\n\t\t// String registrations carry no explicit schema version; the events\n\t\t// registry treats the bare name as the initial version of the type.\n\t\treturn { eventType, schemaVersion: 1 };\n\t}\n\tconst normalized: ModuleManifestEventType = {\n\t\teventType: getEventTypeName(eventType),\n\t\tschemaVersion: eventType.schemaVersion,\n\t};\n\tif (eventType.description !== undefined) normalized.description = eventType.description;\n\tif (eventType.schema !== undefined) normalized.schema = cloneJson(eventType.schema);\n\treturn normalized;\n}\n\nfunction exportAction(action: ActionDefinition): ModuleManifestAction {\n\tassertSurfaceDeclaration(action, `Action \"${action?.actionId ?? \"unknown\"}\"`);\n\tassertAdapterStepDeadlines(action);\n\tconst manifest: ModuleManifestAction = {\n\t\tactionId: action.actionId,\n\t\tversion: action.version,\n\t\tkind: action.kind ?? \"atomic\",\n\t\tidempotent: action.idempotent,\n\t\tmutatesDomain: action.mutatesDomain,\n\t\temitsEvents: [...action.emitsEvents],\n\t};\n\n\tif (action.surface !== undefined) manifest.surface = action.surface;\n\tif (action.surfaceReason !== undefined) manifest.surfaceReason = action.surfaceReason;\n\tif (action.policies !== undefined) manifest.policies = [...action.policies];\n\tif (action.requiredRoles !== undefined) manifest.requiredRoles = [...action.requiredRoles];\n\tif (action.requiredPermissions !== undefined) {\n\t\tmanifest.requiredPermissions = [...action.requiredPermissions];\n\t}\n\tif (action.stagesInvocations !== undefined) manifest.stagesInvocations = [...action.stagesInvocations];\n\tif (action.stagedInvocationPrincipals !== undefined) {\n\t\tmanifest.stagedInvocationPrincipals = Object.fromEntries(\n\t\t\tObject.entries(action.stagedInvocationPrincipals).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0),\n\t\t);\n\t}\n\tif (action.eventPhase !== undefined) manifest.eventPhase = action.eventPhase;\n\tif (action.finalize !== undefined) manifest.finalization = { protocol: \"atomic-after-adapters-v1\" };\n\tif (action.execution !== undefined) manifest.execution = cloneJson(action.execution);\n\n\tif (isJsonSchemaExportableValidator(action.schema)) {\n\t\ttry {\n\t\t\tmanifest.parameterSchema = action.schema.toJSONSchema();\n\t\t\tmanifest.parameterSchemaFormat = \"json-schema\";\n\t\t} catch {\n\t\t\t// Runtime-valid schemas that cannot be represented portably remain executable;\n\t\t\t// build-time consumers see the schema as unavailable rather than crashing export.\n\t\t}\n\t}\n\tif (action.resultSchema && isJsonSchemaExportableValidator(action.resultSchema)) {\n\t\ttry {\n\t\t\tmanifest.resultSchema = action.resultSchema.toJSONSchema();\n\t\t\tmanifest.resultSchemaFormat = \"json-schema\";\n\t\t} catch {\n\t\t\t// See parameter-schema behavior above.\n\t\t}\n\t}\n\n\tif (action.stateMachine !== undefined) {\n\t\tconst binding: ModuleManifestActionStateMachine = {\n\t\t\tentityType: action.stateMachine.entityType,\n\t\t};\n\t\tif (typeof action.stateMachine.targetState === \"string\") {\n\t\t\tbinding.targetState = action.stateMachine.targetState;\n\t\t}\n\t\tmanifest.stateMachine = binding;\n\t}\n\n\tif (action.adapterSteps !== undefined) {\n\t\tmanifest.adapterSteps = action.adapterSteps.map((step) => {\n\t\t\tconst exported: ModuleManifestAdapterStep = {\n\t\t\t\tadapterType: step.adapterType,\n\t\t\t\toperation: step.operation,\n\t\t\t};\n\t\t\tif (step.retryPolicy !== undefined) exported.retryPolicy = { ...step.retryPolicy };\n\t\t\tif (step.deadlineMs !== undefined) exported.deadlineMs = step.deadlineMs;\n\t\t\treturn exported;\n\t\t});\n\t}\n\n\treturn manifest;\n}\n\nfunction exportPolicy(policy: unknown): ModuleManifestPolicy | undefined {\n\tif (!isRecord(policy) || typeof policy.policyId !== \"string\") {\n\t\treturn undefined;\n\t}\n\n\t// Code evaluator: identified by its `evaluate` function (never serialized).\n\tif (typeof policy.evaluate === \"function\") {\n\t\tconst exported: ModuleManifestCodePolicy = {\n\t\t\ttype: \"code\",\n\t\t\tpolicyId: policy.policyId,\n\t\t\tversion: typeof policy.version === \"number\" ? policy.version : 1,\n\t\t};\n\t\tif (typeof policy.previewSafe === \"boolean\") exported.previewSafe = policy.previewSafe;\n\t\treturn exported;\n\t}\n\n\t// Declarative runtime policy definition: pure data, serialized as-is.\n\tif (typeof policy.kind === \"string\" && typeof policy.policyVersion === \"number\") {\n\t\tconst exported: ModuleManifestDataPolicy = {\n\t\t\ttype: \"data\",\n\t\t\tpolicyId: policy.policyId,\n\t\t\tpolicyVersion: policy.policyVersion,\n\t\t\tkind: policy.kind as PolicyKind,\n\t\t};\n\t\tif (isRecord(policy.dataDefinition)) {\n\t\t\texported.dataDefinition = policy.dataDefinition as unknown as DataPolicyDefinition;\n\t\t}\n\t\tif (typeof policy.codeEvaluatorPolicyId === \"string\") {\n\t\t\texported.codeEvaluatorPolicyId = policy.codeEvaluatorPolicyId;\n\t\t}\n\t\tif (isRecord(policy.fallback)) {\n\t\t\texported.fallback = policy.fallback as unknown as PolicyFallbackDefinition;\n\t\t}\n\t\treturn exported;\n\t}\n\n\t// Unknown policy shape: omit rather than guess.\n\treturn undefined;\n}\n\nfunction exportStateMachine(machine: unknown): ModuleManifestStateMachine | undefined {\n\tif (\n\t\t!isRecord(machine) ||\n\t\ttypeof machine.entityType !== \"string\" ||\n\t\t!isRecord(machine.states) ||\n\t\t!Array.isArray(machine.transitions)\n\t) {\n\t\treturn undefined;\n\t}\n\n\tconst definition = machine as unknown as StateMachineDefinition;\n\treturn {\n\t\tentityType: definition.entityType,\n\t\tstates: Object.values(definition.states),\n\t\ttransitions: definition.transitions.map((transition) => ({\n\t\t\tfrom: transition.from,\n\t\t\tto: transition.to,\n\t\t\tcausedByAction: transition.causedByAction,\n\t\t\thasGuard: typeof transition.guard === \"function\",\n\t\t})),\n\t};\n}\n\nfunction exportView(view: ViewContract): ModuleManifestView {\n\tassertSurfaceDeclaration(view, `View \"${view?.name ?? \"unknown\"}\"`);\n\tconst output: ModuleManifestView = {\n\t\tname: view.name,\n\t\tversion: view.version,\n\t\tshape: cloneJson(view.shape),\n\t\tconsumes: view.consumes.map((consumption) => ({\n\t\t\teventType: consumption.eventType,\n\t\t\tschemaVersions: [...consumption.schemaVersions],\n\t\t})),\n\t\tscope: view.scope,\n\t\tsnapshotVersion: view.snapshotVersion,\n\t};\n\tif (view.surface !== undefined) output.surface = view.surface;\n\tif (view.surfaceReason !== undefined) output.surfaceReason = view.surfaceReason;\n\tif (view.parameterSchema !== undefined) output.parameterSchema = cloneJson(view.parameterSchema);\n\tif (view.compatibleSnapshotVersions) output.compatibleSnapshotVersions = [...view.compatibleSnapshotVersions];\n\tif (view.usage) output.usage = cloneJson(view.usage);\n\treturn output;\n}\n\n/**\n * Export a stable, JSON-serializable manifest of a module's ontology.\n *\n * This is a pure function of the module object: it does not read or mutate the\n * global module/action/policy/state-machine registries, and the module does\n * not need to be registered first. Declaration order is preserved everywhere\n * (nothing is sorted), so the same module object always produces a\n * byte-identical `JSON.stringify` result.\n *\n * The manifest contains definitions only — never raw parameter values,\n * secrets, or runtime data. Function fields are elided (`handler`,\n * policy `evaluate`, transition `guard` → `hasGuard`, dynamic `targetState`,\n * adapter `getInput`).\n */\nexport function exportModuleManifest(module: FabricModule<unknown>): ModuleManifest {\n\tconst manifest: ModuleManifest = {\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tnamespace: module.namespace,\n\t\tdependencies: (module.dependencies ?? []).map(exportDependency),\n\t\tobjectTypes: (module.objectTypes ?? []).map(exportObjectType),\n\t\tsubjectTypes: [...(module.subjectTypes ?? [])],\n\t\tidPrefixes: (module.idPrefixes ?? []).map((registration) => ({\n\t\t\tprefix: registration.prefix,\n\t\t\tname: registration.name,\n\t\t})),\n\t\teventTypes: (module.eventTypes ?? []).map(exportEventType),\n\t\tactions: (module.actions ?? []).map(exportAction),\n\t\tpolicies: (module.policies ?? [])\n\t\t\t.map(exportPolicy)\n\t\t\t.filter((policy): policy is ModuleManifestPolicy => policy !== undefined),\n\t\tstateMachines: (module.stateMachines ?? [])\n\t\t\t.map(exportStateMachine)\n\t\t\t.filter((machine): machine is ModuleManifestStateMachine => machine !== undefined),\n\t\tviews: (module.views ?? []).map(exportView),\n\t};\n\n\tif (module.version !== undefined) manifest.version = module.version;\n\tif (module.displayName !== undefined) manifest.displayName = module.displayName;\n\tif (module.description !== undefined) manifest.description = module.description;\n\tif (module.capability !== undefined) manifest.capability = cloneJson(module.capability);\n\n\treturn manifest;\n}\n\n/**\n * Export manifests for a set of modules, preserving the input order.\n * Like {@link exportModuleManifest}, this is pure and registry-free.\n */\nexport function exportModuleManifestBundle(\n\tmodules: FabricModule<unknown>[],\n): ModuleManifestBundle {\n\treturn {\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tmodules: modules.map(exportModuleManifest),\n\t};\n}\n"],"mappings":"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"}
|
|
@@ -53,6 +53,7 @@ export interface ModuleManifestAction extends SurfaceDeclaration {
|
|
|
53
53
|
requiredRoles?: string[];
|
|
54
54
|
requiredPermissions?: string[];
|
|
55
55
|
stagesInvocations?: string[];
|
|
56
|
+
stagedInvocationPrincipals?: Record<string, string>;
|
|
56
57
|
eventPhase?: "before_adapters" | "after_adapters";
|
|
57
58
|
finalization?: {
|
|
58
59
|
protocol: "atomic-after-adapters-v1";
|
package/dist/manifest/index.d.ts
CHANGED
|
@@ -53,6 +53,7 @@ export interface ModuleManifestAction extends SurfaceDeclaration {
|
|
|
53
53
|
requiredRoles?: string[];
|
|
54
54
|
requiredPermissions?: string[];
|
|
55
55
|
stagesInvocations?: string[];
|
|
56
|
+
stagedInvocationPrincipals?: Record<string, string>;
|
|
56
57
|
eventPhase?: "before_adapters" | "after_adapters";
|
|
57
58
|
finalization?: {
|
|
58
59
|
protocol: "atomic-after-adapters-v1";
|
package/dist/manifest/index.js
CHANGED
|
@@ -95,6 +95,7 @@ function exportAction(action) {
|
|
|
95
95
|
if (action.requiredRoles !== void 0) manifest.requiredRoles = [...action.requiredRoles];
|
|
96
96
|
if (action.requiredPermissions !== void 0) manifest.requiredPermissions = [...action.requiredPermissions];
|
|
97
97
|
if (action.stagesInvocations !== void 0) manifest.stagesInvocations = [...action.stagesInvocations];
|
|
98
|
+
if (action.stagedInvocationPrincipals !== void 0) manifest.stagedInvocationPrincipals = Object.fromEntries(Object.entries(action.stagedInvocationPrincipals).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0));
|
|
98
99
|
if (action.eventPhase !== void 0) manifest.eventPhase = action.eventPhase;
|
|
99
100
|
if (action.finalize !== void 0) manifest.finalization = { protocol: "atomic-after-adapters-v1" };
|
|
100
101
|
if (action.execution !== void 0) manifest.execution = cloneJson(action.execution);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../manifest/index.ts"],"sourcesContent":["import { assertAdapterStepDeadlines } from \"../actions\";\nimport { assertSurfaceDeclaration, type SurfaceDeclaration } from \"../discovery\";\nimport type {\n\tActionExecutionContract,\n\tActionDefinition,\n\tAdapterStepRetryPolicy,\n\tSchemaValidator,\n} from \"../actions\";\nimport {\n\tgetEventTypeName,\n\tgetModuleDependencyNamespace,\n\tgetObjectTypeName,\n\ttype FabricModule,\n\ttype CapabilityMetadata,\n\ttype DeclarativeInvariant,\n\ttype ModuleDependency,\n\ttype ModuleDependencyInput,\n\ttype ObjectRelationDefinition,\n} from \"../modules\";\nimport type { JsonValue, PortableJsonSchema } from \"../objects\";\nimport type {\n\tDataPolicyDefinition,\n\tPolicyFallbackDefinition,\n\tPolicyKind,\n} from \"../policies\";\nimport type { StateDefinition, StateMachineDefinition } from \"../state-machines\";\nimport type { ViewContract } from \"../projections\";\n\n/**\n * Version of the module manifest contract. Bump when the serialized shape\n * changes in a way consumers must detect.\n */\nexport const MODULE_MANIFEST_VERSION = 2 as const;\n\nexport interface ModuleManifestObjectType {\n\ttype: string;\n\tdisplayName?: string;\n\tidPrefix?: string;\n\tschema?: PortableJsonSchema;\n\tsemantics?: Record<string, JsonValue>;\n\trelations?: ObjectRelationDefinition[];\n\tinvariants?: DeclarativeInvariant[];\n}\n\nexport interface ModuleManifestIdPrefix {\n\tprefix: string;\n\tname: string;\n}\n\nexport interface ModuleManifestEventType {\n\teventType: string;\n\tschemaVersion: number;\n\tdescription?: string;\n\tschema?: PortableJsonSchema;\n}\n\nexport interface ModuleManifestActionStateMachine {\n\tentityType: string;\n\t/** Present only when the binding declares a static target state. */\n\ttargetState?: string;\n}\n\nexport interface ModuleManifestAdapterStep {\n\tadapterType: string;\n\toperation: string;\n\tretryPolicy?: AdapterStepRetryPolicy;\n\t/** Positive finite integer duration in milliseconds; overrides Host adapterDeadlineMs for this step. */\n\tdeadlineMs?: number;\n}\n\nexport interface ModuleManifestAction extends SurfaceDeclaration {\n\tactionId: string;\n\tversion: number;\n\tkind: \"atomic\" | \"saga\";\n\tidempotent: boolean;\n\tmutatesDomain: boolean;\n\temitsEvents: string[];\n\tpolicies?: string[];\n\trequiredRoles?: string[];\n\trequiredPermissions?: string[];\n\tstagesInvocations?: string[];\n\teventPhase?: \"before_adapters\" | \"after_adapters\";\n\tfinalization?: { protocol: \"atomic-after-adapters-v1\" };\n\texecution?: ActionExecutionContract;\n\t/**\n\t * JSON Schema for the action parameters, present only when the action's\n\t * `schema` validator implements {@link JsonSchemaExportableValidator}.\n\t */\n\tparameterSchema?: unknown;\n\tparameterSchemaFormat?: \"json-schema\";\n\tresultSchema?: unknown;\n\tresultSchemaFormat?: \"json-schema\";\n\tstateMachine?: ModuleManifestActionStateMachine;\n\tadapterSteps?: ModuleManifestAdapterStep[];\n}\n\nexport interface ModuleManifestCodePolicy {\n\ttype: \"code\";\n\tpolicyId: string;\n\tversion: number;\n\tpreviewSafe?: boolean;\n}\n\nexport interface ModuleManifestDataPolicy {\n\ttype: \"data\";\n\tpolicyId: string;\n\tpolicyVersion: number;\n\tkind: PolicyKind;\n\tdataDefinition?: DataPolicyDefinition;\n\tcodeEvaluatorPolicyId?: string;\n\tfallback?: PolicyFallbackDefinition;\n}\n\nexport type ModuleManifestPolicy = ModuleManifestCodePolicy | ModuleManifestDataPolicy;\n\nexport interface ModuleManifestStateMachineTransition {\n\tfrom: string;\n\tto: string;\n\tcausedByAction: string;\n\t/** `true` when the transition declares a guard function. The guard itself is never serialized. */\n\thasGuard: boolean;\n}\n\nexport interface ModuleManifestStateMachine {\n\tentityType: string;\n\t/** States in declaration order (`Object.values` order of the definition record). */\n\tstates: StateDefinition[];\n\ttransitions: ModuleManifestStateMachineTransition[];\n}\n\nexport interface ModuleManifestView extends SurfaceDeclaration {\n\tname: string;\n\tversion: string;\n\tshape: PortableJsonSchema;\n\tparameterSchema?: PortableJsonSchema;\n\tconsumes: Array<{ eventType: string; schemaVersions: number[] }>;\n\tscope: \"tenant-space\";\n\tsnapshotVersion: number;\n\tcompatibleSnapshotVersions?: number[];\n\tusage?: ViewContract[\"usage\"];\n}\n\n/**\n * Stable, JSON-serializable description of a {@link FabricModule}'s ontology:\n * object types, subject types, id prefixes, event types, actions, policies,\n * and state machines. Intended for downstream tooling (semantics exporters,\n * docs generators, tool generators) that cannot consume live module code.\n *\n * The manifest contains definitions only — never raw parameter values,\n * secrets, or runtime data. Function fields (`handler`, `evaluate`, `guard`,\n * dynamic `targetState`, adapter `getInput`) are never serialized.\n */\nexport interface ModuleManifest {\n\tmanifestVersion: typeof MODULE_MANIFEST_VERSION;\n\tnamespace: string;\n\tversion?: string;\n\tdisplayName?: string;\n\tdescription?: string;\n\tcapability?: CapabilityMetadata;\n\tdependencies: ModuleDependency[];\n\tobjectTypes: ModuleManifestObjectType[];\n\tsubjectTypes: string[];\n\tidPrefixes: ModuleManifestIdPrefix[];\n\teventTypes: ModuleManifestEventType[];\n\tactions: ModuleManifestAction[];\n\tpolicies: ModuleManifestPolicy[];\n\tstateMachines: ModuleManifestStateMachine[];\n\tviews: ModuleManifestView[];\n}\n\nexport interface ModuleManifestBundle {\n\tmanifestVersion: typeof MODULE_MANIFEST_VERSION;\n\t/** Manifests in the input module order. */\n\tmodules: ModuleManifest[];\n}\n\n/** Manifest v1 remains accepted by v2 readers; missing v2 fields normalize to absence. */\nexport type ModuleManifestObjectTypeV1 = Omit<\n\tModuleManifestObjectType,\n\t\"schema\" | \"semantics\" | \"relations\" | \"invariants\"\n>;\nexport type ModuleManifestActionV1 = Omit<\n\tModuleManifestAction,\n\t\"resultSchema\" | \"resultSchemaFormat\"\n>;\nexport type ModuleManifestV1 = Omit<\n\tModuleManifest,\n\t\"manifestVersion\" | \"objectTypes\" | \"actions\" | \"views\"\n> & {\n\tmanifestVersion: 1;\n\tobjectTypes: ModuleManifestObjectTypeV1[];\n\tactions: ModuleManifestActionV1[];\n};\nexport type ModuleManifestBundleV1 = Omit<ModuleManifestBundle, \"manifestVersion\" | \"modules\"> & {\n\tmanifestVersion: 1;\n\tmodules: ModuleManifestV1[];\n};\n\nexport function normalizeModuleManifest(\n\tmanifest: ModuleManifest | ModuleManifestV1,\n): ModuleManifest {\n\tconst version: number = manifest.manifestVersion;\n\tif (version !== 1 && version !== MODULE_MANIFEST_VERSION) {\n\t\tthrow new Error(`Unsupported module manifest version: ${String(version)}`);\n\t}\n\tconst views = \"views\" in manifest && Array.isArray(manifest.views) ? manifest.views : [];\n\t// Preserve the normalizer's legacy tolerance for absent/non-array fields.\n\tif (Array.isArray(manifest.actions))\n\t\tfor (const [index, action] of manifest.actions.entries()) {\n\t\t\tassertSurfaceDeclaration(action, `Module \"${manifest.namespace}\" action[${index}] \"${action?.actionId ?? \"unknown\"}\"`);\n\t\t\tassertAdapterStepDeadlines(action);\n\t\t\tif (action.finalization !== undefined) {\n\t\t\t\tconst descriptor = action.finalization;\n\t\t\t\tif (!descriptor || typeof descriptor !== \"object\" || Array.isArray(descriptor) ||\n\t\t\t\t\tObject.keys(descriptor).some(key => key !== \"protocol\") || descriptor.protocol !== \"atomic-after-adapters-v1\")\n\t\t\t\t\tthrow new Error(\"Invalid action finalization protocol descriptor.\");\n\t\t\t\tif (action.eventPhase !== \"after_adapters\" || (action.kind !== undefined && action.kind !== \"atomic\") ||\n\t\t\t\t\t(action.execution?.completion !== undefined && action.execution.completion !== \"immediate\"))\n\t\t\t\t\tthrow new Error(\"Incompatible action finalization declaration.\");\n\t\t\t}\n\t\t}\n\tfor (const [index, view] of views.entries())\n\t\tassertSurfaceDeclaration(view, `Module \"${manifest.namespace}\" view[${index}] \"${view?.name ?? \"unknown\"}\"`);\n\treturn {\n\t\t...manifest,\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tviews,\n\t};\n}\n\nexport function normalizeModuleManifestBundle(\n\tbundle: ModuleManifestBundle | ModuleManifestBundleV1,\n): ModuleManifestBundle {\n\tconst version: number = bundle.manifestVersion;\n\tif (version !== 1 && version !== MODULE_MANIFEST_VERSION) {\n\t\tthrow new Error(`Unsupported module manifest bundle version: ${String(version)}`);\n\t}\n\treturn {\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tmodules: bundle.modules.map((manifest) => normalizeModuleManifest(manifest)),\n\t};\n}\n\n/**\n * A {@link SchemaValidator} that can also export its parameter schema as JSON\n * Schema (for example a Zod 4 schema via `z.toJSONSchema`). Keeps the platform\n * zero-dependency while letting schema-bearing actions flow into manifests.\n */\nexport interface JsonSchemaExportableValidator extends SchemaValidator {\n\ttoJSONSchema(): Record<string, unknown>;\n}\n\nexport function isJsonSchemaExportableValidator(\n\tschema: SchemaValidator,\n): schema is JsonSchemaExportableValidator {\n\treturn (\n\t\ttypeof (schema as Partial<JsonSchemaExportableValidator>).toJSONSchema === \"function\"\n\t);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction exportDependency(dependency: ModuleDependencyInput): ModuleDependency {\n\tconst namespace = getModuleDependencyNamespace(dependency);\n\tif (typeof dependency === \"string\") {\n\t\treturn { namespace };\n\t}\n\tconst normalized: ModuleDependency = { namespace };\n\tif (dependency.version !== undefined) normalized.version = dependency.version;\n\tif (dependency.optional !== undefined) normalized.optional = dependency.optional;\n\treturn normalized;\n}\n\nfunction exportObjectType(\n\tobjectType: NonNullable<FabricModule[\"objectTypes\"]>[number],\n): ModuleManifestObjectType {\n\tif (typeof objectType === \"string\") {\n\t\treturn { type: objectType };\n\t}\n\tconst normalized: ModuleManifestObjectType = { type: getObjectTypeName(objectType) };\n\tif (objectType.displayName !== undefined) normalized.displayName = objectType.displayName;\n\tif (objectType.idPrefix !== undefined) normalized.idPrefix = objectType.idPrefix;\n\tif (objectType.schema !== undefined) normalized.schema = cloneJson(objectType.schema);\n\tif (objectType.semantics !== undefined) normalized.semantics = cloneJson(objectType.semantics);\n\tif (objectType.relations !== undefined) {\n\t\tnormalized.relations = objectType.relations.map((relation) => ({ ...relation }));\n\t}\n\tif (objectType.invariants !== undefined) {\n\t\tnormalized.invariants = objectType.invariants.map((invariant) => ({ ...invariant }));\n\t}\n\treturn normalized;\n}\n\nfunction cloneJson<T>(value: T): T {\n\tif (Array.isArray(value)) return value.map((item) => cloneJson(item)) as T;\n\tif (value !== null && typeof value === \"object\") {\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(value as Record<string, unknown>).map(([key, child]) => [key, cloneJson(child)]),\n\t\t) as T;\n\t}\n\treturn value;\n}\n\nfunction exportEventType(\n\teventType: NonNullable<FabricModule[\"eventTypes\"]>[number],\n): ModuleManifestEventType {\n\tif (typeof eventType === \"string\") {\n\t\t// String registrations carry no explicit schema version; the events\n\t\t// registry treats the bare name as the initial version of the type.\n\t\treturn { eventType, schemaVersion: 1 };\n\t}\n\tconst normalized: ModuleManifestEventType = {\n\t\teventType: getEventTypeName(eventType),\n\t\tschemaVersion: eventType.schemaVersion,\n\t};\n\tif (eventType.description !== undefined) normalized.description = eventType.description;\n\tif (eventType.schema !== undefined) normalized.schema = cloneJson(eventType.schema);\n\treturn normalized;\n}\n\nfunction exportAction(action: ActionDefinition): ModuleManifestAction {\n\tassertSurfaceDeclaration(action, `Action \"${action?.actionId ?? \"unknown\"}\"`);\n\tassertAdapterStepDeadlines(action);\n\tconst manifest: ModuleManifestAction = {\n\t\tactionId: action.actionId,\n\t\tversion: action.version,\n\t\tkind: action.kind ?? \"atomic\",\n\t\tidempotent: action.idempotent,\n\t\tmutatesDomain: action.mutatesDomain,\n\t\temitsEvents: [...action.emitsEvents],\n\t};\n\n\tif (action.surface !== undefined) manifest.surface = action.surface;\n\tif (action.surfaceReason !== undefined) manifest.surfaceReason = action.surfaceReason;\n\tif (action.policies !== undefined) manifest.policies = [...action.policies];\n\tif (action.requiredRoles !== undefined) manifest.requiredRoles = [...action.requiredRoles];\n\tif (action.requiredPermissions !== undefined) {\n\t\tmanifest.requiredPermissions = [...action.requiredPermissions];\n\t}\n\tif (action.stagesInvocations !== undefined) manifest.stagesInvocations = [...action.stagesInvocations];\n\tif (action.eventPhase !== undefined) manifest.eventPhase = action.eventPhase;\n\tif (action.finalize !== undefined) manifest.finalization = { protocol: \"atomic-after-adapters-v1\" };\n\tif (action.execution !== undefined) manifest.execution = cloneJson(action.execution);\n\n\tif (isJsonSchemaExportableValidator(action.schema)) {\n\t\ttry {\n\t\t\tmanifest.parameterSchema = action.schema.toJSONSchema();\n\t\t\tmanifest.parameterSchemaFormat = \"json-schema\";\n\t\t} catch {\n\t\t\t// Runtime-valid schemas that cannot be represented portably remain executable;\n\t\t\t// build-time consumers see the schema as unavailable rather than crashing export.\n\t\t}\n\t}\n\tif (action.resultSchema && isJsonSchemaExportableValidator(action.resultSchema)) {\n\t\ttry {\n\t\t\tmanifest.resultSchema = action.resultSchema.toJSONSchema();\n\t\t\tmanifest.resultSchemaFormat = \"json-schema\";\n\t\t} catch {\n\t\t\t// See parameter-schema behavior above.\n\t\t}\n\t}\n\n\tif (action.stateMachine !== undefined) {\n\t\tconst binding: ModuleManifestActionStateMachine = {\n\t\t\tentityType: action.stateMachine.entityType,\n\t\t};\n\t\tif (typeof action.stateMachine.targetState === \"string\") {\n\t\t\tbinding.targetState = action.stateMachine.targetState;\n\t\t}\n\t\tmanifest.stateMachine = binding;\n\t}\n\n\tif (action.adapterSteps !== undefined) {\n\t\tmanifest.adapterSteps = action.adapterSteps.map((step) => {\n\t\t\tconst exported: ModuleManifestAdapterStep = {\n\t\t\t\tadapterType: step.adapterType,\n\t\t\t\toperation: step.operation,\n\t\t\t};\n\t\t\tif (step.retryPolicy !== undefined) exported.retryPolicy = { ...step.retryPolicy };\n\t\t\tif (step.deadlineMs !== undefined) exported.deadlineMs = step.deadlineMs;\n\t\t\treturn exported;\n\t\t});\n\t}\n\n\treturn manifest;\n}\n\nfunction exportPolicy(policy: unknown): ModuleManifestPolicy | undefined {\n\tif (!isRecord(policy) || typeof policy.policyId !== \"string\") {\n\t\treturn undefined;\n\t}\n\n\t// Code evaluator: identified by its `evaluate` function (never serialized).\n\tif (typeof policy.evaluate === \"function\") {\n\t\tconst exported: ModuleManifestCodePolicy = {\n\t\t\ttype: \"code\",\n\t\t\tpolicyId: policy.policyId,\n\t\t\tversion: typeof policy.version === \"number\" ? policy.version : 1,\n\t\t};\n\t\tif (typeof policy.previewSafe === \"boolean\") exported.previewSafe = policy.previewSafe;\n\t\treturn exported;\n\t}\n\n\t// Declarative runtime policy definition: pure data, serialized as-is.\n\tif (typeof policy.kind === \"string\" && typeof policy.policyVersion === \"number\") {\n\t\tconst exported: ModuleManifestDataPolicy = {\n\t\t\ttype: \"data\",\n\t\t\tpolicyId: policy.policyId,\n\t\t\tpolicyVersion: policy.policyVersion,\n\t\t\tkind: policy.kind as PolicyKind,\n\t\t};\n\t\tif (isRecord(policy.dataDefinition)) {\n\t\t\texported.dataDefinition = policy.dataDefinition as unknown as DataPolicyDefinition;\n\t\t}\n\t\tif (typeof policy.codeEvaluatorPolicyId === \"string\") {\n\t\t\texported.codeEvaluatorPolicyId = policy.codeEvaluatorPolicyId;\n\t\t}\n\t\tif (isRecord(policy.fallback)) {\n\t\t\texported.fallback = policy.fallback as unknown as PolicyFallbackDefinition;\n\t\t}\n\t\treturn exported;\n\t}\n\n\t// Unknown policy shape: omit rather than guess.\n\treturn undefined;\n}\n\nfunction exportStateMachine(machine: unknown): ModuleManifestStateMachine | undefined {\n\tif (\n\t\t!isRecord(machine) ||\n\t\ttypeof machine.entityType !== \"string\" ||\n\t\t!isRecord(machine.states) ||\n\t\t!Array.isArray(machine.transitions)\n\t) {\n\t\treturn undefined;\n\t}\n\n\tconst definition = machine as unknown as StateMachineDefinition;\n\treturn {\n\t\tentityType: definition.entityType,\n\t\tstates: Object.values(definition.states),\n\t\ttransitions: definition.transitions.map((transition) => ({\n\t\t\tfrom: transition.from,\n\t\t\tto: transition.to,\n\t\t\tcausedByAction: transition.causedByAction,\n\t\t\thasGuard: typeof transition.guard === \"function\",\n\t\t})),\n\t};\n}\n\nfunction exportView(view: ViewContract): ModuleManifestView {\n\tassertSurfaceDeclaration(view, `View \"${view?.name ?? \"unknown\"}\"`);\n\tconst output: ModuleManifestView = {\n\t\tname: view.name,\n\t\tversion: view.version,\n\t\tshape: cloneJson(view.shape),\n\t\tconsumes: view.consumes.map((consumption) => ({\n\t\t\teventType: consumption.eventType,\n\t\t\tschemaVersions: [...consumption.schemaVersions],\n\t\t})),\n\t\tscope: view.scope,\n\t\tsnapshotVersion: view.snapshotVersion,\n\t};\n\tif (view.surface !== undefined) output.surface = view.surface;\n\tif (view.surfaceReason !== undefined) output.surfaceReason = view.surfaceReason;\n\tif (view.parameterSchema !== undefined) output.parameterSchema = cloneJson(view.parameterSchema);\n\tif (view.compatibleSnapshotVersions) output.compatibleSnapshotVersions = [...view.compatibleSnapshotVersions];\n\tif (view.usage) output.usage = cloneJson(view.usage);\n\treturn output;\n}\n\n/**\n * Export a stable, JSON-serializable manifest of a module's ontology.\n *\n * This is a pure function of the module object: it does not read or mutate the\n * global module/action/policy/state-machine registries, and the module does\n * not need to be registered first. Declaration order is preserved everywhere\n * (nothing is sorted), so the same module object always produces a\n * byte-identical `JSON.stringify` result.\n *\n * The manifest contains definitions only — never raw parameter values,\n * secrets, or runtime data. Function fields are elided (`handler`,\n * policy `evaluate`, transition `guard` → `hasGuard`, dynamic `targetState`,\n * adapter `getInput`).\n */\nexport function exportModuleManifest(module: FabricModule<unknown>): ModuleManifest {\n\tconst manifest: ModuleManifest = {\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tnamespace: module.namespace,\n\t\tdependencies: (module.dependencies ?? []).map(exportDependency),\n\t\tobjectTypes: (module.objectTypes ?? []).map(exportObjectType),\n\t\tsubjectTypes: [...(module.subjectTypes ?? [])],\n\t\tidPrefixes: (module.idPrefixes ?? []).map((registration) => ({\n\t\t\tprefix: registration.prefix,\n\t\t\tname: registration.name,\n\t\t})),\n\t\teventTypes: (module.eventTypes ?? []).map(exportEventType),\n\t\tactions: (module.actions ?? []).map(exportAction),\n\t\tpolicies: (module.policies ?? [])\n\t\t\t.map(exportPolicy)\n\t\t\t.filter((policy): policy is ModuleManifestPolicy => policy !== undefined),\n\t\tstateMachines: (module.stateMachines ?? [])\n\t\t\t.map(exportStateMachine)\n\t\t\t.filter((machine): machine is ModuleManifestStateMachine => machine !== undefined),\n\t\tviews: (module.views ?? []).map(exportView),\n\t};\n\n\tif (module.version !== undefined) manifest.version = module.version;\n\tif (module.displayName !== undefined) manifest.displayName = module.displayName;\n\tif (module.description !== undefined) manifest.description = module.description;\n\tif (module.capability !== undefined) manifest.capability = cloneJson(module.capability);\n\n\treturn manifest;\n}\n\n/**\n * Export manifests for a set of modules, preserving the input order.\n * Like {@link exportModuleManifest}, this is pure and registry-free.\n */\nexport function exportModuleManifestBundle(\n\tmodules: FabricModule<unknown>[],\n): ModuleManifestBundle {\n\treturn {\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tmodules: modules.map(exportModuleManifest),\n\t};\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../manifest/index.ts"],"sourcesContent":["import { assertAdapterStepDeadlines } from \"../actions\";\nimport { assertSurfaceDeclaration, type SurfaceDeclaration } from \"../discovery\";\nimport type {\n\tActionExecutionContract,\n\tActionDefinition,\n\tAdapterStepRetryPolicy,\n\tSchemaValidator,\n} from \"../actions\";\nimport {\n\tgetEventTypeName,\n\tgetModuleDependencyNamespace,\n\tgetObjectTypeName,\n\ttype FabricModule,\n\ttype CapabilityMetadata,\n\ttype DeclarativeInvariant,\n\ttype ModuleDependency,\n\ttype ModuleDependencyInput,\n\ttype ObjectRelationDefinition,\n} from \"../modules\";\nimport type { JsonValue, PortableJsonSchema } from \"../objects\";\nimport type {\n\tDataPolicyDefinition,\n\tPolicyFallbackDefinition,\n\tPolicyKind,\n} from \"../policies\";\nimport type { StateDefinition, StateMachineDefinition } from \"../state-machines\";\nimport type { ViewContract } from \"../projections\";\n\n/**\n * Version of the module manifest contract. Bump when the serialized shape\n * changes in a way consumers must detect.\n */\nexport const MODULE_MANIFEST_VERSION = 2 as const;\n\nexport interface ModuleManifestObjectType {\n\ttype: string;\n\tdisplayName?: string;\n\tidPrefix?: string;\n\tschema?: PortableJsonSchema;\n\tsemantics?: Record<string, JsonValue>;\n\trelations?: ObjectRelationDefinition[];\n\tinvariants?: DeclarativeInvariant[];\n}\n\nexport interface ModuleManifestIdPrefix {\n\tprefix: string;\n\tname: string;\n}\n\nexport interface ModuleManifestEventType {\n\teventType: string;\n\tschemaVersion: number;\n\tdescription?: string;\n\tschema?: PortableJsonSchema;\n}\n\nexport interface ModuleManifestActionStateMachine {\n\tentityType: string;\n\t/** Present only when the binding declares a static target state. */\n\ttargetState?: string;\n}\n\nexport interface ModuleManifestAdapterStep {\n\tadapterType: string;\n\toperation: string;\n\tretryPolicy?: AdapterStepRetryPolicy;\n\t/** Positive finite integer duration in milliseconds; overrides Host adapterDeadlineMs for this step. */\n\tdeadlineMs?: number;\n}\n\nexport interface ModuleManifestAction extends SurfaceDeclaration {\n\tactionId: string;\n\tversion: number;\n\tkind: \"atomic\" | \"saga\";\n\tidempotent: boolean;\n\tmutatesDomain: boolean;\n\temitsEvents: string[];\n\tpolicies?: string[];\n\trequiredRoles?: string[];\n\trequiredPermissions?: string[];\n\tstagesInvocations?: string[];\n\tstagedInvocationPrincipals?: Record<string, string>;\n\teventPhase?: \"before_adapters\" | \"after_adapters\";\n\tfinalization?: { protocol: \"atomic-after-adapters-v1\" };\n\texecution?: ActionExecutionContract;\n\t/**\n\t * JSON Schema for the action parameters, present only when the action's\n\t * `schema` validator implements {@link JsonSchemaExportableValidator}.\n\t */\n\tparameterSchema?: unknown;\n\tparameterSchemaFormat?: \"json-schema\";\n\tresultSchema?: unknown;\n\tresultSchemaFormat?: \"json-schema\";\n\tstateMachine?: ModuleManifestActionStateMachine;\n\tadapterSteps?: ModuleManifestAdapterStep[];\n}\n\nexport interface ModuleManifestCodePolicy {\n\ttype: \"code\";\n\tpolicyId: string;\n\tversion: number;\n\tpreviewSafe?: boolean;\n}\n\nexport interface ModuleManifestDataPolicy {\n\ttype: \"data\";\n\tpolicyId: string;\n\tpolicyVersion: number;\n\tkind: PolicyKind;\n\tdataDefinition?: DataPolicyDefinition;\n\tcodeEvaluatorPolicyId?: string;\n\tfallback?: PolicyFallbackDefinition;\n}\n\nexport type ModuleManifestPolicy = ModuleManifestCodePolicy | ModuleManifestDataPolicy;\n\nexport interface ModuleManifestStateMachineTransition {\n\tfrom: string;\n\tto: string;\n\tcausedByAction: string;\n\t/** `true` when the transition declares a guard function. The guard itself is never serialized. */\n\thasGuard: boolean;\n}\n\nexport interface ModuleManifestStateMachine {\n\tentityType: string;\n\t/** States in declaration order (`Object.values` order of the definition record). */\n\tstates: StateDefinition[];\n\ttransitions: ModuleManifestStateMachineTransition[];\n}\n\nexport interface ModuleManifestView extends SurfaceDeclaration {\n\tname: string;\n\tversion: string;\n\tshape: PortableJsonSchema;\n\tparameterSchema?: PortableJsonSchema;\n\tconsumes: Array<{ eventType: string; schemaVersions: number[] }>;\n\tscope: \"tenant-space\";\n\tsnapshotVersion: number;\n\tcompatibleSnapshotVersions?: number[];\n\tusage?: ViewContract[\"usage\"];\n}\n\n/**\n * Stable, JSON-serializable description of a {@link FabricModule}'s ontology:\n * object types, subject types, id prefixes, event types, actions, policies,\n * and state machines. Intended for downstream tooling (semantics exporters,\n * docs generators, tool generators) that cannot consume live module code.\n *\n * The manifest contains definitions only — never raw parameter values,\n * secrets, or runtime data. Function fields (`handler`, `evaluate`, `guard`,\n * dynamic `targetState`, adapter `getInput`) are never serialized.\n */\nexport interface ModuleManifest {\n\tmanifestVersion: typeof MODULE_MANIFEST_VERSION;\n\tnamespace: string;\n\tversion?: string;\n\tdisplayName?: string;\n\tdescription?: string;\n\tcapability?: CapabilityMetadata;\n\tdependencies: ModuleDependency[];\n\tobjectTypes: ModuleManifestObjectType[];\n\tsubjectTypes: string[];\n\tidPrefixes: ModuleManifestIdPrefix[];\n\teventTypes: ModuleManifestEventType[];\n\tactions: ModuleManifestAction[];\n\tpolicies: ModuleManifestPolicy[];\n\tstateMachines: ModuleManifestStateMachine[];\n\tviews: ModuleManifestView[];\n}\n\nexport interface ModuleManifestBundle {\n\tmanifestVersion: typeof MODULE_MANIFEST_VERSION;\n\t/** Manifests in the input module order. */\n\tmodules: ModuleManifest[];\n}\n\n/** Manifest v1 remains accepted by v2 readers; missing v2 fields normalize to absence. */\nexport type ModuleManifestObjectTypeV1 = Omit<\n\tModuleManifestObjectType,\n\t\"schema\" | \"semantics\" | \"relations\" | \"invariants\"\n>;\nexport type ModuleManifestActionV1 = Omit<\n\tModuleManifestAction,\n\t\"resultSchema\" | \"resultSchemaFormat\"\n>;\nexport type ModuleManifestV1 = Omit<\n\tModuleManifest,\n\t\"manifestVersion\" | \"objectTypes\" | \"actions\" | \"views\"\n> & {\n\tmanifestVersion: 1;\n\tobjectTypes: ModuleManifestObjectTypeV1[];\n\tactions: ModuleManifestActionV1[];\n};\nexport type ModuleManifestBundleV1 = Omit<ModuleManifestBundle, \"manifestVersion\" | \"modules\"> & {\n\tmanifestVersion: 1;\n\tmodules: ModuleManifestV1[];\n};\n\nexport function normalizeModuleManifest(\n\tmanifest: ModuleManifest | ModuleManifestV1,\n): ModuleManifest {\n\tconst version: number = manifest.manifestVersion;\n\tif (version !== 1 && version !== MODULE_MANIFEST_VERSION) {\n\t\tthrow new Error(`Unsupported module manifest version: ${String(version)}`);\n\t}\n\tconst views = \"views\" in manifest && Array.isArray(manifest.views) ? manifest.views : [];\n\t// Preserve the normalizer's legacy tolerance for absent/non-array fields.\n\tif (Array.isArray(manifest.actions))\n\t\tfor (const [index, action] of manifest.actions.entries()) {\n\t\t\tassertSurfaceDeclaration(action, `Module \"${manifest.namespace}\" action[${index}] \"${action?.actionId ?? \"unknown\"}\"`);\n\t\t\tassertAdapterStepDeadlines(action);\n\t\t\tif (action.finalization !== undefined) {\n\t\t\t\tconst descriptor = action.finalization;\n\t\t\t\tif (!descriptor || typeof descriptor !== \"object\" || Array.isArray(descriptor) ||\n\t\t\t\t\tObject.keys(descriptor).some(key => key !== \"protocol\") || descriptor.protocol !== \"atomic-after-adapters-v1\")\n\t\t\t\t\tthrow new Error(\"Invalid action finalization protocol descriptor.\");\n\t\t\t\tif (action.eventPhase !== \"after_adapters\" || (action.kind !== undefined && action.kind !== \"atomic\") ||\n\t\t\t\t\t(action.execution?.completion !== undefined && action.execution.completion !== \"immediate\"))\n\t\t\t\t\tthrow new Error(\"Incompatible action finalization declaration.\");\n\t\t\t}\n\t\t}\n\tfor (const [index, view] of views.entries())\n\t\tassertSurfaceDeclaration(view, `Module \"${manifest.namespace}\" view[${index}] \"${view?.name ?? \"unknown\"}\"`);\n\treturn {\n\t\t...manifest,\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tviews,\n\t};\n}\n\nexport function normalizeModuleManifestBundle(\n\tbundle: ModuleManifestBundle | ModuleManifestBundleV1,\n): ModuleManifestBundle {\n\tconst version: number = bundle.manifestVersion;\n\tif (version !== 1 && version !== MODULE_MANIFEST_VERSION) {\n\t\tthrow new Error(`Unsupported module manifest bundle version: ${String(version)}`);\n\t}\n\treturn {\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tmodules: bundle.modules.map((manifest) => normalizeModuleManifest(manifest)),\n\t};\n}\n\n/**\n * A {@link SchemaValidator} that can also export its parameter schema as JSON\n * Schema (for example a Zod 4 schema via `z.toJSONSchema`). Keeps the platform\n * zero-dependency while letting schema-bearing actions flow into manifests.\n */\nexport interface JsonSchemaExportableValidator extends SchemaValidator {\n\ttoJSONSchema(): Record<string, unknown>;\n}\n\nexport function isJsonSchemaExportableValidator(\n\tschema: SchemaValidator,\n): schema is JsonSchemaExportableValidator {\n\treturn (\n\t\ttypeof (schema as Partial<JsonSchemaExportableValidator>).toJSONSchema === \"function\"\n\t);\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n\treturn value !== null && typeof value === \"object\" && !Array.isArray(value);\n}\n\nfunction exportDependency(dependency: ModuleDependencyInput): ModuleDependency {\n\tconst namespace = getModuleDependencyNamespace(dependency);\n\tif (typeof dependency === \"string\") {\n\t\treturn { namespace };\n\t}\n\tconst normalized: ModuleDependency = { namespace };\n\tif (dependency.version !== undefined) normalized.version = dependency.version;\n\tif (dependency.optional !== undefined) normalized.optional = dependency.optional;\n\treturn normalized;\n}\n\nfunction exportObjectType(\n\tobjectType: NonNullable<FabricModule[\"objectTypes\"]>[number],\n): ModuleManifestObjectType {\n\tif (typeof objectType === \"string\") {\n\t\treturn { type: objectType };\n\t}\n\tconst normalized: ModuleManifestObjectType = { type: getObjectTypeName(objectType) };\n\tif (objectType.displayName !== undefined) normalized.displayName = objectType.displayName;\n\tif (objectType.idPrefix !== undefined) normalized.idPrefix = objectType.idPrefix;\n\tif (objectType.schema !== undefined) normalized.schema = cloneJson(objectType.schema);\n\tif (objectType.semantics !== undefined) normalized.semantics = cloneJson(objectType.semantics);\n\tif (objectType.relations !== undefined) {\n\t\tnormalized.relations = objectType.relations.map((relation) => ({ ...relation }));\n\t}\n\tif (objectType.invariants !== undefined) {\n\t\tnormalized.invariants = objectType.invariants.map((invariant) => ({ ...invariant }));\n\t}\n\treturn normalized;\n}\n\nfunction cloneJson<T>(value: T): T {\n\tif (Array.isArray(value)) return value.map((item) => cloneJson(item)) as T;\n\tif (value !== null && typeof value === \"object\") {\n\t\treturn Object.fromEntries(\n\t\t\tObject.entries(value as Record<string, unknown>).map(([key, child]) => [key, cloneJson(child)]),\n\t\t) as T;\n\t}\n\treturn value;\n}\n\nfunction exportEventType(\n\teventType: NonNullable<FabricModule[\"eventTypes\"]>[number],\n): ModuleManifestEventType {\n\tif (typeof eventType === \"string\") {\n\t\t// String registrations carry no explicit schema version; the events\n\t\t// registry treats the bare name as the initial version of the type.\n\t\treturn { eventType, schemaVersion: 1 };\n\t}\n\tconst normalized: ModuleManifestEventType = {\n\t\teventType: getEventTypeName(eventType),\n\t\tschemaVersion: eventType.schemaVersion,\n\t};\n\tif (eventType.description !== undefined) normalized.description = eventType.description;\n\tif (eventType.schema !== undefined) normalized.schema = cloneJson(eventType.schema);\n\treturn normalized;\n}\n\nfunction exportAction(action: ActionDefinition): ModuleManifestAction {\n\tassertSurfaceDeclaration(action, `Action \"${action?.actionId ?? \"unknown\"}\"`);\n\tassertAdapterStepDeadlines(action);\n\tconst manifest: ModuleManifestAction = {\n\t\tactionId: action.actionId,\n\t\tversion: action.version,\n\t\tkind: action.kind ?? \"atomic\",\n\t\tidempotent: action.idempotent,\n\t\tmutatesDomain: action.mutatesDomain,\n\t\temitsEvents: [...action.emitsEvents],\n\t};\n\n\tif (action.surface !== undefined) manifest.surface = action.surface;\n\tif (action.surfaceReason !== undefined) manifest.surfaceReason = action.surfaceReason;\n\tif (action.policies !== undefined) manifest.policies = [...action.policies];\n\tif (action.requiredRoles !== undefined) manifest.requiredRoles = [...action.requiredRoles];\n\tif (action.requiredPermissions !== undefined) {\n\t\tmanifest.requiredPermissions = [...action.requiredPermissions];\n\t}\n\tif (action.stagesInvocations !== undefined) manifest.stagesInvocations = [...action.stagesInvocations];\n\tif (action.stagedInvocationPrincipals !== undefined) {\n\t\tmanifest.stagedInvocationPrincipals = Object.fromEntries(\n\t\t\tObject.entries(action.stagedInvocationPrincipals).sort(([left], [right]) => left < right ? -1 : left > right ? 1 : 0),\n\t\t);\n\t}\n\tif (action.eventPhase !== undefined) manifest.eventPhase = action.eventPhase;\n\tif (action.finalize !== undefined) manifest.finalization = { protocol: \"atomic-after-adapters-v1\" };\n\tif (action.execution !== undefined) manifest.execution = cloneJson(action.execution);\n\n\tif (isJsonSchemaExportableValidator(action.schema)) {\n\t\ttry {\n\t\t\tmanifest.parameterSchema = action.schema.toJSONSchema();\n\t\t\tmanifest.parameterSchemaFormat = \"json-schema\";\n\t\t} catch {\n\t\t\t// Runtime-valid schemas that cannot be represented portably remain executable;\n\t\t\t// build-time consumers see the schema as unavailable rather than crashing export.\n\t\t}\n\t}\n\tif (action.resultSchema && isJsonSchemaExportableValidator(action.resultSchema)) {\n\t\ttry {\n\t\t\tmanifest.resultSchema = action.resultSchema.toJSONSchema();\n\t\t\tmanifest.resultSchemaFormat = \"json-schema\";\n\t\t} catch {\n\t\t\t// See parameter-schema behavior above.\n\t\t}\n\t}\n\n\tif (action.stateMachine !== undefined) {\n\t\tconst binding: ModuleManifestActionStateMachine = {\n\t\t\tentityType: action.stateMachine.entityType,\n\t\t};\n\t\tif (typeof action.stateMachine.targetState === \"string\") {\n\t\t\tbinding.targetState = action.stateMachine.targetState;\n\t\t}\n\t\tmanifest.stateMachine = binding;\n\t}\n\n\tif (action.adapterSteps !== undefined) {\n\t\tmanifest.adapterSteps = action.adapterSteps.map((step) => {\n\t\t\tconst exported: ModuleManifestAdapterStep = {\n\t\t\t\tadapterType: step.adapterType,\n\t\t\t\toperation: step.operation,\n\t\t\t};\n\t\t\tif (step.retryPolicy !== undefined) exported.retryPolicy = { ...step.retryPolicy };\n\t\t\tif (step.deadlineMs !== undefined) exported.deadlineMs = step.deadlineMs;\n\t\t\treturn exported;\n\t\t});\n\t}\n\n\treturn manifest;\n}\n\nfunction exportPolicy(policy: unknown): ModuleManifestPolicy | undefined {\n\tif (!isRecord(policy) || typeof policy.policyId !== \"string\") {\n\t\treturn undefined;\n\t}\n\n\t// Code evaluator: identified by its `evaluate` function (never serialized).\n\tif (typeof policy.evaluate === \"function\") {\n\t\tconst exported: ModuleManifestCodePolicy = {\n\t\t\ttype: \"code\",\n\t\t\tpolicyId: policy.policyId,\n\t\t\tversion: typeof policy.version === \"number\" ? policy.version : 1,\n\t\t};\n\t\tif (typeof policy.previewSafe === \"boolean\") exported.previewSafe = policy.previewSafe;\n\t\treturn exported;\n\t}\n\n\t// Declarative runtime policy definition: pure data, serialized as-is.\n\tif (typeof policy.kind === \"string\" && typeof policy.policyVersion === \"number\") {\n\t\tconst exported: ModuleManifestDataPolicy = {\n\t\t\ttype: \"data\",\n\t\t\tpolicyId: policy.policyId,\n\t\t\tpolicyVersion: policy.policyVersion,\n\t\t\tkind: policy.kind as PolicyKind,\n\t\t};\n\t\tif (isRecord(policy.dataDefinition)) {\n\t\t\texported.dataDefinition = policy.dataDefinition as unknown as DataPolicyDefinition;\n\t\t}\n\t\tif (typeof policy.codeEvaluatorPolicyId === \"string\") {\n\t\t\texported.codeEvaluatorPolicyId = policy.codeEvaluatorPolicyId;\n\t\t}\n\t\tif (isRecord(policy.fallback)) {\n\t\t\texported.fallback = policy.fallback as unknown as PolicyFallbackDefinition;\n\t\t}\n\t\treturn exported;\n\t}\n\n\t// Unknown policy shape: omit rather than guess.\n\treturn undefined;\n}\n\nfunction exportStateMachine(machine: unknown): ModuleManifestStateMachine | undefined {\n\tif (\n\t\t!isRecord(machine) ||\n\t\ttypeof machine.entityType !== \"string\" ||\n\t\t!isRecord(machine.states) ||\n\t\t!Array.isArray(machine.transitions)\n\t) {\n\t\treturn undefined;\n\t}\n\n\tconst definition = machine as unknown as StateMachineDefinition;\n\treturn {\n\t\tentityType: definition.entityType,\n\t\tstates: Object.values(definition.states),\n\t\ttransitions: definition.transitions.map((transition) => ({\n\t\t\tfrom: transition.from,\n\t\t\tto: transition.to,\n\t\t\tcausedByAction: transition.causedByAction,\n\t\t\thasGuard: typeof transition.guard === \"function\",\n\t\t})),\n\t};\n}\n\nfunction exportView(view: ViewContract): ModuleManifestView {\n\tassertSurfaceDeclaration(view, `View \"${view?.name ?? \"unknown\"}\"`);\n\tconst output: ModuleManifestView = {\n\t\tname: view.name,\n\t\tversion: view.version,\n\t\tshape: cloneJson(view.shape),\n\t\tconsumes: view.consumes.map((consumption) => ({\n\t\t\teventType: consumption.eventType,\n\t\t\tschemaVersions: [...consumption.schemaVersions],\n\t\t})),\n\t\tscope: view.scope,\n\t\tsnapshotVersion: view.snapshotVersion,\n\t};\n\tif (view.surface !== undefined) output.surface = view.surface;\n\tif (view.surfaceReason !== undefined) output.surfaceReason = view.surfaceReason;\n\tif (view.parameterSchema !== undefined) output.parameterSchema = cloneJson(view.parameterSchema);\n\tif (view.compatibleSnapshotVersions) output.compatibleSnapshotVersions = [...view.compatibleSnapshotVersions];\n\tif (view.usage) output.usage = cloneJson(view.usage);\n\treturn output;\n}\n\n/**\n * Export a stable, JSON-serializable manifest of a module's ontology.\n *\n * This is a pure function of the module object: it does not read or mutate the\n * global module/action/policy/state-machine registries, and the module does\n * not need to be registered first. Declaration order is preserved everywhere\n * (nothing is sorted), so the same module object always produces a\n * byte-identical `JSON.stringify` result.\n *\n * The manifest contains definitions only — never raw parameter values,\n * secrets, or runtime data. Function fields are elided (`handler`,\n * policy `evaluate`, transition `guard` → `hasGuard`, dynamic `targetState`,\n * adapter `getInput`).\n */\nexport function exportModuleManifest(module: FabricModule<unknown>): ModuleManifest {\n\tconst manifest: ModuleManifest = {\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tnamespace: module.namespace,\n\t\tdependencies: (module.dependencies ?? []).map(exportDependency),\n\t\tobjectTypes: (module.objectTypes ?? []).map(exportObjectType),\n\t\tsubjectTypes: [...(module.subjectTypes ?? [])],\n\t\tidPrefixes: (module.idPrefixes ?? []).map((registration) => ({\n\t\t\tprefix: registration.prefix,\n\t\t\tname: registration.name,\n\t\t})),\n\t\teventTypes: (module.eventTypes ?? []).map(exportEventType),\n\t\tactions: (module.actions ?? []).map(exportAction),\n\t\tpolicies: (module.policies ?? [])\n\t\t\t.map(exportPolicy)\n\t\t\t.filter((policy): policy is ModuleManifestPolicy => policy !== undefined),\n\t\tstateMachines: (module.stateMachines ?? [])\n\t\t\t.map(exportStateMachine)\n\t\t\t.filter((machine): machine is ModuleManifestStateMachine => machine !== undefined),\n\t\tviews: (module.views ?? []).map(exportView),\n\t};\n\n\tif (module.version !== undefined) manifest.version = module.version;\n\tif (module.displayName !== undefined) manifest.displayName = module.displayName;\n\tif (module.description !== undefined) manifest.description = module.description;\n\tif (module.capability !== undefined) manifest.capability = cloneJson(module.capability);\n\n\treturn manifest;\n}\n\n/**\n * Export manifests for a set of modules, preserving the input order.\n * Like {@link exportModuleManifest}, this is pure and registry-free.\n */\nexport function exportModuleManifestBundle(\n\tmodules: FabricModule<unknown>[],\n): ModuleManifestBundle {\n\treturn {\n\t\tmanifestVersion: MODULE_MANIFEST_VERSION,\n\t\tmodules: modules.map(exportModuleManifest),\n\t};\n}\n"],"mappings":"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"}
|
package/dist/modules/index.cjs
CHANGED
|
@@ -168,6 +168,12 @@ function validateManifest(module, context = {}) {
|
|
|
168
168
|
if (action.mutatesDomain && action.emitsEvents.length === 0) throw new Error(`Action "${action.actionId}" mutates domain but emits no events. Every mutating action must emit at least one AssetEvent.`);
|
|
169
169
|
if (action.admitSubmission !== void 0 && typeof action.admitSubmission !== "function") throw new Error(`Action "${action.actionId}" declares admitSubmission that is not a function.`);
|
|
170
170
|
const stagedTargets = action.stagesInvocations ?? [];
|
|
171
|
+
const stagedInvocationPrincipals = action.stagedInvocationPrincipals;
|
|
172
|
+
if (stagedInvocationPrincipals !== void 0 && (!stagedInvocationPrincipals || typeof stagedInvocationPrincipals !== "object" || Array.isArray(stagedInvocationPrincipals))) throw new Error(`Action "${action.actionId}" stagedInvocationPrincipals must be an object.`);
|
|
173
|
+
for (const [targetId, principal] of Object.entries(stagedInvocationPrincipals ?? {})) {
|
|
174
|
+
if (!stagedTargets.includes(targetId)) throw new Error(`Action "${action.actionId}" does not declare staged invocation target "${targetId}".`);
|
|
175
|
+
if (typeof principal !== "string" || !/^[a-z][a-z0-9._:-]{0,127}$/.test(principal)) throw new Error(`Action "${action.actionId}" declares invalid staged invocation principal for "${targetId}".`);
|
|
176
|
+
}
|
|
171
177
|
for (const [index, targetId] of stagedTargets.entries()) {
|
|
172
178
|
if (stagedTargets.indexOf(targetId) !== index) throw new Error(`Action "${action.actionId}" declares duplicate staged invocation target "${targetId}".`);
|
|
173
179
|
if (targetId === action.actionId) throw new Error(`Action "${action.actionId}" cannot stage itself.`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.cjs","names":["viewContractKey","createEventContractRegistry"],"sources":["../../modules/index.ts"],"sourcesContent":["import { assertActionFinalization, assertAdapterStepDeadlines } from \"../actions\";\nimport { assertSurfaceDeclaration } from \"../discovery\";\nimport type { ActionDefinition } from \"../actions\";\nimport { createEventContractRegistry } from \"../events\";\nimport {\n\tassertPortableJsonSchema,\n\ttype JsonValue,\n\ttype PortableJsonSchema,\n} from \"../objects\";\nimport type { PolicyEvaluator, PolicyId } from \"../policies\";\nimport type { StateMachineDefinition } from \"../state-machines\";\nimport { viewContractKey, type ViewContract } from \"../projections\";\n\nexport interface ModuleDependency {\n\tnamespace: string;\n\tversion?: string;\n\toptional?: boolean;\n}\n\nexport type ModuleDependencyInput = string | ModuleDependency;\n\nexport interface IdPrefixRegistration {\n\tprefix: string;\n\tname: string;\n\tmodule: string;\n}\n\nexport interface EventTypeRegistration {\n\teventType: string;\n\tschemaVersion: number;\n\tdescription?: string;\n\tschema?: PortableJsonSchema;\n}\n\nexport type EventTypeRegistrationInput = string | EventTypeRegistration;\n\nexport interface ObjectTypeRegistration {\n\ttype: string;\n\tdisplayName?: string;\n\tidPrefix?: string;\n\tisCoreModuleType?: boolean;\n\tschema?: PortableJsonSchema;\n\tsemantics?: Record<string, JsonValue>;\n\trelations?: ObjectRelationDefinition[];\n\tinvariants?: DeclarativeInvariant[];\n}\n\nexport type ObjectRelationCardinality = \"one\" | \"many\";\nexport type ObjectRelationSemantics = \"reference\" | \"owned\";\nexport type ObjectRelationDeleteBehavior = \"restrict\" | \"cascade\" | \"set-null\";\n\nexport interface ObjectRelationDefinition {\n\tname: string;\n\ttarget: `${string}.${string}`;\n\tcardinality: ObjectRelationCardinality;\n\trequired?: boolean;\n\tsemantics: ObjectRelationSemantics;\n\tonTargetDelete: ObjectRelationDeleteBehavior;\n}\n\nexport type InvariantEnforcement =\n\t| \"json-schema\"\n\t| \"state-machine\"\n\t| \"policy\"\n\t| \"host-adapter\"\n\t| \"application\";\n\nexport interface DeclarativeInvariant {\n\tid: string;\n\tdescription: string;\n\trequired?: boolean;\n\tenforcement: InvariantEnforcement;\n\tenforcementRef?: string;\n}\n\nexport type ObjectTypeRegistrationInput = string | ObjectTypeRegistration;\n\nexport interface PolicyRegistration {\n\tid: string;\n\tversion?: string;\n\tdescription?: string;\n}\n\nexport interface StateMachineRegistration {\n\tentityType: string;\n\tstates: string[];\n}\n\nexport interface CapabilityPortRequirement {\n\tname: string;\n\tversion?: string;\n\tstandard?: { name: string; version?: string };\n}\n\nexport interface CapabilityRequirements {\n\tports?: CapabilityPortRequirement[];\n\tpermissions?: string[];\n\tentitlements?: string[];\n\tfeatureFlags?: string[];\n}\n\nexport interface CapabilityWorkflowTimer {\n\t/** Workflow-local identity of the deadline, for example \"right-to-cure\". */\n\tname: string;\n\t/** Configuration key the duration is resolved from when the workflow starts. */\n\tconfigKey: string;\n\tdescription?: string;\n}\n\nexport interface CapabilityWorkflowCompensation {\n\t/** Workflow step whose effect this reverses. */\n\tstep: string;\n\t/** Governed action that performs the reversal. Must belong to the declaring module. */\n\tactionId: `${string}.${string}`;\n}\n\n/**\n * A durable workflow this capability owns. Declaring it makes durability a\n * reviewable fact of the contract rather than a property of worker deployment:\n * the queue it runs on, the deadlines it carries, and what reverses each step\n * are all diffable.\n */\nexport interface CapabilityWorkflowDeclaration {\n\tname: string;\n\t/** Routing identity, conventionally `capability.vertical`. */\n\ttaskQueue: string;\n\t/** Event type whose arrival starts this workflow by choreography. */\n\tstartedBy?: string;\n\ttimers?: CapabilityWorkflowTimer[];\n\tcompensations?: CapabilityWorkflowCompensation[];\n}\n\nexport interface CapabilityMetadata {\n\tdisplayName: string;\n\tdescription: string;\n\tstability: \"experimental\" | \"beta\" | \"stable\" | \"deprecated\";\n\tdeprecated?: { since: string; replacement?: string; message: string };\n\trequirements?: CapabilityRequirements;\n\tcertification?: { profile: string; required: boolean };\n\t/** Durable workflows this capability owns, with their queues, deadlines and reversals. */\n\tworkflows?: CapabilityWorkflowDeclaration[];\n\t/** Namespaced declared data preserved by Platform and interpreted only by its owning package. */\n\textensions?: Record<string, JsonValue>;\n}\n\nexport interface FabricModule<TDb = unknown> {\n\tnamespace: string;\n\tversion?: string;\n\t/** Compiler manifest digest for exact runtime assembly verification. */\n\tmanifestDigest?: string;\n\tdisplayName?: string;\n\tdescription?: string;\n\tcapability?: CapabilityMetadata;\n\tdependencies?: ModuleDependencyInput[];\n\tobjectTypes?: ObjectTypeRegistrationInput[];\n\tsubjectTypes?: string[];\n\tidPrefixes?: IdPrefixRegistration[];\n\teventTypes?: EventTypeRegistrationInput[];\n\tactions?: ActionDefinition<TDb>[];\n\tpolicies?: unknown[];\n\tstateMachines?: unknown[];\n\tadapterDefinitions?: unknown[];\n\tpermissions?: unknown[];\n\troles?: unknown[];\n\tredactionRules?: unknown[];\n\tdataClassifications?: unknown[];\n\tretentionRules?: unknown[];\n\tevidenceRenderers?: unknown[];\n\tviews?: ViewContract[];\n}\n\nexport interface ModuleRegistry<TDb = unknown> {\n\tmodules: ReadonlyMap<string, FabricModule<TDb>>;\n\torderedModules: readonly FabricModule<TDb>[];\n\tresolveAction(actionId: `${string}.${string}`): ActionDefinition<TDb> | undefined;\n\tresolvePolicy(policyId: PolicyId): PolicyEvaluator | undefined;\n\tresolveStateMachine(entityType: string): StateMachineDefinition | undefined;\n\tresolveView(name: string, version: string): ViewContract | undefined;\n}\n\ninterface ModuleValidationContext {\n\tavailableNamespaces?: Set<string>;\n\tplannedEventTypes?: Set<string>;\n\tavailableObjectTypes?: Set<string>;\n\tavailableActions?: Map<string, ActionDefinition<unknown>>;\n}\n\nexport function getModuleDependencyNamespace(dependency: ModuleDependencyInput): string {\n\treturn typeof dependency === \"string\" ? dependency : dependency.namespace;\n}\n\nexport function getObjectTypeName(objectType: ObjectTypeRegistrationInput): string {\n\treturn typeof objectType === \"string\" ? objectType : objectType.type;\n}\n\nexport function getEventTypeName(eventType: EventTypeRegistrationInput): string {\n\treturn typeof eventType === \"string\" ? eventType : eventType.eventType;\n}\n\nexport function validateModuleNamespace(namespace: string): void {\n\tif (!namespace) {\n\t\tthrow new Error(\"Module namespace cannot be empty\");\n\t}\n\tif (!/^[a-z][a-z0-9-]*$/.test(namespace)) {\n\t\tthrow new Error(\n\t\t\t`Invalid module namespace: \"${namespace}\". Must be lowercase letters, numbers, and hyphens only.`,\n\t\t);\n\t}\n}\n\nexport function createModuleRegistry<TDb = unknown>(\n\tmodules: FabricModule<TDb>[] = [],\n): ModuleRegistry<TDb> {\n\tconst orderedModules = validateAndOrderFabricModules(modules);\n\tconst registered = new Map(orderedModules.map((module) => [module.namespace, module]));\n\tconst actions = new Map(orderedModules.flatMap((module) => (module.actions ?? []).map((action) => [action.actionId, action] as const)));\n\tconst policies = new Map(orderedModules.flatMap((module) => (module.policies ?? []).map((policy) => {\n\t\tconst evaluator = policy as PolicyEvaluator;\n\t\treturn [evaluator.policyId, evaluator] as const;\n\t})));\n\tconst machines = new Map(orderedModules.flatMap((module) => (module.stateMachines ?? []).map((machine) => {\n\t\tconst definition = machine as StateMachineDefinition;\n\t\treturn [definition.entityType, definition] as const;\n\t})));\n\tconst views = new Map(orderedModules.flatMap((module) => (module.views ?? []).map((view) => [viewContractKey(view), view] as const)));\n\treturn {\n\t\tmodules: registered,\n\t\torderedModules,\n\t\tresolveAction: (actionId) => actions.get(actionId),\n\t\tresolvePolicy: (policyId) => policies.get(policyId),\n\t\tresolveStateMachine: (entityType) => machines.get(entityType),\n\t\tresolveView: (name, version) => views.get(`${name}@${version}`),\n\t};\n}\n\nfunction validateIdentifierList(\n\tvalues: string[] | undefined,\n\tlabel: string,\n\tnamespace: string,\n): void {\n\tfor (const value of values ?? []) {\n\t\tif (!value) {\n\t\t\tthrow new Error(`Module \"${namespace}\" has an empty ${label} entry.`);\n\t\t}\n\t}\n}\n\nfunction assertJsonValue(value: unknown, path: string): asserts value is JsonValue {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return;\n\tif (typeof value === \"number\" && Number.isFinite(value)) return;\n\tif (Array.isArray(value)) {\n\t\tvalue.forEach((item, index) => assertJsonValue(item, `${path}[${index}]`));\n\t\treturn;\n\t}\n\tif (typeof value === \"object\") {\n\t\tfor (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n\t\t\tassertJsonValue(child, `${path}.${key}`);\n\t\t}\n\t\treturn;\n\t}\n\tthrow new Error(`${path} must contain JSON-serializable values.`);\n}\n\nfunction qualifiedObjectType(namespace: string, type: string): string {\n\treturn `${namespace}.${type}`;\n}\n\nfunction validateObjectDefinition(\n\tobjectType: ObjectTypeRegistrationInput,\n\tnamespace: string,\n\tcontext: ModuleValidationContext,\n): void {\n\tif (typeof objectType === \"string\") return;\n\tif (objectType.schema !== undefined) {\n\t\tassertPortableJsonSchema(objectType.schema, `Module \"${namespace}\" object \"${objectType.type}\" schema`);\n\t}\n\tif (objectType.semantics !== undefined) {\n\t\tassertJsonValue(objectType.semantics, `Module \"${namespace}\" object \"${objectType.type}\" semantics`);\n\t}\n\tconst relationNames = new Set<string>();\n\tfor (const relation of objectType.relations ?? []) {\n\t\tif (!/^[a-z][a-zA-Z0-9]*$/.test(relation.name)) {\n\t\t\tthrow new Error(`Module \"${namespace}\" object \"${objectType.type}\" has invalid relation name \"${relation.name}\".`);\n\t\t}\n\t\tif (relationNames.has(relation.name)) {\n\t\t\tthrow new Error(`Module \"${namespace}\" object \"${objectType.type}\" has duplicate relation \"${relation.name}\".`);\n\t\t}\n\t\trelationNames.add(relation.name);\n\t\tif (!/^[a-z][a-z0-9-]*\\.[A-Z][a-zA-Z0-9]*$/.test(relation.target)) {\n\t\t\tthrow new Error(`Relation \"${relation.name}\" target \"${relation.target}\" must be module-qualified.`);\n\t\t}\n\t\tif (context.availableObjectTypes && !context.availableObjectTypes.has(relation.target)) {\n\t\t\tthrow new Error(`Relation \"${relation.name}\" targets missing object type \"${relation.target}\".`);\n\t\t}\n\t\tif (relation.required && relation.onTargetDelete === \"set-null\") {\n\t\t\tthrow new Error(`Required relation \"${relation.name}\" cannot use onTargetDelete \"set-null\".`);\n\t\t}\n\t}\n\tconst invariantIds = new Set<string>();\n\tfor (const invariant of objectType.invariants ?? []) {\n\t\tif (!invariant.id.trim() || !invariant.description.trim()) {\n\t\t\tthrow new Error(`Module \"${namespace}\" object \"${objectType.type}\" has an invariant without an id or description.`);\n\t\t}\n\t\tif (invariantIds.has(invariant.id)) {\n\t\t\tthrow new Error(`Module \"${namespace}\" object \"${objectType.type}\" has duplicate invariant \"${invariant.id}\".`);\n\t\t}\n\t\tinvariantIds.add(invariant.id);\n\t\tif (invariant.required && !invariant.enforcementRef?.trim()) {\n\t\t\tthrow new Error(`Required invariant \"${invariant.id}\" must declare enforcementRef.`);\n\t\t}\n\t}\n}\n\nfunction validateCapabilityWorkflows(module: FabricModule<unknown>, context: ModuleValidationContext): void {\n\tconst workflows = module.capability?.workflows ?? [];\n\tconst actionsById = new Map((module.actions ?? []).map((action) => [action.actionId, action]));\n\tconst names = new Set<string>();\n\tfor (const workflow of workflows) {\n\t\tif (!/^[A-Za-z][A-Za-z0-9_-]*$/.test(workflow.name)) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" declares invalid workflow name \"${workflow.name}\".`);\n\t\t}\n\t\tif (names.has(workflow.name)) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" declares duplicate workflow \"${workflow.name}\".`);\n\t\t}\n\t\tnames.add(workflow.name);\n\t\tif (!/^[a-z][a-z0-9-]*(\\.[a-z][a-z0-9-]*)*$/.test(workflow.taskQueue)) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" declares invalid task queue \"${workflow.taskQueue}\".`);\n\t\t}\n\t\tif (workflow.startedBy !== undefined) {\n\t\t\tconst known = context.plannedEventTypes?.has(workflow.startedBy)\n\t\t\t\t?? (module.eventTypes ?? []).some((eventType) => getEventTypeName(eventType) === workflow.startedBy);\n\t\t\tif (!known) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" is started by unknown event type \"${workflow.startedBy}\".`);\n\t\t\t}\n\t\t}\n\t\tconst timerNames = new Set<string>();\n\t\tfor (const timer of workflow.timers ?? []) {\n\t\t\tif (!timer.name.trim() || !timer.configKey.trim()) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" has a timer without a name or configKey.`);\n\t\t\t}\n\t\t\tif (timerNames.has(timer.name)) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" declares duplicate timer \"${timer.name}\".`);\n\t\t\t}\n\t\t\ttimerNames.add(timer.name);\n\t\t}\n\t\tconst steps = new Set<string>();\n\t\tfor (const compensation of workflow.compensations ?? []) {\n\t\t\tif (!compensation.step.trim()) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" has a compensation without a step.`);\n\t\t\t}\n\t\t\tif (steps.has(compensation.step)) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" declares duplicate compensation for step \"${compensation.step}\".`);\n\t\t\t}\n\t\t\tsteps.add(compensation.step);\n\t\t\tconst compensatingAction = actionsById.get(compensation.actionId);\n\t\t\tif (!compensatingAction) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" compensates step \"${compensation.step}\" with unknown action \"${compensation.actionId}\".`);\n\t\t\t}\n\t\t\t// An unwind is retried like any other durable step, so a reversal that cannot be\n\t\t\t// safely repeated would turn one failure into a different kind of corruption.\n\t\t\tif (!compensatingAction.idempotent || compensatingAction.execution?.idempotency === \"prohibited\") {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" compensates step \"${compensation.step}\" with non-idempotent action \"${compensation.actionId}\"; a reversal must be safely repeatable.`);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction validateManifest(module: FabricModule<unknown>, context: ModuleValidationContext = {}): void {\n\tvalidateModuleNamespace(module.namespace);\n\n\tconst dependencies = (module.dependencies ?? []).map(getModuleDependencyNamespace);\n\tconst objectTypes = (module.objectTypes ?? []).map(getObjectTypeName);\n\tconst eventTypes = (module.eventTypes ?? []).map(getEventTypeName);\n\tif (module.capability) {\n\t\tif (!module.capability.displayName.trim() || !module.capability.description.trim()) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" capability requires displayName and description.`);\n\t\t}\n\t\tfor (const namespace of Object.keys(module.capability.extensions ?? {})) {\n\t\t\tif (!/^[a-z][a-z0-9.-]*\\.[a-z0-9.-]+\\/v[1-9][0-9]*$/.test(namespace)) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" capability has invalid extension namespace \"${namespace}\".`);\n\t\t\t}\n\t\t}\n\t\tfor (const port of module.capability.requirements?.ports ?? []) {\n\t\t\t// Dotted segments are permitted so a capability can require a port\n\t\t\t// defined outside this repository: an enterprise integrates hundreds\n\t\t\t// of external systems, and namespacing is what keeps two of them from\n\t\t\t// colliding on a name. Widening only, so existing names still parse.\n\t\t\tif (!/^[a-z][a-z0-9-]*(?:\\.[a-z0-9-]+)*$/.test(port.name)) throw new Error(`Module \"${module.namespace}\" capability has invalid port requirement \"${port.name}\".`);\n\t\t}\n\t\tvalidateCapabilityWorkflows(module, context);\n\t}\n\tfor (const eventType of module.eventTypes ?? []) if (typeof eventType !== \"string\" && eventType.schema) assertPortableJsonSchema(eventType.schema, `Event \"${eventType.eventType}\" schema`);\n\tfor (const action of module.actions ?? []) {\n\t\tif (action.execution?.idempotency === \"required\" && !action.idempotent) throw new Error(`Action \"${action.actionId}\" requires idempotency but is not declared idempotent.`);\n\t\tif (action.execution?.connectivity === \"offline-capturable\" && action.execution.idempotency === \"prohibited\") throw new Error(`Offline action \"${action.actionId}\" cannot prohibit idempotency.`);\n\t\tif (action.execution?.completionDeadlineMs !== undefined && !(typeof action.execution.completionDeadlineMs === \"number\" && action.execution.completionDeadlineMs > 0)) throw new Error(`Action \"${action.actionId}\" completionDeadlineMs must be a positive number of milliseconds.`);\n\t\tif (action.execution?.completion === \"immediate\" && action.execution.completionDeadlineMs !== undefined) throw new Error(`Immediate action \"${action.actionId}\" cannot declare a completion deadline; nothing external completes it.`);\n\t}\n\tfor (const view of module.views ?? []) if (view.usage?.collection?.filterSchema) assertPortableJsonSchema(view.usage.collection.filterSchema, `View \"${view.name}\" filter schema`);\n\n\tfor (const dependency of dependencies) {\n\t\tvalidateModuleNamespace(dependency);\n\t\tif (dependency === module.namespace) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" cannot depend on itself.`);\n\t\t}\n\t\tif (context.availableNamespaces && !context.availableNamespaces.has(dependency)) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" depends on missing module \"${dependency}\".`);\n\t\t}\n\t}\n\n\tvalidateIdentifierList(objectTypes, \"objectTypes\", module.namespace);\n\tvalidateIdentifierList(module.subjectTypes, \"subjectTypes\", module.namespace);\n\tvalidateIdentifierList(eventTypes, \"eventTypes\", module.namespace);\n\n\tfor (const objectType of objectTypes) {\n\t\tif (!/^[A-Z][a-zA-Z0-9]*$/.test(objectType)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid object type: \"${objectType}\". Object types must be PascalCase alphanumeric.`,\n\t\t\t);\n\t\t}\n\t}\n\tfor (const objectType of module.objectTypes ?? []) {\n\t\tif (typeof objectType !== \"string\") {\n\t\t\tfor (const relation of objectType.relations ?? []) {\n\t\t\t\tconst targetNamespace = relation.target.slice(0, relation.target.indexOf(\".\"));\n\t\t\t\tif (targetNamespace !== module.namespace && !dependencies.includes(targetNamespace)) {\n\t\t\t\t\tthrow new Error(`Module \"${module.namespace}\" relation \"${relation.name}\" targets module \"${targetNamespace}\" without declaring it as a dependency.`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tvalidateObjectDefinition(objectType, module.namespace, context);\n\t}\n\n\tfor (const action of module.actions ?? []) {\n\t\tassertSurfaceDeclaration(action, `Action \"${action?.actionId ?? \"unknown\"}\"`);\n\t\tassertAdapterStepDeadlines(action);\n\t\tassertActionFinalization(action);\n\t\tlet parameterSchema: unknown;\n\t\ttry { parameterSchema = (action.schema as { toJSONSchema?: () => unknown }).toJSONSchema?.(); } catch { parameterSchema = undefined; }\n\t\tif (parameterSchema !== undefined) assertPortableJsonSchema(parameterSchema, `Action \"${action.actionId}\" parameters`);\n\t\tlet resultSchema: unknown;\n\t\ttry { resultSchema = (action.resultSchema as { toJSONSchema?: () => unknown } | undefined)?.toJSONSchema?.(); } catch { resultSchema = undefined; }\n\t\tif (resultSchema !== undefined) assertPortableJsonSchema(resultSchema, `Action \"${action.actionId}\" result`);\n\t\tif (!/^[a-z][a-z0-9-]*\\.[a-z][a-z0-9_]*$/.test(action.actionId)) {\n\t\t\tthrow new Error(`Invalid action ID: ${action.actionId}`);\n\t\t}\n\n\t\tif (action.namespace !== module.namespace) {\n\t\t\tthrow new Error(\n\t\t\t\t`Action \"${action.actionId}\" declares namespace \"${action.namespace}\" ` +\n\t\t\t\t\t`but is registered by module \"${module.namespace}\".`,\n\t\t\t);\n\t\t}\n\n\t\tif (!action.actionId.startsWith(`${module.namespace}.`)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Action \"${action.actionId}\" must start with module namespace \"${module.namespace}.\"`,\n\t\t\t);\n\t\t}\n\n\t\tif (action.mutatesDomain && action.emitsEvents.length === 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`Action \"${action.actionId}\" mutates domain but emits no events. ` +\n\t\t\t\t\t`Every mutating action must emit at least one AssetEvent.`,\n\t\t\t);\n\t\t}\n\n\t\tif (action.admitSubmission !== undefined && typeof action.admitSubmission !== \"function\") {\n\t\t\tthrow new Error(`Action \"${action.actionId}\" declares admitSubmission that is not a function.`);\n\t\t}\n\t\tconst stagedTargets = action.stagesInvocations ?? [];\n\t\tfor (const [index, targetId] of stagedTargets.entries()) {\n\t\t\tif (stagedTargets.indexOf(targetId) !== index) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" declares duplicate staged invocation target \"${targetId}\".`);\n\t\t\t}\n\t\t\tif (targetId === action.actionId) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" cannot stage itself.`);\n\t\t\t}\n\t\t\tconst target = context.availableActions?.get(targetId);\n\t\t\tif (!target) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" stages unknown action \"${targetId}\".`);\n\t\t\t}\n\t\t\tconst targetNamespace = targetId.slice(0, targetId.indexOf(\".\"));\n\t\t\tif (targetNamespace !== module.namespace && !dependencies.includes(targetNamespace)) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" stages action \"${targetId}\" without declaring module \"${targetNamespace}\" as a dependency.`);\n\t\t\t}\n\t\t\tif (target.execution?.authorityMoment === \"capture\") {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" cannot stage capture-authority action \"${targetId}\".`);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst viewKeys = new Set<string>();\n\tfor (const view of module.views ?? []) {\n\t\tassertSurfaceDeclaration(view, `View \"${view?.name ?? \"unknown\"}\"`);\n\t\tif (!view.name.startsWith(`${module.namespace}/`) || !/^[a-z][a-z0-9-]*\\/[a-z][a-z0-9/_-]*$/.test(view.name)) {\n\t\t\tthrow new Error(`View \"${view.name}\" must start with module namespace \"${module.namespace}/\" and use lowercase path segments.`);\n\t\t}\n\t\tif (!view.version.trim()) throw new Error(`View \"${view.name}\" must declare a version.`);\n\t\tconst key = `${view.name}@${view.version}`;\n\t\tif (viewKeys.has(key)) throw new Error(`Module \"${module.namespace}\" has duplicate view contract \"${key}\".`);\n\t\tviewKeys.add(key);\n\t\tassertPortableJsonSchema(view.shape, `View \"${key}\" shape`);\n\t\tif (view.parameterSchema !== undefined) assertPortableJsonSchema(view.parameterSchema, `View \"${key}\" parameters`);\n\t\tif (!Number.isInteger(view.snapshotVersion) || view.snapshotVersion < 1) {\n\t\t\tthrow new Error(`View \"${key}\" snapshotVersion must be a positive integer.`);\n\t\t}\n\t\tif ((view.compatibleSnapshotVersions?.some((version) => version !== view.snapshotVersion) ?? false) && !view.upgradeSnapshot) {\n\t\t\tthrow new Error(`View \"${key}\" declares older compatible snapshots but no upgradeSnapshot function.`);\n\t\t}\n\t\tfor (const consumption of view.consumes) {\n\t\t\tconst isPlanned = context.plannedEventTypes?.has(consumption.eventType) ?? false;\n\t\t\tconst isModuleEvent = eventTypes.includes(consumption.eventType);\n\t\t\tif (!isPlanned && !isModuleEvent) {\n\t\t\t\tthrow new Error(`View \"${key}\" consumes unknown event type \"${consumption.eventType}\".`);\n\t\t\t}\n\t\t\tif (consumption.schemaVersions.length === 0 || consumption.schemaVersions.some((version) => !Number.isInteger(version) || version < 1)) {\n\t\t\t\tthrow new Error(`View \"${key}\" must declare positive consumed schema versions for \"${consumption.eventType}\".`);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction sortModulesByDependency(\n\tmodules: FabricModule<unknown>[],\n\tregisteredNamespaces: ReadonlySet<string> = new Set(),\n): FabricModule<unknown>[] {\n\tconst modulesByNamespace = new Map<string, FabricModule<unknown>>();\n\n\tfor (const module of modules) {\n\t\tvalidateModuleNamespace(module.namespace);\n\t\tif (modulesByNamespace.has(module.namespace)) {\n\t\t\tthrow new Error(`Duplicate FabricModule namespace \"${module.namespace}\".`);\n\t\t}\n\t\tmodulesByNamespace.set(module.namespace, module);\n\t}\n\n\tconst sorted: FabricModule<unknown>[] = [];\n\tconst visiting = new Set<string>();\n\tconst visited = new Set<string>();\n\n\tfunction visit(module: FabricModule<unknown>, path: string[]): void {\n\t\tif (visited.has(module.namespace)) {\n\t\t\treturn;\n\t\t}\n\t\tif (visiting.has(module.namespace)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cyclic Fabric module dependency detected: ${[...path, module.namespace].join(\" -> \")}`,\n\t\t\t);\n\t\t}\n\n\t\tvisiting.add(module.namespace);\n\t\tfor (const dependency of (module.dependencies ?? []).map(getModuleDependencyNamespace)) {\n\t\t\tconst dependencyModule = modulesByNamespace.get(dependency);\n\t\t\tif (!dependencyModule) {\n\t\t\t\tif (registeredNamespaces.has(dependency)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" depends on missing module \"${dependency}\".`);\n\t\t\t}\n\t\t\tvisit(dependencyModule, [...path, module.namespace]);\n\t\t}\n\t\tvisiting.delete(module.namespace);\n\t\tvisited.add(module.namespace);\n\t\tsorted.push(module);\n\t}\n\n\tfor (const module of modules) {\n\t\tvisit(module, []);\n\t}\n\n\treturn sorted;\n}\n\nfunction assertAcyclicRelations(modules: FabricModule<unknown>[]): void {\n\tconst relationKinds = [\n\t\t{ label: \"owned containment\", include: (relation: ObjectRelationDefinition) => relation.semantics === \"owned\" },\n\t\t{ label: \"cascade-delete\", include: (relation: ObjectRelationDefinition) => relation.onTargetDelete === \"cascade\" },\n\t\t{ label: \"required-construction\", include: (relation: ObjectRelationDefinition) => relation.required === true },\n\t];\n\tfor (const kind of relationKinds) {\n\t\tconst edges = new Map<string, string[]>();\n\t\tfor (const module of modules) {\n\t\t\tfor (const objectType of module.objectTypes ?? []) {\n\t\t\t\tif (typeof objectType === \"string\") continue;\n\t\t\t\tconst source = qualifiedObjectType(module.namespace, objectType.type);\n\t\t\t\tedges.set(source, (objectType.relations ?? []).filter(kind.include).map((relation) => relation.target));\n\t\t\t}\n\t\t}\n\t\tconst visiting = new Set<string>();\n\t\tconst visited = new Set<string>();\n\t\tconst visit = (node: string, path: string[]): void => {\n\t\t\tif (visiting.has(node)) {\n\t\t\t\tthrow new Error(`${kind.label} relation cycle detected: ${[...path, node].join(\" -> \")}`);\n\t\t\t}\n\t\t\tif (visited.has(node)) return;\n\t\t\tvisiting.add(node);\n\t\t\tfor (const target of edges.get(node) ?? []) visit(target, [...path, node]);\n\t\t\tvisiting.delete(node);\n\t\t\tvisited.add(node);\n\t\t};\n\t\tfor (const node of edges.keys()) visit(node, []);\n\t}\n}\n\nexport function validateAndOrderFabricModules<TDb = unknown>(modules: FabricModule<TDb>[]): FabricModule<TDb>[] {\n\tconst availableNamespaces = new Set(modules.map((module) => module.namespace));\n\tconst plannedEventTypes = new Set(\n\t\tmodules.flatMap((module) => (module.eventTypes ?? []).map(getEventTypeName)),\n\t);\n\tfor (const eventType of createEventContractRegistry().eventTypes()) plannedEventTypes.add(eventType);\n\tconst availableObjectTypes = new Set([\n\t\t...modules.flatMap((module) =>\n\t\t\t(module.objectTypes ?? []).map((objectType) => qualifiedObjectType(module.namespace, getObjectTypeName(objectType))),\n\t\t),\n\t]);\n\tconst availableActions = new Map<string, ActionDefinition<unknown>>(\n\t\tmodules.flatMap((module) => (module.actions ?? []).map((action) => [action.actionId, action as ActionDefinition<unknown>] as const)),\n\t);\n\n\tfor (const module of modules) {\n\t\tvalidateManifest(module as FabricModule<unknown>, { availableNamespaces, plannedEventTypes, availableObjectTypes, availableActions });\n\t}\n\tassertAcyclicRelations(modules as FabricModule<unknown>[]);\n\treturn sortModulesByDependency(modules as FabricModule<unknown>[]) as FabricModule<TDb>[];\n}\n\n/** @deprecated Use createModuleRegistry(); registration is now explicit and instance-scoped. */\nexport function registerFabricModules<TDb = unknown>(modules: FabricModule<TDb>[]): FabricModule<TDb>[] {\n\treturn validateAndOrderFabricModules(modules);\n}\n\n/** @deprecated Use createModuleRegistry([module]); registration is now explicit and instance-scoped. */\nexport function registerFabricModule<TDb = unknown>(module: FabricModule<TDb>): void {\n\tvalidateAndOrderFabricModules([module]);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.cjs","names":["viewContractKey","createEventContractRegistry"],"sources":["../../modules/index.ts"],"sourcesContent":["import { assertActionFinalization, assertAdapterStepDeadlines } from \"../actions\";\nimport { assertSurfaceDeclaration } from \"../discovery\";\nimport type { ActionDefinition, ActionId } from \"../actions\";\nimport { createEventContractRegistry } from \"../events\";\nimport {\n\tassertPortableJsonSchema,\n\ttype JsonValue,\n\ttype PortableJsonSchema,\n} from \"../objects\";\nimport type { PolicyEvaluator, PolicyId } from \"../policies\";\nimport type { StateMachineDefinition } from \"../state-machines\";\nimport { viewContractKey, type ViewContract } from \"../projections\";\n\nexport interface ModuleDependency {\n\tnamespace: string;\n\tversion?: string;\n\toptional?: boolean;\n}\n\nexport type ModuleDependencyInput = string | ModuleDependency;\n\nexport interface IdPrefixRegistration {\n\tprefix: string;\n\tname: string;\n\tmodule: string;\n}\n\nexport interface EventTypeRegistration {\n\teventType: string;\n\tschemaVersion: number;\n\tdescription?: string;\n\tschema?: PortableJsonSchema;\n}\n\nexport type EventTypeRegistrationInput = string | EventTypeRegistration;\n\nexport interface ObjectTypeRegistration {\n\ttype: string;\n\tdisplayName?: string;\n\tidPrefix?: string;\n\tisCoreModuleType?: boolean;\n\tschema?: PortableJsonSchema;\n\tsemantics?: Record<string, JsonValue>;\n\trelations?: ObjectRelationDefinition[];\n\tinvariants?: DeclarativeInvariant[];\n}\n\nexport type ObjectRelationCardinality = \"one\" | \"many\";\nexport type ObjectRelationSemantics = \"reference\" | \"owned\";\nexport type ObjectRelationDeleteBehavior = \"restrict\" | \"cascade\" | \"set-null\";\n\nexport interface ObjectRelationDefinition {\n\tname: string;\n\ttarget: `${string}.${string}`;\n\tcardinality: ObjectRelationCardinality;\n\trequired?: boolean;\n\tsemantics: ObjectRelationSemantics;\n\tonTargetDelete: ObjectRelationDeleteBehavior;\n}\n\nexport type InvariantEnforcement =\n\t| \"json-schema\"\n\t| \"state-machine\"\n\t| \"policy\"\n\t| \"host-adapter\"\n\t| \"application\";\n\nexport interface DeclarativeInvariant {\n\tid: string;\n\tdescription: string;\n\trequired?: boolean;\n\tenforcement: InvariantEnforcement;\n\tenforcementRef?: string;\n}\n\nexport type ObjectTypeRegistrationInput = string | ObjectTypeRegistration;\n\nexport interface PolicyRegistration {\n\tid: string;\n\tversion?: string;\n\tdescription?: string;\n}\n\nexport interface StateMachineRegistration {\n\tentityType: string;\n\tstates: string[];\n}\n\nexport interface CapabilityPortRequirement {\n\tname: string;\n\tversion?: string;\n\tstandard?: { name: string; version?: string };\n}\n\nexport interface CapabilityRequirements {\n\tports?: CapabilityPortRequirement[];\n\tpermissions?: string[];\n\tentitlements?: string[];\n\tfeatureFlags?: string[];\n}\n\nexport interface CapabilityWorkflowTimer {\n\t/** Workflow-local identity of the deadline, for example \"right-to-cure\". */\n\tname: string;\n\t/** Configuration key the duration is resolved from when the workflow starts. */\n\tconfigKey: string;\n\tdescription?: string;\n}\n\nexport interface CapabilityWorkflowCompensation {\n\t/** Workflow step whose effect this reverses. */\n\tstep: string;\n\t/** Governed action that performs the reversal. Must belong to the declaring module. */\n\tactionId: `${string}.${string}`;\n}\n\n/**\n * A durable workflow this capability owns. Declaring it makes durability a\n * reviewable fact of the contract rather than a property of worker deployment:\n * the queue it runs on, the deadlines it carries, and what reverses each step\n * are all diffable.\n */\nexport interface CapabilityWorkflowDeclaration {\n\tname: string;\n\t/** Routing identity, conventionally `capability.vertical`. */\n\ttaskQueue: string;\n\t/** Event type whose arrival starts this workflow by choreography. */\n\tstartedBy?: string;\n\ttimers?: CapabilityWorkflowTimer[];\n\tcompensations?: CapabilityWorkflowCompensation[];\n}\n\nexport interface CapabilityMetadata {\n\tdisplayName: string;\n\tdescription: string;\n\tstability: \"experimental\" | \"beta\" | \"stable\" | \"deprecated\";\n\tdeprecated?: { since: string; replacement?: string; message: string };\n\trequirements?: CapabilityRequirements;\n\tcertification?: { profile: string; required: boolean };\n\t/** Durable workflows this capability owns, with their queues, deadlines and reversals. */\n\tworkflows?: CapabilityWorkflowDeclaration[];\n\t/** Namespaced declared data preserved by Platform and interpreted only by its owning package. */\n\textensions?: Record<string, JsonValue>;\n}\n\nexport interface FabricModule<TDb = unknown> {\n\tnamespace: string;\n\tversion?: string;\n\t/** Compiler manifest digest for exact runtime assembly verification. */\n\tmanifestDigest?: string;\n\tdisplayName?: string;\n\tdescription?: string;\n\tcapability?: CapabilityMetadata;\n\tdependencies?: ModuleDependencyInput[];\n\tobjectTypes?: ObjectTypeRegistrationInput[];\n\tsubjectTypes?: string[];\n\tidPrefixes?: IdPrefixRegistration[];\n\teventTypes?: EventTypeRegistrationInput[];\n\tactions?: ActionDefinition<TDb>[];\n\tpolicies?: unknown[];\n\tstateMachines?: unknown[];\n\tadapterDefinitions?: unknown[];\n\tpermissions?: unknown[];\n\troles?: unknown[];\n\tredactionRules?: unknown[];\n\tdataClassifications?: unknown[];\n\tretentionRules?: unknown[];\n\tevidenceRenderers?: unknown[];\n\tviews?: ViewContract[];\n}\n\nexport interface ModuleRegistry<TDb = unknown> {\n\tmodules: ReadonlyMap<string, FabricModule<TDb>>;\n\torderedModules: readonly FabricModule<TDb>[];\n\tresolveAction(actionId: `${string}.${string}`): ActionDefinition<TDb> | undefined;\n\tresolvePolicy(policyId: PolicyId): PolicyEvaluator | undefined;\n\tresolveStateMachine(entityType: string): StateMachineDefinition | undefined;\n\tresolveView(name: string, version: string): ViewContract | undefined;\n}\n\ninterface ModuleValidationContext {\n\tavailableNamespaces?: Set<string>;\n\tplannedEventTypes?: Set<string>;\n\tavailableObjectTypes?: Set<string>;\n\tavailableActions?: Map<string, ActionDefinition<unknown>>;\n}\n\nexport function getModuleDependencyNamespace(dependency: ModuleDependencyInput): string {\n\treturn typeof dependency === \"string\" ? dependency : dependency.namespace;\n}\n\nexport function getObjectTypeName(objectType: ObjectTypeRegistrationInput): string {\n\treturn typeof objectType === \"string\" ? objectType : objectType.type;\n}\n\nexport function getEventTypeName(eventType: EventTypeRegistrationInput): string {\n\treturn typeof eventType === \"string\" ? eventType : eventType.eventType;\n}\n\nexport function validateModuleNamespace(namespace: string): void {\n\tif (!namespace) {\n\t\tthrow new Error(\"Module namespace cannot be empty\");\n\t}\n\tif (!/^[a-z][a-z0-9-]*$/.test(namespace)) {\n\t\tthrow new Error(\n\t\t\t`Invalid module namespace: \"${namespace}\". Must be lowercase letters, numbers, and hyphens only.`,\n\t\t);\n\t}\n}\n\nexport function createModuleRegistry<TDb = unknown>(\n\tmodules: FabricModule<TDb>[] = [],\n): ModuleRegistry<TDb> {\n\tconst orderedModules = validateAndOrderFabricModules(modules);\n\tconst registered = new Map(orderedModules.map((module) => [module.namespace, module]));\n\tconst actions = new Map(orderedModules.flatMap((module) => (module.actions ?? []).map((action) => [action.actionId, action] as const)));\n\tconst policies = new Map(orderedModules.flatMap((module) => (module.policies ?? []).map((policy) => {\n\t\tconst evaluator = policy as PolicyEvaluator;\n\t\treturn [evaluator.policyId, evaluator] as const;\n\t})));\n\tconst machines = new Map(orderedModules.flatMap((module) => (module.stateMachines ?? []).map((machine) => {\n\t\tconst definition = machine as StateMachineDefinition;\n\t\treturn [definition.entityType, definition] as const;\n\t})));\n\tconst views = new Map(orderedModules.flatMap((module) => (module.views ?? []).map((view) => [viewContractKey(view), view] as const)));\n\treturn {\n\t\tmodules: registered,\n\t\torderedModules,\n\t\tresolveAction: (actionId) => actions.get(actionId),\n\t\tresolvePolicy: (policyId) => policies.get(policyId),\n\t\tresolveStateMachine: (entityType) => machines.get(entityType),\n\t\tresolveView: (name, version) => views.get(`${name}@${version}`),\n\t};\n}\n\nfunction validateIdentifierList(\n\tvalues: string[] | undefined,\n\tlabel: string,\n\tnamespace: string,\n): void {\n\tfor (const value of values ?? []) {\n\t\tif (!value) {\n\t\t\tthrow new Error(`Module \"${namespace}\" has an empty ${label} entry.`);\n\t\t}\n\t}\n}\n\nfunction assertJsonValue(value: unknown, path: string): asserts value is JsonValue {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return;\n\tif (typeof value === \"number\" && Number.isFinite(value)) return;\n\tif (Array.isArray(value)) {\n\t\tvalue.forEach((item, index) => assertJsonValue(item, `${path}[${index}]`));\n\t\treturn;\n\t}\n\tif (typeof value === \"object\") {\n\t\tfor (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n\t\t\tassertJsonValue(child, `${path}.${key}`);\n\t\t}\n\t\treturn;\n\t}\n\tthrow new Error(`${path} must contain JSON-serializable values.`);\n}\n\nfunction qualifiedObjectType(namespace: string, type: string): string {\n\treturn `${namespace}.${type}`;\n}\n\nfunction validateObjectDefinition(\n\tobjectType: ObjectTypeRegistrationInput,\n\tnamespace: string,\n\tcontext: ModuleValidationContext,\n): void {\n\tif (typeof objectType === \"string\") return;\n\tif (objectType.schema !== undefined) {\n\t\tassertPortableJsonSchema(objectType.schema, `Module \"${namespace}\" object \"${objectType.type}\" schema`);\n\t}\n\tif (objectType.semantics !== undefined) {\n\t\tassertJsonValue(objectType.semantics, `Module \"${namespace}\" object \"${objectType.type}\" semantics`);\n\t}\n\tconst relationNames = new Set<string>();\n\tfor (const relation of objectType.relations ?? []) {\n\t\tif (!/^[a-z][a-zA-Z0-9]*$/.test(relation.name)) {\n\t\t\tthrow new Error(`Module \"${namespace}\" object \"${objectType.type}\" has invalid relation name \"${relation.name}\".`);\n\t\t}\n\t\tif (relationNames.has(relation.name)) {\n\t\t\tthrow new Error(`Module \"${namespace}\" object \"${objectType.type}\" has duplicate relation \"${relation.name}\".`);\n\t\t}\n\t\trelationNames.add(relation.name);\n\t\tif (!/^[a-z][a-z0-9-]*\\.[A-Z][a-zA-Z0-9]*$/.test(relation.target)) {\n\t\t\tthrow new Error(`Relation \"${relation.name}\" target \"${relation.target}\" must be module-qualified.`);\n\t\t}\n\t\tif (context.availableObjectTypes && !context.availableObjectTypes.has(relation.target)) {\n\t\t\tthrow new Error(`Relation \"${relation.name}\" targets missing object type \"${relation.target}\".`);\n\t\t}\n\t\tif (relation.required && relation.onTargetDelete === \"set-null\") {\n\t\t\tthrow new Error(`Required relation \"${relation.name}\" cannot use onTargetDelete \"set-null\".`);\n\t\t}\n\t}\n\tconst invariantIds = new Set<string>();\n\tfor (const invariant of objectType.invariants ?? []) {\n\t\tif (!invariant.id.trim() || !invariant.description.trim()) {\n\t\t\tthrow new Error(`Module \"${namespace}\" object \"${objectType.type}\" has an invariant without an id or description.`);\n\t\t}\n\t\tif (invariantIds.has(invariant.id)) {\n\t\t\tthrow new Error(`Module \"${namespace}\" object \"${objectType.type}\" has duplicate invariant \"${invariant.id}\".`);\n\t\t}\n\t\tinvariantIds.add(invariant.id);\n\t\tif (invariant.required && !invariant.enforcementRef?.trim()) {\n\t\t\tthrow new Error(`Required invariant \"${invariant.id}\" must declare enforcementRef.`);\n\t\t}\n\t}\n}\n\nfunction validateCapabilityWorkflows(module: FabricModule<unknown>, context: ModuleValidationContext): void {\n\tconst workflows = module.capability?.workflows ?? [];\n\tconst actionsById = new Map((module.actions ?? []).map((action) => [action.actionId, action]));\n\tconst names = new Set<string>();\n\tfor (const workflow of workflows) {\n\t\tif (!/^[A-Za-z][A-Za-z0-9_-]*$/.test(workflow.name)) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" declares invalid workflow name \"${workflow.name}\".`);\n\t\t}\n\t\tif (names.has(workflow.name)) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" declares duplicate workflow \"${workflow.name}\".`);\n\t\t}\n\t\tnames.add(workflow.name);\n\t\tif (!/^[a-z][a-z0-9-]*(\\.[a-z][a-z0-9-]*)*$/.test(workflow.taskQueue)) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" declares invalid task queue \"${workflow.taskQueue}\".`);\n\t\t}\n\t\tif (workflow.startedBy !== undefined) {\n\t\t\tconst known = context.plannedEventTypes?.has(workflow.startedBy)\n\t\t\t\t?? (module.eventTypes ?? []).some((eventType) => getEventTypeName(eventType) === workflow.startedBy);\n\t\t\tif (!known) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" is started by unknown event type \"${workflow.startedBy}\".`);\n\t\t\t}\n\t\t}\n\t\tconst timerNames = new Set<string>();\n\t\tfor (const timer of workflow.timers ?? []) {\n\t\t\tif (!timer.name.trim() || !timer.configKey.trim()) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" has a timer without a name or configKey.`);\n\t\t\t}\n\t\t\tif (timerNames.has(timer.name)) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" declares duplicate timer \"${timer.name}\".`);\n\t\t\t}\n\t\t\ttimerNames.add(timer.name);\n\t\t}\n\t\tconst steps = new Set<string>();\n\t\tfor (const compensation of workflow.compensations ?? []) {\n\t\t\tif (!compensation.step.trim()) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" has a compensation without a step.`);\n\t\t\t}\n\t\t\tif (steps.has(compensation.step)) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" declares duplicate compensation for step \"${compensation.step}\".`);\n\t\t\t}\n\t\t\tsteps.add(compensation.step);\n\t\t\tconst compensatingAction = actionsById.get(compensation.actionId);\n\t\t\tif (!compensatingAction) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" compensates step \"${compensation.step}\" with unknown action \"${compensation.actionId}\".`);\n\t\t\t}\n\t\t\t// An unwind is retried like any other durable step, so a reversal that cannot be\n\t\t\t// safely repeated would turn one failure into a different kind of corruption.\n\t\t\tif (!compensatingAction.idempotent || compensatingAction.execution?.idempotency === \"prohibited\") {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" compensates step \"${compensation.step}\" with non-idempotent action \"${compensation.actionId}\"; a reversal must be safely repeatable.`);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction validateManifest(module: FabricModule<unknown>, context: ModuleValidationContext = {}): void {\n\tvalidateModuleNamespace(module.namespace);\n\n\tconst dependencies = (module.dependencies ?? []).map(getModuleDependencyNamespace);\n\tconst objectTypes = (module.objectTypes ?? []).map(getObjectTypeName);\n\tconst eventTypes = (module.eventTypes ?? []).map(getEventTypeName);\n\tif (module.capability) {\n\t\tif (!module.capability.displayName.trim() || !module.capability.description.trim()) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" capability requires displayName and description.`);\n\t\t}\n\t\tfor (const namespace of Object.keys(module.capability.extensions ?? {})) {\n\t\t\tif (!/^[a-z][a-z0-9.-]*\\.[a-z0-9.-]+\\/v[1-9][0-9]*$/.test(namespace)) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" capability has invalid extension namespace \"${namespace}\".`);\n\t\t\t}\n\t\t}\n\t\tfor (const port of module.capability.requirements?.ports ?? []) {\n\t\t\t// Dotted segments are permitted so a capability can require a port\n\t\t\t// defined outside this repository: an enterprise integrates hundreds\n\t\t\t// of external systems, and namespacing is what keeps two of them from\n\t\t\t// colliding on a name. Widening only, so existing names still parse.\n\t\t\tif (!/^[a-z][a-z0-9-]*(?:\\.[a-z0-9-]+)*$/.test(port.name)) throw new Error(`Module \"${module.namespace}\" capability has invalid port requirement \"${port.name}\".`);\n\t\t}\n\t\tvalidateCapabilityWorkflows(module, context);\n\t}\n\tfor (const eventType of module.eventTypes ?? []) if (typeof eventType !== \"string\" && eventType.schema) assertPortableJsonSchema(eventType.schema, `Event \"${eventType.eventType}\" schema`);\n\tfor (const action of module.actions ?? []) {\n\t\tif (action.execution?.idempotency === \"required\" && !action.idempotent) throw new Error(`Action \"${action.actionId}\" requires idempotency but is not declared idempotent.`);\n\t\tif (action.execution?.connectivity === \"offline-capturable\" && action.execution.idempotency === \"prohibited\") throw new Error(`Offline action \"${action.actionId}\" cannot prohibit idempotency.`);\n\t\tif (action.execution?.completionDeadlineMs !== undefined && !(typeof action.execution.completionDeadlineMs === \"number\" && action.execution.completionDeadlineMs > 0)) throw new Error(`Action \"${action.actionId}\" completionDeadlineMs must be a positive number of milliseconds.`);\n\t\tif (action.execution?.completion === \"immediate\" && action.execution.completionDeadlineMs !== undefined) throw new Error(`Immediate action \"${action.actionId}\" cannot declare a completion deadline; nothing external completes it.`);\n\t}\n\tfor (const view of module.views ?? []) if (view.usage?.collection?.filterSchema) assertPortableJsonSchema(view.usage.collection.filterSchema, `View \"${view.name}\" filter schema`);\n\n\tfor (const dependency of dependencies) {\n\t\tvalidateModuleNamespace(dependency);\n\t\tif (dependency === module.namespace) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" cannot depend on itself.`);\n\t\t}\n\t\tif (context.availableNamespaces && !context.availableNamespaces.has(dependency)) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" depends on missing module \"${dependency}\".`);\n\t\t}\n\t}\n\n\tvalidateIdentifierList(objectTypes, \"objectTypes\", module.namespace);\n\tvalidateIdentifierList(module.subjectTypes, \"subjectTypes\", module.namespace);\n\tvalidateIdentifierList(eventTypes, \"eventTypes\", module.namespace);\n\n\tfor (const objectType of objectTypes) {\n\t\tif (!/^[A-Z][a-zA-Z0-9]*$/.test(objectType)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid object type: \"${objectType}\". Object types must be PascalCase alphanumeric.`,\n\t\t\t);\n\t\t}\n\t}\n\tfor (const objectType of module.objectTypes ?? []) {\n\t\tif (typeof objectType !== \"string\") {\n\t\t\tfor (const relation of objectType.relations ?? []) {\n\t\t\t\tconst targetNamespace = relation.target.slice(0, relation.target.indexOf(\".\"));\n\t\t\t\tif (targetNamespace !== module.namespace && !dependencies.includes(targetNamespace)) {\n\t\t\t\t\tthrow new Error(`Module \"${module.namespace}\" relation \"${relation.name}\" targets module \"${targetNamespace}\" without declaring it as a dependency.`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tvalidateObjectDefinition(objectType, module.namespace, context);\n\t}\n\n\tfor (const action of module.actions ?? []) {\n\t\tassertSurfaceDeclaration(action, `Action \"${action?.actionId ?? \"unknown\"}\"`);\n\t\tassertAdapterStepDeadlines(action);\n\t\tassertActionFinalization(action);\n\t\tlet parameterSchema: unknown;\n\t\ttry { parameterSchema = (action.schema as { toJSONSchema?: () => unknown }).toJSONSchema?.(); } catch { parameterSchema = undefined; }\n\t\tif (parameterSchema !== undefined) assertPortableJsonSchema(parameterSchema, `Action \"${action.actionId}\" parameters`);\n\t\tlet resultSchema: unknown;\n\t\ttry { resultSchema = (action.resultSchema as { toJSONSchema?: () => unknown } | undefined)?.toJSONSchema?.(); } catch { resultSchema = undefined; }\n\t\tif (resultSchema !== undefined) assertPortableJsonSchema(resultSchema, `Action \"${action.actionId}\" result`);\n\t\tif (!/^[a-z][a-z0-9-]*\\.[a-z][a-z0-9_]*$/.test(action.actionId)) {\n\t\t\tthrow new Error(`Invalid action ID: ${action.actionId}`);\n\t\t}\n\n\t\tif (action.namespace !== module.namespace) {\n\t\t\tthrow new Error(\n\t\t\t\t`Action \"${action.actionId}\" declares namespace \"${action.namespace}\" ` +\n\t\t\t\t\t`but is registered by module \"${module.namespace}\".`,\n\t\t\t);\n\t\t}\n\n\t\tif (!action.actionId.startsWith(`${module.namespace}.`)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Action \"${action.actionId}\" must start with module namespace \"${module.namespace}.\"`,\n\t\t\t);\n\t\t}\n\n\t\tif (action.mutatesDomain && action.emitsEvents.length === 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`Action \"${action.actionId}\" mutates domain but emits no events. ` +\n\t\t\t\t\t`Every mutating action must emit at least one AssetEvent.`,\n\t\t\t);\n\t\t}\n\n\t\tif (action.admitSubmission !== undefined && typeof action.admitSubmission !== \"function\") {\n\t\t\tthrow new Error(`Action \"${action.actionId}\" declares admitSubmission that is not a function.`);\n\t\t}\n\t\tconst stagedTargets = action.stagesInvocations ?? [];\n\t\tconst stagedInvocationPrincipals = action.stagedInvocationPrincipals;\n\t\tif (stagedInvocationPrincipals !== undefined &&\n\t\t\t(!stagedInvocationPrincipals || typeof stagedInvocationPrincipals !== \"object\" || Array.isArray(stagedInvocationPrincipals))) {\n\t\t\tthrow new Error(`Action \"${action.actionId}\" stagedInvocationPrincipals must be an object.`);\n\t\t}\n\t\tfor (const [targetId, principal] of Object.entries(stagedInvocationPrincipals ?? {})) {\n\t\t\tif (!stagedTargets.includes(targetId as ActionId)) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" does not declare staged invocation target \"${targetId}\".`);\n\t\t\t}\n\t\t\tif (typeof principal !== \"string\" || !/^[a-z][a-z0-9._:-]{0,127}$/.test(principal)) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" declares invalid staged invocation principal for \"${targetId}\".`);\n\t\t\t}\n\t\t}\n\t\tfor (const [index, targetId] of stagedTargets.entries()) {\n\t\t\tif (stagedTargets.indexOf(targetId) !== index) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" declares duplicate staged invocation target \"${targetId}\".`);\n\t\t\t}\n\t\t\tif (targetId === action.actionId) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" cannot stage itself.`);\n\t\t\t}\n\t\t\tconst target = context.availableActions?.get(targetId);\n\t\t\tif (!target) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" stages unknown action \"${targetId}\".`);\n\t\t\t}\n\t\t\tconst targetNamespace = targetId.slice(0, targetId.indexOf(\".\"));\n\t\t\tif (targetNamespace !== module.namespace && !dependencies.includes(targetNamespace)) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" stages action \"${targetId}\" without declaring module \"${targetNamespace}\" as a dependency.`);\n\t\t\t}\n\t\t\tif (target.execution?.authorityMoment === \"capture\") {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" cannot stage capture-authority action \"${targetId}\".`);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst viewKeys = new Set<string>();\n\tfor (const view of module.views ?? []) {\n\t\tassertSurfaceDeclaration(view, `View \"${view?.name ?? \"unknown\"}\"`);\n\t\tif (!view.name.startsWith(`${module.namespace}/`) || !/^[a-z][a-z0-9-]*\\/[a-z][a-z0-9/_-]*$/.test(view.name)) {\n\t\t\tthrow new Error(`View \"${view.name}\" must start with module namespace \"${module.namespace}/\" and use lowercase path segments.`);\n\t\t}\n\t\tif (!view.version.trim()) throw new Error(`View \"${view.name}\" must declare a version.`);\n\t\tconst key = `${view.name}@${view.version}`;\n\t\tif (viewKeys.has(key)) throw new Error(`Module \"${module.namespace}\" has duplicate view contract \"${key}\".`);\n\t\tviewKeys.add(key);\n\t\tassertPortableJsonSchema(view.shape, `View \"${key}\" shape`);\n\t\tif (view.parameterSchema !== undefined) assertPortableJsonSchema(view.parameterSchema, `View \"${key}\" parameters`);\n\t\tif (!Number.isInteger(view.snapshotVersion) || view.snapshotVersion < 1) {\n\t\t\tthrow new Error(`View \"${key}\" snapshotVersion must be a positive integer.`);\n\t\t}\n\t\tif ((view.compatibleSnapshotVersions?.some((version) => version !== view.snapshotVersion) ?? false) && !view.upgradeSnapshot) {\n\t\t\tthrow new Error(`View \"${key}\" declares older compatible snapshots but no upgradeSnapshot function.`);\n\t\t}\n\t\tfor (const consumption of view.consumes) {\n\t\t\tconst isPlanned = context.plannedEventTypes?.has(consumption.eventType) ?? false;\n\t\t\tconst isModuleEvent = eventTypes.includes(consumption.eventType);\n\t\t\tif (!isPlanned && !isModuleEvent) {\n\t\t\t\tthrow new Error(`View \"${key}\" consumes unknown event type \"${consumption.eventType}\".`);\n\t\t\t}\n\t\t\tif (consumption.schemaVersions.length === 0 || consumption.schemaVersions.some((version) => !Number.isInteger(version) || version < 1)) {\n\t\t\t\tthrow new Error(`View \"${key}\" must declare positive consumed schema versions for \"${consumption.eventType}\".`);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction sortModulesByDependency(\n\tmodules: FabricModule<unknown>[],\n\tregisteredNamespaces: ReadonlySet<string> = new Set(),\n): FabricModule<unknown>[] {\n\tconst modulesByNamespace = new Map<string, FabricModule<unknown>>();\n\n\tfor (const module of modules) {\n\t\tvalidateModuleNamespace(module.namespace);\n\t\tif (modulesByNamespace.has(module.namespace)) {\n\t\t\tthrow new Error(`Duplicate FabricModule namespace \"${module.namespace}\".`);\n\t\t}\n\t\tmodulesByNamespace.set(module.namespace, module);\n\t}\n\n\tconst sorted: FabricModule<unknown>[] = [];\n\tconst visiting = new Set<string>();\n\tconst visited = new Set<string>();\n\n\tfunction visit(module: FabricModule<unknown>, path: string[]): void {\n\t\tif (visited.has(module.namespace)) {\n\t\t\treturn;\n\t\t}\n\t\tif (visiting.has(module.namespace)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cyclic Fabric module dependency detected: ${[...path, module.namespace].join(\" -> \")}`,\n\t\t\t);\n\t\t}\n\n\t\tvisiting.add(module.namespace);\n\t\tfor (const dependency of (module.dependencies ?? []).map(getModuleDependencyNamespace)) {\n\t\t\tconst dependencyModule = modulesByNamespace.get(dependency);\n\t\t\tif (!dependencyModule) {\n\t\t\t\tif (registeredNamespaces.has(dependency)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" depends on missing module \"${dependency}\".`);\n\t\t\t}\n\t\t\tvisit(dependencyModule, [...path, module.namespace]);\n\t\t}\n\t\tvisiting.delete(module.namespace);\n\t\tvisited.add(module.namespace);\n\t\tsorted.push(module);\n\t}\n\n\tfor (const module of modules) {\n\t\tvisit(module, []);\n\t}\n\n\treturn sorted;\n}\n\nfunction assertAcyclicRelations(modules: FabricModule<unknown>[]): void {\n\tconst relationKinds = [\n\t\t{ label: \"owned containment\", include: (relation: ObjectRelationDefinition) => relation.semantics === \"owned\" },\n\t\t{ label: \"cascade-delete\", include: (relation: ObjectRelationDefinition) => relation.onTargetDelete === \"cascade\" },\n\t\t{ label: \"required-construction\", include: (relation: ObjectRelationDefinition) => relation.required === true },\n\t];\n\tfor (const kind of relationKinds) {\n\t\tconst edges = new Map<string, string[]>();\n\t\tfor (const module of modules) {\n\t\t\tfor (const objectType of module.objectTypes ?? []) {\n\t\t\t\tif (typeof objectType === \"string\") continue;\n\t\t\t\tconst source = qualifiedObjectType(module.namespace, objectType.type);\n\t\t\t\tedges.set(source, (objectType.relations ?? []).filter(kind.include).map((relation) => relation.target));\n\t\t\t}\n\t\t}\n\t\tconst visiting = new Set<string>();\n\t\tconst visited = new Set<string>();\n\t\tconst visit = (node: string, path: string[]): void => {\n\t\t\tif (visiting.has(node)) {\n\t\t\t\tthrow new Error(`${kind.label} relation cycle detected: ${[...path, node].join(\" -> \")}`);\n\t\t\t}\n\t\t\tif (visited.has(node)) return;\n\t\t\tvisiting.add(node);\n\t\t\tfor (const target of edges.get(node) ?? []) visit(target, [...path, node]);\n\t\t\tvisiting.delete(node);\n\t\t\tvisited.add(node);\n\t\t};\n\t\tfor (const node of edges.keys()) visit(node, []);\n\t}\n}\n\nexport function validateAndOrderFabricModules<TDb = unknown>(modules: FabricModule<TDb>[]): FabricModule<TDb>[] {\n\tconst availableNamespaces = new Set(modules.map((module) => module.namespace));\n\tconst plannedEventTypes = new Set(\n\t\tmodules.flatMap((module) => (module.eventTypes ?? []).map(getEventTypeName)),\n\t);\n\tfor (const eventType of createEventContractRegistry().eventTypes()) plannedEventTypes.add(eventType);\n\tconst availableObjectTypes = new Set([\n\t\t...modules.flatMap((module) =>\n\t\t\t(module.objectTypes ?? []).map((objectType) => qualifiedObjectType(module.namespace, getObjectTypeName(objectType))),\n\t\t),\n\t]);\n\tconst availableActions = new Map<string, ActionDefinition<unknown>>(\n\t\tmodules.flatMap((module) => (module.actions ?? []).map((action) => [action.actionId, action as ActionDefinition<unknown>] as const)),\n\t);\n\n\tfor (const module of modules) {\n\t\tvalidateManifest(module as FabricModule<unknown>, { availableNamespaces, plannedEventTypes, availableObjectTypes, availableActions });\n\t}\n\tassertAcyclicRelations(modules as FabricModule<unknown>[]);\n\treturn sortModulesByDependency(modules as FabricModule<unknown>[]) as FabricModule<TDb>[];\n}\n\n/** @deprecated Use createModuleRegistry(); registration is now explicit and instance-scoped. */\nexport function registerFabricModules<TDb = unknown>(modules: FabricModule<TDb>[]): FabricModule<TDb>[] {\n\treturn validateAndOrderFabricModules(modules);\n}\n\n/** @deprecated Use createModuleRegistry([module]); registration is now explicit and instance-scoped. */\nexport function registerFabricModule<TDb = unknown>(module: FabricModule<TDb>): void {\n\tvalidateAndOrderFabricModules([module]);\n}\n"],"mappings":"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"}
|
package/dist/modules/index.js
CHANGED
|
@@ -167,6 +167,12 @@ function validateManifest(module, context = {}) {
|
|
|
167
167
|
if (action.mutatesDomain && action.emitsEvents.length === 0) throw new Error(`Action "${action.actionId}" mutates domain but emits no events. Every mutating action must emit at least one AssetEvent.`);
|
|
168
168
|
if (action.admitSubmission !== void 0 && typeof action.admitSubmission !== "function") throw new Error(`Action "${action.actionId}" declares admitSubmission that is not a function.`);
|
|
169
169
|
const stagedTargets = action.stagesInvocations ?? [];
|
|
170
|
+
const stagedInvocationPrincipals = action.stagedInvocationPrincipals;
|
|
171
|
+
if (stagedInvocationPrincipals !== void 0 && (!stagedInvocationPrincipals || typeof stagedInvocationPrincipals !== "object" || Array.isArray(stagedInvocationPrincipals))) throw new Error(`Action "${action.actionId}" stagedInvocationPrincipals must be an object.`);
|
|
172
|
+
for (const [targetId, principal] of Object.entries(stagedInvocationPrincipals ?? {})) {
|
|
173
|
+
if (!stagedTargets.includes(targetId)) throw new Error(`Action "${action.actionId}" does not declare staged invocation target "${targetId}".`);
|
|
174
|
+
if (typeof principal !== "string" || !/^[a-z][a-z0-9._:-]{0,127}$/.test(principal)) throw new Error(`Action "${action.actionId}" declares invalid staged invocation principal for "${targetId}".`);
|
|
175
|
+
}
|
|
170
176
|
for (const [index, targetId] of stagedTargets.entries()) {
|
|
171
177
|
if (stagedTargets.indexOf(targetId) !== index) throw new Error(`Action "${action.actionId}" declares duplicate staged invocation target "${targetId}".`);
|
|
172
178
|
if (targetId === action.actionId) throw new Error(`Action "${action.actionId}" cannot stage itself.`);
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../modules/index.ts"],"sourcesContent":["import { assertActionFinalization, assertAdapterStepDeadlines } from \"../actions\";\nimport { assertSurfaceDeclaration } from \"../discovery\";\nimport type { ActionDefinition } from \"../actions\";\nimport { createEventContractRegistry } from \"../events\";\nimport {\n\tassertPortableJsonSchema,\n\ttype JsonValue,\n\ttype PortableJsonSchema,\n} from \"../objects\";\nimport type { PolicyEvaluator, PolicyId } from \"../policies\";\nimport type { StateMachineDefinition } from \"../state-machines\";\nimport { viewContractKey, type ViewContract } from \"../projections\";\n\nexport interface ModuleDependency {\n\tnamespace: string;\n\tversion?: string;\n\toptional?: boolean;\n}\n\nexport type ModuleDependencyInput = string | ModuleDependency;\n\nexport interface IdPrefixRegistration {\n\tprefix: string;\n\tname: string;\n\tmodule: string;\n}\n\nexport interface EventTypeRegistration {\n\teventType: string;\n\tschemaVersion: number;\n\tdescription?: string;\n\tschema?: PortableJsonSchema;\n}\n\nexport type EventTypeRegistrationInput = string | EventTypeRegistration;\n\nexport interface ObjectTypeRegistration {\n\ttype: string;\n\tdisplayName?: string;\n\tidPrefix?: string;\n\tisCoreModuleType?: boolean;\n\tschema?: PortableJsonSchema;\n\tsemantics?: Record<string, JsonValue>;\n\trelations?: ObjectRelationDefinition[];\n\tinvariants?: DeclarativeInvariant[];\n}\n\nexport type ObjectRelationCardinality = \"one\" | \"many\";\nexport type ObjectRelationSemantics = \"reference\" | \"owned\";\nexport type ObjectRelationDeleteBehavior = \"restrict\" | \"cascade\" | \"set-null\";\n\nexport interface ObjectRelationDefinition {\n\tname: string;\n\ttarget: `${string}.${string}`;\n\tcardinality: ObjectRelationCardinality;\n\trequired?: boolean;\n\tsemantics: ObjectRelationSemantics;\n\tonTargetDelete: ObjectRelationDeleteBehavior;\n}\n\nexport type InvariantEnforcement =\n\t| \"json-schema\"\n\t| \"state-machine\"\n\t| \"policy\"\n\t| \"host-adapter\"\n\t| \"application\";\n\nexport interface DeclarativeInvariant {\n\tid: string;\n\tdescription: string;\n\trequired?: boolean;\n\tenforcement: InvariantEnforcement;\n\tenforcementRef?: string;\n}\n\nexport type ObjectTypeRegistrationInput = string | ObjectTypeRegistration;\n\nexport interface PolicyRegistration {\n\tid: string;\n\tversion?: string;\n\tdescription?: string;\n}\n\nexport interface StateMachineRegistration {\n\tentityType: string;\n\tstates: string[];\n}\n\nexport interface CapabilityPortRequirement {\n\tname: string;\n\tversion?: string;\n\tstandard?: { name: string; version?: string };\n}\n\nexport interface CapabilityRequirements {\n\tports?: CapabilityPortRequirement[];\n\tpermissions?: string[];\n\tentitlements?: string[];\n\tfeatureFlags?: string[];\n}\n\nexport interface CapabilityWorkflowTimer {\n\t/** Workflow-local identity of the deadline, for example \"right-to-cure\". */\n\tname: string;\n\t/** Configuration key the duration is resolved from when the workflow starts. */\n\tconfigKey: string;\n\tdescription?: string;\n}\n\nexport interface CapabilityWorkflowCompensation {\n\t/** Workflow step whose effect this reverses. */\n\tstep: string;\n\t/** Governed action that performs the reversal. Must belong to the declaring module. */\n\tactionId: `${string}.${string}`;\n}\n\n/**\n * A durable workflow this capability owns. Declaring it makes durability a\n * reviewable fact of the contract rather than a property of worker deployment:\n * the queue it runs on, the deadlines it carries, and what reverses each step\n * are all diffable.\n */\nexport interface CapabilityWorkflowDeclaration {\n\tname: string;\n\t/** Routing identity, conventionally `capability.vertical`. */\n\ttaskQueue: string;\n\t/** Event type whose arrival starts this workflow by choreography. */\n\tstartedBy?: string;\n\ttimers?: CapabilityWorkflowTimer[];\n\tcompensations?: CapabilityWorkflowCompensation[];\n}\n\nexport interface CapabilityMetadata {\n\tdisplayName: string;\n\tdescription: string;\n\tstability: \"experimental\" | \"beta\" | \"stable\" | \"deprecated\";\n\tdeprecated?: { since: string; replacement?: string; message: string };\n\trequirements?: CapabilityRequirements;\n\tcertification?: { profile: string; required: boolean };\n\t/** Durable workflows this capability owns, with their queues, deadlines and reversals. */\n\tworkflows?: CapabilityWorkflowDeclaration[];\n\t/** Namespaced declared data preserved by Platform and interpreted only by its owning package. */\n\textensions?: Record<string, JsonValue>;\n}\n\nexport interface FabricModule<TDb = unknown> {\n\tnamespace: string;\n\tversion?: string;\n\t/** Compiler manifest digest for exact runtime assembly verification. */\n\tmanifestDigest?: string;\n\tdisplayName?: string;\n\tdescription?: string;\n\tcapability?: CapabilityMetadata;\n\tdependencies?: ModuleDependencyInput[];\n\tobjectTypes?: ObjectTypeRegistrationInput[];\n\tsubjectTypes?: string[];\n\tidPrefixes?: IdPrefixRegistration[];\n\teventTypes?: EventTypeRegistrationInput[];\n\tactions?: ActionDefinition<TDb>[];\n\tpolicies?: unknown[];\n\tstateMachines?: unknown[];\n\tadapterDefinitions?: unknown[];\n\tpermissions?: unknown[];\n\troles?: unknown[];\n\tredactionRules?: unknown[];\n\tdataClassifications?: unknown[];\n\tretentionRules?: unknown[];\n\tevidenceRenderers?: unknown[];\n\tviews?: ViewContract[];\n}\n\nexport interface ModuleRegistry<TDb = unknown> {\n\tmodules: ReadonlyMap<string, FabricModule<TDb>>;\n\torderedModules: readonly FabricModule<TDb>[];\n\tresolveAction(actionId: `${string}.${string}`): ActionDefinition<TDb> | undefined;\n\tresolvePolicy(policyId: PolicyId): PolicyEvaluator | undefined;\n\tresolveStateMachine(entityType: string): StateMachineDefinition | undefined;\n\tresolveView(name: string, version: string): ViewContract | undefined;\n}\n\ninterface ModuleValidationContext {\n\tavailableNamespaces?: Set<string>;\n\tplannedEventTypes?: Set<string>;\n\tavailableObjectTypes?: Set<string>;\n\tavailableActions?: Map<string, ActionDefinition<unknown>>;\n}\n\nexport function getModuleDependencyNamespace(dependency: ModuleDependencyInput): string {\n\treturn typeof dependency === \"string\" ? dependency : dependency.namespace;\n}\n\nexport function getObjectTypeName(objectType: ObjectTypeRegistrationInput): string {\n\treturn typeof objectType === \"string\" ? objectType : objectType.type;\n}\n\nexport function getEventTypeName(eventType: EventTypeRegistrationInput): string {\n\treturn typeof eventType === \"string\" ? eventType : eventType.eventType;\n}\n\nexport function validateModuleNamespace(namespace: string): void {\n\tif (!namespace) {\n\t\tthrow new Error(\"Module namespace cannot be empty\");\n\t}\n\tif (!/^[a-z][a-z0-9-]*$/.test(namespace)) {\n\t\tthrow new Error(\n\t\t\t`Invalid module namespace: \"${namespace}\". Must be lowercase letters, numbers, and hyphens only.`,\n\t\t);\n\t}\n}\n\nexport function createModuleRegistry<TDb = unknown>(\n\tmodules: FabricModule<TDb>[] = [],\n): ModuleRegistry<TDb> {\n\tconst orderedModules = validateAndOrderFabricModules(modules);\n\tconst registered = new Map(orderedModules.map((module) => [module.namespace, module]));\n\tconst actions = new Map(orderedModules.flatMap((module) => (module.actions ?? []).map((action) => [action.actionId, action] as const)));\n\tconst policies = new Map(orderedModules.flatMap((module) => (module.policies ?? []).map((policy) => {\n\t\tconst evaluator = policy as PolicyEvaluator;\n\t\treturn [evaluator.policyId, evaluator] as const;\n\t})));\n\tconst machines = new Map(orderedModules.flatMap((module) => (module.stateMachines ?? []).map((machine) => {\n\t\tconst definition = machine as StateMachineDefinition;\n\t\treturn [definition.entityType, definition] as const;\n\t})));\n\tconst views = new Map(orderedModules.flatMap((module) => (module.views ?? []).map((view) => [viewContractKey(view), view] as const)));\n\treturn {\n\t\tmodules: registered,\n\t\torderedModules,\n\t\tresolveAction: (actionId) => actions.get(actionId),\n\t\tresolvePolicy: (policyId) => policies.get(policyId),\n\t\tresolveStateMachine: (entityType) => machines.get(entityType),\n\t\tresolveView: (name, version) => views.get(`${name}@${version}`),\n\t};\n}\n\nfunction validateIdentifierList(\n\tvalues: string[] | undefined,\n\tlabel: string,\n\tnamespace: string,\n): void {\n\tfor (const value of values ?? []) {\n\t\tif (!value) {\n\t\t\tthrow new Error(`Module \"${namespace}\" has an empty ${label} entry.`);\n\t\t}\n\t}\n}\n\nfunction assertJsonValue(value: unknown, path: string): asserts value is JsonValue {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return;\n\tif (typeof value === \"number\" && Number.isFinite(value)) return;\n\tif (Array.isArray(value)) {\n\t\tvalue.forEach((item, index) => assertJsonValue(item, `${path}[${index}]`));\n\t\treturn;\n\t}\n\tif (typeof value === \"object\") {\n\t\tfor (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n\t\t\tassertJsonValue(child, `${path}.${key}`);\n\t\t}\n\t\treturn;\n\t}\n\tthrow new Error(`${path} must contain JSON-serializable values.`);\n}\n\nfunction qualifiedObjectType(namespace: string, type: string): string {\n\treturn `${namespace}.${type}`;\n}\n\nfunction validateObjectDefinition(\n\tobjectType: ObjectTypeRegistrationInput,\n\tnamespace: string,\n\tcontext: ModuleValidationContext,\n): void {\n\tif (typeof objectType === \"string\") return;\n\tif (objectType.schema !== undefined) {\n\t\tassertPortableJsonSchema(objectType.schema, `Module \"${namespace}\" object \"${objectType.type}\" schema`);\n\t}\n\tif (objectType.semantics !== undefined) {\n\t\tassertJsonValue(objectType.semantics, `Module \"${namespace}\" object \"${objectType.type}\" semantics`);\n\t}\n\tconst relationNames = new Set<string>();\n\tfor (const relation of objectType.relations ?? []) {\n\t\tif (!/^[a-z][a-zA-Z0-9]*$/.test(relation.name)) {\n\t\t\tthrow new Error(`Module \"${namespace}\" object \"${objectType.type}\" has invalid relation name \"${relation.name}\".`);\n\t\t}\n\t\tif (relationNames.has(relation.name)) {\n\t\t\tthrow new Error(`Module \"${namespace}\" object \"${objectType.type}\" has duplicate relation \"${relation.name}\".`);\n\t\t}\n\t\trelationNames.add(relation.name);\n\t\tif (!/^[a-z][a-z0-9-]*\\.[A-Z][a-zA-Z0-9]*$/.test(relation.target)) {\n\t\t\tthrow new Error(`Relation \"${relation.name}\" target \"${relation.target}\" must be module-qualified.`);\n\t\t}\n\t\tif (context.availableObjectTypes && !context.availableObjectTypes.has(relation.target)) {\n\t\t\tthrow new Error(`Relation \"${relation.name}\" targets missing object type \"${relation.target}\".`);\n\t\t}\n\t\tif (relation.required && relation.onTargetDelete === \"set-null\") {\n\t\t\tthrow new Error(`Required relation \"${relation.name}\" cannot use onTargetDelete \"set-null\".`);\n\t\t}\n\t}\n\tconst invariantIds = new Set<string>();\n\tfor (const invariant of objectType.invariants ?? []) {\n\t\tif (!invariant.id.trim() || !invariant.description.trim()) {\n\t\t\tthrow new Error(`Module \"${namespace}\" object \"${objectType.type}\" has an invariant without an id or description.`);\n\t\t}\n\t\tif (invariantIds.has(invariant.id)) {\n\t\t\tthrow new Error(`Module \"${namespace}\" object \"${objectType.type}\" has duplicate invariant \"${invariant.id}\".`);\n\t\t}\n\t\tinvariantIds.add(invariant.id);\n\t\tif (invariant.required && !invariant.enforcementRef?.trim()) {\n\t\t\tthrow new Error(`Required invariant \"${invariant.id}\" must declare enforcementRef.`);\n\t\t}\n\t}\n}\n\nfunction validateCapabilityWorkflows(module: FabricModule<unknown>, context: ModuleValidationContext): void {\n\tconst workflows = module.capability?.workflows ?? [];\n\tconst actionsById = new Map((module.actions ?? []).map((action) => [action.actionId, action]));\n\tconst names = new Set<string>();\n\tfor (const workflow of workflows) {\n\t\tif (!/^[A-Za-z][A-Za-z0-9_-]*$/.test(workflow.name)) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" declares invalid workflow name \"${workflow.name}\".`);\n\t\t}\n\t\tif (names.has(workflow.name)) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" declares duplicate workflow \"${workflow.name}\".`);\n\t\t}\n\t\tnames.add(workflow.name);\n\t\tif (!/^[a-z][a-z0-9-]*(\\.[a-z][a-z0-9-]*)*$/.test(workflow.taskQueue)) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" declares invalid task queue \"${workflow.taskQueue}\".`);\n\t\t}\n\t\tif (workflow.startedBy !== undefined) {\n\t\t\tconst known = context.plannedEventTypes?.has(workflow.startedBy)\n\t\t\t\t?? (module.eventTypes ?? []).some((eventType) => getEventTypeName(eventType) === workflow.startedBy);\n\t\t\tif (!known) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" is started by unknown event type \"${workflow.startedBy}\".`);\n\t\t\t}\n\t\t}\n\t\tconst timerNames = new Set<string>();\n\t\tfor (const timer of workflow.timers ?? []) {\n\t\t\tif (!timer.name.trim() || !timer.configKey.trim()) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" has a timer without a name or configKey.`);\n\t\t\t}\n\t\t\tif (timerNames.has(timer.name)) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" declares duplicate timer \"${timer.name}\".`);\n\t\t\t}\n\t\t\ttimerNames.add(timer.name);\n\t\t}\n\t\tconst steps = new Set<string>();\n\t\tfor (const compensation of workflow.compensations ?? []) {\n\t\t\tif (!compensation.step.trim()) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" has a compensation without a step.`);\n\t\t\t}\n\t\t\tif (steps.has(compensation.step)) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" declares duplicate compensation for step \"${compensation.step}\".`);\n\t\t\t}\n\t\t\tsteps.add(compensation.step);\n\t\t\tconst compensatingAction = actionsById.get(compensation.actionId);\n\t\t\tif (!compensatingAction) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" compensates step \"${compensation.step}\" with unknown action \"${compensation.actionId}\".`);\n\t\t\t}\n\t\t\t// An unwind is retried like any other durable step, so a reversal that cannot be\n\t\t\t// safely repeated would turn one failure into a different kind of corruption.\n\t\t\tif (!compensatingAction.idempotent || compensatingAction.execution?.idempotency === \"prohibited\") {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" compensates step \"${compensation.step}\" with non-idempotent action \"${compensation.actionId}\"; a reversal must be safely repeatable.`);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction validateManifest(module: FabricModule<unknown>, context: ModuleValidationContext = {}): void {\n\tvalidateModuleNamespace(module.namespace);\n\n\tconst dependencies = (module.dependencies ?? []).map(getModuleDependencyNamespace);\n\tconst objectTypes = (module.objectTypes ?? []).map(getObjectTypeName);\n\tconst eventTypes = (module.eventTypes ?? []).map(getEventTypeName);\n\tif (module.capability) {\n\t\tif (!module.capability.displayName.trim() || !module.capability.description.trim()) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" capability requires displayName and description.`);\n\t\t}\n\t\tfor (const namespace of Object.keys(module.capability.extensions ?? {})) {\n\t\t\tif (!/^[a-z][a-z0-9.-]*\\.[a-z0-9.-]+\\/v[1-9][0-9]*$/.test(namespace)) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" capability has invalid extension namespace \"${namespace}\".`);\n\t\t\t}\n\t\t}\n\t\tfor (const port of module.capability.requirements?.ports ?? []) {\n\t\t\t// Dotted segments are permitted so a capability can require a port\n\t\t\t// defined outside this repository: an enterprise integrates hundreds\n\t\t\t// of external systems, and namespacing is what keeps two of them from\n\t\t\t// colliding on a name. Widening only, so existing names still parse.\n\t\t\tif (!/^[a-z][a-z0-9-]*(?:\\.[a-z0-9-]+)*$/.test(port.name)) throw new Error(`Module \"${module.namespace}\" capability has invalid port requirement \"${port.name}\".`);\n\t\t}\n\t\tvalidateCapabilityWorkflows(module, context);\n\t}\n\tfor (const eventType of module.eventTypes ?? []) if (typeof eventType !== \"string\" && eventType.schema) assertPortableJsonSchema(eventType.schema, `Event \"${eventType.eventType}\" schema`);\n\tfor (const action of module.actions ?? []) {\n\t\tif (action.execution?.idempotency === \"required\" && !action.idempotent) throw new Error(`Action \"${action.actionId}\" requires idempotency but is not declared idempotent.`);\n\t\tif (action.execution?.connectivity === \"offline-capturable\" && action.execution.idempotency === \"prohibited\") throw new Error(`Offline action \"${action.actionId}\" cannot prohibit idempotency.`);\n\t\tif (action.execution?.completionDeadlineMs !== undefined && !(typeof action.execution.completionDeadlineMs === \"number\" && action.execution.completionDeadlineMs > 0)) throw new Error(`Action \"${action.actionId}\" completionDeadlineMs must be a positive number of milliseconds.`);\n\t\tif (action.execution?.completion === \"immediate\" && action.execution.completionDeadlineMs !== undefined) throw new Error(`Immediate action \"${action.actionId}\" cannot declare a completion deadline; nothing external completes it.`);\n\t}\n\tfor (const view of module.views ?? []) if (view.usage?.collection?.filterSchema) assertPortableJsonSchema(view.usage.collection.filterSchema, `View \"${view.name}\" filter schema`);\n\n\tfor (const dependency of dependencies) {\n\t\tvalidateModuleNamespace(dependency);\n\t\tif (dependency === module.namespace) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" cannot depend on itself.`);\n\t\t}\n\t\tif (context.availableNamespaces && !context.availableNamespaces.has(dependency)) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" depends on missing module \"${dependency}\".`);\n\t\t}\n\t}\n\n\tvalidateIdentifierList(objectTypes, \"objectTypes\", module.namespace);\n\tvalidateIdentifierList(module.subjectTypes, \"subjectTypes\", module.namespace);\n\tvalidateIdentifierList(eventTypes, \"eventTypes\", module.namespace);\n\n\tfor (const objectType of objectTypes) {\n\t\tif (!/^[A-Z][a-zA-Z0-9]*$/.test(objectType)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid object type: \"${objectType}\". Object types must be PascalCase alphanumeric.`,\n\t\t\t);\n\t\t}\n\t}\n\tfor (const objectType of module.objectTypes ?? []) {\n\t\tif (typeof objectType !== \"string\") {\n\t\t\tfor (const relation of objectType.relations ?? []) {\n\t\t\t\tconst targetNamespace = relation.target.slice(0, relation.target.indexOf(\".\"));\n\t\t\t\tif (targetNamespace !== module.namespace && !dependencies.includes(targetNamespace)) {\n\t\t\t\t\tthrow new Error(`Module \"${module.namespace}\" relation \"${relation.name}\" targets module \"${targetNamespace}\" without declaring it as a dependency.`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tvalidateObjectDefinition(objectType, module.namespace, context);\n\t}\n\n\tfor (const action of module.actions ?? []) {\n\t\tassertSurfaceDeclaration(action, `Action \"${action?.actionId ?? \"unknown\"}\"`);\n\t\tassertAdapterStepDeadlines(action);\n\t\tassertActionFinalization(action);\n\t\tlet parameterSchema: unknown;\n\t\ttry { parameterSchema = (action.schema as { toJSONSchema?: () => unknown }).toJSONSchema?.(); } catch { parameterSchema = undefined; }\n\t\tif (parameterSchema !== undefined) assertPortableJsonSchema(parameterSchema, `Action \"${action.actionId}\" parameters`);\n\t\tlet resultSchema: unknown;\n\t\ttry { resultSchema = (action.resultSchema as { toJSONSchema?: () => unknown } | undefined)?.toJSONSchema?.(); } catch { resultSchema = undefined; }\n\t\tif (resultSchema !== undefined) assertPortableJsonSchema(resultSchema, `Action \"${action.actionId}\" result`);\n\t\tif (!/^[a-z][a-z0-9-]*\\.[a-z][a-z0-9_]*$/.test(action.actionId)) {\n\t\t\tthrow new Error(`Invalid action ID: ${action.actionId}`);\n\t\t}\n\n\t\tif (action.namespace !== module.namespace) {\n\t\t\tthrow new Error(\n\t\t\t\t`Action \"${action.actionId}\" declares namespace \"${action.namespace}\" ` +\n\t\t\t\t\t`but is registered by module \"${module.namespace}\".`,\n\t\t\t);\n\t\t}\n\n\t\tif (!action.actionId.startsWith(`${module.namespace}.`)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Action \"${action.actionId}\" must start with module namespace \"${module.namespace}.\"`,\n\t\t\t);\n\t\t}\n\n\t\tif (action.mutatesDomain && action.emitsEvents.length === 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`Action \"${action.actionId}\" mutates domain but emits no events. ` +\n\t\t\t\t\t`Every mutating action must emit at least one AssetEvent.`,\n\t\t\t);\n\t\t}\n\n\t\tif (action.admitSubmission !== undefined && typeof action.admitSubmission !== \"function\") {\n\t\t\tthrow new Error(`Action \"${action.actionId}\" declares admitSubmission that is not a function.`);\n\t\t}\n\t\tconst stagedTargets = action.stagesInvocations ?? [];\n\t\tfor (const [index, targetId] of stagedTargets.entries()) {\n\t\t\tif (stagedTargets.indexOf(targetId) !== index) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" declares duplicate staged invocation target \"${targetId}\".`);\n\t\t\t}\n\t\t\tif (targetId === action.actionId) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" cannot stage itself.`);\n\t\t\t}\n\t\t\tconst target = context.availableActions?.get(targetId);\n\t\t\tif (!target) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" stages unknown action \"${targetId}\".`);\n\t\t\t}\n\t\t\tconst targetNamespace = targetId.slice(0, targetId.indexOf(\".\"));\n\t\t\tif (targetNamespace !== module.namespace && !dependencies.includes(targetNamespace)) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" stages action \"${targetId}\" without declaring module \"${targetNamespace}\" as a dependency.`);\n\t\t\t}\n\t\t\tif (target.execution?.authorityMoment === \"capture\") {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" cannot stage capture-authority action \"${targetId}\".`);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst viewKeys = new Set<string>();\n\tfor (const view of module.views ?? []) {\n\t\tassertSurfaceDeclaration(view, `View \"${view?.name ?? \"unknown\"}\"`);\n\t\tif (!view.name.startsWith(`${module.namespace}/`) || !/^[a-z][a-z0-9-]*\\/[a-z][a-z0-9/_-]*$/.test(view.name)) {\n\t\t\tthrow new Error(`View \"${view.name}\" must start with module namespace \"${module.namespace}/\" and use lowercase path segments.`);\n\t\t}\n\t\tif (!view.version.trim()) throw new Error(`View \"${view.name}\" must declare a version.`);\n\t\tconst key = `${view.name}@${view.version}`;\n\t\tif (viewKeys.has(key)) throw new Error(`Module \"${module.namespace}\" has duplicate view contract \"${key}\".`);\n\t\tviewKeys.add(key);\n\t\tassertPortableJsonSchema(view.shape, `View \"${key}\" shape`);\n\t\tif (view.parameterSchema !== undefined) assertPortableJsonSchema(view.parameterSchema, `View \"${key}\" parameters`);\n\t\tif (!Number.isInteger(view.snapshotVersion) || view.snapshotVersion < 1) {\n\t\t\tthrow new Error(`View \"${key}\" snapshotVersion must be a positive integer.`);\n\t\t}\n\t\tif ((view.compatibleSnapshotVersions?.some((version) => version !== view.snapshotVersion) ?? false) && !view.upgradeSnapshot) {\n\t\t\tthrow new Error(`View \"${key}\" declares older compatible snapshots but no upgradeSnapshot function.`);\n\t\t}\n\t\tfor (const consumption of view.consumes) {\n\t\t\tconst isPlanned = context.plannedEventTypes?.has(consumption.eventType) ?? false;\n\t\t\tconst isModuleEvent = eventTypes.includes(consumption.eventType);\n\t\t\tif (!isPlanned && !isModuleEvent) {\n\t\t\t\tthrow new Error(`View \"${key}\" consumes unknown event type \"${consumption.eventType}\".`);\n\t\t\t}\n\t\t\tif (consumption.schemaVersions.length === 0 || consumption.schemaVersions.some((version) => !Number.isInteger(version) || version < 1)) {\n\t\t\t\tthrow new Error(`View \"${key}\" must declare positive consumed schema versions for \"${consumption.eventType}\".`);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction sortModulesByDependency(\n\tmodules: FabricModule<unknown>[],\n\tregisteredNamespaces: ReadonlySet<string> = new Set(),\n): FabricModule<unknown>[] {\n\tconst modulesByNamespace = new Map<string, FabricModule<unknown>>();\n\n\tfor (const module of modules) {\n\t\tvalidateModuleNamespace(module.namespace);\n\t\tif (modulesByNamespace.has(module.namespace)) {\n\t\t\tthrow new Error(`Duplicate FabricModule namespace \"${module.namespace}\".`);\n\t\t}\n\t\tmodulesByNamespace.set(module.namespace, module);\n\t}\n\n\tconst sorted: FabricModule<unknown>[] = [];\n\tconst visiting = new Set<string>();\n\tconst visited = new Set<string>();\n\n\tfunction visit(module: FabricModule<unknown>, path: string[]): void {\n\t\tif (visited.has(module.namespace)) {\n\t\t\treturn;\n\t\t}\n\t\tif (visiting.has(module.namespace)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cyclic Fabric module dependency detected: ${[...path, module.namespace].join(\" -> \")}`,\n\t\t\t);\n\t\t}\n\n\t\tvisiting.add(module.namespace);\n\t\tfor (const dependency of (module.dependencies ?? []).map(getModuleDependencyNamespace)) {\n\t\t\tconst dependencyModule = modulesByNamespace.get(dependency);\n\t\t\tif (!dependencyModule) {\n\t\t\t\tif (registeredNamespaces.has(dependency)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" depends on missing module \"${dependency}\".`);\n\t\t\t}\n\t\t\tvisit(dependencyModule, [...path, module.namespace]);\n\t\t}\n\t\tvisiting.delete(module.namespace);\n\t\tvisited.add(module.namespace);\n\t\tsorted.push(module);\n\t}\n\n\tfor (const module of modules) {\n\t\tvisit(module, []);\n\t}\n\n\treturn sorted;\n}\n\nfunction assertAcyclicRelations(modules: FabricModule<unknown>[]): void {\n\tconst relationKinds = [\n\t\t{ label: \"owned containment\", include: (relation: ObjectRelationDefinition) => relation.semantics === \"owned\" },\n\t\t{ label: \"cascade-delete\", include: (relation: ObjectRelationDefinition) => relation.onTargetDelete === \"cascade\" },\n\t\t{ label: \"required-construction\", include: (relation: ObjectRelationDefinition) => relation.required === true },\n\t];\n\tfor (const kind of relationKinds) {\n\t\tconst edges = new Map<string, string[]>();\n\t\tfor (const module of modules) {\n\t\t\tfor (const objectType of module.objectTypes ?? []) {\n\t\t\t\tif (typeof objectType === \"string\") continue;\n\t\t\t\tconst source = qualifiedObjectType(module.namespace, objectType.type);\n\t\t\t\tedges.set(source, (objectType.relations ?? []).filter(kind.include).map((relation) => relation.target));\n\t\t\t}\n\t\t}\n\t\tconst visiting = new Set<string>();\n\t\tconst visited = new Set<string>();\n\t\tconst visit = (node: string, path: string[]): void => {\n\t\t\tif (visiting.has(node)) {\n\t\t\t\tthrow new Error(`${kind.label} relation cycle detected: ${[...path, node].join(\" -> \")}`);\n\t\t\t}\n\t\t\tif (visited.has(node)) return;\n\t\t\tvisiting.add(node);\n\t\t\tfor (const target of edges.get(node) ?? []) visit(target, [...path, node]);\n\t\t\tvisiting.delete(node);\n\t\t\tvisited.add(node);\n\t\t};\n\t\tfor (const node of edges.keys()) visit(node, []);\n\t}\n}\n\nexport function validateAndOrderFabricModules<TDb = unknown>(modules: FabricModule<TDb>[]): FabricModule<TDb>[] {\n\tconst availableNamespaces = new Set(modules.map((module) => module.namespace));\n\tconst plannedEventTypes = new Set(\n\t\tmodules.flatMap((module) => (module.eventTypes ?? []).map(getEventTypeName)),\n\t);\n\tfor (const eventType of createEventContractRegistry().eventTypes()) plannedEventTypes.add(eventType);\n\tconst availableObjectTypes = new Set([\n\t\t...modules.flatMap((module) =>\n\t\t\t(module.objectTypes ?? []).map((objectType) => qualifiedObjectType(module.namespace, getObjectTypeName(objectType))),\n\t\t),\n\t]);\n\tconst availableActions = new Map<string, ActionDefinition<unknown>>(\n\t\tmodules.flatMap((module) => (module.actions ?? []).map((action) => [action.actionId, action as ActionDefinition<unknown>] as const)),\n\t);\n\n\tfor (const module of modules) {\n\t\tvalidateManifest(module as FabricModule<unknown>, { availableNamespaces, plannedEventTypes, availableObjectTypes, availableActions });\n\t}\n\tassertAcyclicRelations(modules as FabricModule<unknown>[]);\n\treturn sortModulesByDependency(modules as FabricModule<unknown>[]) as FabricModule<TDb>[];\n}\n\n/** @deprecated Use createModuleRegistry(); registration is now explicit and instance-scoped. */\nexport function registerFabricModules<TDb = unknown>(modules: FabricModule<TDb>[]): FabricModule<TDb>[] {\n\treturn validateAndOrderFabricModules(modules);\n}\n\n/** @deprecated Use createModuleRegistry([module]); registration is now explicit and instance-scoped. */\nexport function registerFabricModule<TDb = unknown>(module: FabricModule<TDb>): void {\n\tvalidateAndOrderFabricModules([module]);\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../modules/index.ts"],"sourcesContent":["import { assertActionFinalization, assertAdapterStepDeadlines } from \"../actions\";\nimport { assertSurfaceDeclaration } from \"../discovery\";\nimport type { ActionDefinition, ActionId } from \"../actions\";\nimport { createEventContractRegistry } from \"../events\";\nimport {\n\tassertPortableJsonSchema,\n\ttype JsonValue,\n\ttype PortableJsonSchema,\n} from \"../objects\";\nimport type { PolicyEvaluator, PolicyId } from \"../policies\";\nimport type { StateMachineDefinition } from \"../state-machines\";\nimport { viewContractKey, type ViewContract } from \"../projections\";\n\nexport interface ModuleDependency {\n\tnamespace: string;\n\tversion?: string;\n\toptional?: boolean;\n}\n\nexport type ModuleDependencyInput = string | ModuleDependency;\n\nexport interface IdPrefixRegistration {\n\tprefix: string;\n\tname: string;\n\tmodule: string;\n}\n\nexport interface EventTypeRegistration {\n\teventType: string;\n\tschemaVersion: number;\n\tdescription?: string;\n\tschema?: PortableJsonSchema;\n}\n\nexport type EventTypeRegistrationInput = string | EventTypeRegistration;\n\nexport interface ObjectTypeRegistration {\n\ttype: string;\n\tdisplayName?: string;\n\tidPrefix?: string;\n\tisCoreModuleType?: boolean;\n\tschema?: PortableJsonSchema;\n\tsemantics?: Record<string, JsonValue>;\n\trelations?: ObjectRelationDefinition[];\n\tinvariants?: DeclarativeInvariant[];\n}\n\nexport type ObjectRelationCardinality = \"one\" | \"many\";\nexport type ObjectRelationSemantics = \"reference\" | \"owned\";\nexport type ObjectRelationDeleteBehavior = \"restrict\" | \"cascade\" | \"set-null\";\n\nexport interface ObjectRelationDefinition {\n\tname: string;\n\ttarget: `${string}.${string}`;\n\tcardinality: ObjectRelationCardinality;\n\trequired?: boolean;\n\tsemantics: ObjectRelationSemantics;\n\tonTargetDelete: ObjectRelationDeleteBehavior;\n}\n\nexport type InvariantEnforcement =\n\t| \"json-schema\"\n\t| \"state-machine\"\n\t| \"policy\"\n\t| \"host-adapter\"\n\t| \"application\";\n\nexport interface DeclarativeInvariant {\n\tid: string;\n\tdescription: string;\n\trequired?: boolean;\n\tenforcement: InvariantEnforcement;\n\tenforcementRef?: string;\n}\n\nexport type ObjectTypeRegistrationInput = string | ObjectTypeRegistration;\n\nexport interface PolicyRegistration {\n\tid: string;\n\tversion?: string;\n\tdescription?: string;\n}\n\nexport interface StateMachineRegistration {\n\tentityType: string;\n\tstates: string[];\n}\n\nexport interface CapabilityPortRequirement {\n\tname: string;\n\tversion?: string;\n\tstandard?: { name: string; version?: string };\n}\n\nexport interface CapabilityRequirements {\n\tports?: CapabilityPortRequirement[];\n\tpermissions?: string[];\n\tentitlements?: string[];\n\tfeatureFlags?: string[];\n}\n\nexport interface CapabilityWorkflowTimer {\n\t/** Workflow-local identity of the deadline, for example \"right-to-cure\". */\n\tname: string;\n\t/** Configuration key the duration is resolved from when the workflow starts. */\n\tconfigKey: string;\n\tdescription?: string;\n}\n\nexport interface CapabilityWorkflowCompensation {\n\t/** Workflow step whose effect this reverses. */\n\tstep: string;\n\t/** Governed action that performs the reversal. Must belong to the declaring module. */\n\tactionId: `${string}.${string}`;\n}\n\n/**\n * A durable workflow this capability owns. Declaring it makes durability a\n * reviewable fact of the contract rather than a property of worker deployment:\n * the queue it runs on, the deadlines it carries, and what reverses each step\n * are all diffable.\n */\nexport interface CapabilityWorkflowDeclaration {\n\tname: string;\n\t/** Routing identity, conventionally `capability.vertical`. */\n\ttaskQueue: string;\n\t/** Event type whose arrival starts this workflow by choreography. */\n\tstartedBy?: string;\n\ttimers?: CapabilityWorkflowTimer[];\n\tcompensations?: CapabilityWorkflowCompensation[];\n}\n\nexport interface CapabilityMetadata {\n\tdisplayName: string;\n\tdescription: string;\n\tstability: \"experimental\" | \"beta\" | \"stable\" | \"deprecated\";\n\tdeprecated?: { since: string; replacement?: string; message: string };\n\trequirements?: CapabilityRequirements;\n\tcertification?: { profile: string; required: boolean };\n\t/** Durable workflows this capability owns, with their queues, deadlines and reversals. */\n\tworkflows?: CapabilityWorkflowDeclaration[];\n\t/** Namespaced declared data preserved by Platform and interpreted only by its owning package. */\n\textensions?: Record<string, JsonValue>;\n}\n\nexport interface FabricModule<TDb = unknown> {\n\tnamespace: string;\n\tversion?: string;\n\t/** Compiler manifest digest for exact runtime assembly verification. */\n\tmanifestDigest?: string;\n\tdisplayName?: string;\n\tdescription?: string;\n\tcapability?: CapabilityMetadata;\n\tdependencies?: ModuleDependencyInput[];\n\tobjectTypes?: ObjectTypeRegistrationInput[];\n\tsubjectTypes?: string[];\n\tidPrefixes?: IdPrefixRegistration[];\n\teventTypes?: EventTypeRegistrationInput[];\n\tactions?: ActionDefinition<TDb>[];\n\tpolicies?: unknown[];\n\tstateMachines?: unknown[];\n\tadapterDefinitions?: unknown[];\n\tpermissions?: unknown[];\n\troles?: unknown[];\n\tredactionRules?: unknown[];\n\tdataClassifications?: unknown[];\n\tretentionRules?: unknown[];\n\tevidenceRenderers?: unknown[];\n\tviews?: ViewContract[];\n}\n\nexport interface ModuleRegistry<TDb = unknown> {\n\tmodules: ReadonlyMap<string, FabricModule<TDb>>;\n\torderedModules: readonly FabricModule<TDb>[];\n\tresolveAction(actionId: `${string}.${string}`): ActionDefinition<TDb> | undefined;\n\tresolvePolicy(policyId: PolicyId): PolicyEvaluator | undefined;\n\tresolveStateMachine(entityType: string): StateMachineDefinition | undefined;\n\tresolveView(name: string, version: string): ViewContract | undefined;\n}\n\ninterface ModuleValidationContext {\n\tavailableNamespaces?: Set<string>;\n\tplannedEventTypes?: Set<string>;\n\tavailableObjectTypes?: Set<string>;\n\tavailableActions?: Map<string, ActionDefinition<unknown>>;\n}\n\nexport function getModuleDependencyNamespace(dependency: ModuleDependencyInput): string {\n\treturn typeof dependency === \"string\" ? dependency : dependency.namespace;\n}\n\nexport function getObjectTypeName(objectType: ObjectTypeRegistrationInput): string {\n\treturn typeof objectType === \"string\" ? objectType : objectType.type;\n}\n\nexport function getEventTypeName(eventType: EventTypeRegistrationInput): string {\n\treturn typeof eventType === \"string\" ? eventType : eventType.eventType;\n}\n\nexport function validateModuleNamespace(namespace: string): void {\n\tif (!namespace) {\n\t\tthrow new Error(\"Module namespace cannot be empty\");\n\t}\n\tif (!/^[a-z][a-z0-9-]*$/.test(namespace)) {\n\t\tthrow new Error(\n\t\t\t`Invalid module namespace: \"${namespace}\". Must be lowercase letters, numbers, and hyphens only.`,\n\t\t);\n\t}\n}\n\nexport function createModuleRegistry<TDb = unknown>(\n\tmodules: FabricModule<TDb>[] = [],\n): ModuleRegistry<TDb> {\n\tconst orderedModules = validateAndOrderFabricModules(modules);\n\tconst registered = new Map(orderedModules.map((module) => [module.namespace, module]));\n\tconst actions = new Map(orderedModules.flatMap((module) => (module.actions ?? []).map((action) => [action.actionId, action] as const)));\n\tconst policies = new Map(orderedModules.flatMap((module) => (module.policies ?? []).map((policy) => {\n\t\tconst evaluator = policy as PolicyEvaluator;\n\t\treturn [evaluator.policyId, evaluator] as const;\n\t})));\n\tconst machines = new Map(orderedModules.flatMap((module) => (module.stateMachines ?? []).map((machine) => {\n\t\tconst definition = machine as StateMachineDefinition;\n\t\treturn [definition.entityType, definition] as const;\n\t})));\n\tconst views = new Map(orderedModules.flatMap((module) => (module.views ?? []).map((view) => [viewContractKey(view), view] as const)));\n\treturn {\n\t\tmodules: registered,\n\t\torderedModules,\n\t\tresolveAction: (actionId) => actions.get(actionId),\n\t\tresolvePolicy: (policyId) => policies.get(policyId),\n\t\tresolveStateMachine: (entityType) => machines.get(entityType),\n\t\tresolveView: (name, version) => views.get(`${name}@${version}`),\n\t};\n}\n\nfunction validateIdentifierList(\n\tvalues: string[] | undefined,\n\tlabel: string,\n\tnamespace: string,\n): void {\n\tfor (const value of values ?? []) {\n\t\tif (!value) {\n\t\t\tthrow new Error(`Module \"${namespace}\" has an empty ${label} entry.`);\n\t\t}\n\t}\n}\n\nfunction assertJsonValue(value: unknown, path: string): asserts value is JsonValue {\n\tif (value === null || typeof value === \"string\" || typeof value === \"boolean\") return;\n\tif (typeof value === \"number\" && Number.isFinite(value)) return;\n\tif (Array.isArray(value)) {\n\t\tvalue.forEach((item, index) => assertJsonValue(item, `${path}[${index}]`));\n\t\treturn;\n\t}\n\tif (typeof value === \"object\") {\n\t\tfor (const [key, child] of Object.entries(value as Record<string, unknown>)) {\n\t\t\tassertJsonValue(child, `${path}.${key}`);\n\t\t}\n\t\treturn;\n\t}\n\tthrow new Error(`${path} must contain JSON-serializable values.`);\n}\n\nfunction qualifiedObjectType(namespace: string, type: string): string {\n\treturn `${namespace}.${type}`;\n}\n\nfunction validateObjectDefinition(\n\tobjectType: ObjectTypeRegistrationInput,\n\tnamespace: string,\n\tcontext: ModuleValidationContext,\n): void {\n\tif (typeof objectType === \"string\") return;\n\tif (objectType.schema !== undefined) {\n\t\tassertPortableJsonSchema(objectType.schema, `Module \"${namespace}\" object \"${objectType.type}\" schema`);\n\t}\n\tif (objectType.semantics !== undefined) {\n\t\tassertJsonValue(objectType.semantics, `Module \"${namespace}\" object \"${objectType.type}\" semantics`);\n\t}\n\tconst relationNames = new Set<string>();\n\tfor (const relation of objectType.relations ?? []) {\n\t\tif (!/^[a-z][a-zA-Z0-9]*$/.test(relation.name)) {\n\t\t\tthrow new Error(`Module \"${namespace}\" object \"${objectType.type}\" has invalid relation name \"${relation.name}\".`);\n\t\t}\n\t\tif (relationNames.has(relation.name)) {\n\t\t\tthrow new Error(`Module \"${namespace}\" object \"${objectType.type}\" has duplicate relation \"${relation.name}\".`);\n\t\t}\n\t\trelationNames.add(relation.name);\n\t\tif (!/^[a-z][a-z0-9-]*\\.[A-Z][a-zA-Z0-9]*$/.test(relation.target)) {\n\t\t\tthrow new Error(`Relation \"${relation.name}\" target \"${relation.target}\" must be module-qualified.`);\n\t\t}\n\t\tif (context.availableObjectTypes && !context.availableObjectTypes.has(relation.target)) {\n\t\t\tthrow new Error(`Relation \"${relation.name}\" targets missing object type \"${relation.target}\".`);\n\t\t}\n\t\tif (relation.required && relation.onTargetDelete === \"set-null\") {\n\t\t\tthrow new Error(`Required relation \"${relation.name}\" cannot use onTargetDelete \"set-null\".`);\n\t\t}\n\t}\n\tconst invariantIds = new Set<string>();\n\tfor (const invariant of objectType.invariants ?? []) {\n\t\tif (!invariant.id.trim() || !invariant.description.trim()) {\n\t\t\tthrow new Error(`Module \"${namespace}\" object \"${objectType.type}\" has an invariant without an id or description.`);\n\t\t}\n\t\tif (invariantIds.has(invariant.id)) {\n\t\t\tthrow new Error(`Module \"${namespace}\" object \"${objectType.type}\" has duplicate invariant \"${invariant.id}\".`);\n\t\t}\n\t\tinvariantIds.add(invariant.id);\n\t\tif (invariant.required && !invariant.enforcementRef?.trim()) {\n\t\t\tthrow new Error(`Required invariant \"${invariant.id}\" must declare enforcementRef.`);\n\t\t}\n\t}\n}\n\nfunction validateCapabilityWorkflows(module: FabricModule<unknown>, context: ModuleValidationContext): void {\n\tconst workflows = module.capability?.workflows ?? [];\n\tconst actionsById = new Map((module.actions ?? []).map((action) => [action.actionId, action]));\n\tconst names = new Set<string>();\n\tfor (const workflow of workflows) {\n\t\tif (!/^[A-Za-z][A-Za-z0-9_-]*$/.test(workflow.name)) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" declares invalid workflow name \"${workflow.name}\".`);\n\t\t}\n\t\tif (names.has(workflow.name)) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" declares duplicate workflow \"${workflow.name}\".`);\n\t\t}\n\t\tnames.add(workflow.name);\n\t\tif (!/^[a-z][a-z0-9-]*(\\.[a-z][a-z0-9-]*)*$/.test(workflow.taskQueue)) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" declares invalid task queue \"${workflow.taskQueue}\".`);\n\t\t}\n\t\tif (workflow.startedBy !== undefined) {\n\t\t\tconst known = context.plannedEventTypes?.has(workflow.startedBy)\n\t\t\t\t?? (module.eventTypes ?? []).some((eventType) => getEventTypeName(eventType) === workflow.startedBy);\n\t\t\tif (!known) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" is started by unknown event type \"${workflow.startedBy}\".`);\n\t\t\t}\n\t\t}\n\t\tconst timerNames = new Set<string>();\n\t\tfor (const timer of workflow.timers ?? []) {\n\t\t\tif (!timer.name.trim() || !timer.configKey.trim()) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" has a timer without a name or configKey.`);\n\t\t\t}\n\t\t\tif (timerNames.has(timer.name)) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" declares duplicate timer \"${timer.name}\".`);\n\t\t\t}\n\t\t\ttimerNames.add(timer.name);\n\t\t}\n\t\tconst steps = new Set<string>();\n\t\tfor (const compensation of workflow.compensations ?? []) {\n\t\t\tif (!compensation.step.trim()) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" has a compensation without a step.`);\n\t\t\t}\n\t\t\tif (steps.has(compensation.step)) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" declares duplicate compensation for step \"${compensation.step}\".`);\n\t\t\t}\n\t\t\tsteps.add(compensation.step);\n\t\t\tconst compensatingAction = actionsById.get(compensation.actionId);\n\t\t\tif (!compensatingAction) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" compensates step \"${compensation.step}\" with unknown action \"${compensation.actionId}\".`);\n\t\t\t}\n\t\t\t// An unwind is retried like any other durable step, so a reversal that cannot be\n\t\t\t// safely repeated would turn one failure into a different kind of corruption.\n\t\t\tif (!compensatingAction.idempotent || compensatingAction.execution?.idempotency === \"prohibited\") {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" workflow \"${workflow.name}\" compensates step \"${compensation.step}\" with non-idempotent action \"${compensation.actionId}\"; a reversal must be safely repeatable.`);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction validateManifest(module: FabricModule<unknown>, context: ModuleValidationContext = {}): void {\n\tvalidateModuleNamespace(module.namespace);\n\n\tconst dependencies = (module.dependencies ?? []).map(getModuleDependencyNamespace);\n\tconst objectTypes = (module.objectTypes ?? []).map(getObjectTypeName);\n\tconst eventTypes = (module.eventTypes ?? []).map(getEventTypeName);\n\tif (module.capability) {\n\t\tif (!module.capability.displayName.trim() || !module.capability.description.trim()) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" capability requires displayName and description.`);\n\t\t}\n\t\tfor (const namespace of Object.keys(module.capability.extensions ?? {})) {\n\t\t\tif (!/^[a-z][a-z0-9.-]*\\.[a-z0-9.-]+\\/v[1-9][0-9]*$/.test(namespace)) {\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" capability has invalid extension namespace \"${namespace}\".`);\n\t\t\t}\n\t\t}\n\t\tfor (const port of module.capability.requirements?.ports ?? []) {\n\t\t\t// Dotted segments are permitted so a capability can require a port\n\t\t\t// defined outside this repository: an enterprise integrates hundreds\n\t\t\t// of external systems, and namespacing is what keeps two of them from\n\t\t\t// colliding on a name. Widening only, so existing names still parse.\n\t\t\tif (!/^[a-z][a-z0-9-]*(?:\\.[a-z0-9-]+)*$/.test(port.name)) throw new Error(`Module \"${module.namespace}\" capability has invalid port requirement \"${port.name}\".`);\n\t\t}\n\t\tvalidateCapabilityWorkflows(module, context);\n\t}\n\tfor (const eventType of module.eventTypes ?? []) if (typeof eventType !== \"string\" && eventType.schema) assertPortableJsonSchema(eventType.schema, `Event \"${eventType.eventType}\" schema`);\n\tfor (const action of module.actions ?? []) {\n\t\tif (action.execution?.idempotency === \"required\" && !action.idempotent) throw new Error(`Action \"${action.actionId}\" requires idempotency but is not declared idempotent.`);\n\t\tif (action.execution?.connectivity === \"offline-capturable\" && action.execution.idempotency === \"prohibited\") throw new Error(`Offline action \"${action.actionId}\" cannot prohibit idempotency.`);\n\t\tif (action.execution?.completionDeadlineMs !== undefined && !(typeof action.execution.completionDeadlineMs === \"number\" && action.execution.completionDeadlineMs > 0)) throw new Error(`Action \"${action.actionId}\" completionDeadlineMs must be a positive number of milliseconds.`);\n\t\tif (action.execution?.completion === \"immediate\" && action.execution.completionDeadlineMs !== undefined) throw new Error(`Immediate action \"${action.actionId}\" cannot declare a completion deadline; nothing external completes it.`);\n\t}\n\tfor (const view of module.views ?? []) if (view.usage?.collection?.filterSchema) assertPortableJsonSchema(view.usage.collection.filterSchema, `View \"${view.name}\" filter schema`);\n\n\tfor (const dependency of dependencies) {\n\t\tvalidateModuleNamespace(dependency);\n\t\tif (dependency === module.namespace) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" cannot depend on itself.`);\n\t\t}\n\t\tif (context.availableNamespaces && !context.availableNamespaces.has(dependency)) {\n\t\t\tthrow new Error(`Module \"${module.namespace}\" depends on missing module \"${dependency}\".`);\n\t\t}\n\t}\n\n\tvalidateIdentifierList(objectTypes, \"objectTypes\", module.namespace);\n\tvalidateIdentifierList(module.subjectTypes, \"subjectTypes\", module.namespace);\n\tvalidateIdentifierList(eventTypes, \"eventTypes\", module.namespace);\n\n\tfor (const objectType of objectTypes) {\n\t\tif (!/^[A-Z][a-zA-Z0-9]*$/.test(objectType)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Invalid object type: \"${objectType}\". Object types must be PascalCase alphanumeric.`,\n\t\t\t);\n\t\t}\n\t}\n\tfor (const objectType of module.objectTypes ?? []) {\n\t\tif (typeof objectType !== \"string\") {\n\t\t\tfor (const relation of objectType.relations ?? []) {\n\t\t\t\tconst targetNamespace = relation.target.slice(0, relation.target.indexOf(\".\"));\n\t\t\t\tif (targetNamespace !== module.namespace && !dependencies.includes(targetNamespace)) {\n\t\t\t\t\tthrow new Error(`Module \"${module.namespace}\" relation \"${relation.name}\" targets module \"${targetNamespace}\" without declaring it as a dependency.`);\n\t\t\t\t}\n\t\t\t}\n\t\t}\n\t\tvalidateObjectDefinition(objectType, module.namespace, context);\n\t}\n\n\tfor (const action of module.actions ?? []) {\n\t\tassertSurfaceDeclaration(action, `Action \"${action?.actionId ?? \"unknown\"}\"`);\n\t\tassertAdapterStepDeadlines(action);\n\t\tassertActionFinalization(action);\n\t\tlet parameterSchema: unknown;\n\t\ttry { parameterSchema = (action.schema as { toJSONSchema?: () => unknown }).toJSONSchema?.(); } catch { parameterSchema = undefined; }\n\t\tif (parameterSchema !== undefined) assertPortableJsonSchema(parameterSchema, `Action \"${action.actionId}\" parameters`);\n\t\tlet resultSchema: unknown;\n\t\ttry { resultSchema = (action.resultSchema as { toJSONSchema?: () => unknown } | undefined)?.toJSONSchema?.(); } catch { resultSchema = undefined; }\n\t\tif (resultSchema !== undefined) assertPortableJsonSchema(resultSchema, `Action \"${action.actionId}\" result`);\n\t\tif (!/^[a-z][a-z0-9-]*\\.[a-z][a-z0-9_]*$/.test(action.actionId)) {\n\t\t\tthrow new Error(`Invalid action ID: ${action.actionId}`);\n\t\t}\n\n\t\tif (action.namespace !== module.namespace) {\n\t\t\tthrow new Error(\n\t\t\t\t`Action \"${action.actionId}\" declares namespace \"${action.namespace}\" ` +\n\t\t\t\t\t`but is registered by module \"${module.namespace}\".`,\n\t\t\t);\n\t\t}\n\n\t\tif (!action.actionId.startsWith(`${module.namespace}.`)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Action \"${action.actionId}\" must start with module namespace \"${module.namespace}.\"`,\n\t\t\t);\n\t\t}\n\n\t\tif (action.mutatesDomain && action.emitsEvents.length === 0) {\n\t\t\tthrow new Error(\n\t\t\t\t`Action \"${action.actionId}\" mutates domain but emits no events. ` +\n\t\t\t\t\t`Every mutating action must emit at least one AssetEvent.`,\n\t\t\t);\n\t\t}\n\n\t\tif (action.admitSubmission !== undefined && typeof action.admitSubmission !== \"function\") {\n\t\t\tthrow new Error(`Action \"${action.actionId}\" declares admitSubmission that is not a function.`);\n\t\t}\n\t\tconst stagedTargets = action.stagesInvocations ?? [];\n\t\tconst stagedInvocationPrincipals = action.stagedInvocationPrincipals;\n\t\tif (stagedInvocationPrincipals !== undefined &&\n\t\t\t(!stagedInvocationPrincipals || typeof stagedInvocationPrincipals !== \"object\" || Array.isArray(stagedInvocationPrincipals))) {\n\t\t\tthrow new Error(`Action \"${action.actionId}\" stagedInvocationPrincipals must be an object.`);\n\t\t}\n\t\tfor (const [targetId, principal] of Object.entries(stagedInvocationPrincipals ?? {})) {\n\t\t\tif (!stagedTargets.includes(targetId as ActionId)) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" does not declare staged invocation target \"${targetId}\".`);\n\t\t\t}\n\t\t\tif (typeof principal !== \"string\" || !/^[a-z][a-z0-9._:-]{0,127}$/.test(principal)) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" declares invalid staged invocation principal for \"${targetId}\".`);\n\t\t\t}\n\t\t}\n\t\tfor (const [index, targetId] of stagedTargets.entries()) {\n\t\t\tif (stagedTargets.indexOf(targetId) !== index) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" declares duplicate staged invocation target \"${targetId}\".`);\n\t\t\t}\n\t\t\tif (targetId === action.actionId) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" cannot stage itself.`);\n\t\t\t}\n\t\t\tconst target = context.availableActions?.get(targetId);\n\t\t\tif (!target) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" stages unknown action \"${targetId}\".`);\n\t\t\t}\n\t\t\tconst targetNamespace = targetId.slice(0, targetId.indexOf(\".\"));\n\t\t\tif (targetNamespace !== module.namespace && !dependencies.includes(targetNamespace)) {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" stages action \"${targetId}\" without declaring module \"${targetNamespace}\" as a dependency.`);\n\t\t\t}\n\t\t\tif (target.execution?.authorityMoment === \"capture\") {\n\t\t\t\tthrow new Error(`Action \"${action.actionId}\" cannot stage capture-authority action \"${targetId}\".`);\n\t\t\t}\n\t\t}\n\t}\n\n\tconst viewKeys = new Set<string>();\n\tfor (const view of module.views ?? []) {\n\t\tassertSurfaceDeclaration(view, `View \"${view?.name ?? \"unknown\"}\"`);\n\t\tif (!view.name.startsWith(`${module.namespace}/`) || !/^[a-z][a-z0-9-]*\\/[a-z][a-z0-9/_-]*$/.test(view.name)) {\n\t\t\tthrow new Error(`View \"${view.name}\" must start with module namespace \"${module.namespace}/\" and use lowercase path segments.`);\n\t\t}\n\t\tif (!view.version.trim()) throw new Error(`View \"${view.name}\" must declare a version.`);\n\t\tconst key = `${view.name}@${view.version}`;\n\t\tif (viewKeys.has(key)) throw new Error(`Module \"${module.namespace}\" has duplicate view contract \"${key}\".`);\n\t\tviewKeys.add(key);\n\t\tassertPortableJsonSchema(view.shape, `View \"${key}\" shape`);\n\t\tif (view.parameterSchema !== undefined) assertPortableJsonSchema(view.parameterSchema, `View \"${key}\" parameters`);\n\t\tif (!Number.isInteger(view.snapshotVersion) || view.snapshotVersion < 1) {\n\t\t\tthrow new Error(`View \"${key}\" snapshotVersion must be a positive integer.`);\n\t\t}\n\t\tif ((view.compatibleSnapshotVersions?.some((version) => version !== view.snapshotVersion) ?? false) && !view.upgradeSnapshot) {\n\t\t\tthrow new Error(`View \"${key}\" declares older compatible snapshots but no upgradeSnapshot function.`);\n\t\t}\n\t\tfor (const consumption of view.consumes) {\n\t\t\tconst isPlanned = context.plannedEventTypes?.has(consumption.eventType) ?? false;\n\t\t\tconst isModuleEvent = eventTypes.includes(consumption.eventType);\n\t\t\tif (!isPlanned && !isModuleEvent) {\n\t\t\t\tthrow new Error(`View \"${key}\" consumes unknown event type \"${consumption.eventType}\".`);\n\t\t\t}\n\t\t\tif (consumption.schemaVersions.length === 0 || consumption.schemaVersions.some((version) => !Number.isInteger(version) || version < 1)) {\n\t\t\t\tthrow new Error(`View \"${key}\" must declare positive consumed schema versions for \"${consumption.eventType}\".`);\n\t\t\t}\n\t\t}\n\t}\n}\n\nfunction sortModulesByDependency(\n\tmodules: FabricModule<unknown>[],\n\tregisteredNamespaces: ReadonlySet<string> = new Set(),\n): FabricModule<unknown>[] {\n\tconst modulesByNamespace = new Map<string, FabricModule<unknown>>();\n\n\tfor (const module of modules) {\n\t\tvalidateModuleNamespace(module.namespace);\n\t\tif (modulesByNamespace.has(module.namespace)) {\n\t\t\tthrow new Error(`Duplicate FabricModule namespace \"${module.namespace}\".`);\n\t\t}\n\t\tmodulesByNamespace.set(module.namespace, module);\n\t}\n\n\tconst sorted: FabricModule<unknown>[] = [];\n\tconst visiting = new Set<string>();\n\tconst visited = new Set<string>();\n\n\tfunction visit(module: FabricModule<unknown>, path: string[]): void {\n\t\tif (visited.has(module.namespace)) {\n\t\t\treturn;\n\t\t}\n\t\tif (visiting.has(module.namespace)) {\n\t\t\tthrow new Error(\n\t\t\t\t`Cyclic Fabric module dependency detected: ${[...path, module.namespace].join(\" -> \")}`,\n\t\t\t);\n\t\t}\n\n\t\tvisiting.add(module.namespace);\n\t\tfor (const dependency of (module.dependencies ?? []).map(getModuleDependencyNamespace)) {\n\t\t\tconst dependencyModule = modulesByNamespace.get(dependency);\n\t\t\tif (!dependencyModule) {\n\t\t\t\tif (registeredNamespaces.has(dependency)) {\n\t\t\t\t\tcontinue;\n\t\t\t\t}\n\t\t\t\tthrow new Error(`Module \"${module.namespace}\" depends on missing module \"${dependency}\".`);\n\t\t\t}\n\t\t\tvisit(dependencyModule, [...path, module.namespace]);\n\t\t}\n\t\tvisiting.delete(module.namespace);\n\t\tvisited.add(module.namespace);\n\t\tsorted.push(module);\n\t}\n\n\tfor (const module of modules) {\n\t\tvisit(module, []);\n\t}\n\n\treturn sorted;\n}\n\nfunction assertAcyclicRelations(modules: FabricModule<unknown>[]): void {\n\tconst relationKinds = [\n\t\t{ label: \"owned containment\", include: (relation: ObjectRelationDefinition) => relation.semantics === \"owned\" },\n\t\t{ label: \"cascade-delete\", include: (relation: ObjectRelationDefinition) => relation.onTargetDelete === \"cascade\" },\n\t\t{ label: \"required-construction\", include: (relation: ObjectRelationDefinition) => relation.required === true },\n\t];\n\tfor (const kind of relationKinds) {\n\t\tconst edges = new Map<string, string[]>();\n\t\tfor (const module of modules) {\n\t\t\tfor (const objectType of module.objectTypes ?? []) {\n\t\t\t\tif (typeof objectType === \"string\") continue;\n\t\t\t\tconst source = qualifiedObjectType(module.namespace, objectType.type);\n\t\t\t\tedges.set(source, (objectType.relations ?? []).filter(kind.include).map((relation) => relation.target));\n\t\t\t}\n\t\t}\n\t\tconst visiting = new Set<string>();\n\t\tconst visited = new Set<string>();\n\t\tconst visit = (node: string, path: string[]): void => {\n\t\t\tif (visiting.has(node)) {\n\t\t\t\tthrow new Error(`${kind.label} relation cycle detected: ${[...path, node].join(\" -> \")}`);\n\t\t\t}\n\t\t\tif (visited.has(node)) return;\n\t\t\tvisiting.add(node);\n\t\t\tfor (const target of edges.get(node) ?? []) visit(target, [...path, node]);\n\t\t\tvisiting.delete(node);\n\t\t\tvisited.add(node);\n\t\t};\n\t\tfor (const node of edges.keys()) visit(node, []);\n\t}\n}\n\nexport function validateAndOrderFabricModules<TDb = unknown>(modules: FabricModule<TDb>[]): FabricModule<TDb>[] {\n\tconst availableNamespaces = new Set(modules.map((module) => module.namespace));\n\tconst plannedEventTypes = new Set(\n\t\tmodules.flatMap((module) => (module.eventTypes ?? []).map(getEventTypeName)),\n\t);\n\tfor (const eventType of createEventContractRegistry().eventTypes()) plannedEventTypes.add(eventType);\n\tconst availableObjectTypes = new Set([\n\t\t...modules.flatMap((module) =>\n\t\t\t(module.objectTypes ?? []).map((objectType) => qualifiedObjectType(module.namespace, getObjectTypeName(objectType))),\n\t\t),\n\t]);\n\tconst availableActions = new Map<string, ActionDefinition<unknown>>(\n\t\tmodules.flatMap((module) => (module.actions ?? []).map((action) => [action.actionId, action as ActionDefinition<unknown>] as const)),\n\t);\n\n\tfor (const module of modules) {\n\t\tvalidateManifest(module as FabricModule<unknown>, { availableNamespaces, plannedEventTypes, availableObjectTypes, availableActions });\n\t}\n\tassertAcyclicRelations(modules as FabricModule<unknown>[]);\n\treturn sortModulesByDependency(modules as FabricModule<unknown>[]) as FabricModule<TDb>[];\n}\n\n/** @deprecated Use createModuleRegistry(); registration is now explicit and instance-scoped. */\nexport function registerFabricModules<TDb = unknown>(modules: FabricModule<TDb>[]): FabricModule<TDb>[] {\n\treturn validateAndOrderFabricModules(modules);\n}\n\n/** @deprecated Use createModuleRegistry([module]); registration is now explicit and instance-scoped. */\nexport function registerFabricModule<TDb = unknown>(module: FabricModule<TDb>): void {\n\tvalidateAndOrderFabricModules([module]);\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@fabricorg/platform",
|
|
3
|
-
"version": "1.
|
|
3
|
+
"version": "1.15.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",
|