@fabricorg/platform 1.11.0 → 1.12.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 +32 -0
- package/README.md +31 -1
- package/dist/actions/index.cjs +32 -0
- package/dist/actions/index.cjs.map +1 -1
- package/dist/actions/index.d.cts +50 -0
- package/dist/actions/index.d.ts +50 -0
- package/dist/actions/index.js +30 -1
- package/dist/actions/index.js.map +1 -1
- package/dist/index.cjs +3 -0
- package/dist/index.d.cts +2 -2
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/manifest/index.cjs +13 -1
- package/dist/manifest/index.cjs.map +1 -1
- package/dist/manifest/index.d.cts +5 -0
- package/dist/manifest/index.d.ts +5 -0
- package/dist/manifest/index.js +13 -1
- package/dist/manifest/index.js.map +1 -1
- package/dist/modules/index.cjs +3 -0
- package/dist/modules/index.cjs.map +1 -1
- package/dist/modules/index.js +3 -0
- package/dist/modules/index.js.map +1 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,37 @@
|
|
|
1
1
|
# @fabricorg/platform
|
|
2
2
|
|
|
3
|
+
## 1.12.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- 71d306f: Add optional action-level finalization for atomic, immediate after_adapters actions, including non-idempotent actions. Export JSON finalization types, registration validation, a manifest protocol descriptor and defineFinalizingAction to guard handlers against older hosts.
|
|
8
|
+
|
|
9
|
+
Host requires atomic transactions, invocation locking and transaction-scoped lease fencing before application execution. On normal success the hook consumes stored redacted outputs and commits transaction-local domain writes, declared events, outbox and the merged result together. Hook or validation failure rolls back finalization and settles reconciliation_required when durable provider effects exist, or failed when there are none, with redacted error text. Lease loss escapes without a stale-worker verdict. Handler preparation writes remain separately committed.
|
|
10
|
+
|
|
11
|
+
If entry to or COMMIT of the final success transaction (after adapters) fails with an unknown outcome, Host raises RecoverableFinalizationError and records no verdict. An uncommitted invocation stays running for recovery; a committed completed invocation retains its stored verdict and result for re-execution.
|
|
12
|
+
|
|
13
|
+
Explicit undefined on the optional hook return fields events, resultPatch and eventSchemaVersion is treated as omitted. Payloads and result-patch values retain strict JSON validation and reject undefined.
|
|
14
|
+
|
|
15
|
+
Failed, ambiguous, degraded and accepted/handoff outcomes do not invoke the hook. Existing actions retain their lifecycle.
|
|
16
|
+
|
|
17
|
+
Before adapters, normalize hook parameters and public handler data through a JSON round-trip, stripping private handler carriers. Dates become ISO strings and undefined object properties drop; serialization failures such as cycles or BigInt fail before provider execution. Handler events are normalized separately. Hook event schema versions default to the action version when omitted.
|
|
18
|
+
|
|
19
|
+
Add optional Host eventContracts name validation for events returned by the finalize hook. It checks eventType and subjectType membership only; handler events, payload schemas and schema-version compatibility are outside this option's scope. Recovery refusal also preserves ambiguity evidence for in-flight adapter rows alongside succeeded effects.
|
|
20
|
+
|
|
21
|
+
- d5e7caa: Add optional adapter-step deadlineMs durations overriding the Host-wide duration,
|
|
22
|
+
including when the Host duration is unset or zero. Action and module registration, manifest export,
|
|
23
|
+
and manifest normalization reject step durations that are not positive finite integers.
|
|
24
|
+
Host validates resolved steps before handler or adapter execution. Invalid
|
|
25
|
+
durations fail a first execution without invoking adapters; retries with recorded
|
|
26
|
+
applied effects or unknown adapter outcomes require reconciliation instead.
|
|
27
|
+
Manifests preserve valid step durations.
|
|
28
|
+
|
|
29
|
+
Correct adapterDeadlineMs documentation: it is a duration starting just before
|
|
30
|
+
step retry execution, not an epoch timestamp. Host-wide behavior is unchanged.
|
|
31
|
+
Budgets span retries; expiry prevents a subsequent attempt and signals cooperative
|
|
32
|
+
cancellation of an in-flight call. An aborted call that throws retains the existing
|
|
33
|
+
ambiguous-outcome reconciliation semantics.
|
|
34
|
+
|
|
3
35
|
## 1.11.0
|
|
4
36
|
|
|
5
37
|
### Minor Changes
|
package/README.md
CHANGED
|
@@ -101,7 +101,7 @@ const json = JSON.stringify(manifest, null, 2);
|
|
|
101
101
|
|
|
102
102
|
`exportModuleManifest` is a pure function of the module object: it does not touch the registries and the module does not need to be registered first. Declaration order is preserved everywhere, so the same module always produces byte-identical JSON. Function fields (`handler`, policy `evaluate`, transition `guard`, dynamic `targetState`, adapter `getInput`) are never serialized — the manifest contains definitions only, never raw parameter values, secrets, or runtime data. Manifest v2 object registrations may include `PortableJsonSchema`, qualified relations, namespaced semantic annotations, and enforcement-owned invariants. Actions whose validators expose `toJSONSchema()` include `parameterSchema` and optional `resultSchema` definitions. `normalizeModuleManifest` and `normalizeModuleManifestBundle` let v2 readers accept v1 input without promising down-conversion.
|
|
103
103
|
|
|
104
|
-
An entity schema does not validate arbitrary writes through `TDb`. Persisted-record validation requires an explicit Host/database adapter.
|
|
104
|
+
An entity schema does not validate arbitrary writes through `TDb`. Persisted-record validation requires an explicit Host/database adapter. For actions without `finalize`, when an action declares `resultSchema`, Platform Host validates the public result after the handler and before events or adapters; failure rolls back domain writes only when the Host store has a transaction provider that includes them.
|
|
105
105
|
|
|
106
106
|
An action may also declare `admitSubmission`, an async check that decides whether a submission may be recorded at all. It receives the trusted `tenantId`, `spaceId`, `actorId` and `actorType`, the submitted parameters and a `signal` (`ActionAdmissionSignal`, a structural subset of `AbortSignal`; Host passes a real one), and answers `{ admitted: true }` or `{ admitted: false, code }` with a fixed code. `@fabricorg/platform-host` 7.3.0 and later runs it after authorizing the submitter and before writing anything for the submission, refuses on a throw, timeout or any other answer, and passes the admission time to the handler as `ActionContext.admittedAt`. An older host ignores the field, so a handler that relies on it should refuse without `ctx.admittedAt`. Registration rejects an `admitSubmission` that is not a function.
|
|
107
107
|
|
|
@@ -141,6 +141,26 @@ Every `invokeAction(id, params)` call goes through:
|
|
|
141
141
|
state-guard, adapter, or finalization failure semantics; see the
|
|
142
142
|
[Host boundary and rollback contract](../platform-host/README.md#atomic-mutation-unit-of-work).
|
|
143
143
|
|
|
144
|
+
Provider-dependent records can use the optional action-level `finalize` hook through
|
|
145
|
+
`defineFinalizingAction`. It requires an atomic, immediate `after_adapters` action;
|
|
146
|
+
idempotency is not required. Before adapters, Host normalizes the hook's parameters and
|
|
147
|
+
public handler data with `JSON.parse(JSON.stringify(value))`, then validates the normalized
|
|
148
|
+
JSON: Dates become ISO strings, undefined object properties drop, class instances use their
|
|
149
|
+
JSON representation, and non-finite numbers become null. Serialization failures such as
|
|
150
|
+
cycles or BigInt fail before adapter execution. Host strips private `eventResultFields`
|
|
151
|
+
from hook handler data; handler events are normalized separately. The hook receives copies
|
|
152
|
+
of those saved inputs and ordered succeeded/skipped stored redacted adapter outputs, plus
|
|
153
|
+
transaction-bound `db` without services. Hook event schema versions default to
|
|
154
|
+
`action.version` when omitted.
|
|
155
|
+
It returns declared events and/or a shallow result patch. The manifest exports only
|
|
156
|
+
`finalization: { protocol: "atomic-after-adapters-v1" }`, not the callback.
|
|
157
|
+
The helper refuses older hosts before handler code runs. See the
|
|
158
|
+
[Host finalization contract](../platform-host/README.md#action-level-finalization) for
|
|
159
|
+
transaction requirements, validation, rollback and reconciliation semantics.
|
|
160
|
+
With a compatible durable preparation checkpoint, Host recovery reuses recorded outputs
|
|
161
|
+
and replays finalization without rerunning the handler. Missing or incompatible evidence
|
|
162
|
+
retains effect-aware refusal; see the Host finalization contract for rollout and limits.
|
|
163
|
+
|
|
144
164
|
4. **Adapters** — for each `actionDef.adapterSteps`, the registered implementation runs via
|
|
145
165
|
`executeWithAdapterRetry` (idempotent retry, exponential backoff, and an optional per-adapter
|
|
146
166
|
circuit breaker; see [Adapter circuit breakers](#adapter-circuit-breakers)). Adapters may
|
|
@@ -534,6 +554,16 @@ Lifecycle evidence copies the supplied metadata's checksums; its options do not
|
|
|
534
554
|
previously generated metadata. This option does not change `FieldRedactor`, `hash`,
|
|
535
555
|
`tokenize`, `stableChecksum`, or packet-level checksum algorithms.
|
|
536
556
|
|
|
557
|
+
## Adapter step deadlines
|
|
558
|
+
|
|
559
|
+
Adapter steps may declare `deadlineMs`, a positive finite integer duration in
|
|
560
|
+
milliseconds. Platform Host uses it instead of its `adapterDeadlineMs` duration for
|
|
561
|
+
that step. The budget begins just before retry execution and spans attempts and
|
|
562
|
+
retry delays. Action and module registration, manifest normalization and export,
|
|
563
|
+
and Host execution validate step durations. Host rejects invalid resolved steps
|
|
564
|
+
before handler or adapter execution. Manifest export preserves valid durations.
|
|
565
|
+
See the Platform Host README for cooperative cancellation and failure semantics.
|
|
566
|
+
|
|
537
567
|
## License
|
|
538
568
|
|
|
539
569
|
MIT
|
package/dist/actions/index.cjs
CHANGED
|
@@ -14,6 +14,33 @@ function isActorType(value) {
|
|
|
14
14
|
function assertActorType(value) {
|
|
15
15
|
if (!isActorType(value)) throw new Error(`Invalid actorType: ${value}`);
|
|
16
16
|
}
|
|
17
|
+
/** Validate declarations at registration and at dynamically resolved execution boundaries. */
|
|
18
|
+
function assertActionFinalization(action) {
|
|
19
|
+
if (action.finalize === void 0) return;
|
|
20
|
+
if (typeof action.finalize !== "function") throw new Error("Action finalization hook must be a function.");
|
|
21
|
+
if (action.eventPhase !== "after_adapters") throw new Error("Action finalization requires eventPhase after_adapters.");
|
|
22
|
+
if (action.kind !== void 0 && action.kind !== "atomic") throw new Error("Action finalization requires an atomic action.");
|
|
23
|
+
if (action.execution?.completion !== void 0 && action.execution.completion !== "immediate") throw new Error("Action finalization requires immediate completion.");
|
|
24
|
+
}
|
|
25
|
+
/** Refuse older hosts before application handler code executes. Use for distributed finalizing actions. */
|
|
26
|
+
function defineFinalizingAction(action) {
|
|
27
|
+
assertActionFinalization(action);
|
|
28
|
+
const handler = action.handler;
|
|
29
|
+
return {
|
|
30
|
+
...action,
|
|
31
|
+
handler: async (ctx, params) => {
|
|
32
|
+
if (ctx.finalizationProtocol !== "atomic-after-adapters-v1") throw new Error("Host does not support atomic-after-adapters-v1 finalization.");
|
|
33
|
+
return handler ? handler(ctx, params) : {
|
|
34
|
+
success: true,
|
|
35
|
+
data: {}
|
|
36
|
+
};
|
|
37
|
+
}
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
/** Validate optional step execution budgets before accepting or executing an action. */
|
|
41
|
+
function assertAdapterStepDeadlines(action) {
|
|
42
|
+
for (const step of action.adapterSteps ?? []) if (step.deadlineMs !== void 0 && (!Number.isInteger(step.deadlineMs) || step.deadlineMs <= 0)) throw new Error(`Action "${action.actionId}" adapter step deadlineMs must be a positive finite integer.`);
|
|
43
|
+
}
|
|
17
44
|
function assertActionId(actionId) {
|
|
18
45
|
if (!/^[a-z][a-z0-9-]*\.[a-z][a-z0-9_]*$/.test(actionId)) throw new Error(`Invalid action ID: ${actionId}`);
|
|
19
46
|
}
|
|
@@ -24,6 +51,8 @@ function createActionRegistry(definitions = []) {
|
|
|
24
51
|
if (actions.has(definition.actionId)) throw new Error(`Action "${definition.actionId}" is already registered`);
|
|
25
52
|
if (definition.mutatesDomain && definition.emitsEvents.length === 0) throw new Error(`Action "${definition.actionId}" mutates domain but emits no events. Every mutating action must emit at least one AssetEvent.`);
|
|
26
53
|
if (definition.admitSubmission !== void 0 && typeof definition.admitSubmission !== "function") throw new Error(`Action "${definition.actionId}" declares admitSubmission that is not a function.`);
|
|
54
|
+
assertAdapterStepDeadlines(definition);
|
|
55
|
+
assertActionFinalization(definition);
|
|
27
56
|
actions.set(definition.actionId, definition);
|
|
28
57
|
};
|
|
29
58
|
for (const definition of definitions) register(definition);
|
|
@@ -39,9 +68,12 @@ function createActionRegistry(definitions = []) {
|
|
|
39
68
|
}
|
|
40
69
|
//#endregion
|
|
41
70
|
exports.ACTOR_TYPES = ACTOR_TYPES;
|
|
71
|
+
exports.assertActionFinalization = assertActionFinalization;
|
|
42
72
|
exports.assertActionId = assertActionId;
|
|
43
73
|
exports.assertActorType = assertActorType;
|
|
74
|
+
exports.assertAdapterStepDeadlines = assertAdapterStepDeadlines;
|
|
44
75
|
exports.createActionRegistry = createActionRegistry;
|
|
76
|
+
exports.defineFinalizingAction = defineFinalizingAction;
|
|
45
77
|
exports.isActorType = isActorType;
|
|
46
78
|
|
|
47
79
|
//# sourceMappingURL=index.cjs.map
|
|
@@ -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\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\nexport interface ActionResult {\n\tsuccess: boolean;\n\tdata?: Record<string, unknown>;\n\terror?: string;\n}\n\nexport type ActionHandler<TDb = unknown> = (\n\tctx: ActionContext<TDb>,\n\tparams: unknown,\n) => Promise<ActionResult>;\n\nexport interface AdapterStepRetryPolicy {\n\tidempotent: boolean;\n\tmaxAttempts?: number;\n\tinitialDelayMs?: number;\n\tbackoffMultiplier?: number;\n\tmaxDelayMs?: number;\n}\n\nexport interface AdapterStep {\n\tadapterType: string;\n\toperation: string;\n\tretryPolicy?: AdapterStepRetryPolicy;\n\tgetInput: (\n\t\tparams: unknown,\n\t\thandlerResult: Record<string, unknown>,\n\t) => Record<string, unknown> | undefined;\n}\n\nexport interface ActionStateMachineBinding {\n\tentityType: string;\n\ttargetState: string | ((params: unknown) => string);\n\tgetEntityId: (params: unknown) => string | undefined;\n}\n\nexport interface ActionDefinition<TDb = unknown> 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\trequiredRoles?: string[];\n\trequiredPermissions?: string[];\n\tpolicies?: `${string}.v${number}`[];\n\temitsEvents: string[];\n\tidempotent: boolean;\n\tmutatesDomain: boolean;\n\t/** Portable execution semantics used by hosts, gateways, and generated capability contracts. */\n\texecution?: ActionExecutionContract;\n\tstateMachine?: ActionStateMachineBinding;\n\tadapterSteps?: AdapterStep[];\n\t/** Completion actions can attest only after all external adapter work succeeds. */\n\teventPhase?: \"before_adapters\" | \"after_adapters\";\n\t/**\n\t * If \"saga\", the action is a multi-step orchestration. The worker dispatches\n\t * to a registered saga implementation instead of running `handler` directly.\n\t */\n\tkind?: \"atomic\" | \"saga\";\n}\n\nexport type ActionConnectivity = \"online-required\" | \"offline-capturable\";\nexport type AuthorityMoment = \"capture\" | \"execution\" | \"both\";\nexport type ActionIdempotencyStance = \"required\" | \"supported\" | \"prohibited\";\nexport type ActionCompletionMode = \"immediate\" | \"accepted\" | \"long-running\";\nexport type ActionConsistency = \"authoritative-now\" | \"provisional-until-reconciled\";\nexport type ActionDataSensitivity = \"public\" | \"internal\" | \"confidential\" | \"restricted\";\n\nexport interface ActionExecutionContract {\n\tconnectivity: ActionConnectivity;\n\tauthorityMoment: AuthorityMoment;\n\tidempotency: ActionIdempotencyStance;\n\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\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;AA0QA,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,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/**\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\nexport interface ActionResult {\n\tsuccess: boolean;\n\tdata?: Record<string, unknown>;\n\terror?: string;\n}\n\nexport type ActionHandler<TDb = unknown> = (\n\tctx: ActionContext<TDb>,\n\tparams: unknown,\n) => Promise<ActionResult>;\n\nexport 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}\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/** 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;;AAyIA,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;AAmJA,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
|
@@ -40,6 +40,7 @@ export interface ActionContext<TDb = unknown> {
|
|
|
40
40
|
};
|
|
41
41
|
db: TDb;
|
|
42
42
|
services?: FabricRuntimeServices;
|
|
43
|
+
finalizationProtocol?: "atomic-after-adapters-v1";
|
|
43
44
|
/**
|
|
44
45
|
* When the host admitted this invocation's submission through the
|
|
45
46
|
* action's `admitSubmission` check, read from the durable invocation
|
|
@@ -112,6 +113,47 @@ export interface ActionResult {
|
|
|
112
113
|
error?: string;
|
|
113
114
|
}
|
|
114
115
|
export type ActionHandler<TDb = unknown> = (ctx: ActionContext<TDb>, params: unknown) => Promise<ActionResult>;
|
|
116
|
+
export type FinalizationJson = null | boolean | number | string | readonly FinalizationJson[] | {
|
|
117
|
+
readonly [key: string]: FinalizationJson;
|
|
118
|
+
};
|
|
119
|
+
export type FinalizationRecord = {
|
|
120
|
+
readonly [key: string]: FinalizationJson;
|
|
121
|
+
};
|
|
122
|
+
export type ActionFinalizationContext<TDb = unknown> = Pick<ActionContext<TDb>, "actionInvocationId" | "tenantId" | "spaceId" | "actorId" | "actorType" | "correlationId" | "causationId" | "provenance" | "db">;
|
|
123
|
+
export type ActionFinalizationStep = {
|
|
124
|
+
readonly stepIndex: number;
|
|
125
|
+
readonly adapterType: string;
|
|
126
|
+
readonly operation: string;
|
|
127
|
+
} & ({
|
|
128
|
+
readonly status: "succeeded";
|
|
129
|
+
readonly adapterInvocationId: string;
|
|
130
|
+
readonly output: FinalizationRecord;
|
|
131
|
+
} | {
|
|
132
|
+
readonly status: "skipped";
|
|
133
|
+
});
|
|
134
|
+
export interface ActionFinalizationInput {
|
|
135
|
+
readonly params: FinalizationJson;
|
|
136
|
+
readonly handlerData: FinalizationRecord;
|
|
137
|
+
readonly adapterOutputs: readonly ActionFinalizationStep[];
|
|
138
|
+
}
|
|
139
|
+
export interface ActionFinalizationEvent {
|
|
140
|
+
readonly eventType: string;
|
|
141
|
+
readonly subjectType: string;
|
|
142
|
+
readonly subjectId: string;
|
|
143
|
+
readonly payload: FinalizationJson;
|
|
144
|
+
readonly eventSchemaVersion?: number;
|
|
145
|
+
}
|
|
146
|
+
export interface ActionFinalizationResult {
|
|
147
|
+
readonly events?: readonly ActionFinalizationEvent[];
|
|
148
|
+
readonly resultPatch?: FinalizationRecord;
|
|
149
|
+
}
|
|
150
|
+
export type ActionFinalizer<TDb = unknown> = (ctx: ActionFinalizationContext<TDb>, input: ActionFinalizationInput) => Promise<ActionFinalizationResult>;
|
|
151
|
+
/** Validate declarations at registration and at dynamically resolved execution boundaries. */
|
|
152
|
+
export declare function assertActionFinalization<TDb>(action: Pick<ActionDefinition<TDb>, "actionId" | "finalize" | "eventPhase" | "kind" | "execution">): void;
|
|
153
|
+
/** Refuse older hosts before application handler code executes. Use for distributed finalizing actions. */
|
|
154
|
+
export declare function defineFinalizingAction<TDb>(action: ActionDefinition<TDb> & {
|
|
155
|
+
finalize: ActionFinalizer<TDb>;
|
|
156
|
+
}): ActionDefinition<TDb>;
|
|
115
157
|
export interface AdapterStepRetryPolicy {
|
|
116
158
|
idempotent: boolean;
|
|
117
159
|
maxAttempts?: number;
|
|
@@ -123,8 +165,15 @@ export interface AdapterStep {
|
|
|
123
165
|
adapterType: string;
|
|
124
166
|
operation: string;
|
|
125
167
|
retryPolicy?: AdapterStepRetryPolicy;
|
|
168
|
+
/** Positive finite integer duration in milliseconds; overrides Host adapterDeadlineMs for this step. */
|
|
169
|
+
deadlineMs?: number;
|
|
126
170
|
getInput: (params: unknown, handlerResult: Record<string, unknown>) => Record<string, unknown> | undefined;
|
|
127
171
|
}
|
|
172
|
+
/** Validate optional step execution budgets before accepting or executing an action. */
|
|
173
|
+
export declare function assertAdapterStepDeadlines(action: {
|
|
174
|
+
actionId: string;
|
|
175
|
+
adapterSteps?: readonly Pick<AdapterStep, "deadlineMs">[];
|
|
176
|
+
}): void;
|
|
128
177
|
export interface ActionStateMachineBinding {
|
|
129
178
|
entityType: string;
|
|
130
179
|
targetState: string | ((params: unknown) => string);
|
|
@@ -148,6 +197,7 @@ export interface ActionDefinition<TDb = unknown> extends SurfaceDeclaration {
|
|
|
148
197
|
/** Optional validation contract for the public handler result data. */
|
|
149
198
|
resultSchema?: SchemaValidator;
|
|
150
199
|
handler?: ActionHandler<TDb>;
|
|
200
|
+
finalize?: ActionFinalizer<TDb>;
|
|
151
201
|
requiredRoles?: string[];
|
|
152
202
|
requiredPermissions?: string[];
|
|
153
203
|
policies?: `${string}.v${number}`[];
|
package/dist/actions/index.d.ts
CHANGED
|
@@ -40,6 +40,7 @@ export interface ActionContext<TDb = unknown> {
|
|
|
40
40
|
};
|
|
41
41
|
db: TDb;
|
|
42
42
|
services?: FabricRuntimeServices;
|
|
43
|
+
finalizationProtocol?: "atomic-after-adapters-v1";
|
|
43
44
|
/**
|
|
44
45
|
* When the host admitted this invocation's submission through the
|
|
45
46
|
* action's `admitSubmission` check, read from the durable invocation
|
|
@@ -112,6 +113,47 @@ export interface ActionResult {
|
|
|
112
113
|
error?: string;
|
|
113
114
|
}
|
|
114
115
|
export type ActionHandler<TDb = unknown> = (ctx: ActionContext<TDb>, params: unknown) => Promise<ActionResult>;
|
|
116
|
+
export type FinalizationJson = null | boolean | number | string | readonly FinalizationJson[] | {
|
|
117
|
+
readonly [key: string]: FinalizationJson;
|
|
118
|
+
};
|
|
119
|
+
export type FinalizationRecord = {
|
|
120
|
+
readonly [key: string]: FinalizationJson;
|
|
121
|
+
};
|
|
122
|
+
export type ActionFinalizationContext<TDb = unknown> = Pick<ActionContext<TDb>, "actionInvocationId" | "tenantId" | "spaceId" | "actorId" | "actorType" | "correlationId" | "causationId" | "provenance" | "db">;
|
|
123
|
+
export type ActionFinalizationStep = {
|
|
124
|
+
readonly stepIndex: number;
|
|
125
|
+
readonly adapterType: string;
|
|
126
|
+
readonly operation: string;
|
|
127
|
+
} & ({
|
|
128
|
+
readonly status: "succeeded";
|
|
129
|
+
readonly adapterInvocationId: string;
|
|
130
|
+
readonly output: FinalizationRecord;
|
|
131
|
+
} | {
|
|
132
|
+
readonly status: "skipped";
|
|
133
|
+
});
|
|
134
|
+
export interface ActionFinalizationInput {
|
|
135
|
+
readonly params: FinalizationJson;
|
|
136
|
+
readonly handlerData: FinalizationRecord;
|
|
137
|
+
readonly adapterOutputs: readonly ActionFinalizationStep[];
|
|
138
|
+
}
|
|
139
|
+
export interface ActionFinalizationEvent {
|
|
140
|
+
readonly eventType: string;
|
|
141
|
+
readonly subjectType: string;
|
|
142
|
+
readonly subjectId: string;
|
|
143
|
+
readonly payload: FinalizationJson;
|
|
144
|
+
readonly eventSchemaVersion?: number;
|
|
145
|
+
}
|
|
146
|
+
export interface ActionFinalizationResult {
|
|
147
|
+
readonly events?: readonly ActionFinalizationEvent[];
|
|
148
|
+
readonly resultPatch?: FinalizationRecord;
|
|
149
|
+
}
|
|
150
|
+
export type ActionFinalizer<TDb = unknown> = (ctx: ActionFinalizationContext<TDb>, input: ActionFinalizationInput) => Promise<ActionFinalizationResult>;
|
|
151
|
+
/** Validate declarations at registration and at dynamically resolved execution boundaries. */
|
|
152
|
+
export declare function assertActionFinalization<TDb>(action: Pick<ActionDefinition<TDb>, "actionId" | "finalize" | "eventPhase" | "kind" | "execution">): void;
|
|
153
|
+
/** Refuse older hosts before application handler code executes. Use for distributed finalizing actions. */
|
|
154
|
+
export declare function defineFinalizingAction<TDb>(action: ActionDefinition<TDb> & {
|
|
155
|
+
finalize: ActionFinalizer<TDb>;
|
|
156
|
+
}): ActionDefinition<TDb>;
|
|
115
157
|
export interface AdapterStepRetryPolicy {
|
|
116
158
|
idempotent: boolean;
|
|
117
159
|
maxAttempts?: number;
|
|
@@ -123,8 +165,15 @@ export interface AdapterStep {
|
|
|
123
165
|
adapterType: string;
|
|
124
166
|
operation: string;
|
|
125
167
|
retryPolicy?: AdapterStepRetryPolicy;
|
|
168
|
+
/** Positive finite integer duration in milliseconds; overrides Host adapterDeadlineMs for this step. */
|
|
169
|
+
deadlineMs?: number;
|
|
126
170
|
getInput: (params: unknown, handlerResult: Record<string, unknown>) => Record<string, unknown> | undefined;
|
|
127
171
|
}
|
|
172
|
+
/** Validate optional step execution budgets before accepting or executing an action. */
|
|
173
|
+
export declare function assertAdapterStepDeadlines(action: {
|
|
174
|
+
actionId: string;
|
|
175
|
+
adapterSteps?: readonly Pick<AdapterStep, "deadlineMs">[];
|
|
176
|
+
}): void;
|
|
128
177
|
export interface ActionStateMachineBinding {
|
|
129
178
|
entityType: string;
|
|
130
179
|
targetState: string | ((params: unknown) => string);
|
|
@@ -148,6 +197,7 @@ export interface ActionDefinition<TDb = unknown> extends SurfaceDeclaration {
|
|
|
148
197
|
/** Optional validation contract for the public handler result data. */
|
|
149
198
|
resultSchema?: SchemaValidator;
|
|
150
199
|
handler?: ActionHandler<TDb>;
|
|
200
|
+
finalize?: ActionFinalizer<TDb>;
|
|
151
201
|
requiredRoles?: string[];
|
|
152
202
|
requiredPermissions?: string[];
|
|
153
203
|
policies?: `${string}.v${number}`[];
|
package/dist/actions/index.js
CHANGED
|
@@ -13,6 +13,33 @@ function isActorType(value) {
|
|
|
13
13
|
function assertActorType(value) {
|
|
14
14
|
if (!isActorType(value)) throw new Error(`Invalid actorType: ${value}`);
|
|
15
15
|
}
|
|
16
|
+
/** Validate declarations at registration and at dynamically resolved execution boundaries. */
|
|
17
|
+
function assertActionFinalization(action) {
|
|
18
|
+
if (action.finalize === void 0) return;
|
|
19
|
+
if (typeof action.finalize !== "function") throw new Error("Action finalization hook must be a function.");
|
|
20
|
+
if (action.eventPhase !== "after_adapters") throw new Error("Action finalization requires eventPhase after_adapters.");
|
|
21
|
+
if (action.kind !== void 0 && action.kind !== "atomic") throw new Error("Action finalization requires an atomic action.");
|
|
22
|
+
if (action.execution?.completion !== void 0 && action.execution.completion !== "immediate") throw new Error("Action finalization requires immediate completion.");
|
|
23
|
+
}
|
|
24
|
+
/** Refuse older hosts before application handler code executes. Use for distributed finalizing actions. */
|
|
25
|
+
function defineFinalizingAction(action) {
|
|
26
|
+
assertActionFinalization(action);
|
|
27
|
+
const handler = action.handler;
|
|
28
|
+
return {
|
|
29
|
+
...action,
|
|
30
|
+
handler: async (ctx, params) => {
|
|
31
|
+
if (ctx.finalizationProtocol !== "atomic-after-adapters-v1") throw new Error("Host does not support atomic-after-adapters-v1 finalization.");
|
|
32
|
+
return handler ? handler(ctx, params) : {
|
|
33
|
+
success: true,
|
|
34
|
+
data: {}
|
|
35
|
+
};
|
|
36
|
+
}
|
|
37
|
+
};
|
|
38
|
+
}
|
|
39
|
+
/** Validate optional step execution budgets before accepting or executing an action. */
|
|
40
|
+
function assertAdapterStepDeadlines(action) {
|
|
41
|
+
for (const step of action.adapterSteps ?? []) if (step.deadlineMs !== void 0 && (!Number.isInteger(step.deadlineMs) || step.deadlineMs <= 0)) throw new Error(`Action "${action.actionId}" adapter step deadlineMs must be a positive finite integer.`);
|
|
42
|
+
}
|
|
16
43
|
function assertActionId(actionId) {
|
|
17
44
|
if (!/^[a-z][a-z0-9-]*\.[a-z][a-z0-9_]*$/.test(actionId)) throw new Error(`Invalid action ID: ${actionId}`);
|
|
18
45
|
}
|
|
@@ -23,6 +50,8 @@ function createActionRegistry(definitions = []) {
|
|
|
23
50
|
if (actions.has(definition.actionId)) throw new Error(`Action "${definition.actionId}" is already registered`);
|
|
24
51
|
if (definition.mutatesDomain && definition.emitsEvents.length === 0) throw new Error(`Action "${definition.actionId}" mutates domain but emits no events. Every mutating action must emit at least one AssetEvent.`);
|
|
25
52
|
if (definition.admitSubmission !== void 0 && typeof definition.admitSubmission !== "function") throw new Error(`Action "${definition.actionId}" declares admitSubmission that is not a function.`);
|
|
53
|
+
assertAdapterStepDeadlines(definition);
|
|
54
|
+
assertActionFinalization(definition);
|
|
26
55
|
actions.set(definition.actionId, definition);
|
|
27
56
|
};
|
|
28
57
|
for (const definition of definitions) register(definition);
|
|
@@ -37,6 +66,6 @@ function createActionRegistry(definitions = []) {
|
|
|
37
66
|
};
|
|
38
67
|
}
|
|
39
68
|
//#endregion
|
|
40
|
-
export { ACTOR_TYPES, assertActionId, assertActorType, createActionRegistry, isActorType };
|
|
69
|
+
export { ACTOR_TYPES, assertActionFinalization, assertActionId, assertActorType, assertAdapterStepDeadlines, createActionRegistry, defineFinalizingAction, isActorType };
|
|
41
70
|
|
|
42
71
|
//# sourceMappingURL=index.js.map
|
|
@@ -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\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\nexport interface ActionResult {\n\tsuccess: boolean;\n\tdata?: Record<string, unknown>;\n\terror?: string;\n}\n\nexport type ActionHandler<TDb = unknown> = (\n\tctx: ActionContext<TDb>,\n\tparams: unknown,\n) => Promise<ActionResult>;\n\nexport interface AdapterStepRetryPolicy {\n\tidempotent: boolean;\n\tmaxAttempts?: number;\n\tinitialDelayMs?: number;\n\tbackoffMultiplier?: number;\n\tmaxDelayMs?: number;\n}\n\nexport interface AdapterStep {\n\tadapterType: string;\n\toperation: string;\n\tretryPolicy?: AdapterStepRetryPolicy;\n\tgetInput: (\n\t\tparams: unknown,\n\t\thandlerResult: Record<string, unknown>,\n\t) => Record<string, unknown> | undefined;\n}\n\nexport interface ActionStateMachineBinding {\n\tentityType: string;\n\ttargetState: string | ((params: unknown) => string);\n\tgetEntityId: (params: unknown) => string | undefined;\n}\n\nexport interface ActionDefinition<TDb = unknown> 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\trequiredRoles?: string[];\n\trequiredPermissions?: string[];\n\tpolicies?: `${string}.v${number}`[];\n\temitsEvents: string[];\n\tidempotent: boolean;\n\tmutatesDomain: boolean;\n\t/** Portable execution semantics used by hosts, gateways, and generated capability contracts. */\n\texecution?: ActionExecutionContract;\n\tstateMachine?: ActionStateMachineBinding;\n\tadapterSteps?: AdapterStep[];\n\t/** Completion actions can attest only after all external adapter work succeeds. */\n\teventPhase?: \"before_adapters\" | \"after_adapters\";\n\t/**\n\t * If \"saga\", the action is a multi-step orchestration. The worker dispatches\n\t * to a registered saga implementation instead of running `handler` directly.\n\t */\n\tkind?: \"atomic\" | \"saga\";\n}\n\nexport type ActionConnectivity = \"online-required\" | \"offline-capturable\";\nexport type AuthorityMoment = \"capture\" | \"execution\" | \"both\";\nexport type ActionIdempotencyStance = \"required\" | \"supported\" | \"prohibited\";\nexport type ActionCompletionMode = \"immediate\" | \"accepted\" | \"long-running\";\nexport type ActionConsistency = \"authoritative-now\" | \"provisional-until-reconciled\";\nexport type ActionDataSensitivity = \"public\" | \"internal\" | \"confidential\" | \"restricted\";\n\nexport interface ActionExecutionContract {\n\tconnectivity: ActionConnectivity;\n\tauthorityMoment: AuthorityMoment;\n\tidempotency: ActionIdempotencyStance;\n\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\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;AA0QA,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,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/**\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\nexport interface ActionResult {\n\tsuccess: boolean;\n\tdata?: Record<string, unknown>;\n\terror?: string;\n}\n\nexport type ActionHandler<TDb = unknown> = (\n\tctx: ActionContext<TDb>,\n\tparams: unknown,\n) => Promise<ActionResult>;\n\nexport 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}\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/** 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;;AAyIA,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;AAmJA,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/index.cjs
CHANGED
|
@@ -44,10 +44,12 @@ exports.aggregatePolicyOutcomes = require_policies.aggregatePolicyOutcomes;
|
|
|
44
44
|
exports.anonymizeAssetEventPayload = require_privacy_index.anonymizeAssetEventPayload;
|
|
45
45
|
exports.anonymizeEvidencePacket = require_privacy_index.anonymizeEvidencePacket;
|
|
46
46
|
exports.anonymizeJsonValue = require_privacy_index.anonymizeJsonValue;
|
|
47
|
+
exports.assertActionFinalization = require_actions_index.assertActionFinalization;
|
|
47
48
|
exports.assertActionId = require_actions_index.assertActionId;
|
|
48
49
|
exports.assertActorType = require_actions_index.assertActorType;
|
|
49
50
|
exports.assertAdapterCircuitBreakerConfig = require_adapters_index.assertAdapterCircuitBreakerConfig;
|
|
50
51
|
exports.assertAdapterOutcomeConsistency = require_adapters_index.assertAdapterOutcomeConsistency;
|
|
52
|
+
exports.assertAdapterStepDeadlines = require_actions_index.assertAdapterStepDeadlines;
|
|
51
53
|
exports.assertGovernanceRuntimeEvidence = require_governance_index.assertGovernanceRuntimeEvidence;
|
|
52
54
|
exports.assertMutationGovernanceContext = require_governance_index.assertMutationGovernanceContext;
|
|
53
55
|
exports.assertObjectType = require_objects_index.assertObjectType;
|
|
@@ -71,6 +73,7 @@ exports.createObjectTypeRegistry = require_objects_index.createObjectTypeRegistr
|
|
|
71
73
|
exports.createPolicyRegistry = require_policies.createPolicyRegistry;
|
|
72
74
|
exports.createStateMachineRegistry = require_state_machines_index.createStateMachineRegistry;
|
|
73
75
|
exports.createViewRegistry = require_projections_index.createViewRegistry;
|
|
76
|
+
exports.defineFinalizingAction = require_actions_index.defineFinalizingAction;
|
|
74
77
|
exports.evaluatePolicyDefinition = require_policies.evaluatePolicyDefinition;
|
|
75
78
|
exports.evaluatePolicyDefinitions = require_policies.evaluatePolicyDefinitions;
|
|
76
79
|
exports.evaluateRegisteredPolicies = require_policies.evaluateRegisteredPolicies;
|
package/dist/index.d.cts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { n as assertSurfaceDeclaration, t as SurfaceDeclaration } from "./index-CIl1rYRv.cjs";
|
|
2
|
-
import { ACTOR_TYPES, ActionAdmission, ActionAdmissionDecision, ActionAdmissionInput, ActionAdmissionSignal, ActionCompletionMode, ActionConnectivity, ActionConsistency, ActionContext, ActionDataSensitivity, ActionDefinition, ActionExecutionContract, ActionHandler, ActionId, ActionIdempotencyStance, ActionRegistry, ActionResult, ActionStateMachineBinding, ActionStatus, ActorType, AdapterStep, AdapterStepRetryPolicy, AuthorityMoment, FabricRuntimeServices, SagaChildActionInput, SagaCompletion, SagaCompletionEvent, SagaContext, SagaImplementation, SagaRunChild, SchemaParseIssue, SchemaParseResult, SchemaValidator, assertActionId, assertActorType, createActionRegistry, isActorType } from "./actions/index.cjs";
|
|
2
|
+
import { ACTOR_TYPES, ActionAdmission, ActionAdmissionDecision, ActionAdmissionInput, ActionAdmissionSignal, ActionCompletionMode, ActionConnectivity, ActionConsistency, ActionContext, ActionDataSensitivity, ActionDefinition, ActionExecutionContract, ActionFinalizationContext, ActionFinalizationEvent, ActionFinalizationInput, ActionFinalizationResult, ActionFinalizationStep, ActionFinalizer, ActionHandler, ActionId, ActionIdempotencyStance, ActionRegistry, ActionResult, ActionStateMachineBinding, ActionStatus, ActorType, AdapterStep, AdapterStepRetryPolicy, AuthorityMoment, FabricRuntimeServices, FinalizationJson, FinalizationRecord, SagaChildActionInput, SagaCompletion, SagaCompletionEvent, SagaContext, SagaImplementation, SagaRunChild, SchemaParseIssue, SchemaParseResult, SchemaValidator, assertActionFinalization, assertActionId, assertActorType, assertAdapterStepDeadlines, createActionRegistry, defineFinalizingAction, isActorType } from "./actions/index.cjs";
|
|
3
3
|
import { AcceptedExternalOperation, AdapterAttempt, AdapterCircuitAdmission, AdapterCircuitBreaker, AdapterCircuitBreakerConfig, AdapterCircuitBreakerEvent, AdapterCircuitBreakerEventListener, AdapterCircuitBreakerEventReason, AdapterCircuitBreakerManualOverride, AdapterCircuitBreakerProvider, AdapterCircuitBreakerRegistry, AdapterCircuitBreakerRegistryOptions, AdapterCircuitBreakerScope, AdapterCircuitOpenError, AdapterCircuitOutcome, AdapterCircuitState, AdapterExecutionContext, AdapterExecutionResult, AdapterExecutor, AdapterImplementation, AdapterOutcomeEvidence, AdapterOutcomeKind, AdapterRegistry, AdapterRetryPolicy, ExecuteWithRetryOptions, InMemoryAdapterCircuitBreaker, InMemoryAdapterCircuitBreakerOptions, MissingAdapterRegistrationError, ResolvedAdapterRetryPolicy, assertAdapterCircuitBreakerConfig, assertAdapterOutcomeConsistency, classifyAdapterOutcome, classifyCircuitBreakerOutcome, executeWithAdapterRetry, getRetryDelayMs, isAdapterCircuitOpenError, resolveAdapterRetryPolicy, scopedAdapterCircuitBreakerKey, shouldRetryAdapterOutcome } from "./adapters/index.cjs";
|
|
4
4
|
import { AgentActionPolicyContext, AgentActionPolicyDecision, AgentActionPolicyDefinition, AgentActionPolicyEvaluator, AgentActionPolicyRegistry, AgentActionRiskTier, AgentActionRoute } from "./agent-hitl/index.cjs";
|
|
5
5
|
import { a as ObjectTypeRegistry, c as assertPortableJsonSchema, i as JsonValue, l as createObjectTypeRegistry, n as JsonPrimitive, o as PortableJsonSchema, r as JsonSchemaValidationIssue, s as assertObjectType, t as FabricObjectType, u as validatePortableJson } from "./index-DZ4mnNb7.cjs";
|
|
@@ -15,4 +15,4 @@ import { C as AnonymizationPolicy, D as stableChecksum, E as FieldRedactor, S as
|
|
|
15
15
|
import { ExecutionAttestation, ExecutionPrincipal, ExternalReconciliation, ExternalResourceOperation, ExternalResourceRef, FABRIC_GOVERNANCE_CONTRACT_VERSION, GovernanceRuntimeEvidence, MutationFootprint, MutationFootprintEntry, MutationGovernanceContext, MutationGovernanceResolutionInput, MutationGovernanceResolver, PolicyObligation, PolicyObligationStatus, ReconciliationStatus, assertGovernanceRuntimeEvidence, assertMutationGovernanceContext } from "./governance/index.cjs";
|
|
16
16
|
import { FABRIC_ID_PREFIXES, FabricIdPrefix, createFabricId, isFabricId, parseFabricId } from "./ids/index.cjs";
|
|
17
17
|
import { FakeActionContextOptions, createDeterministicIdFactory, createFakeActionContext, createInMemoryAdapterRegistry } from "./testing/index.cjs";
|
|
18
|
-
export { ACTOR_TYPES, ANONYMIZATION_POLICY_VERSION, AcceptedExternalOperation, ActionAdmission, ActionAdmissionDecision, ActionAdmissionInput, ActionAdmissionSignal, ActionCompletionMode, ActionConnectivity, ActionConsistency, ActionContext, ActionDataSensitivity, ActionDefinition, ActionExecutionContract, ActionHandler, ActionId, ActionIdempotencyStance, ActionRegistry, ActionResult, ActionStateMachineBinding, ActionStatus, ActorType, AdapterAttempt, AdapterCircuitAdmission, AdapterCircuitBreaker, AdapterCircuitBreakerConfig, AdapterCircuitBreakerEvent, AdapterCircuitBreakerEventListener, AdapterCircuitBreakerEventReason, AdapterCircuitBreakerManualOverride, AdapterCircuitBreakerProvider, AdapterCircuitBreakerRegistry, AdapterCircuitBreakerRegistryOptions, AdapterCircuitBreakerScope, AdapterCircuitOpenError, AdapterCircuitOutcome, AdapterCircuitState, AdapterExecutionContext, AdapterExecutionResult, AdapterExecutor, AdapterImplementation, AdapterOutcomeEvidence, AdapterOutcomeKind, AdapterRegistry, AdapterRetryPolicy, AdapterStep, AdapterStepRetryPolicy, AgentActionPolicyContext, AgentActionPolicyDecision, AgentActionPolicyDefinition, AgentActionPolicyEvaluator, AgentActionPolicyRegistry, AgentActionRiskTier, AgentActionRoute, AnalyticsDataContract, AnalyticsDataContractSource, AnalyticsEligibilityDecision, AnonymizationContext, AnonymizationEngine, type AnonymizationEngineOptions, AnonymizationFieldMetadata, type AnonymizationFieldPolicy, type AnonymizationLifecycleEvidence, AnonymizationMetadata, type AnonymizationPolicy, AnonymizationResult, AssetEventActorType, AssetEventEnvelope, type AssetEventLike, AssetEventSubjectType, AssetEventType, AuthorityMoment, CapabilityMetadata, CapabilityPortRequirement, CapabilityRequirements, CapabilityWorkflowCompensation, CapabilityWorkflowDeclaration, CapabilityWorkflowTimer, DEFAULT_EVIDENCE_PACKET_TYPE, DEFAULT_EVIDENCE_REDACTION_REASON, DataClassificationRule, DataPolicyComparisonOperator, DataPolicyCondition, DataPolicyConditionResult, DataPolicyDefinition, DataPolicyLiteral, DataPolicySource, DataPolicySourceReference, DataPolicyValidationResult, DeclarativeInvariant, EVIDENCE_PACKET_CHECKSUM_ALGORITHM, EVIDENCE_PACKET_SCHEMA_VERSION, EventContractRegistry, EventProvenance, EventTypeRegistration, EventTypeRegistrationInput, type EvidenceEventQuery, type EvidenceEventRecord, EvidenceGenerationContext, type EvidenceInvocationRecord, type EvidenceJsonRecord, EvidencePacketEnvelope, EvidencePacketGenerationError, type EvidencePacketGenerationErrorCode, type EvidencePacketLike, type EvidencePacketPayload, type EvidencePacketReadPort, EvidencePacketReference, type EvidencePacketRendererInput, type EvidencePacketRendererOptions, EvidencePacketStatus, EvidencePacketSubject, type EvidenceRecord, EvidenceRenderer, type EvidenceScope, type EvidenceTimestamp, ExecuteWithRetryOptions, ExecutionAttestation, ExecutionContractFinding, ExecutionContractFindingCode, ExecutionContractProfile, ExecutionContractProfileOptions, ExecutionPrincipal, ExternalReconciliation, ExternalResourceOperation, ExternalResourceRef, FABRIC_GOVERNANCE_CONTRACT_VERSION, FABRIC_ID_PREFIXES, FabricIdPrefix, FabricModule, FabricObjectType, FabricRuntimeServices, FakeActionContextOptions, FieldRedactor, type GenerateEvidencePacketInput, type GenerateEvidencePacketOptions, GovernanceRuntimeEvidence, IdPrefixRegistration, InMemoryAdapterCircuitBreaker, InMemoryAdapterCircuitBreakerOptions, InvariantEnforcement, JsonPrimitive, JsonSchemaExportableValidator, JsonSchemaValidationIssue, JsonValue, MODULE_MANIFEST_VERSION, MissingAdapterRegistrationError, ModuleDependency, ModuleDependencyInput, ModuleManifest, ModuleManifestAction, ModuleManifestActionStateMachine, ModuleManifestActionV1, ModuleManifestAdapterStep, ModuleManifestBundle, ModuleManifestBundleV1, ModuleManifestCodePolicy, ModuleManifestDataPolicy, ModuleManifestEventType, ModuleManifestIdPrefix, ModuleManifestObjectType, ModuleManifestObjectTypeV1, ModuleManifestPolicy, ModuleManifestStateMachine, ModuleManifestStateMachineTransition, ModuleManifestV1, ModuleManifestView, ModuleRegistry, MutationFootprint, MutationFootprintEntry, MutationGovernanceContext, MutationGovernanceResolutionInput, MutationGovernanceResolver, ObjectRelationCardinality, ObjectRelationDefinition, ObjectRelationDeleteBehavior, ObjectRelationSemantics, ObjectTypeRegistration, ObjectTypeRegistrationInput, ObjectTypeRegistry, PLATFORM_PRIVACY_POLICY_VERSION, PlatformDataClass, PolicyAuthorityReference, PolicyContext, PolicyCorrectiveAction, PolicyCorrectiveActionBase, PolicyCorrectiveActionKind, PolicyDispatchEvidence, PolicyEvaluationMode, PolicyEvaluationResult, PolicyEvaluator, PolicyFact, PolicyFallbackDefinition, PolicyFallbackTrigger, PolicyGuidance, PolicyGuidanceValidationResult, PolicyId, PolicyInvokeActionCorrectiveAction, PolicyKind, PolicyManualCorrectiveAction, PolicyNavigateCorrectiveAction, PolicyObligation, PolicyObligationStatus, PolicyOutcome, PolicyRegistration, PolicyRegistry, PortableJsonSchema, ReconciliationRequiredError, ReconciliationStatus, RedactionMethod, RedactionRule, ReplayEventsOptions, ReplayEventsResult, ReplayScope, ReplaySnapshot, ReplayViewOptions, ReplayWarning, ReplayWarningCode, ReplayableAssetEvent, ResolvedAdapterRetryPolicy, RetentionRule, RetryableExecutionError, RuntimePolicyDefinition, STRICT_EXECUTION_CONTRACT_PROFILE, STRICT_EXECUTION_CONTRACT_PROFILE_ID, SagaChildActionInput, SagaCompletion, SagaCompletionEvent, SagaContext, SagaImplementation, SagaRunChild, SchemaParseIssue, SchemaParseResult, SchemaValidator, StateClass, StateDefinition, StateMachineDatabaseClient, StateMachineDefinition, StateMachineRegistration, StateMachineRegistry, SurfaceDeclaration, TransitionContext, ViewContract, ViewEventConsumption, ViewRegistry, ViewUsageMetadata, aggregatePolicyOutcomes, anonymizeAssetEventPayload, anonymizeEvidencePacket, anonymizeJsonValue, assertActionId, assertActorType, assertAdapterCircuitBreakerConfig, assertAdapterOutcomeConsistency, assertGovernanceRuntimeEvidence, assertMutationGovernanceContext, assertObjectType, assertPolicyId, assertPortableJsonSchema, assertSurfaceDeclaration, buildAnonymizationLifecycleEvidence, canonicalJson, classifyAdapterOutcome, classifyCircuitBreakerOutcome, computeEvidencePacketChecksum, createActionRegistry, createDeterministicIdFactory, createEventContractRegistry, createEvidencePacketRenderer, createFabricId, createFakeActionContext, createInMemoryAdapterRegistry, createModuleRegistry, createObjectTypeRegistry, createPolicyRegistry, createStateMachineRegistry, createViewRegistry, evaluatePolicyDefinition, evaluatePolicyDefinitions, evaluateRegisteredPolicies, evaluateStateMachineTransition, executeWithAdapterRetry, executionContractProfile, exportModuleManifest, exportModuleManifestBundle, generateEvidencePacket, getEventTypeName, getModuleDependencyNamespace, getObjectTypeName, getRetryDelayMs, isActorType, isAdapterCircuitOpenError, isFabricId, isJsonSchemaExportableValidator, isReconciliationRequiredError, isRetryableExecutionError, normalizeModuleManifest, normalizeModuleManifestBundle, parseFabricId, registerFabricModule, registerFabricModules, replayEvents, replayView, resolveAdapterRetryPolicy, scopedAdapterCircuitBreakerKey, shouldRetryAdapterOutcome, stableChecksum, validateAndOrderFabricModules, validateDataPolicyDefinition, validateModuleNamespace, validatePolicyGuidance, validatePortableJson, validateStateMachineTransition, verifyEvidencePacketChecksum, viewContractKey };
|
|
18
|
+
export { ACTOR_TYPES, ANONYMIZATION_POLICY_VERSION, AcceptedExternalOperation, ActionAdmission, ActionAdmissionDecision, ActionAdmissionInput, ActionAdmissionSignal, ActionCompletionMode, ActionConnectivity, ActionConsistency, ActionContext, ActionDataSensitivity, ActionDefinition, ActionExecutionContract, ActionFinalizationContext, ActionFinalizationEvent, ActionFinalizationInput, ActionFinalizationResult, ActionFinalizationStep, ActionFinalizer, ActionHandler, ActionId, ActionIdempotencyStance, ActionRegistry, ActionResult, ActionStateMachineBinding, ActionStatus, ActorType, AdapterAttempt, AdapterCircuitAdmission, AdapterCircuitBreaker, AdapterCircuitBreakerConfig, AdapterCircuitBreakerEvent, AdapterCircuitBreakerEventListener, AdapterCircuitBreakerEventReason, AdapterCircuitBreakerManualOverride, AdapterCircuitBreakerProvider, AdapterCircuitBreakerRegistry, AdapterCircuitBreakerRegistryOptions, AdapterCircuitBreakerScope, AdapterCircuitOpenError, AdapterCircuitOutcome, AdapterCircuitState, AdapterExecutionContext, AdapterExecutionResult, AdapterExecutor, AdapterImplementation, AdapterOutcomeEvidence, AdapterOutcomeKind, AdapterRegistry, AdapterRetryPolicy, AdapterStep, AdapterStepRetryPolicy, AgentActionPolicyContext, AgentActionPolicyDecision, AgentActionPolicyDefinition, AgentActionPolicyEvaluator, AgentActionPolicyRegistry, AgentActionRiskTier, AgentActionRoute, AnalyticsDataContract, AnalyticsDataContractSource, AnalyticsEligibilityDecision, AnonymizationContext, AnonymizationEngine, type AnonymizationEngineOptions, AnonymizationFieldMetadata, type AnonymizationFieldPolicy, type AnonymizationLifecycleEvidence, AnonymizationMetadata, type AnonymizationPolicy, AnonymizationResult, AssetEventActorType, AssetEventEnvelope, type AssetEventLike, AssetEventSubjectType, AssetEventType, AuthorityMoment, CapabilityMetadata, CapabilityPortRequirement, CapabilityRequirements, CapabilityWorkflowCompensation, CapabilityWorkflowDeclaration, CapabilityWorkflowTimer, DEFAULT_EVIDENCE_PACKET_TYPE, DEFAULT_EVIDENCE_REDACTION_REASON, DataClassificationRule, DataPolicyComparisonOperator, DataPolicyCondition, DataPolicyConditionResult, DataPolicyDefinition, DataPolicyLiteral, DataPolicySource, DataPolicySourceReference, DataPolicyValidationResult, DeclarativeInvariant, EVIDENCE_PACKET_CHECKSUM_ALGORITHM, EVIDENCE_PACKET_SCHEMA_VERSION, EventContractRegistry, EventProvenance, EventTypeRegistration, EventTypeRegistrationInput, type EvidenceEventQuery, type EvidenceEventRecord, EvidenceGenerationContext, type EvidenceInvocationRecord, type EvidenceJsonRecord, EvidencePacketEnvelope, EvidencePacketGenerationError, type EvidencePacketGenerationErrorCode, type EvidencePacketLike, type EvidencePacketPayload, type EvidencePacketReadPort, EvidencePacketReference, type EvidencePacketRendererInput, type EvidencePacketRendererOptions, EvidencePacketStatus, EvidencePacketSubject, type EvidenceRecord, EvidenceRenderer, type EvidenceScope, type EvidenceTimestamp, ExecuteWithRetryOptions, ExecutionAttestation, ExecutionContractFinding, ExecutionContractFindingCode, ExecutionContractProfile, ExecutionContractProfileOptions, ExecutionPrincipal, ExternalReconciliation, ExternalResourceOperation, ExternalResourceRef, FABRIC_GOVERNANCE_CONTRACT_VERSION, FABRIC_ID_PREFIXES, FabricIdPrefix, FabricModule, FabricObjectType, FabricRuntimeServices, FakeActionContextOptions, FieldRedactor, FinalizationJson, FinalizationRecord, type GenerateEvidencePacketInput, type GenerateEvidencePacketOptions, GovernanceRuntimeEvidence, IdPrefixRegistration, InMemoryAdapterCircuitBreaker, InMemoryAdapterCircuitBreakerOptions, InvariantEnforcement, JsonPrimitive, JsonSchemaExportableValidator, JsonSchemaValidationIssue, JsonValue, MODULE_MANIFEST_VERSION, MissingAdapterRegistrationError, ModuleDependency, ModuleDependencyInput, ModuleManifest, ModuleManifestAction, ModuleManifestActionStateMachine, ModuleManifestActionV1, ModuleManifestAdapterStep, ModuleManifestBundle, ModuleManifestBundleV1, ModuleManifestCodePolicy, ModuleManifestDataPolicy, ModuleManifestEventType, ModuleManifestIdPrefix, ModuleManifestObjectType, ModuleManifestObjectTypeV1, ModuleManifestPolicy, ModuleManifestStateMachine, ModuleManifestStateMachineTransition, ModuleManifestV1, ModuleManifestView, ModuleRegistry, MutationFootprint, MutationFootprintEntry, MutationGovernanceContext, MutationGovernanceResolutionInput, MutationGovernanceResolver, ObjectRelationCardinality, ObjectRelationDefinition, ObjectRelationDeleteBehavior, ObjectRelationSemantics, ObjectTypeRegistration, ObjectTypeRegistrationInput, ObjectTypeRegistry, PLATFORM_PRIVACY_POLICY_VERSION, PlatformDataClass, PolicyAuthorityReference, PolicyContext, PolicyCorrectiveAction, PolicyCorrectiveActionBase, PolicyCorrectiveActionKind, PolicyDispatchEvidence, PolicyEvaluationMode, PolicyEvaluationResult, PolicyEvaluator, PolicyFact, PolicyFallbackDefinition, PolicyFallbackTrigger, PolicyGuidance, PolicyGuidanceValidationResult, PolicyId, PolicyInvokeActionCorrectiveAction, PolicyKind, PolicyManualCorrectiveAction, PolicyNavigateCorrectiveAction, PolicyObligation, PolicyObligationStatus, PolicyOutcome, PolicyRegistration, PolicyRegistry, PortableJsonSchema, ReconciliationRequiredError, ReconciliationStatus, RedactionMethod, RedactionRule, ReplayEventsOptions, ReplayEventsResult, ReplayScope, ReplaySnapshot, ReplayViewOptions, ReplayWarning, ReplayWarningCode, ReplayableAssetEvent, ResolvedAdapterRetryPolicy, RetentionRule, RetryableExecutionError, RuntimePolicyDefinition, STRICT_EXECUTION_CONTRACT_PROFILE, STRICT_EXECUTION_CONTRACT_PROFILE_ID, SagaChildActionInput, SagaCompletion, SagaCompletionEvent, SagaContext, SagaImplementation, SagaRunChild, SchemaParseIssue, SchemaParseResult, SchemaValidator, StateClass, StateDefinition, StateMachineDatabaseClient, StateMachineDefinition, StateMachineRegistration, StateMachineRegistry, SurfaceDeclaration, TransitionContext, ViewContract, ViewEventConsumption, ViewRegistry, ViewUsageMetadata, aggregatePolicyOutcomes, anonymizeAssetEventPayload, anonymizeEvidencePacket, anonymizeJsonValue, assertActionFinalization, assertActionId, assertActorType, assertAdapterCircuitBreakerConfig, assertAdapterOutcomeConsistency, assertAdapterStepDeadlines, assertGovernanceRuntimeEvidence, assertMutationGovernanceContext, assertObjectType, assertPolicyId, assertPortableJsonSchema, assertSurfaceDeclaration, buildAnonymizationLifecycleEvidence, canonicalJson, classifyAdapterOutcome, classifyCircuitBreakerOutcome, computeEvidencePacketChecksum, createActionRegistry, createDeterministicIdFactory, createEventContractRegistry, createEvidencePacketRenderer, createFabricId, createFakeActionContext, createInMemoryAdapterRegistry, createModuleRegistry, createObjectTypeRegistry, createPolicyRegistry, createStateMachineRegistry, createViewRegistry, defineFinalizingAction, evaluatePolicyDefinition, evaluatePolicyDefinitions, evaluateRegisteredPolicies, evaluateStateMachineTransition, executeWithAdapterRetry, executionContractProfile, exportModuleManifest, exportModuleManifestBundle, generateEvidencePacket, getEventTypeName, getModuleDependencyNamespace, getObjectTypeName, getRetryDelayMs, isActorType, isAdapterCircuitOpenError, isFabricId, isJsonSchemaExportableValidator, isReconciliationRequiredError, isRetryableExecutionError, normalizeModuleManifest, normalizeModuleManifestBundle, parseFabricId, registerFabricModule, registerFabricModules, replayEvents, replayView, resolveAdapterRetryPolicy, scopedAdapterCircuitBreakerKey, shouldRetryAdapterOutcome, stableChecksum, validateAndOrderFabricModules, validateDataPolicyDefinition, validateModuleNamespace, validatePolicyGuidance, validatePortableJson, validateStateMachineTransition, verifyEvidencePacketChecksum, viewContractKey };
|