@sphereon/ssi-sdk.xstate-machine-persistence 0.33.1-next.3 → 0.33.1-next.73

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (45) hide show
  1. package/dist/index.cjs +1014 -0
  2. package/dist/index.cjs.map +1 -0
  3. package/dist/{ssi-sdk.xstate-machine-persistence.d.ts → index.d.cts} +426 -467
  4. package/dist/index.d.ts +425 -5
  5. package/dist/index.js +982 -21
  6. package/dist/index.js.map +1 -1
  7. package/package.json +25 -14
  8. package/plugin.schema.json +80 -320
  9. package/src/__tests__/localAgent.test.ts +1 -0
  10. package/src/__tests__/restAgent.test.ts +4 -1
  11. package/src/__tests__/shared/MachineStatePersistenceAgentLogic.ts +1 -0
  12. package/dist/agent/MachineStatePersistence.d.ts +0 -26
  13. package/dist/agent/MachineStatePersistence.d.ts.map +0 -1
  14. package/dist/agent/MachineStatePersistence.js +0 -197
  15. package/dist/agent/MachineStatePersistence.js.map +0 -1
  16. package/dist/functions/index.d.ts +0 -4
  17. package/dist/functions/index.d.ts.map +0 -1
  18. package/dist/functions/index.js +0 -20
  19. package/dist/functions/index.js.map +0 -1
  20. package/dist/functions/machineRegistration.d.ts +0 -130
  21. package/dist/functions/machineRegistration.d.ts.map +0 -1
  22. package/dist/functions/machineRegistration.js +0 -303
  23. package/dist/functions/machineRegistration.js.map +0 -1
  24. package/dist/functions/stateEventEmitter.d.ts +0 -10
  25. package/dist/functions/stateEventEmitter.d.ts.map +0 -1
  26. package/dist/functions/stateEventEmitter.js +0 -21
  27. package/dist/functions/stateEventEmitter.js.map +0 -1
  28. package/dist/functions/stateMapper.d.ts +0 -34
  29. package/dist/functions/stateMapper.d.ts.map +0 -1
  30. package/dist/functions/stateMapper.js +0 -83
  31. package/dist/functions/stateMapper.js.map +0 -1
  32. package/dist/index.d.ts.map +0 -1
  33. package/dist/tsdoc-metadata.json +0 -11
  34. package/dist/types/IMachineStatePersistence.d.ts +0 -62
  35. package/dist/types/IMachineStatePersistence.d.ts.map +0 -1
  36. package/dist/types/IMachineStatePersistence.js +0 -3
  37. package/dist/types/IMachineStatePersistence.js.map +0 -1
  38. package/dist/types/index.d.ts +0 -3
  39. package/dist/types/index.d.ts.map +0 -1
  40. package/dist/types/index.js +0 -19
  41. package/dist/types/index.js.map +0 -1
  42. package/dist/types/types.d.ts +0 -173
  43. package/dist/types/types.d.ts.map +0 -1
  44. package/dist/types/types.js +0 -13
  45. package/dist/types/types.js.map +0 -1
