@arvo-tools/postgres 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (37) hide show
  1. package/dist/index.d.ts +5 -0
  2. package/dist/index.d.ts.map +1 -0
  3. package/dist/index.js +10 -0
  4. package/dist/index.js.map +1 -0
  5. package/dist/memory/factory/defaults.d.ts +5 -0
  6. package/dist/memory/factory/defaults.d.ts.map +1 -0
  7. package/dist/memory/factory/defaults.js +9 -0
  8. package/dist/memory/factory/defaults.js.map +1 -0
  9. package/dist/memory/factory/index.d.ts +117 -0
  10. package/dist/memory/factory/index.d.ts.map +1 -0
  11. package/dist/memory/factory/index.js +202 -0
  12. package/dist/memory/factory/index.js.map +1 -0
  13. package/dist/memory/factory/type.d.ts +29 -0
  14. package/dist/memory/factory/type.d.ts.map +1 -0
  15. package/dist/memory/factory/type.js +3 -0
  16. package/dist/memory/factory/type.js.map +1 -0
  17. package/dist/memory/types.d.ts +49 -0
  18. package/dist/memory/types.d.ts.map +1 -0
  19. package/dist/memory/types.js +3 -0
  20. package/dist/memory/types.js.map +1 -0
  21. package/dist/memory/v1/helper.d.ts +9 -0
  22. package/dist/memory/v1/helper.d.ts.map +1 -0
  23. package/dist/memory/v1/helper.js +84 -0
  24. package/dist/memory/v1/helper.js.map +1 -0
  25. package/dist/memory/v1/index.d.ts +88 -0
  26. package/dist/memory/v1/index.d.ts.map +1 -0
  27. package/dist/memory/v1/index.js +667 -0
  28. package/dist/memory/v1/index.js.map +1 -0
  29. package/dist/memory/v1/schema.d.ts +334 -0
  30. package/dist/memory/v1/schema.d.ts.map +1 -0
  31. package/dist/memory/v1/schema.js +159 -0
  32. package/dist/memory/v1/schema.js.map +1 -0
  33. package/dist/memory/v1/types.d.ts +28 -0
  34. package/dist/memory/v1/types.d.ts.map +1 -0
  35. package/dist/memory/v1/types.js +3 -0
  36. package/dist/memory/v1/types.js.map +1 -0
  37. package/package.json +54 -0
