@onereach/state-machine-store 1.0.0-framework.2
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 +3 -0
- package/dist/index.d.mts +321 -0
- package/dist/index.d.mts.map +1 -0
- package/dist/index.mjs +2 -0
- package/dist/index.mjs.map +1 -0
- package/package.json +45 -0
package/README.md
ADDED
package/dist/index.d.mts
ADDED
|
@@ -0,0 +1,321 @@
|
|
|
1
|
+
import { CompiledStateTemplateValidators, JsonSchemaValidatorCompiler, StateMachineInstance, StateTemplateDefinition, StateTemplateValidatorCompiler } from "@onereach/state-machine-core";
|
|
2
|
+
//#region src/types/driver-contract.d.ts
|
|
3
|
+
interface DriverLoadOptions {
|
|
4
|
+
signal?: AbortSignal;
|
|
5
|
+
}
|
|
6
|
+
interface DriverSaveOptions extends DriverLoadOptions {
|
|
7
|
+
/**
|
|
8
|
+
* - `undefined`: unconditional write
|
|
9
|
+
* - `null`: create only; resource must not exist
|
|
10
|
+
* - `string`: current revision must match
|
|
11
|
+
*/
|
|
12
|
+
expectedRevision?: string | null;
|
|
13
|
+
}
|
|
14
|
+
interface DriverDeleteOptions extends DriverLoadOptions {
|
|
15
|
+
expectedRevision?: string | null;
|
|
16
|
+
}
|
|
17
|
+
interface DriverWatchOptions {
|
|
18
|
+
signal?: AbortSignal;
|
|
19
|
+
}
|
|
20
|
+
interface DriverLoadResult<TState = unknown> {
|
|
21
|
+
value: TState;
|
|
22
|
+
/**
|
|
23
|
+
* Opaque revision understood by the driver.
|
|
24
|
+
*
|
|
25
|
+
* Examples:
|
|
26
|
+
*
|
|
27
|
+
* - SHA256
|
|
28
|
+
* - S3 VersionId
|
|
29
|
+
* - database row version
|
|
30
|
+
* - Git hash
|
|
31
|
+
*/
|
|
32
|
+
revision: string;
|
|
33
|
+
metadata?: Readonly<Record<string, unknown>>;
|
|
34
|
+
}
|
|
35
|
+
interface DriverSaveResult {
|
|
36
|
+
revision: string;
|
|
37
|
+
metadata?: Readonly<Record<string, unknown>>;
|
|
38
|
+
}
|
|
39
|
+
type DriverChangeType = 'created' | 'updated' | 'deleted';
|
|
40
|
+
interface DriverChange<TReference> {
|
|
41
|
+
type: DriverChangeType;
|
|
42
|
+
ref: TReference;
|
|
43
|
+
revision?: string;
|
|
44
|
+
}
|
|
45
|
+
type DriverConcurrency =
|
|
46
|
+
/**
|
|
47
|
+
* `expectedRevision` may be checked, but the check and write are not
|
|
48
|
+
* protected from concurrent writers.
|
|
49
|
+
*/
|
|
50
|
+
'none' |
|
|
51
|
+
/**
|
|
52
|
+
* Revision check + write/delete are serialized using a shared lock.
|
|
53
|
+
*
|
|
54
|
+
* Correct as long as all writers participate in the same locking protocol.
|
|
55
|
+
*/
|
|
56
|
+
'cooperative-lock' |
|
|
57
|
+
/**
|
|
58
|
+
* Backend natively performs compare-and-set atomically.
|
|
59
|
+
*
|
|
60
|
+
* Examples:
|
|
61
|
+
* - PostgreSQL UPDATE ... WHERE revision = ...
|
|
62
|
+
* - DynamoDB ConditionExpression
|
|
63
|
+
* - Redis Lua transaction
|
|
64
|
+
*/
|
|
65
|
+
'atomic-cas';
|
|
66
|
+
type DriverWatch = false | 'polling' | 'push';
|
|
67
|
+
interface DriverCapabilities {
|
|
68
|
+
/**
|
|
69
|
+
* Concurrency guarantee provided for conditional writes using
|
|
70
|
+
* expectedRevision.
|
|
71
|
+
*/
|
|
72
|
+
concurrency: DriverConcurrency;
|
|
73
|
+
/**
|
|
74
|
+
* Change notification implementation.
|
|
75
|
+
*/
|
|
76
|
+
watch: DriverWatch;
|
|
77
|
+
}
|
|
78
|
+
interface DocumentDriver<TReference> {
|
|
79
|
+
readonly capabilities: DriverCapabilities;
|
|
80
|
+
load<TState = unknown>(reference: TReference, options?: DriverLoadOptions): Promise<DriverLoadResult<TState> | undefined>;
|
|
81
|
+
save<TState = unknown>(reference: TReference, value: TState, options?: DriverSaveOptions): Promise<DriverSaveResult>;
|
|
82
|
+
delete(reference: TReference, options?: DriverDeleteOptions): Promise<boolean>;
|
|
83
|
+
/**
|
|
84
|
+
* Optional because not every backend can efficiently
|
|
85
|
+
* push changes.
|
|
86
|
+
*
|
|
87
|
+
* An S3 driver might implement this with SQS/EventBridge,
|
|
88
|
+
* for example.
|
|
89
|
+
*/
|
|
90
|
+
watch?(this: void, reference: TReference, options?: DriverWatchOptions): AsyncIterable<DriverChange<TReference>>;
|
|
91
|
+
}
|
|
92
|
+
//#endregion
|
|
93
|
+
//#region src/errors.d.ts
|
|
94
|
+
declare class RevisionConflictError extends Error {
|
|
95
|
+
readonly expected: string | null | undefined;
|
|
96
|
+
readonly actual: string | undefined;
|
|
97
|
+
constructor(expected: string | null | undefined, actual: string | undefined);
|
|
98
|
+
}
|
|
99
|
+
declare class NotFoundError extends Error {
|
|
100
|
+
readonly resource: string;
|
|
101
|
+
constructor(resource: string);
|
|
102
|
+
}
|
|
103
|
+
declare class DriverCapabilityError extends Error {
|
|
104
|
+
readonly capability: string;
|
|
105
|
+
constructor(capability: string);
|
|
106
|
+
}
|
|
107
|
+
declare class TemplateRevisionMismatchError extends Error {
|
|
108
|
+
readonly expected: string;
|
|
109
|
+
readonly actual: string;
|
|
110
|
+
constructor(expected: string, actual: string);
|
|
111
|
+
}
|
|
112
|
+
declare class UnsafeConcurrencyError extends Error {
|
|
113
|
+
readonly concurrency: DriverConcurrency;
|
|
114
|
+
constructor(concurrency: DriverConcurrency);
|
|
115
|
+
}
|
|
116
|
+
//#endregion
|
|
117
|
+
//#region src/helpers.d.ts
|
|
118
|
+
declare function hasSafeConditionalWrites(capabilities: DriverCapabilities): boolean;
|
|
119
|
+
//#endregion
|
|
120
|
+
//#region src/template-store/types.d.ts
|
|
121
|
+
interface StateTemplateReference {
|
|
122
|
+
id: string;
|
|
123
|
+
version?: string;
|
|
124
|
+
}
|
|
125
|
+
interface LoadedStateTemplate {
|
|
126
|
+
definition: StateTemplateDefinition;
|
|
127
|
+
revision: string;
|
|
128
|
+
validators: CompiledStateTemplateValidators;
|
|
129
|
+
metadata?: Readonly<Record<string, unknown>>;
|
|
130
|
+
}
|
|
131
|
+
type StateTemplateDriver = DocumentDriver<StateTemplateReference>;
|
|
132
|
+
//#endregion
|
|
133
|
+
//#region src/template-store/template-store.d.ts
|
|
134
|
+
declare class StateTemplateStore {
|
|
135
|
+
private readonly driver;
|
|
136
|
+
private readonly compiler;
|
|
137
|
+
/**
|
|
138
|
+
* Cache fully prepared loaded templates.
|
|
139
|
+
*
|
|
140
|
+
* This avoids:
|
|
141
|
+
*
|
|
142
|
+
* - repeated Zod parsing
|
|
143
|
+
* - repeated compiler lookup
|
|
144
|
+
* - repeatedly rebuilding wrapper objects
|
|
145
|
+
*/
|
|
146
|
+
private readonly cache;
|
|
147
|
+
constructor(driver: StateTemplateDriver, compiler: JsonSchemaValidatorCompiler | StateTemplateValidatorCompiler);
|
|
148
|
+
/**
|
|
149
|
+
* Load a state template from the driver.
|
|
150
|
+
* @param reference - The reference to the state template.
|
|
151
|
+
* @param options - The options for the load operation.
|
|
152
|
+
* @returns The loaded state template.
|
|
153
|
+
*/
|
|
154
|
+
load(reference: StateTemplateReference, options?: DriverLoadOptions): Promise<LoadedStateTemplate | undefined>;
|
|
155
|
+
/**
|
|
156
|
+
* Load a state template from the driver and throw an error if it is not found.
|
|
157
|
+
* @param reference - The reference to the state template.
|
|
158
|
+
* @param options - The options for the load operation.
|
|
159
|
+
* @returns The loaded state template.
|
|
160
|
+
*/
|
|
161
|
+
require(reference: StateTemplateReference, options?: DriverLoadOptions): Promise<LoadedStateTemplate>;
|
|
162
|
+
/**
|
|
163
|
+
* Save a state template to the driver.
|
|
164
|
+
* @param raw - The state template definition to save.
|
|
165
|
+
* @param options - The options for the save operation.
|
|
166
|
+
* @returns The saved state template.
|
|
167
|
+
*/
|
|
168
|
+
save(raw: StateTemplateDefinition, options?: DriverSaveOptions): Promise<LoadedStateTemplate>;
|
|
169
|
+
delete(reference: StateTemplateReference, options?: DriverDeleteOptions): Promise<boolean>;
|
|
170
|
+
watch(reference: StateTemplateReference, options?: DriverWatchOptions): AsyncIterable<{
|
|
171
|
+
type: 'created' | 'updated';
|
|
172
|
+
template: LoadedStateTemplate;
|
|
173
|
+
} | {
|
|
174
|
+
type: 'deleted';
|
|
175
|
+
ref: StateTemplateReference;
|
|
176
|
+
}>;
|
|
177
|
+
get capabilities(): DriverCapabilities;
|
|
178
|
+
}
|
|
179
|
+
//#endregion
|
|
180
|
+
//#region src/instance-store/types.d.ts
|
|
181
|
+
interface StateMachineInstanceReference {
|
|
182
|
+
id: string;
|
|
183
|
+
}
|
|
184
|
+
type StateMachineInstanceDriver = DocumentDriver<StateMachineInstanceReference>;
|
|
185
|
+
interface LoadedStateMachineInstance {
|
|
186
|
+
/**
|
|
187
|
+
* The loaded instance.
|
|
188
|
+
*/
|
|
189
|
+
instance: StateMachineInstance;
|
|
190
|
+
/**
|
|
191
|
+
* Revision of the persisted instance itself.
|
|
192
|
+
*/
|
|
193
|
+
revision: string;
|
|
194
|
+
/**
|
|
195
|
+
* The loaded template that was used to create the instance.
|
|
196
|
+
*/
|
|
197
|
+
template: LoadedStateTemplate;
|
|
198
|
+
/**
|
|
199
|
+
* Additional metadata about the instance.
|
|
200
|
+
*/
|
|
201
|
+
metadata?: Readonly<Record<string, unknown>>;
|
|
202
|
+
}
|
|
203
|
+
interface CreateStateMachineInstance {
|
|
204
|
+
/**
|
|
205
|
+
* The unique identifier of the instance.
|
|
206
|
+
*/
|
|
207
|
+
id: string;
|
|
208
|
+
/**
|
|
209
|
+
* Reference to the template that was used to create the instance.
|
|
210
|
+
*/
|
|
211
|
+
template: StateTemplateReference;
|
|
212
|
+
/**
|
|
213
|
+
* Defaults to {@link template.initialState}.
|
|
214
|
+
*/
|
|
215
|
+
state?: Record<string, unknown>;
|
|
216
|
+
/**
|
|
217
|
+
* Additional metadata about the instance.
|
|
218
|
+
*/
|
|
219
|
+
metadata?: Record<string, unknown>;
|
|
220
|
+
}
|
|
221
|
+
interface UpdateStateMachineInstance {
|
|
222
|
+
state?: Record<string, unknown>;
|
|
223
|
+
metadata?: Record<string, unknown>;
|
|
224
|
+
}
|
|
225
|
+
type StateMachineInstanceChange = {
|
|
226
|
+
type: 'current' | 'created' | 'updated';
|
|
227
|
+
instance: LoadedStateMachineInstance;
|
|
228
|
+
} | {
|
|
229
|
+
type: 'deleted';
|
|
230
|
+
ref: StateMachineInstanceReference;
|
|
231
|
+
};
|
|
232
|
+
interface InstanceWatchOptions extends DriverWatchOptions {
|
|
233
|
+
/**
|
|
234
|
+
* Emit the current instance before listening for
|
|
235
|
+
* subsequent changes.
|
|
236
|
+
*/
|
|
237
|
+
emitCurrent?: boolean;
|
|
238
|
+
}
|
|
239
|
+
//#endregion
|
|
240
|
+
//#region src/instance-store/instance-store.d.ts
|
|
241
|
+
declare class StateMachineInstanceStore {
|
|
242
|
+
private readonly driver;
|
|
243
|
+
private readonly templates;
|
|
244
|
+
constructor(driver: StateMachineInstanceDriver, templates: StateTemplateStore);
|
|
245
|
+
/**
|
|
246
|
+
* Creates a new state machine instance.
|
|
247
|
+
* @param options - The options for the create operation.
|
|
248
|
+
* @returns The created state machine instance.
|
|
249
|
+
*/
|
|
250
|
+
create(options: CreateStateMachineInstance): Promise<LoadedStateMachineInstance>;
|
|
251
|
+
/**
|
|
252
|
+
* Loads a state machine instance from the driver.
|
|
253
|
+
* @param reference - The reference to the state machine instance.
|
|
254
|
+
* @param options - The options for the load operation.
|
|
255
|
+
* @returns The loaded state machine instance.
|
|
256
|
+
*/
|
|
257
|
+
load(reference: StateMachineInstanceReference, options?: DriverLoadOptions): Promise<LoadedStateMachineInstance | undefined>;
|
|
258
|
+
/**
|
|
259
|
+
* Loads a state machine instance from the driver and throws an error if it is not found.
|
|
260
|
+
* @param reference - The reference to the state machine instance.
|
|
261
|
+
* @param options - The options for the load operation.
|
|
262
|
+
* @returns The loaded state machine instance.
|
|
263
|
+
*/
|
|
264
|
+
require(reference: StateMachineInstanceReference, options?: DriverLoadOptions): Promise<LoadedStateMachineInstance>;
|
|
265
|
+
/**
|
|
266
|
+
* Saves a new instance revision.
|
|
267
|
+
*
|
|
268
|
+
* The caller cannot accidentally change:
|
|
269
|
+
*
|
|
270
|
+
* - id
|
|
271
|
+
* - template binding
|
|
272
|
+
* - createdAt
|
|
273
|
+
* - sequence manually
|
|
274
|
+
*/
|
|
275
|
+
save(loaded: LoadedStateMachineInstance, update: UpdateStateMachineInstance): Promise<LoadedStateMachineInstance>;
|
|
276
|
+
/**
|
|
277
|
+
* Saves a new state for a state machine instance.
|
|
278
|
+
* @param loaded - The loaded state machine instance.
|
|
279
|
+
* @param state - The state to save.
|
|
280
|
+
* @returns The saved state machine instance.
|
|
281
|
+
*/
|
|
282
|
+
saveState(loaded: LoadedStateMachineInstance, state: Record<string, unknown>): Promise<LoadedStateMachineInstance>;
|
|
283
|
+
/**
|
|
284
|
+
* Saves metadata for a state machine instance.
|
|
285
|
+
* @param loaded - The loaded state machine instance.
|
|
286
|
+
* @param metadata - The metadata to save.
|
|
287
|
+
* @returns The saved state machine instance.
|
|
288
|
+
*/
|
|
289
|
+
saveMetadata(loaded: LoadedStateMachineInstance, metadata: Record<string, unknown>): Promise<LoadedStateMachineInstance>;
|
|
290
|
+
/**
|
|
291
|
+
* Deletes a state machine instance.
|
|
292
|
+
* @param loaded - The loaded state machine instance.
|
|
293
|
+
* @returns True if the instance was deleted, false otherwise.
|
|
294
|
+
*/
|
|
295
|
+
delete(loaded: LoadedStateMachineInstance): Promise<boolean>;
|
|
296
|
+
/**
|
|
297
|
+
* Watches a state machine instance for changes.
|
|
298
|
+
* @param reference - The reference to the state machine instance.
|
|
299
|
+
* @param options - The options for the watch operation.
|
|
300
|
+
* @returns An iterable of state machine instance changes.
|
|
301
|
+
*/
|
|
302
|
+
watch(reference: StateMachineInstanceReference, options?: InstanceWatchOptions): AsyncIterable<StateMachineInstanceChange>;
|
|
303
|
+
/**
|
|
304
|
+
* Convenience callback interface over watch().
|
|
305
|
+
* @param reference - The reference to the state machine instance.
|
|
306
|
+
* @param listener - The listener to call when a change occurs.
|
|
307
|
+
* @param options - The options for the watch operation.
|
|
308
|
+
* @returns A function to unsubscribe from the watch.
|
|
309
|
+
*/
|
|
310
|
+
subscribe(reference: StateMachineInstanceReference, listener: (change: StateMachineInstanceChange) => void | Promise<void>, options?: InstanceWatchOptions & {
|
|
311
|
+
onError?: (error: unknown) => void;
|
|
312
|
+
}): () => void;
|
|
313
|
+
/**
|
|
314
|
+
* Returns the capabilities of the state machine instance driver.
|
|
315
|
+
* @returns The capabilities of the state machine instance driver.
|
|
316
|
+
*/
|
|
317
|
+
get capabilities(): DriverCapabilities;
|
|
318
|
+
}
|
|
319
|
+
//#endregion
|
|
320
|
+
export { type CreateStateMachineInstance, type DocumentDriver, type DriverCapabilities, DriverCapabilityError, type DriverChange, type DriverChangeType, type DriverConcurrency, type DriverDeleteOptions, type DriverLoadOptions, type DriverLoadResult, type DriverSaveOptions, type DriverSaveResult, type DriverWatch, type DriverWatchOptions, type InstanceWatchOptions, type LoadedStateMachineInstance, type LoadedStateTemplate, NotFoundError, RevisionConflictError, type StateMachineInstanceChange, type StateMachineInstanceDriver, type StateMachineInstanceReference, StateMachineInstanceStore, type StateTemplateDriver, type StateTemplateReference, StateTemplateStore, TemplateRevisionMismatchError, UnsafeConcurrencyError, type UpdateStateMachineInstance, hasSafeConditionalWrites };
|
|
321
|
+
//# sourceMappingURL=index.d.mts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/types/driver-contract.ts","../src/errors.ts","../src/helpers.ts","../src/template-store/types.ts","../src/template-store/template-store.ts","../src/instance-store/types.ts","../src/instance-store/instance-store.ts"],"mappings":";;UAAiB;EACf,SAAS;;UAGM,0BAA0B;;;;;;EAMzC;;UAGe,4BAA4B;EAC3C;;UAGe;EACf,SAAS;;UAGM,iBAAiB;EAChC,OAAO;;;;;;;;;;;EAYP;EAEA,WAAW,SAAS;;UAGL;EACf;EAEA,WAAW,SAAS;;KAGV;UAEK,aAAa;EAC5B,MAAM;EAEN,KAAK;EAEL;;KAGU;;;;;;;;;;;;;;;;;;;;;KAwBA;UAEK;;;;;EAKf,aAAa;;;;EAKb,OAAO;;UAGQ,eAAe;WACrB,cAAc;EAEvB,KAAK,kBACH,WAAW,YACX,UAAU,oBACT,QAAQ,iBAAiB;EAE5B,KAAK,kBAAkB,WAAW,YAAY,OAAO,QAAQ,UAAU,oBAAoB,QAAQ;EAEnG,OAAO,WAAW,YAAY,UAAU,sBAAsB;;;;;;;;EAS9D,OAAO,YAAY,WAAW,YAAY,UAAU,qBAAqB,cAAc,aAAa;;;;cC/GzF,8BAA8B;WACzB;WACA;EAEJ,YAAA,qCAAqC;;cAStC,sBAAsB;WACjB;EAEJ,YAAA;;cAQD,8BAA8B;WACzB;EAEJ,YAAA;;cAQD,sCAAsC;WACjC;WACA;EAEJ,YAAA,kBAAkB;;cAWnB,+BAA+B;WAC1B,aAAa;EAEjB,YAAA,aAAa;;;;iBCrDX,yBAAyB,cAAc;;;UCEtC;EACf;EACA;;UAGe;EACf,YAAY;EACZ;EACA,YAAY;EACZ,WAAW,SAAS;;KAGV,sBAAsB,eAAe;;;cCFpC;mBACM;mBACA;;;;;;;;;;mBAUA;EAEL,YAAA,QAAQ,qBAAqB,UAAU,8BAA8B;;;;;;;EAYpE,KACX,WAAW,wBACX,UAAU,oBACT,QAAQ;;;;;;;EAkCE,QAAQ,WAAW,wBAAwB,UAAU,oBAAoB,QAAQ;;;;;;;EAgBjF,KAAK,KAAK,yBAAyB,UAAU,oBAAoB,QAAQ;EA8BzE,OAAO,WAAW,wBAAwB,UAAU,sBAAsB;EASzE,MACZ,WAAW,wBACX,UAAU,qBACT;IAEG;IACA,UAAU;;IAGV;IACA,KAAK;;MAmCA,gBAAgB;;;;UC5KZ;EACf;;KAGU,6BAA6B,eAAe;UAEvC;;;;EAIf,UAAU;;;;EAKV;;;;EAKA,UAAU;;;;EAKV,WAAW,SAAS;;UAGL;;;;EAIf;;;;EAKA,UAAU;;;;EAKV,QAAQ;;;;EAKR,WAAW;;UAGI;EACf,QAAQ;EACR,WAAW;;KAGD;EAEN;EAEA,UAAU;;EAGV;EAEA,KAAK;;UAGM,6BAA6B;;;;;EAK5C;;;;cC7DW;mBACM;mBACA;EAEL,YAAA,QAAQ,4BAA4B,WAAW;;;;;;EAU9C,OAAO,SAAS,6BAA6B,QAAQ;;;;;;;EAkDrD,KACX,WAAW,+BACX,UAAU,oBACT,QAAQ;;;;;;;EAkCE,QACX,WAAW,+BACX,UAAU,oBACT,QAAQ;;;;;;;;;;;EAoBE,KACX,QAAQ,4BACR,QAAQ,6BACP,QAAQ;;;;;;;EAiDE,UACX,QAAQ,4BACR,OAAO,0BACN,QAAQ;;;;;;;EAUE,aACX,QAAQ,4BACR,UAAU,0BACT,QAAQ;;;;;;EASE,OAAO,QAAQ,6BAA6B;;;;;;;EAUlD,MACL,WAAW,+BACX,UAAS,uBACR,cAAc;;;;;;;;EAwDV,UACL,WAAW,+BACX,WAAW,QAAQ,sCAAsC,eACzD,UAAS;IACP,WAAW;;;;;;MAwCJ,gBAAgB"}
|
package/dist/index.mjs
ADDED
|
@@ -0,0 +1,2 @@
|
|
|
1
|
+
import{StateMachineInstanceSchema as e,StateTemplateSchema as t,StateTemplateValidatorCompiler as n,assertSchema as r}from"@onereach/state-machine-core";var i=class extends Error{expected;actual;constructor(e,t){super(`Revision conflict: expected ${e??`<not-exists>`}, actual ${t??`<not-exists>`}`),this.name=`RevisionConflictError`,this.expected=e,this.actual=t}},a=class extends Error{resource;constructor(e){super(`Not found: ${e}`),this.name=`NotFoundError`,this.resource=e}},o=class extends Error{capability;constructor(e){super(`Driver does not support ${e}`),this.name=`DriverCapabilityError`,this.capability=e}},s=class extends Error{expected;actual;constructor(e,t){super(`State-machine instance expects template revision "${e}", but current template revision is "${t}"`),this.name=`TemplateRevisionMismatchError`,this.expected=e,this.actual=t}},c=class extends Error{concurrency;constructor(e){super(`State-machine mutations require safe conditional writes, but the instance driver provides concurrency="${e}"`),this.name=`UnsafeConcurrencyError`,this.concurrency=e}};function l(e){return e.concurrency===`cooperative-lock`||e.concurrency===`atomic-cas`}var u=class{driver;templates;constructor(e,t){this.driver=e,this.templates=t}async create(t){let n=await this.templates.require(t.template),i=structuredClone(t.state??n.definition.initialState);r(n.validators.state,i,`state-before`);let a=new Date().toISOString(),o=e.parse({schemaVersion:1,id:t.id,template:{id:n.definition.id,version:n.definition.version??t.template.version,revision:n.revision},state:i,sequence:0,createdAt:a,updatedAt:a,metadata:t.metadata}),s=await this.driver.save({id:o.id},o,{expectedRevision:null});return{instance:o,revision:s.revision,template:n,metadata:s.metadata}}async load(t,n){let i=await this.driver.load(t,n);if(!i)return;let a=e.parse(i.value),o=await this.templates.require({id:a.template.id,version:a.template.version},n);if(o.revision!==a.template.revision)throw new s(a.template.revision,o.revision);return r(o.validators.state,a.state,`state-before`),{instance:a,revision:i.revision,template:o,metadata:i.metadata}}async require(e,t){let n=await this.load(e,t);if(!n)throw new a(`StateMachineInstance:${e.id}`);return n}async save(t,n){let i=await this.templates.require({id:t.instance.template.id,version:t.instance.template.version});if(i.revision!==t.instance.template.revision)throw new s(t.instance.template.revision,i.revision);let a=structuredClone(n.state??t.instance.state);r(i.validators.state,a,`state-after`);let o=new Date().toISOString(),c=e.parse({...t.instance,state:a,metadata:n.metadata??t.instance.metadata,sequence:t.instance.sequence+1,updatedAt:o}),l=await this.driver.save({id:c.id},c,{expectedRevision:t.revision});return{instance:c,revision:l.revision,template:i,metadata:l.metadata}}async saveState(e,t){return this.save(e,{state:t})}async saveMetadata(e,t){return this.save(e,{metadata:t})}async delete(e){return this.driver.delete({id:e.instance.id},{expectedRevision:e.revision})}async*watch(e,t={}){if(!this.driver.watch)throw new o(`watch`);let n;if(t.emitCurrent){let r=await this.load(e,t);r&&(n=r.revision,yield{type:`current`,instance:r})}for await(let r of this.driver.watch(e,t)){if(r.type===`deleted`){n=void 0,yield{type:`deleted`,ref:e};continue}let i=await this.load(e,t);i&&i.revision!==n&&(n=i.revision,yield{type:r.type,instance:i})}}subscribe(e,t,n={}){let r=new AbortController,i=n.signal,a=()=>r.abort();return i?.aborted?r.abort():i?.addEventListener(`abort`,a,{once:!0}),(async()=>{try{let i=this.watch(e,{...n,signal:r.signal});for await(let e of i)await t(e)}catch(e){r.signal.aborted||n.onError?.(e)}finally{i?.removeEventListener(`abort`,a)}})(),()=>{r.abort()}}get capabilities(){return this.driver.capabilities}},d=class{driver;compiler;cache=new Map;constructor(e,t){this.driver=e,this.compiler=t instanceof n?t:new n(t)}async load(e,n){let r=await this.driver.load(e,n);if(!r)return;let i=f(e,r.revision),a=this.cache.get(i);if(a)return a;let o=t.parse(r.value),s=this.compiler.compile(o,i),c={definition:o,revision:r.revision,validators:s,metadata:r.metadata};return this.cache.set(i,c),c}async require(e,t){let n=await this.load(e,t);if(!n)throw new a(`StateTemplate:${e.id}`);return n}async save(e,n){let r=t.parse(e),i=this.compiler.compile(r),a={id:r.id,version:r.version},o=await this.driver.save(a,r,n),s=f(a,o.revision);this.compiler.bind(s,i);let c={definition:r,revision:o.revision,validators:i,metadata:o.metadata};return this.cache.set(s,c),c}async delete(e,t){return this.driver.delete(e,t)}async*watch(e,t){if(!this.driver.watch)throw new o(`watch`);let n;for await(let r of this.driver.watch(e,t)){if(r.type===`deleted`){n=void 0,yield{type:`deleted`,ref:e};continue}let i=await this.load(e,t);i&&i.revision!==n&&(n=i.revision,yield{type:r.type,template:i})}}get capabilities(){return this.driver.capabilities}};function f(e,t){return JSON.stringify([e.id,e.version??`latest`,t])}export{o as DriverCapabilityError,a as NotFoundError,i as RevisionConflictError,u as StateMachineInstanceStore,d as StateTemplateStore,s as TemplateRevisionMismatchError,c as UnsafeConcurrencyError,l as hasSafeConditionalWrites};
|
|
2
|
+
//# sourceMappingURL=index.mjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"index.mjs","names":[],"sources":["../src/errors.ts","../src/helpers.ts","../src/instance-store/instance-store.ts","../src/template-store/template-store.ts"],"sourcesContent":["import { DriverConcurrency } from './types/driver-contract.ts';\n\nexport class RevisionConflictError extends Error {\n public readonly expected: string | null | undefined;\n public readonly actual: string | undefined;\n\n constructor(expected: string | null | undefined, actual: string | undefined) {\n super(`Revision conflict: expected ${expected ?? '<not-exists>'}, actual ${actual ?? '<not-exists>'}`);\n\n this.name = 'RevisionConflictError';\n this.expected = expected;\n this.actual = actual;\n }\n}\n\nexport class NotFoundError extends Error {\n public readonly resource: string;\n\n constructor(resource: string) {\n super(`Not found: ${resource}`);\n\n this.name = 'NotFoundError';\n this.resource = resource;\n }\n}\n\nexport class DriverCapabilityError extends Error {\n public readonly capability: string;\n\n constructor(capability: string) {\n super(`Driver does not support ${capability}`);\n\n this.name = 'DriverCapabilityError';\n this.capability = capability;\n }\n}\n\nexport class TemplateRevisionMismatchError extends Error {\n public readonly expected: string;\n public readonly actual: string;\n\n constructor(expected: string, actual: string) {\n super(\n `State-machine instance expects template revision \"${expected}\", but current template revision is \"${actual}\"`,\n );\n\n this.name = 'TemplateRevisionMismatchError';\n this.expected = expected;\n this.actual = actual;\n }\n}\n\nexport class UnsafeConcurrencyError extends Error {\n public readonly concurrency: DriverConcurrency;\n\n constructor(concurrency: DriverConcurrency) {\n super(\n `State-machine mutations require safe conditional writes, ` +\n `but the instance driver provides concurrency=\"${concurrency}\"`,\n );\n\n this.name = 'UnsafeConcurrencyError';\n this.concurrency = concurrency;\n }\n}\n","import { DriverCapabilities } from './types/driver-contract.ts';\n\nexport function hasSafeConditionalWrites(capabilities: DriverCapabilities): boolean {\n return capabilities.concurrency === 'cooperative-lock' || capabilities.concurrency === 'atomic-cas';\n}\n","import { assertSchema, StateMachineInstanceSchema } from '@onereach/state-machine-core';\n\nimport { DriverCapabilityError, NotFoundError, TemplateRevisionMismatchError } from '../errors.ts';\nimport { StateTemplateStore } from '../template-store/template-store.ts';\nimport { DriverCapabilities, DriverLoadOptions } from '../types/driver-contract.ts';\n\nimport type {\n CreateStateMachineInstance,\n InstanceWatchOptions,\n LoadedStateMachineInstance,\n StateMachineInstanceChange,\n StateMachineInstanceDriver,\n StateMachineInstanceReference,\n UpdateStateMachineInstance,\n} from './types.ts';\n\nexport class StateMachineInstanceStore {\n private readonly driver: StateMachineInstanceDriver;\n private readonly templates: StateTemplateStore;\n\n constructor(driver: StateMachineInstanceDriver, templates: StateTemplateStore) {\n this.driver = driver;\n this.templates = templates;\n }\n\n /**\n * Creates a new state machine instance.\n * @param options - The options for the create operation.\n * @returns The created state machine instance.\n */\n public async create(options: CreateStateMachineInstance): Promise<LoadedStateMachineInstance> {\n const template = await this.templates.require(options.template);\n const state = structuredClone(options.state ?? template.definition.initialState);\n\n assertSchema(template.validators.state, state, 'state-before');\n\n const now = new Date();\n const datetime = now.toISOString();\n\n const instance = StateMachineInstanceSchema.parse({\n schemaVersion: 1,\n id: options.id,\n\n template: {\n id: template.definition.id,\n version: template.definition.version ?? options.template.version,\n revision: template.revision,\n },\n\n state,\n sequence: 0,\n\n createdAt: datetime,\n updatedAt: datetime,\n\n metadata: options.metadata,\n });\n\n const result = await this.driver.save({ id: instance.id }, instance, {\n /**\n * null = create only.\n */\n // eslint-disable-next-line unicorn/no-null\n expectedRevision: null,\n });\n\n return {\n instance,\n revision: result.revision,\n template,\n metadata: result.metadata,\n };\n }\n\n /**\n * Loads a state machine instance from the driver.\n * @param reference - The reference to the state machine instance.\n * @param options - The options for the load operation.\n * @returns The loaded state machine instance.\n */\n public async load(\n reference: StateMachineInstanceReference,\n options?: DriverLoadOptions,\n ): Promise<LoadedStateMachineInstance | undefined> {\n const loaded = await this.driver.load(reference, options);\n\n if (!loaded) return undefined;\n\n const instance = StateMachineInstanceSchema.parse(loaded.value);\n const template = await this.templates.require(\n {\n id: instance.template.id,\n version: instance.template.version,\n },\n options,\n );\n\n if (template.revision !== instance.template.revision) {\n throw new TemplateRevisionMismatchError(instance.template.revision, template.revision);\n }\n\n assertSchema(template.validators.state, instance.state, 'state-before');\n\n return {\n instance,\n revision: loaded.revision,\n template,\n metadata: loaded.metadata,\n };\n }\n\n /**\n * Loads a state machine instance from the driver and throws an error if it is not found.\n * @param reference - The reference to the state machine instance.\n * @param options - The options for the load operation.\n * @returns The loaded state machine instance.\n */\n public async require(\n reference: StateMachineInstanceReference,\n options?: DriverLoadOptions,\n ): Promise<LoadedStateMachineInstance> {\n const instance = await this.load(reference, options);\n\n if (!instance) {\n throw new NotFoundError(`StateMachineInstance:${reference.id}`);\n }\n\n return instance;\n }\n\n /**\n * Saves a new instance revision.\n *\n * The caller cannot accidentally change:\n *\n * - id\n * - template binding\n * - createdAt\n * - sequence manually\n */\n public async save(\n loaded: LoadedStateMachineInstance,\n update: UpdateStateMachineInstance,\n ): Promise<LoadedStateMachineInstance> {\n /**\n * Ensure the bound template still exists and hasn't\n * changed underneath this instance.\n */\n const template = await this.templates.require({\n id: loaded.instance.template.id,\n version: loaded.instance.template.version,\n });\n\n // TODO: Add logic to load specific revision from template store\n if (template.revision !== loaded.instance.template.revision) {\n throw new TemplateRevisionMismatchError(loaded.instance.template.revision, template.revision);\n }\n\n const state = structuredClone(update.state ?? loaded.instance.state);\n\n // TODO: do not validate if state was not provided\n assertSchema(template.validators.state, state, 'state-after');\n\n const now = new Date();\n const datetime = now.toISOString();\n\n const next = StateMachineInstanceSchema.parse({\n ...loaded.instance,\n state,\n metadata: update.metadata ?? loaded.instance.metadata,\n sequence: loaded.instance.sequence + 1,\n updatedAt: datetime,\n });\n\n const result = await this.driver.save({ id: next.id }, next, {\n expectedRevision: loaded.revision,\n });\n\n return {\n instance: next,\n revision: result.revision,\n template,\n metadata: result.metadata,\n };\n }\n\n /**\n * Saves a new state for a state machine instance.\n * @param loaded - The loaded state machine instance.\n * @param state - The state to save.\n * @returns The saved state machine instance.\n */\n public async saveState(\n loaded: LoadedStateMachineInstance,\n state: Record<string, unknown>,\n ): Promise<LoadedStateMachineInstance> {\n return this.save(loaded, { state });\n }\n\n /**\n * Saves metadata for a state machine instance.\n * @param loaded - The loaded state machine instance.\n * @param metadata - The metadata to save.\n * @returns The saved state machine instance.\n */\n public async saveMetadata(\n loaded: LoadedStateMachineInstance,\n metadata: Record<string, unknown>,\n ): Promise<LoadedStateMachineInstance> {\n return this.save(loaded, { metadata });\n }\n\n /**\n * Deletes a state machine instance.\n * @param loaded - The loaded state machine instance.\n * @returns True if the instance was deleted, false otherwise.\n */\n public async delete(loaded: LoadedStateMachineInstance): Promise<boolean> {\n return this.driver.delete({ id: loaded.instance.id }, { expectedRevision: loaded.revision });\n }\n\n /**\n * Watches a state machine instance for changes.\n * @param reference - The reference to the state machine instance.\n * @param options - The options for the watch operation.\n * @returns An iterable of state machine instance changes.\n */\n async *watch(\n reference: StateMachineInstanceReference,\n options: InstanceWatchOptions = {},\n ): AsyncIterable<StateMachineInstanceChange> {\n if (!this.driver.watch) throw new DriverCapabilityError('watch');\n\n let lastRevision: string | undefined;\n\n if (options.emitCurrent) {\n const current = await this.load(reference, options);\n\n if (current) {\n lastRevision = current.revision;\n\n yield {\n type: 'current',\n instance: current,\n };\n }\n }\n\n for await (const change of this.driver.watch(reference, options)) {\n if (change.type === 'deleted') {\n lastRevision = undefined;\n\n yield {\n type: 'deleted',\n ref: reference,\n };\n\n continue;\n }\n\n const current = await this.load(reference, options);\n\n if (!current) continue;\n\n /**\n * fs.watch and many other backends can produce\n * duplicate notifications.\n */\n if (current.revision === lastRevision) continue;\n\n lastRevision = current.revision;\n\n yield {\n type: change.type,\n instance: current,\n };\n }\n }\n\n /**\n * Convenience callback interface over watch().\n * @param reference - The reference to the state machine instance.\n * @param listener - The listener to call when a change occurs.\n * @param options - The options for the watch operation.\n * @returns A function to unsubscribe from the watch.\n */\n public subscribe(\n reference: StateMachineInstanceReference,\n listener: (change: StateMachineInstanceChange) => void | Promise<void>,\n options: InstanceWatchOptions & {\n onError?: (error: unknown) => void;\n } = {},\n ): () => void {\n const controller = new AbortController();\n const externalSignal = options.signal;\n const abort = () => controller.abort();\n\n if (externalSignal?.aborted) {\n controller.abort();\n } else {\n externalSignal?.addEventListener('abort', abort, { once: true });\n }\n\n void (async () => {\n try {\n const changesIterable = this.watch(reference, {\n ...options,\n signal: controller.signal,\n });\n for await (const change of changesIterable) {\n await listener(change);\n }\n } catch (error) {\n if (!controller.signal.aborted) {\n options.onError?.(error);\n }\n } finally {\n externalSignal?.removeEventListener('abort', abort);\n }\n })();\n\n return () => {\n controller.abort();\n };\n }\n\n /**\n * Returns the capabilities of the state machine instance driver.\n * @returns The capabilities of the state machine instance driver.\n */\n public get capabilities(): DriverCapabilities {\n return this.driver.capabilities;\n }\n}\n","import { StateTemplateSchema, StateTemplateValidatorCompiler } from '@onereach/state-machine-core';\nimport type { JsonSchemaValidatorCompiler, StateTemplateDefinition } from '@onereach/state-machine-core';\n\nimport { DriverCapabilityError, NotFoundError } from '../errors.ts';\nimport type {\n DriverCapabilities,\n DriverDeleteOptions,\n DriverLoadOptions,\n DriverSaveOptions,\n DriverWatchOptions,\n} from '../types/driver-contract.ts';\n\nimport type { LoadedStateTemplate, StateTemplateDriver, StateTemplateReference } from './types.ts';\n\nexport class StateTemplateStore {\n private readonly driver: StateTemplateDriver;\n private readonly compiler: StateTemplateValidatorCompiler;\n /**\n * Cache fully prepared loaded templates.\n *\n * This avoids:\n *\n * - repeated Zod parsing\n * - repeated compiler lookup\n * - repeatedly rebuilding wrapper objects\n */\n private readonly cache = new Map<string, LoadedStateTemplate>();\n\n constructor(driver: StateTemplateDriver, compiler: JsonSchemaValidatorCompiler | StateTemplateValidatorCompiler) {\n this.driver = driver;\n this.compiler =\n compiler instanceof StateTemplateValidatorCompiler ? compiler : new StateTemplateValidatorCompiler(compiler);\n }\n\n /**\n * Load a state template from the driver.\n * @param reference - The reference to the state template.\n * @param options - The options for the load operation.\n * @returns The loaded state template.\n */\n public async load(\n reference: StateTemplateReference,\n options?: DriverLoadOptions,\n ): Promise<LoadedStateTemplate | undefined> {\n const loaded = await this.driver.load(reference, options);\n\n if (!loaded) return undefined;\n\n /*\n * We can construct this before parsing because ref already\n * identifies the logical template.\n */\n const cacheKey = templateCacheKey(reference, loaded.revision);\n const cached = this.cache.get(cacheKey);\n if (cached) return cached;\n\n const definition = StateTemplateSchema.parse(loaded.value);\n const validators = this.compiler.compile(definition, cacheKey);\n\n const result: LoadedStateTemplate = {\n definition,\n revision: loaded.revision,\n validators,\n metadata: loaded.metadata,\n };\n\n this.cache.set(cacheKey, result);\n\n return result;\n }\n\n /**\n * Load a state template from the driver and throw an error if it is not found.\n * @param reference - The reference to the state template.\n * @param options - The options for the load operation.\n * @returns The loaded state template.\n */\n public async require(reference: StateTemplateReference, options?: DriverLoadOptions): Promise<LoadedStateTemplate> {\n const template = await this.load(reference, options);\n\n if (!template) {\n throw new NotFoundError(`StateTemplate:${reference.id}`);\n }\n\n return template;\n }\n\n /**\n * Save a state template to the driver.\n * @param raw - The state template definition to save.\n * @param options - The options for the save operation.\n * @returns The saved state template.\n */\n public async save(raw: StateTemplateDefinition, options?: DriverSaveOptions): Promise<LoadedStateTemplate> {\n const definition = StateTemplateSchema.parse(raw);\n /*\n * Compile/validate schemas BEFORE writing bad data\n * to persistence.\n *\n * This compilation is cached by object identity.\n */\n const validators = this.compiler.compile(definition);\n const reference: StateTemplateReference = {\n id: definition.id,\n version: definition.version,\n };\n const saved = await this.driver.save(reference, definition, options);\n const cacheKey = templateCacheKey(reference, saved.revision);\n\n this.compiler.bind(cacheKey, validators);\n\n const result: LoadedStateTemplate = {\n definition,\n revision: saved.revision,\n validators,\n metadata: saved.metadata,\n };\n\n this.cache.set(cacheKey, result);\n\n return result;\n }\n\n public async delete(reference: StateTemplateReference, options?: DriverDeleteOptions): Promise<boolean> {\n /*\n * You can invalidate cache if you know the revision,\n * but leaving immutable revision entries cached is\n * harmless.\n */\n return this.driver.delete(reference, options);\n }\n\n public async *watch(\n reference: StateTemplateReference,\n options?: DriverWatchOptions,\n ): AsyncIterable<\n | {\n type: 'created' | 'updated';\n template: LoadedStateTemplate;\n }\n | {\n type: 'deleted';\n ref: StateTemplateReference;\n }\n > {\n if (!this.driver.watch) {\n throw new DriverCapabilityError('watch');\n }\n\n let lastRevision: string | undefined;\n\n for await (const change of this.driver.watch(reference, options)) {\n if (change.type === 'deleted') {\n lastRevision = undefined;\n\n yield {\n type: 'deleted',\n ref: reference,\n };\n\n continue;\n }\n\n const template = await this.load(reference, options);\n\n if (!template) continue;\n if (template.revision === lastRevision) continue;\n\n lastRevision = template.revision;\n\n yield {\n type: change.type,\n template,\n };\n }\n }\n\n public get capabilities(): DriverCapabilities {\n return this.driver.capabilities;\n }\n}\n\nfunction templateCacheKey(reference: StateTemplateReference, revision: string): string {\n return JSON.stringify([reference.id, reference.version ?? 'latest', revision]);\n}\n"],"mappings":"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"}
|
package/package.json
ADDED
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@onereach/state-machine-store",
|
|
3
|
+
"version": "1.0.0-framework.2",
|
|
4
|
+
"description": "State Machine persistence abstraction",
|
|
5
|
+
"keywords": [
|
|
6
|
+
"onereach",
|
|
7
|
+
"toolkit",
|
|
8
|
+
"state-machine"
|
|
9
|
+
],
|
|
10
|
+
"author": "OneReach Development Team <dev.team@onereach.ai>",
|
|
11
|
+
"license": "Apache-2.0",
|
|
12
|
+
"type": "module",
|
|
13
|
+
"publishConfig": {
|
|
14
|
+
"access": "public"
|
|
15
|
+
},
|
|
16
|
+
"files": [
|
|
17
|
+
"dist",
|
|
18
|
+
"!dist/metafile*.json"
|
|
19
|
+
],
|
|
20
|
+
"devDependencies": {
|
|
21
|
+
"@arethetypeswrong/core": "^0.18.5",
|
|
22
|
+
"@types/source-map-support": "^0.5.10",
|
|
23
|
+
"publint": "^0.3.24",
|
|
24
|
+
"rollup-plugin-visualizer": "^7.1.1",
|
|
25
|
+
"tsdown": "^0.22.14",
|
|
26
|
+
"typescript": "^6.0.3"
|
|
27
|
+
},
|
|
28
|
+
"dependencies": {
|
|
29
|
+
"@onereach/state-machine-core": "1.0.0-framework.2"
|
|
30
|
+
},
|
|
31
|
+
"exports": {
|
|
32
|
+
".": "./dist/index.mjs",
|
|
33
|
+
"./package.json": "./package.json"
|
|
34
|
+
},
|
|
35
|
+
"scripts": {
|
|
36
|
+
"build": "tsdown --config tsdown.config.mts",
|
|
37
|
+
"build:visualize": "VISUALIZE=1 pnpm build",
|
|
38
|
+
"typecheck": "tsc --noEmit",
|
|
39
|
+
"preversion_": "pnpm build && pnpm test",
|
|
40
|
+
"publish:rc": "pnpm version prerelease --preid rc && pnpm publish --tag rc",
|
|
41
|
+
"test": "pnpm run unit",
|
|
42
|
+
"unit": "vitest run",
|
|
43
|
+
"preversion": "pnpm build"
|
|
44
|
+
}
|
|
45
|
+
}
|