@happyvertical/smrt-agents 0.49.2 → 0.49.4
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/README.md +22 -5
- package/dist/index.js +1 -1
- package/dist/manifest.json +631 -16
- package/dist/server/data-surface-actions.d.ts +36 -13
- package/dist/server/data-surface-actions.d.ts.map +1 -1
- package/dist/server/index.d.ts +5 -1
- package/dist/server/index.d.ts.map +1 -1
- package/dist/server/jobs-data-surface-action-queue.d.ts +33 -0
- package/dist/server/jobs-data-surface-action-queue.d.ts.map +1 -0
- package/dist/server/sql-data-surface-action-state.d.ts +60 -0
- package/dist/server/sql-data-surface-action-state.d.ts.map +1 -0
- package/dist/server.js +468 -20
- package/dist/server.js.map +1 -1
- package/dist/smrt-knowledge.json +165 -5
- package/package.json +14 -12
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DurableJobPayloadIntegrity } from '@happyvertical/smrt-jobs';
|
|
2
|
+
import { DataSurfaceActionDescriptor, DataSurfaceActionResult, DataSurfaceActionWireRequest, DataSurfaceDescriptor, DataSurfaceIdentity, DataSurfaceJsonObject, DataSurfaceJsonValue, DataSurfaceRowId, DataSurfaceSelectionReference } from '@happyvertical/smrt-types';
|
|
2
3
|
import { ExecuteAsPrincipalOptions, executeAsPrincipal, PrincipalRun } from '../execute-as-principal.js';
|
|
3
4
|
export type DataSurfaceConfirmationPolicy = 'required' | 'none';
|
|
4
5
|
export type DataSurfaceActionExecution = 'foreground' | 'background';
|
|
@@ -12,13 +13,6 @@ export type DataSurfaceActionPayloadValidation = {
|
|
|
12
13
|
valid: false;
|
|
13
14
|
reason?: string;
|
|
14
15
|
};
|
|
15
|
-
export interface DataSurfaceActionRowOutcome {
|
|
16
|
-
rowId: DataSurfaceRowId;
|
|
17
|
-
status: 'accepted' | 'skipped' | 'failed';
|
|
18
|
-
reason?: string;
|
|
19
|
-
/** Serializable per-row result returned by the action implementation. */
|
|
20
|
-
metadata?: DataSurfaceJsonObject;
|
|
21
|
-
}
|
|
22
16
|
export interface ResolvedDataSurfaceSelection {
|
|
23
17
|
/** Fresh server-side revision of the selected surface/query. */
|
|
24
18
|
revision: number;
|
|
@@ -64,20 +58,34 @@ export interface ResolvedDataSurfaceActions {
|
|
|
64
58
|
revision: number;
|
|
65
59
|
actions: Record<string, DataSurfaceServerActionDefinition>;
|
|
66
60
|
}
|
|
67
|
-
export interface DataSurfaceServerActionRequest extends
|
|
68
|
-
/** Required on apply and bound into the preview token. */
|
|
69
|
-
expectedRevision: number;
|
|
70
|
-
/** Required on apply. Identical retries replay the first terminal result. */
|
|
71
|
-
idempotencyKey?: string;
|
|
61
|
+
export interface DataSurfaceServerActionRequest extends DataSurfaceActionWireRequest {
|
|
72
62
|
}
|
|
73
63
|
export interface DataSurfaceActionContext {
|
|
74
64
|
principal: ExecuteAsPrincipalOptions;
|
|
75
65
|
}
|
|
66
|
+
export interface DataSurfaceDeferredPrincipalReference {
|
|
67
|
+
runAsUserId: string;
|
|
68
|
+
tenantId: string | null;
|
|
69
|
+
actsAsProfileId: string | null;
|
|
70
|
+
onBehalfOfUserId: string | null;
|
|
71
|
+
agentClass?: string;
|
|
72
|
+
}
|
|
73
|
+
/** Serializable, versioned payload persisted by a durable background queue. */
|
|
74
|
+
export interface DataSurfaceBackgroundActionEnvelope {
|
|
75
|
+
version: 1;
|
|
76
|
+
handlerId: string;
|
|
77
|
+
request: DataSurfaceServerActionRequest;
|
|
78
|
+
principal: DataSurfaceDeferredPrincipalReference;
|
|
79
|
+
previewToken?: DataSurfacePreviewTokenRecord;
|
|
80
|
+
/** Server-authenticated binding over every other persisted envelope field. */
|
|
81
|
+
binding: DurableJobPayloadIntegrity;
|
|
82
|
+
}
|
|
76
83
|
export interface DataSurfaceBackgroundActionJob {
|
|
77
84
|
idempotencyKey: string;
|
|
78
85
|
identity: DataSurfaceIdentity;
|
|
79
86
|
actionId: string;
|
|
80
87
|
rowIds: DataSurfaceRowId[];
|
|
88
|
+
envelope: DataSurfaceBackgroundActionEnvelope;
|
|
81
89
|
/**
|
|
82
90
|
* The queue must call this task to perform the work. It re-enters the bound
|
|
83
91
|
* principal and repeats descriptor, authorization, selection, and eligibility
|
|
@@ -117,7 +125,13 @@ export type DataSurfaceIdempotencyRecord = {
|
|
|
117
125
|
status: 'completed';
|
|
118
126
|
requestFingerprint: string;
|
|
119
127
|
result: DataSurfaceActionResult;
|
|
128
|
+
recovery?: DataSurfaceIdempotencyRecoveryEvidence;
|
|
120
129
|
};
|
|
130
|
+
export interface DataSurfaceIdempotencyRecoveryEvidence {
|
|
131
|
+
authorizedBy: string;
|
|
132
|
+
evidence: string;
|
|
133
|
+
reconciledAt: number;
|
|
134
|
+
}
|
|
121
135
|
export interface DataSurfaceIdempotencyReservation {
|
|
122
136
|
requestFingerprint: string;
|
|
123
137
|
ownerToken: string;
|
|
@@ -127,6 +141,8 @@ export interface DataSurfaceActionStateStore {
|
|
|
127
141
|
putToken(token: string, record: DataSurfacePreviewTokenRecord): Promise<void> | void;
|
|
128
142
|
getToken(token: string): Promise<DataSurfacePreviewTokenRecord | undefined> | DataSurfacePreviewTokenRecord | undefined;
|
|
129
143
|
markTokenConsumed(token: string, idempotencyKey: string): Promise<boolean> | boolean;
|
|
144
|
+
/** Atomically consume a preview token and create/read its apply reservation. */
|
|
145
|
+
consumeTokenAndReserveIdempotency(token: string, idempotencyKey: string, scope: string, reservation: DataSurfaceIdempotencyReservation): Promise<DataSurfaceIdempotencyRecord | undefined> | DataSurfaceIdempotencyRecord | undefined;
|
|
130
146
|
getIdempotency(key: string): Promise<DataSurfaceIdempotencyRecord | undefined> | DataSurfaceIdempotencyRecord | undefined;
|
|
131
147
|
/** Atomically create a durable reservation or return the existing record. */
|
|
132
148
|
reserveIdempotency(key: string, reservation: DataSurfaceIdempotencyReservation): Promise<DataSurfaceIdempotencyRecord> | DataSurfaceIdempotencyRecord;
|
|
@@ -140,6 +156,7 @@ export declare class InMemoryDataSurfaceActionStateStore implements DataSurfaceA
|
|
|
140
156
|
putToken(token: string, record: DataSurfacePreviewTokenRecord): void;
|
|
141
157
|
getToken(token: string): DataSurfacePreviewTokenRecord | undefined;
|
|
142
158
|
markTokenConsumed(token: string, idempotencyKey: string): boolean;
|
|
159
|
+
consumeTokenAndReserveIdempotency(token: string, idempotencyKey: string, scope: string, reservation: DataSurfaceIdempotencyReservation): DataSurfaceIdempotencyRecord | undefined;
|
|
143
160
|
getIdempotency(key: string): DataSurfaceIdempotencyRecord | undefined;
|
|
144
161
|
reserveIdempotency(key: string, reservation: DataSurfaceIdempotencyReservation): DataSurfaceIdempotencyRecord;
|
|
145
162
|
completeIdempotency(key: string, ownerToken: string, result: DataSurfaceActionResult): boolean;
|
|
@@ -149,6 +166,10 @@ export interface DataSurfaceActionAdapterOptions {
|
|
|
149
166
|
resolveSurface(run: PrincipalRun, identity: DataSurfaceIdentity): Promise<ResolvedDataSurfaceActions>;
|
|
150
167
|
resolveSelection(invocation: Omit<DataSurfaceActionInvocation, 'selection'>, selection: DataSurfaceSelectionReference): Promise<ResolvedDataSurfaceSelection>;
|
|
151
168
|
backgroundQueue?: DataSurfaceBackgroundQueue;
|
|
169
|
+
/** Stable worker registration key required by durable background queues. */
|
|
170
|
+
backgroundHandlerId?: string;
|
|
171
|
+
/** Secret used only in-process to authenticate durable background envelopes. */
|
|
172
|
+
deferredEnvelopeSigningKey?: string | Uint8Array;
|
|
152
173
|
/** Required durable, shared backend in production; memory storage is opt-in. */
|
|
153
174
|
state: DataSurfaceActionStateStore;
|
|
154
175
|
tokenTtlMs?: number;
|
|
@@ -177,6 +198,8 @@ export interface DataSurfaceActionAdapterOptions {
|
|
|
177
198
|
export interface DataSurfaceActionAdapter {
|
|
178
199
|
preview(request: DataSurfaceServerActionRequest, context: DataSurfaceActionContext): Promise<DataSurfaceActionResult>;
|
|
179
200
|
apply(request: DataSurfaceServerActionRequest, context: DataSurfaceActionContext): Promise<DataSurfaceActionResult>;
|
|
201
|
+
/** Worker entry point; re-resolves current authority before any mutation. */
|
|
202
|
+
executeDeferred(envelope: DataSurfaceBackgroundActionEnvelope): Promise<DataSurfaceActionResult>;
|
|
180
203
|
}
|
|
181
204
|
/** Validates untrusted extension values before they enter canonical hashing. */
|
|
182
205
|
export declare function isBoundedDataSurfaceJsonValue(value: unknown): value is DataSurfaceJsonValue;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"data-surface-actions.d.ts","sourceRoot":"","sources":["../../src/server/data-surface-actions.ts"],"names":[],"mappings":"AASA,OAAO,KAAK,EACV,2BAA2B,EAC3B,
|
|
1
|
+
{"version":3,"file":"data-surface-actions.d.ts","sourceRoot":"","sources":["../../src/server/data-surface-actions.ts"],"names":[],"mappings":"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"}
|
package/dist/server/index.d.ts
CHANGED
|
@@ -26,10 +26,14 @@
|
|
|
26
26
|
*
|
|
27
27
|
* @module @happyvertical/smrt-agents/server
|
|
28
28
|
*/
|
|
29
|
+
export type { DataSurfaceActionRowOutcome } from '@happyvertical/smrt-types';
|
|
29
30
|
export type { AgentActionContext, AgentActionHandler, AgentActionMap, } from './action-types.js';
|
|
30
31
|
export { type AgentAPIRouteInfo, buildRouteMap, type ResolvedAPIRoute, resolveAPIRoute, } from './api-routes.js';
|
|
31
32
|
export { loadSlotConfigs } from './config-loader.js';
|
|
32
|
-
export { createDataSurfaceActionAdapter, type DataSurfaceActionAdapter, type DataSurfaceActionAdapterOptions, type DataSurfaceActionContext as DataSurfaceServerActionContext, type DataSurfaceActionEligibility, type DataSurfaceActionExecution, type DataSurfaceActionPayloadValidation, type
|
|
33
|
+
export { createDataSurfaceActionAdapter, type DataSurfaceActionAdapter, type DataSurfaceActionAdapterOptions, type DataSurfaceActionContext as DataSurfaceServerActionContext, type DataSurfaceActionEligibility, type DataSurfaceActionExecution, type DataSurfaceActionPayloadValidation, type DataSurfaceActionStateStore, type DataSurfaceBackgroundActionEnvelope, type DataSurfaceBackgroundActionJob, type DataSurfaceBackgroundQueue, type DataSurfaceConfirmationPolicy, type DataSurfaceDeferredPrincipalReference, type DataSurfaceIdempotencyRecord, type DataSurfaceIdempotencyRecoveryEvidence, type DataSurfaceIdempotencyReservation, type DataSurfacePreviewTokenRecord, type DataSurfaceServerActionDefinition, type DataSurfaceServerActionRequest, InMemoryDataSurfaceActionStateStore, isBoundedDataSurfaceJsonValue, type ResolvedDataSurfaceActions, type ResolvedDataSurfaceSelection, } from './data-surface-actions.js';
|
|
34
|
+
export type { DataSurfaceActionJobArgs, JobsDataSurfaceBackgroundQueueOptions, } from './jobs-data-surface-action-queue.js';
|
|
35
|
+
export { createJobsDataSurfaceBackgroundQueue, registerDataSurfaceBackgroundActionHandler, SmrtDataSurfaceActionTask, } from './jobs-data-surface-action-queue.js';
|
|
33
36
|
export { extractAgentManifest, extractAgentPackagesFromConfig, loadManifestsFromConfig, loadManifestsFromPackages, type PackageManifest, } from './manifest-utils.js';
|
|
34
37
|
export { type SerializedAgent, serializeResolvedAgent, } from './serialization.js';
|
|
38
|
+
export { createSqlDataSurfaceActionStateStore, DataSurfaceActionIdempotencyState, DataSurfaceActionStateCorruptionError, DataSurfaceActionTokenState, type DataSurfaceIdempotencyRecoveryRequest, SqlDataSurfaceActionStateStore, type SqlDataSurfaceActionStateStoreOptions, } from './sql-data-surface-action-state.js';
|
|
35
39
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,iBAAiB,EACtB,aAAa,EACb,KAAK,gBAAgB,EACrB,eAAe,GAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,8BAA8B,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,+BAA+B,EACpC,KAAK,wBAAwB,IAAI,8BAA8B,EAC/D,KAAK,4BAA4B,EACjC,KAAK,0BAA0B,EAC/B,KAAK,kCAAkC,EACvC,KAAK,2BAA2B,EAChC,KAAK,
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/server/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;GA2BG;AAEH,YAAY,EAAE,2BAA2B,EAAE,MAAM,2BAA2B,CAAC;AAC7E,YAAY,EACV,kBAAkB,EAClB,kBAAkB,EAClB,cAAc,GACf,MAAM,mBAAmB,CAAC;AAC3B,OAAO,EACL,KAAK,iBAAiB,EACtB,aAAa,EACb,KAAK,gBAAgB,EACrB,eAAe,GAChB,MAAM,iBAAiB,CAAC;AACzB,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EACL,8BAA8B,EAC9B,KAAK,wBAAwB,EAC7B,KAAK,+BAA+B,EACpC,KAAK,wBAAwB,IAAI,8BAA8B,EAC/D,KAAK,4BAA4B,EACjC,KAAK,0BAA0B,EAC/B,KAAK,kCAAkC,EACvC,KAAK,2BAA2B,EAChC,KAAK,mCAAmC,EACxC,KAAK,8BAA8B,EACnC,KAAK,0BAA0B,EAC/B,KAAK,6BAA6B,EAClC,KAAK,qCAAqC,EAC1C,KAAK,4BAA4B,EACjC,KAAK,sCAAsC,EAC3C,KAAK,iCAAiC,EACtC,KAAK,6BAA6B,EAClC,KAAK,iCAAiC,EACtC,KAAK,8BAA8B,EACnC,mCAAmC,EACnC,6BAA6B,EAC7B,KAAK,0BAA0B,EAC/B,KAAK,4BAA4B,GAClC,MAAM,2BAA2B,CAAC;AACnC,YAAY,EACV,wBAAwB,EACxB,qCAAqC,GACtC,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,oCAAoC,EACpC,0CAA0C,EAC1C,yBAAyB,GAC1B,MAAM,qCAAqC,CAAC;AAC7C,OAAO,EACL,oBAAoB,EACpB,8BAA8B,EAC9B,uBAAuB,EACvB,yBAAyB,EACzB,KAAK,eAAe,GACrB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EACL,KAAK,eAAe,EACpB,sBAAsB,GACvB,MAAM,oBAAoB,CAAC;AAC5B,OAAO,EACL,oCAAoC,EACpC,iCAAiC,EACjC,qCAAqC,EACrC,2BAA2B,EAC3B,KAAK,qCAAqC,EAC1C,8BAA8B,EAC9B,KAAK,qCAAqC,GAC3C,MAAM,oCAAoC,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import { SmrtObject } from '@happyvertical/smrt-core';
|
|
2
|
+
import { JobExecutionContext } from '@happyvertical/smrt-jobs';
|
|
3
|
+
import { DataSurfaceActionResult } from '@happyvertical/smrt-types';
|
|
4
|
+
import { DatabaseInterface } from '@happyvertical/sql';
|
|
5
|
+
import { DataSurfaceBackgroundActionEnvelope, DataSurfaceBackgroundQueue } from './data-surface-actions.js';
|
|
6
|
+
export interface DataSurfaceActionJobArgs {
|
|
7
|
+
version: 1;
|
|
8
|
+
envelope: DataSurfaceBackgroundActionEnvelope;
|
|
9
|
+
}
|
|
10
|
+
export interface JobsDataSurfaceBackgroundQueueOptions {
|
|
11
|
+
db: DatabaseInterface;
|
|
12
|
+
handlerId: string;
|
|
13
|
+
execute(envelope: DataSurfaceBackgroundActionEnvelope): Promise<DataSurfaceActionResult>;
|
|
14
|
+
queue?: string;
|
|
15
|
+
priority?: number;
|
|
16
|
+
timeout?: number;
|
|
17
|
+
maxAttempts?: number;
|
|
18
|
+
tenantJobCap?: number;
|
|
19
|
+
}
|
|
20
|
+
export declare class SmrtDataSurfaceActionTask extends SmrtObject {
|
|
21
|
+
tenantId: string | null;
|
|
22
|
+
args: DataSurfaceActionJobArgs;
|
|
23
|
+
run(args?: DataSurfaceActionJobArgs, context?: JobExecutionContext): Promise<DataSurfaceActionResult>;
|
|
24
|
+
}
|
|
25
|
+
/**
|
|
26
|
+
* Register the host handler used by workers after process restart.
|
|
27
|
+
* The returned disposer only removes the same registration.
|
|
28
|
+
*/
|
|
29
|
+
export declare function registerDataSurfaceBackgroundActionHandler(handlerId: string, execute: (envelope: DataSurfaceBackgroundActionEnvelope) => Promise<DataSurfaceActionResult>): () => void;
|
|
30
|
+
export declare function createJobsDataSurfaceBackgroundQueue(options: JobsDataSurfaceBackgroundQueueOptions): DataSurfaceBackgroundQueue & {
|
|
31
|
+
unregister(): void;
|
|
32
|
+
};
|
|
33
|
+
//# sourceMappingURL=jobs-data-surface-action-queue.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"jobs-data-surface-action-queue.d.ts","sourceRoot":"","sources":["../../src/server/jobs-data-surface-action-queue.ts"],"names":[],"mappings":"AAAA,OAAO,EAGL,UAAU,EAEX,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAIL,KAAK,mBAAmB,EAGzB,MAAM,0BAA0B,CAAC;AAMlC,OAAO,KAAK,EACV,uBAAuB,EAExB,MAAM,2BAA2B,CAAC;AACnC,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,oBAAoB,CAAC;AAC5D,OAAO,KAAK,EACV,mCAAmC,EAEnC,0BAA0B,EAC3B,MAAM,2BAA2B,CAAC;AASnC,MAAM,WAAW,wBAAwB;IACvC,OAAO,EAAE,CAAC,CAAC;IACX,QAAQ,EAAE,mCAAmC,CAAC;CAC/C;AAED,MAAM,WAAW,qCAAqC;IACpD,EAAE,EAAE,iBAAiB,CAAC;IACtB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,CACL,QAAQ,EAAE,mCAAmC,GAC5C,OAAO,CAAC,uBAAuB,CAAC,CAAC;IACpC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,WAAW,CAAC,EAAE,MAAM,CAAC;IACrB,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,qBAOa,yBAA0B,SAAQ,UAAU;IAEvD,QAAQ,EAAE,MAAM,GAAG,IAAI,CAAQ;IAG/B,IAAI,EAAE,wBAAwB,CAG5B;IAGI,GAAG,CACP,IAAI,GAAE,wBAAoC,EAC1C,OAAO,CAAC,EAAE,mBAAmB,GAC5B,OAAO,CAAC,uBAAuB,CAAC;CA6CpC;AAED;;;GAGG;AACH,wBAAgB,0CAA0C,CACxD,SAAS,EAAE,MAAM,EACjB,OAAO,EAAE,CACP,QAAQ,EAAE,mCAAmC,KAC1C,OAAO,CAAC,uBAAuB,CAAC,GACpC,MAAM,IAAI,CAgBZ;AAED,wBAAgB,oCAAoC,CAClD,OAAO,EAAE,qCAAqC,GAC7C,0BAA0B,GAAG;IAAE,UAAU,IAAI,IAAI,CAAA;CAAE,CAuBrD"}
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
import { SmrtObject } from '@happyvertical/smrt-core';
|
|
2
|
+
import { DataSurfaceActionResult } from '@happyvertical/smrt-types';
|
|
3
|
+
import { DatabaseInterface } from '@happyvertical/sql';
|
|
4
|
+
import { DataSurfaceActionStateStore, DataSurfaceIdempotencyRecord, DataSurfaceIdempotencyRecoveryEvidence, DataSurfaceIdempotencyReservation, DataSurfacePreviewTokenRecord } from './data-surface-actions.js';
|
|
5
|
+
export declare class DataSurfaceActionTokenState extends SmrtObject {
|
|
6
|
+
tokenHash: string;
|
|
7
|
+
record: DataSurfacePreviewTokenRecord;
|
|
8
|
+
consumedBy: string | null;
|
|
9
|
+
}
|
|
10
|
+
export declare class DataSurfaceActionIdempotencyState extends SmrtObject {
|
|
11
|
+
keyHash: string;
|
|
12
|
+
status: 'reserved' | 'completed';
|
|
13
|
+
requestFingerprint: string;
|
|
14
|
+
ownerHash: string | null;
|
|
15
|
+
reservedAt: string | null;
|
|
16
|
+
result: DataSurfaceActionResult | null;
|
|
17
|
+
recovery: DataSurfaceIdempotencyRecoveryEvidence | null;
|
|
18
|
+
}
|
|
19
|
+
export interface DataSurfaceIdempotencyRecoveryRequest {
|
|
20
|
+
requestFingerprint: string;
|
|
21
|
+
reservedAt: number;
|
|
22
|
+
result: DataSurfaceActionResult;
|
|
23
|
+
authorizedBy: string;
|
|
24
|
+
evidence: string;
|
|
25
|
+
}
|
|
26
|
+
export interface SqlDataSurfaceActionStateStoreOptions {
|
|
27
|
+
db: DatabaseInterface;
|
|
28
|
+
now?: () => number;
|
|
29
|
+
authorizeRecovery?: (request: Readonly<DataSurfaceIdempotencyRecoveryRequest>) => boolean | Promise<boolean>;
|
|
30
|
+
}
|
|
31
|
+
export declare class DataSurfaceActionStateCorruptionError extends Error {
|
|
32
|
+
constructor(table: string);
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* SQL-backed action state shared by server processes.
|
|
36
|
+
*
|
|
37
|
+
* Preview tokens and owner nonces are stored only as hashes. Runtime schema
|
|
38
|
+
* creation remains the application's normal SMRT migration responsibility.
|
|
39
|
+
* An orphaned reservation is never expired or released automatically: a host
|
|
40
|
+
* may only reconcile it to a concrete terminal result after its live authority
|
|
41
|
+
* callback accepts immutable evidence for the exact reservation timestamp.
|
|
42
|
+
*/
|
|
43
|
+
export declare class SqlDataSurfaceActionStateStore implements DataSurfaceActionStateStore {
|
|
44
|
+
private readonly db;
|
|
45
|
+
private readonly now;
|
|
46
|
+
private readonly authorizeRecovery?;
|
|
47
|
+
constructor(options: SqlDataSurfaceActionStateStoreOptions);
|
|
48
|
+
putToken(token: string, record: DataSurfacePreviewTokenRecord): Promise<void>;
|
|
49
|
+
getToken(token: string): Promise<DataSurfacePreviewTokenRecord | undefined>;
|
|
50
|
+
markTokenConsumed(token: string, idempotencyKey: string): Promise<boolean>;
|
|
51
|
+
consumeTokenAndReserveIdempotency(token: string, idempotencyKey: string, scope: string, reservation: DataSurfaceIdempotencyReservation): Promise<DataSurfaceIdempotencyRecord | undefined>;
|
|
52
|
+
getIdempotency(key: string): Promise<DataSurfaceIdempotencyRecord | undefined>;
|
|
53
|
+
reserveIdempotency(key: string, reservation: DataSurfaceIdempotencyReservation): Promise<DataSurfaceIdempotencyRecord>;
|
|
54
|
+
completeIdempotency(key: string, ownerToken: string, result: DataSurfaceActionResult): Promise<boolean>;
|
|
55
|
+
releaseIdempotency(key: string, ownerToken: string): Promise<boolean>;
|
|
56
|
+
reconcileIdempotency(key: string, request: DataSurfaceIdempotencyRecoveryRequest): Promise<boolean>;
|
|
57
|
+
private getIdempotencyWithOwner;
|
|
58
|
+
}
|
|
59
|
+
export declare function createSqlDataSurfaceActionStateStore(options: SqlDataSurfaceActionStateStoreOptions): SqlDataSurfaceActionStateStore;
|
|
60
|
+
//# sourceMappingURL=sql-data-surface-action-state.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"sql-data-surface-action-state.d.ts","sourceRoot":"","sources":["../../src/server/sql-data-surface-action-state.ts"],"names":[],"mappings":"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"}
|