@@ -0,0 +1,667 @@
1
+ "use strict";
2
+ var __assign = (this && this.__assign) || function () {
3
+ __assign = Object.assign || function(t) {
4
+ for (var s, i = 1, n = arguments.length; i < n; i++) {
5
+ s = arguments[i];
6
+ for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p))
7
+ t[p] = s[p];
8
+ }
9
+ return t;
10
+ };
11
+ return __assign.apply(this, arguments);
12
+ };
13
+ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
14
+ function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
15
+ return new (P || (P = Promise))(function (resolve, reject) {
16
+ function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
17
+ function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
18
+ function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
19
+ step((generator = generator.apply(thisArg, _arguments || [])).next());
20
+ });
21
+ };
22
+ var __generator = (this && this.__generator) || function (thisArg, body) {
23
+ var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g = Object.create((typeof Iterator === "function" ? Iterator : Object).prototype);
24
+ return g.next = verb(0), g["throw"] = verb(1), g["return"] = verb(2), typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
25
+ function verb(n) { return function (v) { return step([n, v]); }; }
26
+ function step(op) {
27
+ if (f) throw new TypeError("Generator is already executing.");
28
+ while (g && (g = 0, op[0] && (_ = 0)), _) try {
29
+ if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
30
+ if (y = 0, t) op = [op[0] & 2, t.value];
31
+ switch (op[0]) {
32
+ case 0: case 1: t = op; break;
33
+ case 4: _.label++; return { value: op[1], done: false };
34
+ case 5: _.label++; y = op[1]; op = [0]; continue;
35
+ case 7: op = _.ops.pop(); _.trys.pop(); continue;
36
+ default:
37
+ if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
38
+ if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
39
+ if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
40
+ if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
41
+ if (t[2]) _.ops.pop();
42
+ _.trys.pop(); continue;
43
+ }
44
+ op = body.call(thisArg, _);
45
+ } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
46
+ if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
47
+ }
48
+ };
49
+ Object.defineProperty(exports, "__esModule", { value: true });
50
+ exports.PostgressMachineMemoryV1 = void 0;
51
+ var api_1 = require("@opentelemetry/api");
52
+ var arvo_core_1 = require("arvo-core");
53
+ var arvo_event_handler_1 = require("arvo-event-handler");
54
+ var pg_1 = require("pg");
55
+ var schema_1 = require("./schema");
56
+ /**
57
+ * PostgreSQL-backed implementation of IMachineMemory for distributed workflow state management.
58
+ *
59
+ * This class provides persistent storage for workflow instances using PostgreSQL with the following features:
60
+ * - Optimistic locking via version tracking to prevent concurrent state modifications
61
+ * - Distributed lock management with TTL-based expiration to prevent deadlocks
62
+ * - Hierarchical workflow tracking for parent-child relationship queries
63
+ * - Optional cleanup of completed workflows
64
+ * - Optional OpenTelemetry instrumentation for observability
65
+ *
66
+ * The implementation uses three database tables:
67
+ * - State table: Stores workflow data, versions, execution status, and metadata
68
+ * - Lock table: Manages distributed locks with automatic expiration
69
+ * - Hierarchy table: Tracks workflow parent-child relationships and root subjects
70
+ */
71
+ var PostgressMachineMemoryV1 = /** @class */ (function () {
72
+ function PostgressMachineMemoryV1(param) {
73
+ var _a, _b, _c, _d, _e, _f, _g, _h, _j, _k, _l, _m, _o, _p, _q, _r, _s, _t, _u, _v, _w, _x, _y, _z, _0, _1, _2, _3, _4, _5, _6;
74
+ this.tables = param.tables;
75
+ this.lockConfig = {
76
+ maxRetries: (_c = (_b = (_a = param.config) === null || _a === void 0 ? void 0 : _a.lockConfig) === null || _b === void 0 ? void 0 : _b.maxRetries) !== null && _c !== void 0 ? _c : 3,
77
+ initialDelayMs: (_f = (_e = (_d = param.config) === null || _d === void 0 ? void 0 : _d.lockConfig) === null || _e === void 0 ? void 0 : _e.initialDelayMs) !== null && _f !== void 0 ? _f : 100,
78
+ backoffExponent: (_j = (_h = (_g = param.config) === null || _g === void 0 ? void 0 : _g.lockConfig) === null || _h === void 0 ? void 0 : _h.backoffExponent) !== null && _j !== void 0 ? _j : 1.5,
79
+ ttlMs: (_m = (_l = (_k = param.config) === null || _k === void 0 ? void 0 : _k.lockConfig) === null || _l === void 0 ? void 0 : _l.ttlMs) !== null && _m !== void 0 ? _m : 120000,
80
+ };
81
+ this.enableCleanup = (_p = (_o = param.config) === null || _o === void 0 ? void 0 : _o.enableCleanup) !== null && _p !== void 0 ? _p : false;
82
+ this.enableOtel = (_r = (_q = param.config) === null || _q === void 0 ? void 0 : _q.enableOtel) !== null && _r !== void 0 ? _r : false;
83
+ var poolConfig;
84
+ if (param.config && 'connectionString' in param.config) {
85
+ poolConfig = {
86
+ connectionString: param.config.connectionString,
87
+ max: (_s = param.config.max) !== null && _s !== void 0 ? _s : 10,
88
+ idleTimeoutMillis: (_t = param.config.idleTimeoutMillis) !== null && _t !== void 0 ? _t : 30000,
89
+ connectionTimeoutMillis: (_u = param.config.connectionTimeoutMillis) !== null && _u !== void 0 ? _u : 5000,
90
+ statement_timeout: (_v = param.config.statementTimeoutMillis) !== null && _v !== void 0 ? _v : 30000,
91
+ query_timeout: (_w = param.config.queryTimeoutMillis) !== null && _w !== void 0 ? _w : 30000,
92
+ };
93
+ }
94
+ else {
95
+ var cfg = param.config;
96
+ poolConfig = {
97
+ host: (_x = cfg === null || cfg === void 0 ? void 0 : cfg.host) !== null && _x !== void 0 ? _x : 'localhost',
98
+ port: (_y = cfg === null || cfg === void 0 ? void 0 : cfg.port) !== null && _y !== void 0 ? _y : 5432,
99
+ user: (_z = cfg === null || cfg === void 0 ? void 0 : cfg.user) !== null && _z !== void 0 ? _z : 'postgres',
100
+ password: (_0 = cfg === null || cfg === void 0 ? void 0 : cfg.password) !== null && _0 !== void 0 ? _0 : 'postgres',
101
+ database: (_1 = cfg === null || cfg === void 0 ? void 0 : cfg.database) !== null && _1 !== void 0 ? _1 : 'postgres',
102
+ max: (_2 = cfg === null || cfg === void 0 ? void 0 : cfg.max) !== null && _2 !== void 0 ? _2 : 10,
103
+ idleTimeoutMillis: (_3 = cfg === null || cfg === void 0 ? void 0 : cfg.idleTimeoutMillis) !== null && _3 !== void 0 ? _3 : 30000,
104
+ connectionTimeoutMillis: (_4 = cfg === null || cfg === void 0 ? void 0 : cfg.connectionTimeoutMillis) !== null && _4 !== void 0 ? _4 : 5000,
105
+ statement_timeout: (_5 = cfg === null || cfg === void 0 ? void 0 : cfg.statementTimeoutMillis) !== null && _5 !== void 0 ? _5 : 30000,
106
+ query_timeout: (_6 = cfg === null || cfg === void 0 ? void 0 : cfg.queryTimeoutMillis) !== null && _6 !== void 0 ? _6 : 30000,
107
+ };
108
+ }
109
+ this.pool = new pg_1.Pool(poolConfig);
110
+ }
111
+ PostgressMachineMemoryV1.prototype.close = function () {
112
+ return __awaiter(this, void 0, void 0, function () {
113
+ return __generator(this, function (_a) {
114
+ switch (_a.label) {
115
+ case 0: return [4 /*yield*/, this.pool.end()];
116
+ case 1:
117
+ _a.sent();
118
+ return [2 /*return*/];
119
+ }
120
+ });
121
+ });
122
+ };
123
+ PostgressMachineMemoryV1.prototype.delay = function (ms) {
124
+ return __awaiter(this, void 0, void 0, function () {
125
+ return __generator(this, function (_a) {
126
+ return [2 /*return*/, new Promise(function (resolve) { return setTimeout(resolve, ms); })];
127
+ });
128
+ });
129
+ };
130
+ PostgressMachineMemoryV1.prototype.validateTableStructure = function () {
131
+ return __awaiter(this, void 0, void 0, function () {
132
+ var client;
133
+ return __generator(this, function (_a) {
134
+ switch (_a.label) {
135
+ case 0: return [4 /*yield*/, this.pool.connect()];
136
+ case 1:
137
+ client = _a.sent();
138
+ _a.label = 2;
139
+ case 2:
140
+ _a.trys.push([2, , 4, 5]);
141
+ return [4 /*yield*/, Promise.all([
142
+ (0, schema_1.validateTable)(client, this.tables.state, 'state'),
143
+ (0, schema_1.validateTable)(client, this.tables.lock, 'lock'),
144
+ (0, schema_1.validateTable)(client, this.tables.hierarchy, 'hierarchy'),
145
+ ])];
146
+ case 3:
147
+ _a.sent();
148
+ return [3 /*break*/, 5];
149
+ case 4:
150
+ client.release();
151
+ return [7 /*endfinally*/];
152
+ case 5: return [2 /*return*/];
153
+ }
154
+ });
155
+ });
156
+ };
157
+ PostgressMachineMemoryV1.prototype.otel = function (_a) {
158
+ return __awaiter(this, arguments, void 0, function (_b) {
159
+ var name = _b.name, fn = _b.fn;
160
+ return __generator(this, function (_c) {
161
+ switch (_c.label) {
162
+ case 0:
163
+ if (!!this.enableOtel) return [3 /*break*/, 2];
164
+ return [4 /*yield*/, fn()];
165
+ case 1: return [2 /*return*/, _c.sent()];
166
+ case 2: return [4 /*yield*/, arvo_core_1.ArvoOpenTelemetry.getInstance().startActiveSpan({
167
+ name: name,
168
+ disableSpanManagement: true,
169
+ fn: fn,
170
+ })];
171
+ case 3: return [2 /*return*/, _c.sent()];
172
+ }
173
+ });
174
+ });
175
+ };
176
+ PostgressMachineMemoryV1.prototype.read = function (id) {
177
+ return __awaiter(this, void 0, void 0, function () {
178
+ var _this = this;
179
+ return __generator(this, function (_a) {
180
+ switch (_a.label) {
181
+ case 0: return [4 /*yield*/, this.otel({
182
+ name: 'PostgresMachineMemory.v1.read',
183
+ fn: function (span) { return __awaiter(_this, void 0, void 0, function () {
184
+ var client, result, error_1;
185
+ var _a;
186
+ return __generator(this, function (_b) {
187
+ switch (_b.label) {
188
+ case 0:
189
+ span === null || span === void 0 ? void 0 : span.setStatus({ code: api_1.SpanStatusCode.OK });
190
+ span === null || span === void 0 ? void 0 : span.setAttribute('subject', id);
191
+ return [4 /*yield*/, this.pool.connect()];
192
+ case 1:
193
+ client = _b.sent();
194
+ _b.label = 2;
195
+ case 2:
196
+ _b.trys.push([2, 4, 5, 6]);
197
+ return [4 /*yield*/, client.query("SELECT data, version FROM ".concat(this.tables.state, " WHERE subject = $1"), [id])];
198
+ case 3:
199
+ result = _b.sent();
200
+ if (!result.rows.length) {
201
+ span === null || span === void 0 ? void 0 : span.setAttribute('available', 0);
202
+ return [2 /*return*/, null];
203
+ }
204
+ span === null || span === void 0 ? void 0 : span.setAttribute('available', 1);
205
+ return [2 /*return*/, __assign(__assign({}, ((_a = result.rows[0].data) !== null && _a !== void 0 ? _a : {})), { __postgres_version_counter_data_$$__: result.rows[0].version })];
206
+ case 4:
207
+ error_1 = _b.sent();
208
+ span === null || span === void 0 ? void 0 : span.setStatus({
209
+ code: api_1.SpanStatusCode.ERROR,
210
+ message: error_1.message,
211
+ });
212
+ throw error_1;
213
+ case 5:
214
+ client.release();
215
+ span === null || span === void 0 ? void 0 : span.end();
216
+ return [7 /*endfinally*/];
217
+ case 6: return [2 /*return*/];
218
+ }
219
+ });
220
+ }); },
221
+ })];
222
+ case 1: return [2 /*return*/, _a.sent()];
223
+ }
224
+ });
225
+ });
226
+ };
227
+ PostgressMachineMemoryV1.prototype.write = function (id_1, data_1, prevData_1, _a) {
228
+ return __awaiter(this, arguments, void 0, function (id, data, prevData, _b) {
229
+ var _this = this;
230
+ var source = _b.source, initiator = _b.initiator;
231
+ return __generator(this, function (_c) {
232
+ switch (_c.label) {
233
+ case 0: return [4 /*yield*/, this.otel({
234
+ name: 'PostgresMachineMemory.v1.write',
235
+ fn: function (span) { return __awaiter(_this, void 0, void 0, function () {
236
+ var client, resolvedExectionStatus, resolvedParentSubject, resolvedInitiator, rootSubject, parentResult, error_2, currentVersion, newVersion, result, error, error_3;
237
+ var _a, _b, _c, _d;
238
+ return __generator(this, function (_e) {
239
+ switch (_e.label) {
240
+ case 0:
241
+ span === null || span === void 0 ? void 0 : span.setStatus({ code: api_1.SpanStatusCode.OK });
242
+ span === null || span === void 0 ? void 0 : span.setAttribute('subject', id);
243
+ span === null || span === void 0 ? void 0 : span.setAttribute('isNew', prevData === null ? 1 : 0);
244
+ return [4 /*yield*/, this.pool.connect()];
245
+ case 1:
246
+ client = _e.sent();
247
+ resolvedExectionStatus = (_a = data.executionStatus) !== null && _a !== void 0 ? _a : 'unknown';
248
+ _e.label = 2;
249
+ case 2:
250
+ _e.trys.push([2, 15, 16, 17]);
251
+ if (!(prevData === null)) return [3 /*break*/, 13];
252
+ _e.label = 3;
253
+ case 3:
254
+ _e.trys.push([3, 11, , 13]);
255
+ return [4 /*yield*/, client.query('BEGIN')];
256
+ case 4:
257
+ _e.sent();
258
+ resolvedParentSubject = (_b = data.parentSubject) !== null && _b !== void 0 ? _b : null;
259
+ resolvedInitiator = arvo_event_handler_1.Materialized.isResolved(initiator) ? initiator.value : null;
260
+ return [4 /*yield*/, client.query("INSERT INTO ".concat(this.tables.state, " (subject, data, version, execution_status, parent_subject, initiator, source, created_at, updated_at)\n VALUES ($1, $2, 1, $3, $4, $5, $6, NOW(), NOW())"), [
261
+ id,
262
+ JSON.stringify(data),
263
+ resolvedExectionStatus,
264
+ resolvedParentSubject,
265
+ resolvedInitiator,
266
+ source,
267
+ ])];
268
+ case 5:
269
+ _e.sent();
270
+ rootSubject = void 0;
271
+ if (!(resolvedParentSubject === null)) return [3 /*break*/, 6];
272
+ rootSubject = id;
273
+ return [3 /*break*/, 8];
274
+ case 6: return [4 /*yield*/, client.query("SELECT root_subject FROM ".concat(this.tables.hierarchy, " WHERE subject = $1"), [resolvedParentSubject])];
275
+ case 7:
276
+ parentResult = _e.sent();
277
+ rootSubject = (_d = (_c = parentResult.rows[0]) === null || _c === void 0 ? void 0 : _c.root_subject) !== null && _d !== void 0 ? _d : id;
278
+ _e.label = 8;
279
+ case 8: return [4 /*yield*/, client.query("INSERT INTO ".concat(this.tables.hierarchy, " (subject, parent_subject, root_subject, created_at)\n VALUES ($1, $2, $3, NOW())"), [id, resolvedParentSubject, rootSubject])];
280
+ case 9:
281
+ _e.sent();
282
+ return [4 /*yield*/, client.query('COMMIT')];
283
+ case 10:
284
+ _e.sent();
285
+ return [2 /*return*/];
286
+ case 11:
287
+ error_2 = _e.sent();
288
+ return [4 /*yield*/, client.query('ROLLBACK')];
289
+ case 12:
290
+ _e.sent();
291
+ span === null || span === void 0 ? void 0 : span.setStatus({
292
+ code: api_1.SpanStatusCode.ERROR,
293
+ message: error_2.message,
294
+ });
295
+ throw error_2;
296
+ case 13:
297
+ currentVersion = prevData.__postgres_version_counter_data_$$__;
298
+ newVersion = currentVersion + 1;
299
+ span === null || span === void 0 ? void 0 : span.setAttribute('version', newVersion);
300
+ return [4 /*yield*/, client.query("UPDATE ".concat(this.tables.state, "\n SET data = $1, version = $2, execution_status = $3, updated_at = NOW()\n WHERE subject = $4 AND version = $5"), [JSON.stringify(data), newVersion, resolvedExectionStatus, id, currentVersion])];
301
+ case 14:
302
+ result = _e.sent();
303
+ if (result.rowCount === 0) {
304
+ error = new Error("Data is corrupted due to version mismatch for subject '".concat(id, "'. Expected version ").concat(currentVersion, " but state has been modified."));
305
+ span === null || span === void 0 ? void 0 : span.setStatus({
306
+ code: api_1.SpanStatusCode.ERROR,
307
+ message: error.message,
308
+ });
309
+ throw error;
310
+ }
311
+ return [3 /*break*/, 17];
312
+ case 15:
313
+ error_3 = _e.sent();
314
+ span === null || span === void 0 ? void 0 : span.setStatus({
315
+ code: api_1.SpanStatusCode.ERROR,
316
+ message: error_3.message,
317
+ });
318
+ throw error_3;
319
+ case 16:
320
+ client.release();
321
+ span === null || span === void 0 ? void 0 : span.end();
322
+ return [7 /*endfinally*/];
323
+ case 17: return [2 /*return*/];
324
+ }
325
+ });
326
+ }); },
327
+ })];
328
+ case 1: return [2 /*return*/, _c.sent()];
329
+ }
330
+ });
331
+ });
332
+ };
333
+ PostgressMachineMemoryV1.prototype.lock = function (id) {
334
+ return __awaiter(this, void 0, void 0, function () {
335
+ var _this = this;
336
+ return __generator(this, function (_a) {
337
+ switch (_a.label) {
338
+ case 0: return [4 /*yield*/, this.otel({
339
+ name: 'PostgresMachineMemory.v1.lock',
340
+ fn: function (span) { return __awaiter(_this, void 0, void 0, function () {
341
+ var client, attempt, result, delayMs, error_4, error_5;
342
+ return __generator(this, function (_a) {
343
+ switch (_a.label) {
344
+ case 0:
345
+ span === null || span === void 0 ? void 0 : span.setStatus({ code: api_1.SpanStatusCode.OK });
346
+ span === null || span === void 0 ? void 0 : span.setAttribute('subject', id);
347
+ return [4 /*yield*/, this.pool.connect()];
348
+ case 1:
349
+ client = _a.sent();
350
+ _a.label = 2;
351
+ case 2:
352
+ _a.trys.push([2, 11, 12, 13]);
353
+ attempt = 0;
354
+ _a.label = 3;
355
+ case 3:
356
+ if (!(attempt <= this.lockConfig.maxRetries)) return [3 /*break*/, 10];
357
+ _a.label = 4;
358
+ case 4:
359
+ _a.trys.push([4, 8, , 9]);
360
+ return [4 /*yield*/, client.query("WITH arvo_lock_time AS (SELECT NOW() as now)\n INSERT INTO ".concat(this.tables.lock, " (subject, locked_at, expires_at, created_at)\n SELECT $1, now, now + ($2 || ' milliseconds')::INTERVAL, now FROM arvo_lock_time\n ON CONFLICT (subject) \n DO UPDATE SET \n locked_at = (SELECT now FROM arvo_lock_time), \n expires_at = (SELECT now FROM arvo_lock_time) + ($2 || ' milliseconds')::INTERVAL\n WHERE ").concat(this.tables.lock, ".expires_at < (SELECT now FROM arvo_lock_time)\n RETURNING subject"), [id, this.lockConfig.ttlMs])];
361
+ case 5:
362
+ result = _a.sent();
363
+ if (result.rowCount && result.rowCount > 0) {
364
+ span === null || span === void 0 ? void 0 : span.setAttribute('acquired', 1);
365
+ span === null || span === void 0 ? void 0 : span.setAttribute('attempts', attempt + 1);
366
+ return [2 /*return*/, true];
367
+ }
368
+ if (!(attempt < this.lockConfig.maxRetries)) return [3 /*break*/, 7];
369
+ delayMs = this.lockConfig.initialDelayMs * Math.pow(this.lockConfig.backoffExponent, attempt);
370
+ return [4 /*yield*/, this.delay(delayMs)];
371
+ case 6:
372
+ _a.sent();
373
+ _a.label = 7;
374
+ case 7: return [3 /*break*/, 9];
375
+ case 8:
376
+ error_4 = _a.sent();
377
+ span === null || span === void 0 ? void 0 : span.setStatus({
378
+ code: api_1.SpanStatusCode.ERROR,
379
+ message: error_4.message,
380
+ });
381
+ throw error_4;
382
+ case 9:
383
+ attempt++;
384
+ return [3 /*break*/, 3];
385
+ case 10:
386
+ span === null || span === void 0 ? void 0 : span.setAttribute('acquired', 0);
387
+ span === null || span === void 0 ? void 0 : span.setAttribute('attempts', this.lockConfig.maxRetries + 1);
388
+ return [2 /*return*/, false];
389
+ case 11:
390
+ error_5 = _a.sent();
391
+ span === null || span === void 0 ? void 0 : span.setStatus({
392
+ code: api_1.SpanStatusCode.ERROR,
393
+ message: error_5.message,
394
+ });
395
+ throw error_5;
396
+ case 12:
397
+ client.release();
398
+ span === null || span === void 0 ? void 0 : span.end();
399
+ return [7 /*endfinally*/];
400
+ case 13: return [2 /*return*/];
401
+ }
402
+ });
403
+ }); },
404
+ })];
405
+ case 1: return [2 /*return*/, _a.sent()];
406
+ }
407
+ });
408
+ });
409
+ };
410
+ PostgressMachineMemoryV1.prototype.unlock = function (id) {
411
+ return __awaiter(this, void 0, void 0, function () {
412
+ var _this = this;
413
+ return __generator(this, function (_a) {
414
+ switch (_a.label) {
415
+ case 0: return [4 /*yield*/, this.otel({
416
+ name: 'PostgresMachineMemory.v1.unlock',
417
+ fn: function (span) { return __awaiter(_this, void 0, void 0, function () {
418
+ var client, error_6;
419
+ return __generator(this, function (_a) {
420
+ switch (_a.label) {
421
+ case 0:
422
+ span === null || span === void 0 ? void 0 : span.setStatus({ code: api_1.SpanStatusCode.OK });
423
+ span === null || span === void 0 ? void 0 : span.setAttribute('subject', id);
424
+ return [4 /*yield*/, this.pool.connect()];
425
+ case 1:
426
+ client = _a.sent();
427
+ _a.label = 2;
428
+ case 2:
429
+ _a.trys.push([2, 4, 5, 6]);
430
+ return [4 /*yield*/, client.query("DELETE FROM ".concat(this.tables.lock, " WHERE subject = $1"), [id])];
431
+ case 3:
432
+ _a.sent();
433
+ return [2 /*return*/, true];
434
+ case 4:
435
+ error_6 = _a.sent();
436
+ span === null || span === void 0 ? void 0 : span.setStatus({
437
+ code: api_1.SpanStatusCode.ERROR,
438
+ message: error_6.message,
439
+ });
440
+ return [2 /*return*/, true];
441
+ case 5:
442
+ client.release();
443
+ span === null || span === void 0 ? void 0 : span.end();
444
+ return [7 /*endfinally*/];
445
+ case 6: return [2 /*return*/];
446
+ }
447
+ });
448
+ }); },
449
+ })];
450
+ case 1: return [2 /*return*/, _a.sent()];
451
+ }
452
+ });
453
+ });
454
+ };
455
+ PostgressMachineMemoryV1.prototype.cleanup = function (id) {
456
+ return __awaiter(this, void 0, void 0, function () {
457
+ var _this = this;
458
+ return __generator(this, function (_a) {
459
+ switch (_a.label) {
460
+ case 0: return [4 /*yield*/, this.otel({
461
+ name: 'PostgresMachineMemory.v1.cleanup',
462
+ fn: function (span) { return __awaiter(_this, void 0, void 0, function () {
463
+ var client, error_7;
464
+ return __generator(this, function (_a) {
465
+ switch (_a.label) {
466
+ case 0:
467
+ span === null || span === void 0 ? void 0 : span.setStatus({ code: api_1.SpanStatusCode.OK });
468
+ span === null || span === void 0 ? void 0 : span.setAttribute('subject', id);
469
+ if (!this.enableCleanup) {
470
+ span === null || span === void 0 ? void 0 : span.setAttribute('skipped', 1);
471
+ span === null || span === void 0 ? void 0 : span.end();
472
+ return [2 /*return*/];
473
+ }
474
+ span === null || span === void 0 ? void 0 : span.setAttribute('skipped', 0);
475
+ return [4 /*yield*/, this.pool.connect()];
476
+ case 1:
477
+ client = _a.sent();
478
+ _a.label = 2;
479
+ case 2:
480
+ _a.trys.push([2, 6, 8, 9]);
481
+ return [4 /*yield*/, client.query('BEGIN')];
482
+ case 3:
483
+ _a.sent();
484
+ return [4 /*yield*/, Promise.all([
485
+ client.query("DELETE FROM ".concat(this.tables.state, " WHERE subject = $1"), [id]),
486
+ client.query("DELETE FROM ".concat(this.tables.lock, " WHERE subject = $1"), [id]),
487
+ client.query("DELETE FROM ".concat(this.tables.hierarchy, " WHERE subject = $1"), [id]),
488
+ ])];
489
+ case 4:
490
+ _a.sent();
491
+ return [4 /*yield*/, client.query('COMMIT')];
492
+ case 5:
493
+ _a.sent();
494
+ return [3 /*break*/, 9];
495
+ case 6:
496
+ error_7 = _a.sent();
497
+ return [4 /*yield*/, client.query('ROLLBACK')];
498
+ case 7:
499
+ _a.sent();
500
+ span === null || span === void 0 ? void 0 : span.setStatus({
501
+ code: api_1.SpanStatusCode.ERROR,
502
+ message: error_7.message,
503
+ });
504
+ throw error_7;
505
+ case 8:
506
+ client.release();
507
+ span === null || span === void 0 ? void 0 : span.end();
508
+ return [7 /*endfinally*/];
509
+ case 9: return [2 /*return*/];
510
+ }
511
+ });
512
+ }); },
513
+ })];
514
+ case 1: return [2 /*return*/, _a.sent()];
515
+ }
516
+ });
517
+ });
518
+ };
519
+ /**
520
+ * Retrieves all child workflow subjects belonging to a specific root workflow.
521
+ *
522
+ * This method queries the hierarchy table to find all workflows that are descendants
523
+ * of the specified root workflow. The root subject itself is excluded from the results.
524
+ *
525
+ * @param rootSubject - The subject identifier of the root workflow
526
+ * @returns Array of subject identifiers for all child workflows (excluding the root itself)
527
+ *
528
+ * @example
529
+ * ```typescript
530
+ * const subject = 'some_string'
531
+ * const children = await memory.getSubjectsByRoot(subject);
532
+ * console.log(`Found ${children.length} child workflows subjects`);
533
+ * ```
534
+ */
535
+ PostgressMachineMemoryV1.prototype.getSubjectsByRoot = function (rootSubject) {
536
+ return __awaiter(this, void 0, void 0, function () {
537
+ var _this = this;
538
+ return __generator(this, function (_a) {
539
+ switch (_a.label) {
540
+ case 0: return [4 /*yield*/, this.otel({
541
+ name: 'PostgresMachineMemory.v1.getSubjectsByRoot',
542
+ fn: function (span) { return __awaiter(_this, void 0, void 0, function () {
543
+ var client, result, subjects, error_8;
544
+ return __generator(this, function (_a) {
545
+ switch (_a.label) {
546
+ case 0:
547
+ span === null || span === void 0 ? void 0 : span.setStatus({ code: api_1.SpanStatusCode.OK });
548
+ span === null || span === void 0 ? void 0 : span.setAttribute('rootSubject', rootSubject);
549
+ return [4 /*yield*/, this.pool.connect()];
550
+ case 1:
551
+ client = _a.sent();
552
+ _a.label = 2;
553
+ case 2:
554
+ _a.trys.push([2, 4, 5, 6]);
555
+ return [4 /*yield*/, client.query("SELECT subject FROM ".concat(this.tables.hierarchy, " WHERE root_subject = $1"), [rootSubject])];
556
+ case 3:
557
+ result = _a.sent();
558
+ subjects = result.rows
559
+ .map(function (row) { return row.subject; })
560
+ .filter(function (item) { return item !== rootSubject; });
561
+ span === null || span === void 0 ? void 0 : span.setAttribute('count', subjects.length);
562
+ return [2 /*return*/, subjects];
563
+ case 4:
564
+ error_8 = _a.sent();
565
+ span === null || span === void 0 ? void 0 : span.setStatus({
566
+ code: api_1.SpanStatusCode.ERROR,
567
+ message: error_8.message,
568
+ });
569
+ throw error_8;
570
+ case 5:
571
+ client.release();
572
+ span === null || span === void 0 ? void 0 : span.end();
573
+ return [7 /*endfinally*/];
574
+ case 6: return [2 /*return*/];
575
+ }
576
+ });
577
+ }); },
578
+ })];
579
+ case 1: return [2 /*return*/, _a.sent()];
580
+ }
581
+ });
582
+ });
583
+ };
584
+ /**
585
+ * Retrieves the root workflow subject for a given workflow instance.
586
+ *
587
+ * This method queries the hierarchy table to find the root workflow subject
588
+ * associated with the specified workflow. Every workflow in the hierarchy has
589
+ * a root_subject field that points to the top-level workflow that initiated
590
+ * the entire workflow tree.
591
+ *
592
+ * @param subject - The subject identifier of the workflow to look up
593
+ * @returns The root subject identifier, or null if the subject is not found in the hierarchy table
594
+ *
595
+ * @example
596
+ * ```typescript
597
+ * const subject = 'some_string'
598
+ * const root = await memory.getRootSubject(subject);
599
+ * if (root) {
600
+ * console.log(`Root workflow subject: ${root}`);
601
+ * if (root === subject) {
602
+ * console.log('This is a root workflow');
603
+ * } else {
604
+ * console.log('This is a child workflow');
605
+ * }
606
+ * } else {
607
+ * console.log('Workflow not found in hierarchy');
608
+ * }
609
+ * ```
610
+ */
611
+ PostgressMachineMemoryV1.prototype.getRootSubject = function (subject) {
612
+ return __awaiter(this, void 0, void 0, function () {
613
+ var _this = this;
614
+ return __generator(this, function (_a) {
615
+ switch (_a.label) {
616
+ case 0: return [4 /*yield*/, this.otel({
617
+ name: 'PostgresMachineMemory.v1.getRootSubject',
618
+ fn: function (span) { return __awaiter(_this, void 0, void 0, function () {
619
+ var client, result, rootSubject, error_9;
620
+ return __generator(this, function (_a) {
621
+ switch (_a.label) {
622
+ case 0:
623
+ span === null || span === void 0 ? void 0 : span.setStatus({ code: api_1.SpanStatusCode.OK });
624
+ span === null || span === void 0 ? void 0 : span.setAttribute('subject', subject);
625
+ return [4 /*yield*/, this.pool.connect()];
626
+ case 1:
627
+ client = _a.sent();
628
+ _a.label = 2;
629
+ case 2:
630
+ _a.trys.push([2, 4, 5, 6]);
631
+ return [4 /*yield*/, client.query("SELECT root_subject FROM ".concat(this.tables.hierarchy, " WHERE subject = $1"), [subject])];
632
+ case 3:
633
+ result = _a.sent();
634
+ if (!result.rows.length) {
635
+ span === null || span === void 0 ? void 0 : span.setAttribute('found', 0);
636
+ return [2 /*return*/, null];
637
+ }
638
+ rootSubject = result.rows[0].root_subject;
639
+ span === null || span === void 0 ? void 0 : span.setAttribute('found', 1);
640
+ span === null || span === void 0 ? void 0 : span.setAttribute('isRoot', 0);
641
+ span === null || span === void 0 ? void 0 : span.setAttribute('rootSubject', rootSubject);
642
+ return [2 /*return*/, rootSubject];
643
+ case 4:
644
+ error_9 = _a.sent();
645
+ span === null || span === void 0 ? void 0 : span.setStatus({
646
+ code: api_1.SpanStatusCode.ERROR,
647
+ message: error_9.message,
648
+ });
649
+ throw error_9;
650
+ case 5:
651
+ client.release();
652
+ span === null || span === void 0 ? void 0 : span.end();
653
+ return [7 /*endfinally*/];
654
+ case 6: return [2 /*return*/];
655
+ }
656
+ });
657
+ }); },
658
+ })];
659
+ case 1: return [2 /*return*/, _a.sent()];
660
+ }
661
+ });
662
+ });
663
+ };
664
+ return PostgressMachineMemoryV1;
665
+ }());
666
+ exports.PostgressMachineMemoryV1 = PostgressMachineMemoryV1;
667
+ //# sourceMappingURL=index.js.map