package/dist/index.cjs ADDED
@@ -0,0 +1,1014 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __name = (target, value) => __defProp(target, "name", { value, configurable: true });
9
+ var __commonJS = (cb, mod) => function __require() {
10
+ return mod || (0, cb[__getOwnPropNames(cb)[0]])((mod = { exports: {} }).exports, mod), mod.exports;
11
+ };
12
+ var __export = (target, all) => {
13
+ for (var name in all)
14
+ __defProp(target, name, { get: all[name], enumerable: true });
15
+ };
16
+ var __copyProps = (to, from, except, desc) => {
17
+ if (from && typeof from === "object" || typeof from === "function") {
18
+ for (let key of __getOwnPropNames(from))
19
+ if (!__hasOwnProp.call(to, key) && key !== except)
20
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
21
+ }
22
+ return to;
23
+ };
24
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
25
+ // If the importer is in node compatibility mode or this is not an ESM
26
+ // file that has been converted to a CommonJS file using a Babel-
27
+ // compatible transform (i.e. "__esModule" has not been set), then set
28
+ // "default" to the CommonJS "module.exports" for node compatibility.
29
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
30
+ mod
31
+ ));
32
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
33
+
34
+ // plugin.schema.json
35
+ var require_plugin_schema = __commonJS({
36
+ "plugin.schema.json"(exports, module2) {
37
+ module2.exports = {
38
+ IMachineStatePersistence: {
39
+ components: {
40
+ schemas: {
41
+ MachineStateDeleteArgs: {
42
+ $ref: '#/components/schemas/Pick<StoreMachineStateInfo,("instanceId"|"tenantId")>'
43
+ },
44
+ 'Pick<StoreMachineStateInfo,("instanceId"|"tenantId")>': {
45
+ type: "object",
46
+ properties: {
47
+ instanceId: {
48
+ type: "string",
49
+ description: "Unique instance ID of the machine"
50
+ },
51
+ tenantId: {
52
+ type: "string"
53
+ }
54
+ },
55
+ required: ["instanceId"],
56
+ additionalProperties: false
57
+ },
58
+ MachineStateGetArgs: {
59
+ $ref: '#/components/schemas/Pick<StoreMachineStateInfo,("instanceId"|"tenantId")>'
60
+ },
61
+ MachineStateInfo: {
62
+ type: "object",
63
+ additionalProperties: false,
64
+ properties: {
65
+ state: {
66
+ $ref: "#/components/schemas/SerializableState"
67
+ },
68
+ instanceId: {
69
+ type: "string",
70
+ description: "Unique instance ID of the machine"
71
+ },
72
+ sessionId: {
73
+ type: "string",
74
+ description: "Session Id of the machine. Not necessarily unique"
75
+ },
76
+ machineName: {
77
+ type: "string",
78
+ description: "Machine name"
79
+ },
80
+ latestStateName: {
81
+ type: "string",
82
+ description: "The latest state name. Can be empty for a newly initialize machine"
83
+ },
84
+ latestEventType: {
85
+ type: "string",
86
+ description: "event types like SET_TOC, SET_FIRSTNAME, .... Will be xstate.init on a newly initialized machine"
87
+ },
88
+ createdAt: {
89
+ type: "string",
90
+ description: "Represents the creation date"
91
+ },
92
+ expiresAt: {
93
+ type: "string",
94
+ description: "Represents the expiration date"
95
+ },
96
+ updatedAt: {
97
+ type: "string",
98
+ description: "Represents the update date"
99
+ },
100
+ updatedCount: {
101
+ type: "number",
102
+ description: "Represents a counter for tracking updates."
103
+ },
104
+ completedAt: {
105
+ type: "string",
106
+ format: "date-time"
107
+ },
108
+ tenantId: {
109
+ type: "string"
110
+ }
111
+ },
112
+ required: ["createdAt", "instanceId", "latestEventType", "machineName", "state", "updatedAt", "updatedCount"]
113
+ },
114
+ SerializableState: {
115
+ $ref: "#/components/schemas/XStateConfig<any,AnyEventObject>"
116
+ },
117
+ "XStateConfig<any,AnyEventObject>": {
118
+ type: "object",
119
+ properties: {
120
+ value: {
121
+ $ref: "#/components/schemas/StateValue"
122
+ },
123
+ context: {},
124
+ _event: {
125
+ $ref: "#/components/schemas/SCXML.Event<AnyEventObject>"
126
+ },
127
+ _sessionid: {
128
+ type: ["string", "null"]
129
+ },
130
+ historyValue: {
131
+ $ref: "#/components/schemas/HistoryValue"
132
+ },
133
+ history: {},
134
+ actions: {
135
+ type: "array",
136
+ items: {}
137
+ },
138
+ activities: {},
139
+ meta: {},
140
+ events: {
141
+ type: "array",
142
+ items: {
143
+ $ref: "#/components/schemas/AnyEventObject"
144
+ }
145
+ },
146
+ configuration: {
147
+ type: "array",
148
+ items: {}
149
+ },
150
+ transitions: {
151
+ type: "array",
152
+ items: {}
153
+ },
154
+ children: {
155
+ $ref: "#/components/schemas/Record<string,any>"
156
+ },
157
+ done: {
158
+ type: "boolean"
159
+ },
160
+ tags: {
161
+ $ref: "#/components/schemas/Set<string>"
162
+ },
163
+ machine: {}
164
+ },
165
+ required: ["value", "context", "_event", "_sessionid", "configuration", "transitions", "children"],
166
+ additionalProperties: false,
167
+ description: "The configuration for the XState machine state. Simplified StateConfig object from XState so we have a minimal typed structure"
168
+ },
169
+ StateValue: {
170
+ anyOf: [
171
+ {
172
+ type: "string"
173
+ },
174
+ {
175
+ $ref: "#/components/schemas/StateValueMap"
176
+ }
177
+ ],
178
+ description: 'The string or object representing the state value relative to the parent state node.\n\n- For a child atomic state node, this is a string, e.g., `"pending"`.\n- For complex state nodes, this is an object, e.g., `{ success: "someChildState" }`.'
179
+ },
180
+ StateValueMap: {
181
+ type: "object",
182
+ additionalProperties: {
183
+ $ref: "#/components/schemas/StateValue"
184
+ }
185
+ },
186
+ "SCXML.Event<AnyEventObject>": {
187
+ type: "object",
188
+ properties: {
189
+ name: {
190
+ type: "string",
191
+ description: "This is a character string giving the name of the event. The SCXML Processor must set the name field to the name of this event. It is what is matched against the 'event' attribute of <transition>. Note that transitions can do additional tests by using the value of this field inside boolean expressions in the 'cond' attribute."
192
+ },
193
+ type: {
194
+ type: "string",
195
+ enum: ["platform", "internal", "external"],
196
+ description: `This field describes the event type. The SCXML Processor must set it to: "platform" (for events raised by the platform itself, such as error events), "internal" (for events raised by <raise> and <send> with target '_internal') or "external" (for all other events).`
197
+ },
198
+ sendid: {
199
+ type: "string",
200
+ description: "If the sending entity has specified a value for this, the Processor must set this field to that value (see C Event I/O Processors for details). Otherwise, in the case of error events triggered by a failed attempt to send an event, the Processor must set this field to the send id of the triggering <send> element. Otherwise it must leave it blank."
201
+ },
202
+ origin: {
203
+ type: "string",
204
+ description: "This is a URI, equivalent to the 'target' attribute on the <send> element. For external events, the SCXML Processor should set this field to a value which, when used as the value of 'target', will allow the receiver of the event to <send> a response back to the originating entity via the Event I/O Processor specified in 'origintype'. For internal and platform events, the Processor must leave this field blank."
205
+ },
206
+ origintype: {
207
+ type: "string",
208
+ description: "This is equivalent to the 'type' field on the <send> element. For external events, the SCXML Processor should set this field to a value which, when used as the value of 'type', will allow the receiver of the event to <send> a response back to the originating entity at the URI specified by 'origin'. For internal and platform events, the Processor must leave this field blank."
209
+ },
210
+ invokeid: {
211
+ type: "string",
212
+ description: "If this event is generated from an invoked child process, the SCXML Processor must set this field to the invoke id of the invocation that triggered the child process. Otherwise it must leave it blank."
213
+ },
214
+ data: {
215
+ $ref: "#/components/schemas/AnyEventObject",
216
+ description: "This field contains whatever data the sending entity chose to include in this event. The receiving SCXML Processor should reformat this data to match its data model, but must not otherwise modify it.\n\nIf the conversion is not possible, the Processor must leave the field blank and must place an error 'error.execution' in the internal event queue."
217
+ },
218
+ $$type: {
219
+ type: "string",
220
+ const: "scxml"
221
+ }
222
+ },
223
+ required: ["name", "type", "data", "$$type"],
224
+ additionalProperties: false
225
+ },
226
+ AnyEventObject: {
227
+ type: "object",
228
+ properties: {
229
+ type: {
230
+ type: "string",
231
+ description: "The type of event that is sent."
232
+ }
233
+ },
234
+ required: ["type"]
235
+ },
236
+ HistoryValue: {
237
+ type: "object",
238
+ properties: {
239
+ states: {
240
+ $ref: "#/components/schemas/Record<string,(interface-434048446-6094-6223-434048446-0-57488|undefined)>"
241
+ },
242
+ current: {
243
+ $ref: "#/components/schemas/StateValue"
244
+ }
245
+ },
246
+ required: ["states"],
247
+ additionalProperties: false
248
+ },
249
+ "Record<string,(interface-434048446-6094-6223-434048446-0-57488|undefined)>": {
250
+ type: "object",
251
+ additionalProperties: {
252
+ anyOf: [
253
+ {
254
+ $ref: "#/components/schemas/HistoryValue"
255
+ },
256
+ {
257
+ not: {}
258
+ }
259
+ ]
260
+ }
261
+ },
262
+ "Record<string,any>": {
263
+ type: "object"
264
+ },
265
+ "Set<string>": {
266
+ type: "object",
267
+ properties: {
268
+ size: {
269
+ type: "number"
270
+ }
271
+ },
272
+ required: ["size"],
273
+ additionalProperties: false
274
+ },
275
+ InitMachineStateArgs: {
276
+ type: "object",
277
+ additionalProperties: false,
278
+ properties: {
279
+ cleanupAllOtherInstances: {
280
+ type: "boolean"
281
+ },
282
+ customInstanceId: {
283
+ type: "string"
284
+ },
285
+ existingInstanceId: {
286
+ type: "string"
287
+ },
288
+ machineName: {
289
+ type: "string",
290
+ description: "Machine name"
291
+ },
292
+ tenantId: {
293
+ type: "string"
294
+ },
295
+ createdAt: {
296
+ type: "string",
297
+ description: "Represents the creation date"
298
+ },
299
+ expiresAt: {
300
+ type: "string",
301
+ description: "Represents the expiration date"
302
+ },
303
+ stateType: {
304
+ $ref: "#/components/schemas/MachineStateInitType"
305
+ },
306
+ machineState: {
307
+ $ref: "#/components/schemas/MachineStateInfo"
308
+ }
309
+ },
310
+ required: ["machineName"]
311
+ },
312
+ MachineStateInitType: {
313
+ type: "string",
314
+ enum: ["new", "existing"]
315
+ },
316
+ MachineStateInit: {
317
+ type: "object",
318
+ additionalProperties: false,
319
+ properties: {
320
+ stateType: {
321
+ $ref: "#/components/schemas/MachineStateInitType"
322
+ },
323
+ machineState: {
324
+ $ref: "#/components/schemas/MachineStateInfo"
325
+ },
326
+ instanceId: {
327
+ type: "string",
328
+ description: "Unique instance ID of the machine"
329
+ },
330
+ machineName: {
331
+ type: "string",
332
+ description: "Machine name"
333
+ },
334
+ tenantId: {
335
+ type: "string"
336
+ },
337
+ createdAt: {
338
+ type: "string",
339
+ description: "Represents the creation date"
340
+ },
341
+ expiresAt: {
342
+ type: "string",
343
+ description: "Represents the expiration date"
344
+ }
345
+ },
346
+ required: ["createdAt", "instanceId", "machineName", "stateType"]
347
+ },
348
+ MachineStatePersistArgs: {
349
+ type: "object",
350
+ additionalProperties: false,
351
+ properties: {
352
+ cleanupOnFinalState: {
353
+ type: "boolean"
354
+ },
355
+ updatedCount: {
356
+ type: "number",
357
+ description: "Represents a counter for tracking updates."
358
+ },
359
+ state: {
360
+ $ref: "#/components/schemas/SerializableState"
361
+ },
362
+ instanceId: {
363
+ type: "string",
364
+ description: "Unique instance ID of the machine"
365
+ },
366
+ machineName: {
367
+ type: "string",
368
+ description: "Machine name"
369
+ },
370
+ tenantId: {
371
+ type: "string"
372
+ },
373
+ expiresAt: {
374
+ type: "string",
375
+ description: "Represents the expiration date"
376
+ },
377
+ stateType: {
378
+ $ref: "#/components/schemas/MachineStateInitType"
379
+ },
380
+ machineState: {
381
+ $ref: "#/components/schemas/MachineStateInfo"
382
+ }
383
+ },
384
+ required: ["instanceId", "machineName", "state", "stateType"],
385
+ description: "Represents the arguments required to persist the machine state."
386
+ },
387
+ DeleteExpiredStatesArgs: {
388
+ $ref: '#/components/schemas/Pick<StoreMachineStateDeleteExpiredArgs,("deleteDoneStates"|"machineName"|"tenantId")>',
389
+ description: "Represents the arguments for deleting expired states from a machine."
390
+ },
391
+ 'Pick<StoreMachineStateDeleteExpiredArgs,("deleteDoneStates"|"machineName"|"tenantId")>': {
392
+ type: "object",
393
+ properties: {
394
+ deleteDoneStates: {
395
+ type: "boolean"
396
+ },
397
+ machineName: {
398
+ type: "string"
399
+ },
400
+ tenantId: {
401
+ type: "string"
402
+ }
403
+ },
404
+ additionalProperties: false
405
+ },
406
+ DeleteStateResult: {
407
+ type: "number"
408
+ },
409
+ FindActiveStatesArgs: {
410
+ $ref: "#/components/schemas/StoreMachineStatesFindActiveArgs",
411
+ description: "Represents the arguments for finding active states of a store machine."
412
+ },
413
+ StoreMachineStatesFindActiveArgs: {
414
+ $ref: '#/components/schemas/Partial<Pick<StoreMachineStateInfo,("machineName"|"tenantId"|"instanceId")>>'
415
+ },
416
+ 'Partial<Pick<StoreMachineStateInfo,("machineName"|"tenantId"|"instanceId")>>': {
417
+ type: "object",
418
+ properties: {
419
+ machineName: {
420
+ type: "string",
421
+ description: "Machine name"
422
+ },
423
+ tenantId: {
424
+ type: "string"
425
+ },
426
+ instanceId: {
427
+ type: "string",
428
+ description: "Unique instance ID of the machine"
429
+ }
430
+ },
431
+ additionalProperties: false
432
+ }
433
+ },
434
+ methods: {
435
+ machineStateDelete: {
436
+ description: "Delete a particular machine state by instance id and tenant id",
437
+ arguments: {
438
+ $ref: "#/components/schemas/MachineStateDeleteArgs"
439
+ },
440
+ returnType: {
441
+ type: "boolean"
442
+ }
443
+ },
444
+ machineStateGet: {
445
+ description: "Get a particular machine state by instance id and tenant id",
446
+ arguments: {
447
+ $ref: "#/components/schemas/MachineStateGetArgs"
448
+ },
449
+ returnType: {
450
+ $ref: "#/components/schemas/MachineStateInfo"
451
+ }
452
+ },
453
+ machineStateInit: {
454
+ description: "Initializes a state object for a new machine. Does not persist anything",
455
+ arguments: {
456
+ $ref: "#/components/schemas/InitMachineStateArgs"
457
+ },
458
+ returnType: {
459
+ $ref: "#/components/schemas/MachineStateInit"
460
+ }
461
+ },
462
+ machineStatePersist: {
463
+ description: "Persists the state",
464
+ arguments: {
465
+ $ref: "#/components/schemas/MachineStatePersistArgs"
466
+ },
467
+ returnType: {
468
+ $ref: "#/components/schemas/MachineStateInfo"
469
+ }
470
+ },
471
+ machineStatesDeleteExpired: {
472
+ description: "Deletes the state of an xstate machine in the database.",
473
+ arguments: {
474
+ $ref: "#/components/schemas/DeleteExpiredStatesArgs"
475
+ },
476
+ returnType: {
477
+ $ref: "#/components/schemas/DeleteStateResult"
478
+ }
479
+ },
480
+ machineStatesFindActive: {
481
+ description: "Loads the states of active xstate machines from the database.",
482
+ arguments: {
483
+ $ref: "#/components/schemas/FindActiveStatesArgs"
484
+ },
485
+ returnType: {
486
+ type: "array",
487
+ items: {
488
+ $ref: "#/components/schemas/MachineStateInfo"
489
+ }
490
+ }
491
+ }
492
+ }
493
+ }
494
+ }
495
+ };
496
+ }
497
+ });
498
+
499
+ // src/index.ts
500
+ var index_exports = {};
501
+ __export(index_exports, {
502
+ MachineStatePersistEventType: () => MachineStatePersistEventType,
503
+ MachineStatePersistence: () => MachineStatePersistence,
504
+ deserializeMachineState: () => deserializeMachineState,
505
+ emitMachineStatePersistEvent: () => emitMachineStatePersistEvent,
506
+ interpreterResumeFromState: () => interpreterResumeFromState,
507
+ interpreterStartOrResume: () => interpreterStartOrResume,
508
+ interpreterStartOrResumeFromInit: () => interpreterStartOrResumeFromInit,
509
+ machineStatePersistInit: () => machineStatePersistInit,
510
+ machineStatePersistOnTransition: () => machineStatePersistOnTransition,
511
+ machineStatePersistRegistration: () => machineStatePersistRegistration,
512
+ machineStateToMachineInit: () => machineStateToMachineInit,
513
+ machineStateToStoreInfo: () => machineStateToStoreInfo,
514
+ schema: () => schema,
515
+ serializeMachineState: () => serializeMachineState,
516
+ storeInfoToMachineInit: () => storeInfoToMachineInit
517
+ });
518
+ module.exports = __toCommonJS(index_exports);
519
+
520
+ // src/agent/MachineStatePersistence.ts
521
+ var import_debug2 = __toESM(require("debug"), 1);
522
+ var import_uuid = require("uuid");
523
+
524
+ // src/functions/machineRegistration.ts
525
+ var import_xstate2 = require("xstate");
526
+ var import_waitFor = require("xstate/lib/waitFor");
527
+
528
+ // src/types/types.ts
529
+ var MachineStatePersistEventType = /* @__PURE__ */ function(MachineStatePersistEventType2) {
530
+ MachineStatePersistEventType2["INIT"] = "INIT";
531
+ MachineStatePersistEventType2["EVERY"] = "EVERY";
532
+ return MachineStatePersistEventType2;
533
+ }({});
534
+
535
+ // src/functions/stateEventEmitter.ts
536
+ var import_debug = __toESM(require("debug"), 1);
537
+ var debug = (0, import_debug.default)("sphereon:ssi-sdk:machine-state:xstate-persistence");
538
+ var emitMachineStatePersistEvent = /* @__PURE__ */ __name((event, context) => {
539
+ debug(`Emitting machine state persistence event '${event.type}' with counter: ${event.data._eventCounter} and state ${JSON.stringify(event.data.state.value)}`);
540
+ void context.agent.emit(event.type, event.data);
541
+ }, "emitMachineStatePersistEvent");
542
+
543
+ // src/functions/stateMapper.ts
544
+ var import_xstate = require("xstate");
545
+ var machineStateToStoreInfo = /* @__PURE__ */ __name((machineInfo, existingState) => {
546
+ const { state, machineName, tenantId, expiresAt, instanceId, updatedCount } = machineInfo;
547
+ const existing = existingState ?? {
548
+ machineName,
549
+ createdAt: /* @__PURE__ */ new Date(),
550
+ expiresAt
551
+ };
552
+ const stateInstance = import_xstate.State.create(machineInfo.state);
553
+ let latestStateName = void 0;
554
+ if (stateInstance.value) {
555
+ latestStateName = typeof stateInstance.value === "string" ? stateInstance.value : JSON.stringify(stateInstance.value);
556
+ }
557
+ if (latestStateName === "{}") {
558
+ latestStateName = void 0;
559
+ }
560
+ return {
561
+ instanceId,
562
+ updatedCount: updatedCount ?? (existing?.updatedCount ? existing.updatedCount++ : 0),
563
+ sessionId: stateInstance._sessionid ?? void 0,
564
+ machineName,
565
+ state: serializeMachineState(state),
566
+ tenantId,
567
+ latestStateName,
568
+ latestEventType: stateInstance.event.type,
569
+ updatedAt: /* @__PURE__ */ new Date(),
570
+ expiresAt,
571
+ createdAt: existing.createdAt ?? /* @__PURE__ */ new Date(),
572
+ completedAt: existing.completedAt ?? (stateInstance.done ? /* @__PURE__ */ new Date() : void 0)
573
+ };
574
+ }, "machineStateToStoreInfo");
575
+ var storeInfoToMachineInit = /* @__PURE__ */ __name((args) => {
576
+ const { instanceId, machineName, tenantId, expiresAt, createdAt, stateType, machineState } = args;
577
+ return {
578
+ stateType,
579
+ machineName,
580
+ tenantId,
581
+ expiresAt,
582
+ instanceId,
583
+ createdAt,
584
+ machineState
585
+ };
586
+ }, "storeInfoToMachineInit");
587
+ var machineStateToMachineInit = /* @__PURE__ */ __name((machineInfo, existingState) => {
588
+ return storeInfoToMachineInit({
589
+ ...machineStateToStoreInfo(machineInfo, existingState),
590
+ stateType: "existing",
591
+ machineState: machineInfo.machineState
592
+ });
593
+ }, "machineStateToMachineInit");
594
+ var serializeMachineState = /* @__PURE__ */ __name((state) => {
595
+ if (typeof state === "string") {
596
+ return state;
597
+ }
598
+ const jsonState = "toJSON" in state ? state.toJSON() : state;
599
+ return JSON.stringify(jsonState);
600
+ }, "serializeMachineState");
601
+ var deserializeMachineState = /* @__PURE__ */ __name((state) => {
602
+ return import_xstate.State.create(JSON.parse(state));
603
+ }, "deserializeMachineState");
604
+
605
+ // src/functions/machineRegistration.ts
606
+ var machineStatePersistInit = /* @__PURE__ */ __name(async (opts) => {
607
+ const { context, ...args } = opts;
608
+ if (!(context.agent.availableMethods().includes("machineStateInit") && "machineStateInit" in context.agent)) {
609
+ console.log(`IMachineStatePersistence was not exposed in the current agent. Not initializing new persistence object`);
610
+ return;
611
+ }
612
+ return await context.agent.machineStateInit(args);
613
+ }, "machineStatePersistInit");
614
+ var machineStatePersistOnTransition = /* @__PURE__ */ __name(async (opts) => {
615
+ const { cleanupOnFinalState, context, init, interpreter } = opts;
616
+ const { machineState, ...initEventData } = init;
617
+ if (!(context.agent.availableMethods().includes("machineStatePersist") && "machineStatePersist" in context.agent)) {
618
+ console.log(`IMachineStatePersistence was not exposed in the current agent. Disabling machine state persistence events`);
619
+ return;
620
+ }
621
+ let _eventCounter = init.machineState?.updatedCount ?? 0;
622
+ interpreter.onChange(async (_machineContext) => {
623
+ emitMachineStatePersistEvent({
624
+ type: MachineStatePersistEventType.EVERY,
625
+ data: {
626
+ ...initEventData,
627
+ state: interpreter.getSnapshot(),
628
+ _eventCounter: ++_eventCounter,
629
+ _eventDate: /* @__PURE__ */ new Date(),
630
+ _cleanupOnFinalState: cleanupOnFinalState !== false
631
+ }
632
+ }, context);
633
+ });
634
+ if (cleanupOnFinalState && context.agent.availableMethods().includes("machineStateDelete")) {
635
+ interpreter.onDone((doneEvent) => {
636
+ ;
637
+ context.agent.machineStateDelete({
638
+ tenantId: initEventData.tenantId,
639
+ instanceId: initEventData.instanceId
640
+ });
641
+ });
642
+ }
643
+ }, "machineStatePersistOnTransition");
644
+ var machineStatePersistRegistration = /* @__PURE__ */ __name(async (args) => {
645
+ const { disablePersistence } = args;
646
+ if (disablePersistence === true) {
647
+ return;
648
+ }
649
+ const expiresAt = args.expireInMS ? new Date(Date.now() + args.expireInMS) : args.expiresAt;
650
+ const machineName = args.machineName ?? args.interpreter.machine.id ?? args.interpreter.id;
651
+ const init = await machineStatePersistInit({
652
+ ...args,
653
+ machineName,
654
+ expiresAt
655
+ });
656
+ if (init) {
657
+ await machineStatePersistOnTransition({
658
+ ...args,
659
+ init
660
+ });
661
+ }
662
+ return init;
663
+ }, "machineStatePersistRegistration");
664
+ var assertNonExpired = /* @__PURE__ */ __name((args) => {
665
+ const { expiresAt, machineName } = args;
666
+ if (expiresAt && expiresAt.getTime() < Date.now()) {
667
+ throw new Error(`Cannot resume ${machineName}. It expired at ${expiresAt.toLocaleString()}`);
668
+ }
669
+ }, "assertNonExpired");
670
+ var interpreterResumeFromState = /* @__PURE__ */ __name(async (args) => {
671
+ const { interpreter, machineState, context, noRegistration, cleanupAllOtherInstances, cleanupOnFinalState } = args;
672
+ const { machineName, instanceId, tenantId } = machineState;
673
+ assertNonExpired(machineState);
674
+ if (noRegistration !== true) {
675
+ await machineStatePersistRegistration({
676
+ stateType: "existing",
677
+ machineName,
678
+ tenantId,
679
+ existingInstanceId: instanceId,
680
+ cleanupAllOtherInstances,
681
+ cleanupOnFinalState,
682
+ context,
683
+ interpreter
684
+ });
685
+ }
686
+ const state = import_xstate2.State.from(machineState.state.value, machineState.state.context);
687
+ interpreter.start(state);
688
+ await (0, import_waitFor.waitFor)(interpreter, (awaitState) => awaitState.matches(state.value));
689
+ return {
690
+ machineState,
691
+ init: machineStateToMachineInit({
692
+ ...machineState,
693
+ stateType: "existing"
694
+ }, machineStateToStoreInfo({
695
+ ...machineState,
696
+ stateType: "existing"
697
+ })),
698
+ interpreter
699
+ };
700
+ }, "interpreterResumeFromState");
701
+ var interpreterStartOrResumeFromInit = /* @__PURE__ */ __name(async (args) => {
702
+ const { init, noRegistration, interpreter, cleanupOnFinalState, cleanupAllOtherInstances, context } = args;
703
+ const { stateType, instanceId, machineName, tenantId, expiresAt } = init;
704
+ if (init.machineName !== interpreter.id) {
705
+ throw new Error(`Machine state init machine name ${init.machineName} does not match name from state machine interpreter ${interpreter.id}`);
706
+ }
707
+ assertNonExpired({
708
+ machineName,
709
+ expiresAt
710
+ });
711
+ if (noRegistration !== true) {
712
+ await machineStatePersistRegistration({
713
+ stateType: stateType ?? "existing",
714
+ machineName,
715
+ tenantId,
716
+ ...stateType === "existing" && {
717
+ existingInstanceId: instanceId
718
+ },
719
+ ...stateType === "new" && {
720
+ customInstanceId: instanceId
721
+ },
722
+ cleanupAllOtherInstances,
723
+ cleanupOnFinalState,
724
+ context,
725
+ interpreter
726
+ });
727
+ }
728
+ let machineState;
729
+ if (stateType === "new") {
730
+ interpreter.start();
731
+ } else {
732
+ machineState = await context.agent.machineStateGet({
733
+ tenantId,
734
+ instanceId
735
+ });
736
+ interpreter.start(machineState.state);
737
+ }
738
+ await new Promise((res) => setTimeout(res, 50));
739
+ return {
740
+ interpreter,
741
+ machineState,
742
+ init
743
+ };
744
+ }, "interpreterStartOrResumeFromInit");
745
+ var interpreterStartOrResume = /* @__PURE__ */ __name(async (args) => {
746
+ const { stateType, singletonCheck, instanceId, tenantId, noRegistration, context, interpreter, cleanupAllOtherInstances, cleanupOnFinalState } = args;
747
+ const machineName = args.machineName ?? interpreter.id;
748
+ let activeStates = await context.agent.machineStatesFindActive({
749
+ machineName,
750
+ tenantId,
751
+ instanceId
752
+ });
753
+ if (stateType === "new" && activeStates.length > 0 && cleanupAllOtherInstances) {
754
+ await Promise.all(activeStates.map((state) => context.agent.machineStateDelete({
755
+ tenantId: args.tenantId,
756
+ instanceId: state.instanceId
757
+ })));
758
+ activeStates = await context.agent.machineStatesFindActive({
759
+ machineName,
760
+ tenantId,
761
+ instanceId
762
+ });
763
+ }
764
+ if (singletonCheck && activeStates.length > 0) {
765
+ if (stateType === "new" || stateType === "existing" && (!instanceId && activeStates.length > 1 || instanceId && activeStates.every((state) => state.instanceId !== instanceId))) {
766
+ return Promise.reject(new Error(`Found ${activeStates.length} active '${machineName}' instances, but only one is allows at the same time`));
767
+ }
768
+ }
769
+ if (stateType === "new") {
770
+ if (instanceId && activeStates.length > 0) {
771
+ return Promise.reject(new Error(`Found an active '${machineName}' instance with id ${instanceId}, but a new instance was requested with the same id`));
772
+ }
773
+ const init = await context.agent.machineStateInit({
774
+ stateType: "new",
775
+ customInstanceId: instanceId,
776
+ machineName: machineName ?? interpreter.id,
777
+ tenantId,
778
+ cleanupAllOtherInstances
779
+ });
780
+ return await interpreterStartOrResumeFromInit({
781
+ init,
782
+ noRegistration,
783
+ interpreter,
784
+ context,
785
+ cleanupOnFinalState,
786
+ cleanupAllOtherInstances
787
+ });
788
+ }
789
+ if (activeStates.length === 0) {
790
+ if (stateType === "existing") {
791
+ return Promise.reject(new Error(`Could not find existing state machine ${machineName}, instanceId ${instanceId}`));
792
+ }
793
+ const init = await context.agent.machineStateInit({
794
+ stateType: "new",
795
+ customInstanceId: instanceId,
796
+ machineName: machineName ?? interpreter.id,
797
+ tenantId,
798
+ cleanupAllOtherInstances
799
+ });
800
+ return await interpreterStartOrResumeFromInit({
801
+ init,
802
+ noRegistration,
803
+ interpreter,
804
+ context,
805
+ cleanupOnFinalState,
806
+ cleanupAllOtherInstances
807
+ });
808
+ }
809
+ const activeState = activeStates[0];
810
+ return interpreterResumeFromState({
811
+ machineState: activeState,
812
+ noRegistration,
813
+ interpreter,
814
+ context,
815
+ cleanupOnFinalState,
816
+ cleanupAllOtherInstances
817
+ });
818
+ }, "interpreterStartOrResume");
819
+
820
+ // src/agent/MachineStatePersistence.ts
821
+ var debug2 = (0, import_debug2.default)("sphereon:ssi-sdk:machine-state:xstate-persistence");
822
+ var MachineStatePersistence = class {
823
+ static {
824
+ __name(this, "MachineStatePersistence");
825
+ }
826
+ schema = schema.IMachineStatePersistence;
827
+ methods;
828
+ eventTypes;
829
+ _store;
830
+ get store() {
831
+ if (!this._store) {
832
+ throw Error("No store available in options");
833
+ }
834
+ return this._store;
835
+ }
836
+ constructor(opts) {
837
+ const { store, eventTypes, isRESTClient } = opts;
838
+ this.eventTypes = eventTypes;
839
+ this.methods = {
840
+ machineStatesFindActive: this.machineStatesFindActive.bind(this),
841
+ machineStatesDeleteExpired: this.machineStatesDeleteExpired.bind(this),
842
+ machineStateInit: this.machineStateInit.bind(this),
843
+ machineStatePersist: this.machineStatePersist.bind(this),
844
+ machineStateGet: this.machineStateGet.bind(this),
845
+ machineStateDelete: this.machineStateDelete.bind(this)
846
+ };
847
+ this._store = store;
848
+ if (isRESTClient) {
849
+ return;
850
+ } else if (!store) {
851
+ throw Error("No store available in options");
852
+ }
853
+ }
854
+ async onEvent(event, context) {
855
+ debug2(`Received machine state persistence event '${event.type}' counter: ${event.data._eventCounter}}`);
856
+ if (!this.eventTypes.includes(event.type)) {
857
+ console.log(`event type ${event.type} not registered for agent. Registered: ${JSON.stringify(this.eventTypes)}`);
858
+ return;
859
+ }
860
+ switch (event.type) {
861
+ case MachineStatePersistEventType.INIT:
862
+ await context.agent.machineStateInit({
863
+ ...event.data
864
+ });
865
+ break;
866
+ case MachineStatePersistEventType.EVERY:
867
+ await context.agent.machineStatePersist({
868
+ ...event.data,
869
+ cleanupOnFinalState: event.data.cleanupOnFinalState ?? event.data._cleanupOnFinalState,
870
+ updatedCount: event.data._eventCounter ?? event.data.updatedCount
871
+ });
872
+ break;
873
+ default:
874
+ return Promise.reject(Error(`Event type ${event.type} not supported`));
875
+ }
876
+ }
877
+ async machineStateInit(args, context) {
878
+ const { tenantId, machineName, expiresAt, customInstanceId, existingInstanceId, cleanupAllOtherInstances } = args;
879
+ debug2(`machineStateInit for machine name ${machineName}, tenant ${tenantId}, custom instance ${customInstanceId}, existing id ${existingInstanceId}`);
880
+ if (customInstanceId && existingInstanceId) {
881
+ return Promise.reject(new Error(`Cannot have both a custom and existing instance id at the same time`));
882
+ }
883
+ if (cleanupAllOtherInstances) {
884
+ await context.agent.machineStatesDeleteExpired({
885
+ machineName,
886
+ tenantId,
887
+ deleteDoneStates: true
888
+ });
889
+ await context.agent.machineStatesDeleteExpired({
890
+ machineName,
891
+ tenantId,
892
+ deleteDoneStates: false
893
+ });
894
+ const activeMachineStates = (await context.agent.machineStatesFindActive({
895
+ machineName,
896
+ tenantId
897
+ })).filter((state) => !existingInstanceId || state.instanceId !== existingInstanceId);
898
+ await Promise.all(activeMachineStates.map((state) => context.agent.machineStateDelete({
899
+ instanceId: state.instanceId,
900
+ tenantId
901
+ })));
902
+ }
903
+ let machineInit = void 0;
904
+ let machineState;
905
+ if (existingInstanceId) {
906
+ debug2(`machineStateInit is using a previously persisted instance id (${existingInstanceId})`);
907
+ machineState = await context.agent.machineStateGet({
908
+ tenantId,
909
+ instanceId: existingInstanceId
910
+ });
911
+ machineInit = machineStateToMachineInit({
912
+ ...machineState,
913
+ machineState,
914
+ stateType: "existing"
915
+ }, {
916
+ ...machineState,
917
+ state: serializeMachineState(machineState.state)
918
+ });
919
+ }
920
+ if (customInstanceId) {
921
+ debug2(`machineStateInit is using a custom instance id (${customInstanceId})`);
922
+ }
923
+ if (!machineInit) {
924
+ machineInit = {
925
+ machineName,
926
+ tenantId,
927
+ expiresAt,
928
+ instanceId: customInstanceId ?? (0, import_uuid.v4)(),
929
+ createdAt: args.createdAt ?? /* @__PURE__ */ new Date(),
930
+ stateType: "new"
931
+ };
932
+ }
933
+ return machineInit;
934
+ }
935
+ async machineStatePersist(args, context) {
936
+ const { instanceId, tenantId, machineName, updatedCount } = args;
937
+ const cleanupOnFinalState = args.cleanupOnFinalState !== false;
938
+ debug2(`machineStatePersist for machine name ${machineName}, updateCount: ${updatedCount}, instance ${instanceId} and tenant ${tenantId}...`);
939
+ try {
940
+ const queriedStates = await this.store.findMachineStates({
941
+ filter: [
942
+ {
943
+ instanceId,
944
+ tenantId
945
+ }
946
+ ]
947
+ });
948
+ const existingState = queriedStates.length === 1 ? queriedStates[0] : void 0;
949
+ const storeInfoArgs = machineStateToStoreInfo(args, existingState);
950
+ let storedState;
951
+ if (updatedCount !== void 0 && updatedCount > 1 && storeInfoArgs.latestEventType === "xstate.init") {
952
+ console.log(`Not persisting machine state for resumed init event for machine ${machineName}, tenant ${tenantId} and state with id ${instanceId}`);
953
+ storedState = storeInfoArgs;
954
+ } else {
955
+ storedState = await this.store.persistMachineState(storeInfoArgs);
956
+ }
957
+ const machineStateInfo = {
958
+ ...storedState,
959
+ state: deserializeMachineState(storedState.state)
960
+ };
961
+ debug2(`machineStatePersist success for machine name ${machineName}, instance ${instanceId}, update count ${machineStateInfo.updatedCount}, tenant ${tenantId}, last event: ${machineStateInfo.latestEventType}, last state: ${machineStateInfo.latestStateName}`);
962
+ if (cleanupOnFinalState && machineStateInfo.state.done) {
963
+ debug2(`reached final state for machine ${machineName} instance ${instanceId} and auto cleanup was enabled. Deleting machine state`);
964
+ await context.agent.machineStateDelete(machineStateInfo);
965
+ }
966
+ return machineStateInfo;
967
+ } catch (error) {
968
+ console.log(error);
969
+ return Promise.reject(error);
970
+ }
971
+ }
972
+ async machineStatesFindActive(args) {
973
+ const { machineName, tenantId } = args;
974
+ debug2(`machineStateFindActive for machine name ${machineName} and tenant ${tenantId}...`);
975
+ const storedStates = await this.store.findActiveMachineStates(args);
976
+ const machineStateInfos = storedStates.map((storedState) => {
977
+ return {
978
+ ...storedState,
979
+ state: deserializeMachineState(storedState.state)
980
+ };
981
+ });
982
+ debug2(`machineStateFindActive returned ${machineStateInfos.length} results for machine name ${machineName} and tenant ${tenantId}`);
983
+ return machineStateInfos;
984
+ }
985
+ async machineStatesDeleteExpired(args) {
986
+ const { machineName, tenantId } = args;
987
+ debug2(`machineStatesDeleteExpired for machine name ${machineName} and tenant ${tenantId}...`);
988
+ const deleteResult = await this.store.deleteExpiredMachineStates(args);
989
+ debug2(`machineStatesDeleteExpired result for machine name ${machineName} and tenant ${tenantId}: ${deleteResult}`);
990
+ return deleteResult;
991
+ }
992
+ async machineStateGet(args, context) {
993
+ const { instanceId, tenantId } = args;
994
+ debug2(`machineStateGet for machine instance ${instanceId} and tenant ${tenantId}...`);
995
+ const storedState = await this.store.getMachineState(args);
996
+ const machineInfo = {
997
+ ...storedState,
998
+ state: deserializeMachineState(storedState.state)
999
+ };
1000
+ debug2(`machineStateGet success for machine instance ${instanceId} and tenant ${tenantId}`);
1001
+ return machineInfo;
1002
+ }
1003
+ async machineStateDelete(args, context) {
1004
+ const { instanceId, tenantId } = args;
1005
+ debug2(`machineStateDelete for machine instance ${instanceId} and tenant ${tenantId}...`);
1006
+ const deleteResult = await this.store.deleteMachineState(args);
1007
+ debug2(`machineStateDelete result for machine instance ${instanceId} and tenant ${tenantId}: ${deleteResult}`);
1008
+ return deleteResult;
1009
+ }
1010
+ };
1011
+
1012
+ // src/index.ts
1013
+ var schema = require_plugin_schema();
1014
+ //# sourceMappingURL=index.cjs.map