@dbos-inc/dbos-enterprise 5.5.1-preview → 5.5.3-preview

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.
@@ -0,0 +1,278 @@
1
+ // Copyright (c) 2026 DBOS, Inc. All rights reserved.
2
+ //
3
+ // This file is part of Transact Enterprise, proprietary software licensed under the
4
+ // DBOS Conductor Software License: https://www.dbos.dev/conductor-license
5
+ // You may not use, copy, modify, or distribute this file except as that license permits.
6
+ // Disabling or circumventing the entitlement checks in @dbos-inc/dbos-sdk's src/enterprise.ts
7
+ // that gate it is a material breach of that license.
8
+ "use strict";
9
+ Object.defineProperty(exports, "__esModule", { value: true });
10
+ exports.collectExternalObjects = exports.ExternalStorage = exports.keySegment = exports.COLLECT_BATCH_SIZE = exports.REF_VERSION = void 0;
11
+ const node_crypto_1 = require("node:crypto");
12
+ const context_1 = require("@dbos-inc/dbos-sdk/internal/context");
13
+ const error_1 = require("@dbos-inc/dbos-sdk/internal/error");
14
+ const serialization_1 = require("@dbos-inc/dbos-sdk/internal/serialization");
15
+ const system_database_1 = require("@dbos-inc/dbos-sdk/internal/system_database");
16
+ exports.REF_VERSION = 1;
17
+ const UTF8 = 'utf8';
18
+ const RAW = 'raw';
19
+ const BYTES = 'bytes';
20
+ exports.COLLECT_BATCH_SIZE = 1000;
21
+ const KEY_SEGMENT = '[A-Za-z0-9][A-Za-z0-9._=-]*';
22
+ const KEY = new RegExp(`^${KEY_SEGMENT}(/${KEY_SEGMENT})*$`);
23
+ const KEY_MAX_LENGTH = 512;
24
+ function keySegment(text) {
25
+ return encodeURIComponent(text).replace(/[!'()*.]/g, (c) => `%${c.charCodeAt(0).toString(16).toUpperCase()}`);
26
+ }
27
+ exports.keySegment = keySegment;
28
+ function sha256(data) {
29
+ return (0, node_crypto_1.createHash)('sha256').update(data).digest('hex');
30
+ }
31
+ function compareCodeUnits(a, b) {
32
+ return a < b ? -1 : a > b ? 1 : 0;
33
+ }
34
+ async function callStore(store, key, operation, call) {
35
+ try {
36
+ return await call();
37
+ }
38
+ catch (e) {
39
+ throw new error_1.DBOSExternalStoreError(store.storeID, key, operation, e instanceof Error ? e.message : String(e), e);
40
+ }
41
+ }
42
+ class ExternalStorage {
43
+ #sysdb;
44
+ #stores;
45
+ #serializer;
46
+ #checkCallerOwner;
47
+ constructor(sysdb, options) {
48
+ if (options.stores.length === 0) {
49
+ throw new error_1.DBOSError('ExternalStorage needs at least one store');
50
+ }
51
+ this.#sysdb = sysdb;
52
+ this.#stores = new Map(options.stores.map((store) => [store.storeID, store]));
53
+ this.#serializer = options.serializer;
54
+ this.#checkCallerOwner = options.checkCallerOwner ?? false;
55
+ }
56
+ get stores() {
57
+ return [...this.#stores.values()];
58
+ }
59
+ #storeNamed(storeID) {
60
+ if (storeID === undefined) {
61
+ if (this.#stores.size > 1) {
62
+ throw new error_1.DBOSError(`storeExternalObject must specify a storeID when there are multiple external stores: ${[...this.#stores.keys()].join(', ')}`);
63
+ }
64
+ return [...this.#stores.values()][0];
65
+ }
66
+ const store = this.#stores.get(storeID);
67
+ if (store === undefined) {
68
+ throw new error_1.DBOSExternalStoreNotConfiguredError(storeID, [...this.#stores.keys()]);
69
+ }
70
+ return store;
71
+ }
72
+ async #prepare(store, value, options) {
73
+ const { key, ownerWorkflowID } = options;
74
+ if (key !== undefined && (key.length > KEY_MAX_LENGTH || !KEY.test(key))) {
75
+ throw new error_1.DBOSError(`Invalid external object key ${JSON.stringify(key)}: use up to ${KEY_MAX_LENGTH} characters in '/'-separated segments of letters, digits, '.', '_', '=' or '-', each starting with a letter or digit`);
76
+ }
77
+ const { data, digest, serialization, encoding } = await this.#encode(value, options.serializationType);
78
+ const ownerValues = this.#sysdb.wfValues(ownerWorkflowID);
79
+ const shardKey = ownerValues.shard_key;
80
+ let objectKey = (0, node_crypto_1.randomUUID)();
81
+ if (key !== undefined) {
82
+ objectKey = `${keySegment(ownerWorkflowID)}/${key}`;
83
+ if (shardKey !== undefined) {
84
+ objectKey = `${keySegment(shardKey)}/${objectKey}`;
85
+ }
86
+ }
87
+ await this.#claim(store, objectKey, ownerWorkflowID, ownerValues);
88
+ const ref = {
89
+ version: exports.REF_VERSION,
90
+ store: store.storeID,
91
+ key: objectKey,
92
+ size: data.length,
93
+ sha256: digest,
94
+ serialization,
95
+ encoding,
96
+ };
97
+ return { data, ref };
98
+ }
99
+ async #encode(value, serializationType) {
100
+ if (value instanceof Uint8Array) {
101
+ return { data: value, digest: sha256(value), serialization: BYTES, encoding: RAW };
102
+ }
103
+ if (value instanceof ArrayBuffer || value instanceof SharedArrayBuffer || value instanceof DataView) {
104
+ throw new error_1.DBOSError(`Cannot store a ${value.constructor.name} as an external object: store a Buffer or Uint8Array view of its bytes`);
105
+ }
106
+ const { serializedValue, serialization } = await (0, serialization_1.serializeValue)(value, this.#serializer, serializationType);
107
+ if (serializedValue === null || serialization === null) {
108
+ throw new error_1.DBOSError(`Serializer ${this.#serializer.name()} produced no output for an external object`);
109
+ }
110
+ const data = Buffer.from(serializedValue, 'utf8');
111
+ return { data, digest: sha256(data), serialization, encoding: UTF8 };
112
+ }
113
+ #callerOwner() {
114
+ const workflowID = (0, context_1.getCurrentContextStore)()?.workflowId;
115
+ if (!this.#checkCallerOwner || workflowID === undefined) {
116
+ return undefined;
117
+ }
118
+ const ownerXid = (0, context_1.currentOwnerXid)(workflowID);
119
+ return ownerXid === undefined ? undefined : { workflowID, ownerXid };
120
+ }
121
+ async #claim(store, objectKey, ownerWorkflowID, ownerValues) {
122
+ const sysdb = this.#sysdb;
123
+ const table = `"${sysdb.schemaName}".external_objects`;
124
+ const shardKey = ownerValues.shard_key;
125
+ const caller = this.#callerOwner();
126
+ await (0, system_database_1.withDbRetry)(async () => {
127
+ const client = await sysdb.connect();
128
+ try {
129
+ await sysdb.inTransaction(client, async () => {
130
+ if (caller !== undefined && shardKey === undefined) {
131
+ await sysdb.checkOwner(client, caller.workflowID, caller.ownerXid);
132
+ }
133
+ for (;;) {
134
+ const values = {
135
+ ...ownerValues,
136
+ object_key: objectKey,
137
+ store_id: store.storeID,
138
+ workflow_uuid: ownerWorkflowID,
139
+ created_at: Date.now(),
140
+ };
141
+ const columns = Object.keys(values);
142
+ const { rows: inserted } = await client.query(`INSERT INTO ${table} (${columns.join(', ')})
143
+ VALUES (${columns.map((_, i) => `$${i + 1}`).join(', ')})
144
+ ON CONFLICT (${sysdb.keyConflict('store_id', 'object_key')}) DO NOTHING
145
+ RETURNING object_key`, Object.values(values));
146
+ if (inserted.length > 0) {
147
+ return;
148
+ }
149
+ const params = [Date.now(), store.storeID, objectKey];
150
+ const keyed = shardKey === undefined ? '' : ` AND ${sysdb.keyIn(undefined, [shardKey], params)}`;
151
+ const { rows: restamped } = await client.query(`UPDATE ${table} SET created_at = $1 WHERE store_id = $2 AND object_key = $3${keyed} RETURNING object_key`, params);
152
+ if (restamped.length > 0) {
153
+ return;
154
+ }
155
+ }
156
+ });
157
+ }
158
+ finally {
159
+ client.release();
160
+ }
161
+ });
162
+ if (caller !== undefined && shardKey !== undefined) {
163
+ await (0, system_database_1.withDbRetry)(() => sysdb.ownKey(caller.workflowID, undefined, async () => {
164
+ const client = await sysdb.connect();
165
+ try {
166
+ await sysdb.inTransaction(client, () => sysdb.checkOwner(client, caller.workflowID, caller.ownerXid));
167
+ }
168
+ finally {
169
+ client.release();
170
+ }
171
+ }));
172
+ }
173
+ }
174
+ async store(value, options) {
175
+ const store = this.#storeNamed(options.storeID);
176
+ const { data, ref } = await this.#prepare(store, value, options);
177
+ await callStore(store, ref.key, 'store', () => store.put(ref.key, data));
178
+ return ref;
179
+ }
180
+ #checkRef(ref) {
181
+ const store = this.#stores.get(ref.store);
182
+ if (store === undefined) {
183
+ throw new error_1.DBOSExternalStoreNotConfiguredError(ref.store, [...this.#stores.keys()]);
184
+ }
185
+ if (ref.version !== exports.REF_VERSION) {
186
+ throw new error_1.DBOSError(`Unsupported external object ref version ${ref.version}; upgrade DBOS to read it`);
187
+ }
188
+ return store;
189
+ }
190
+ async #decode(ref, data) {
191
+ if (data.length !== ref.size) {
192
+ throw new error_1.DBOSExternalObjectIntegrityError(ref.store, ref.key, `expected ${ref.size} bytes, found ${data.length}`);
193
+ }
194
+ if (sha256(data) !== ref.sha256) {
195
+ throw new error_1.DBOSExternalObjectIntegrityError(ref.store, ref.key, 'sha256 mismatch');
196
+ }
197
+ if (ref.encoding === RAW && ref.serialization === BYTES) {
198
+ return Buffer.from(data.buffer, data.byteOffset, data.byteLength);
199
+ }
200
+ if (ref.encoding !== UTF8) {
201
+ throw new error_1.DBOSError(`Unsupported external object encoding ${ref.encoding} (serialization ${ref.serialization}); ` +
202
+ 'store the object as bytes or with portable serialization to read it from TypeScript');
203
+ }
204
+ const text = Buffer.from(data.buffer, data.byteOffset, data.byteLength).toString('utf8');
205
+ return await (0, serialization_1.deserializeValue)(text, ref.serialization, this.#serializer);
206
+ }
207
+ async get(ref) {
208
+ const store = this.#checkRef(ref);
209
+ const data = await callStore(store, ref.key, 'load', () => store.get(ref.key));
210
+ if (data === undefined) {
211
+ throw new error_1.DBOSExternalObjectMissingError(ref.store, ref.key);
212
+ }
213
+ return await this.#decode(ref, data);
214
+ }
215
+ async collect(cutoffEpochMs) {
216
+ let deleted = 0;
217
+ for (const store of this.#stores.values()) {
218
+ deleted += await collectExternalObjects(this.#sysdb, store, cutoffEpochMs);
219
+ }
220
+ return deleted;
221
+ }
222
+ }
223
+ exports.ExternalStorage = ExternalStorage;
224
+ async function collectExternalObjects(sysdb, store, cutoffEpochMs, batchSize = exports.COLLECT_BATCH_SIZE) {
225
+ const schema = `"${sysdb.schemaName}"`;
226
+ const collectable = `eo.created_at < $2 AND NOT EXISTS (
227
+ SELECT 1 FROM ${schema}.workflow_status ws WHERE ${sysdb.wfJoin('ws', 'eo')})`;
228
+ const keyColumn = sysdb.keyColumn('eo');
229
+ const objectKey = sysdb.sharded ? 'eo.object_key COLLATE "C"' : 'eo.object_key';
230
+ let deleted = 0;
231
+ let after = [-1, ''];
232
+ for (;;) {
233
+ const { rows: read } = await sysdb.pool.query(`SELECT eo.created_at, eo.object_key, ${keyColumn ?? 'NULL'} AS shard_key
234
+ FROM ${schema}.external_objects eo
235
+ WHERE eo.store_id = $1 AND ${collectable}
236
+ AND (eo.created_at, ${objectKey}) > ($3::bigint, $4::text)
237
+ ORDER BY eo.created_at, ${objectKey}
238
+ LIMIT $5`, [store.storeID, cutoffEpochMs, after[0], after[1], batchSize]);
239
+ const exhausted = read.length < batchSize;
240
+ let rows = read.map((row) => ({ ...row, created_at: Number(row.created_at) }));
241
+ if (sysdb.sharded) {
242
+ rows = rows.sort((a, b) => a.created_at - b.created_at || compareCodeUnits(a.object_key, b.object_key));
243
+ rows = rows.slice(0, batchSize);
244
+ }
245
+ if (rows.length === 0) {
246
+ return deleted;
247
+ }
248
+ after = [rows[rows.length - 1].created_at, rows[rows.length - 1].object_key];
249
+ const keys = rows.map((row) => row.object_key);
250
+ try {
251
+ await callStore(store, keys[0], 'delete', () => store.delete(keys));
252
+ }
253
+ catch (e) {
254
+ if (!(e instanceof error_1.DBOSExternalStoreError))
255
+ throw e;
256
+ sysdb.logger.warn(`External store ${store.storeID} failed to delete ${keys.length} objects, ending this collection pass: ${e.message}`);
257
+ return deleted;
258
+ }
259
+ const byShard = new Map();
260
+ for (const row of rows) {
261
+ const group = byShard.get(row.shard_key) ?? [];
262
+ group.push(row.object_key);
263
+ byShard.set(row.shard_key, group);
264
+ }
265
+ for (const [shardKey, objectKeys] of byShard) {
266
+ const params = [store.storeID, cutoffEpochMs, objectKeys];
267
+ const keyed = shardKey === null ? '' : ` AND ${sysdb.keyIn('eo', [shardKey], params)}`;
268
+ const result = await sysdb.pool.query(`DELETE FROM ${schema}.external_objects eo
269
+ WHERE eo.store_id = $1 AND eo.object_key = ANY($3::text[]) AND ${collectable}${keyed}`, params);
270
+ deleted += result.rowCount ?? 0;
271
+ }
272
+ if (exhausted) {
273
+ return deleted;
274
+ }
275
+ }
276
+ }
277
+ exports.collectExternalObjects = collectExternalObjects;
278
+ //# sourceMappingURL=external_storage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external_storage.js","sourceRoot":"","sources":["../../src/external_storage.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ // Copyright (c) 2026 DBOS, Inc. All rights reserved.
2
+ //
3
+ // This file is part of Transact Enterprise, proprietary software licensed under the
4
+ // DBOS Conductor Software License: https://www.dbos.dev/conductor-license
5
+ // You may not use, copy, modify, or distribute this file except as that license permits.
6
+ // Disabling or circumventing the entitlement checks in @dbos-inc/dbos-sdk's src/enterprise.ts
7
+ // that gate it is a material breach of that license.
8
+ import type { ExternalStore } from '@dbos-inc/dbos-sdk/internal/external_storage';
9
+ export declare class FilesystemExternalStore implements ExternalStore {
10
+ #private;
11
+ readonly storeID: string;
12
+ constructor(root: string, options?: {
13
+ storeID?: string;
14
+ });
15
+ filePath(key: string): string;
16
+ put(key: string, data: Uint8Array): Promise<void>;
17
+ get(key: string): Promise<Uint8Array | undefined>;
18
+ delete(keys: string[]): Promise<void>;
19
+ }
20
+ export interface S3ClientLike {
21
+ send(command: unknown, options?: unknown): Promise<unknown>;
22
+ readonly config: unknown;
23
+ }
24
+ export declare class S3ExternalStore implements ExternalStore {
25
+ #private;
26
+ static deleteBatchSize: number;
27
+ readonly storeID: string;
28
+ constructor(client: S3ClientLike, bucket: string, options?: {
29
+ prefix?: string;
30
+ storeID?: string;
31
+ });
32
+ put(key: string, data: Uint8Array): Promise<void>;
33
+ get(key: string): Promise<Uint8Array | undefined>;
34
+ delete(keys: string[]): Promise<void>;
35
+ }
36
+ //# sourceMappingURL=external_stores.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external_stores.d.ts","sourceRoot":"","sources":["../../src/external_stores.ts"],"names":[],"mappings":";;;;;;;AAOA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8CAA8C,CAAC;AAclF,qBAAa,uBAAwB,YAAW,aAAa;;IAE3D,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEb,IAAI,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO;IAM5D,QAAQ,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM;IAUvB,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAkCjD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAWjD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAc5C;AA0BD,MAAM,WAAW,YAAY;IAC3B,IAAI,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,CAAC,EAAE,OAAO,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAC5D,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC;CAC1B;AAGD,qBAAa,eAAgB,YAAW,aAAa;;IAEnD,MAAM,CAAC,eAAe,SAAQ;IAM9B,QAAQ,CAAC,OAAO,EAAE,MAAM,CAAC;gBAEb,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE;QAAE,MAAM,CAAC,EAAE,MAAM,CAAC;QAAC,OAAO,CAAC,EAAE,MAAM,CAAA;KAAO;IAY/F,GAAG,CAAC,GAAG,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAiBjD,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,SAAS,CAAC;IAmBjD,MAAM,CAAC,IAAI,EAAE,MAAM,EAAE,GAAG,OAAO,CAAC,IAAI,CAAC;CAkB5C"}
@@ -0,0 +1,177 @@
1
+ // Copyright (c) 2026 DBOS, Inc. All rights reserved.
2
+ //
3
+ // This file is part of Transact Enterprise, proprietary software licensed under the
4
+ // DBOS Conductor Software License: https://www.dbos.dev/conductor-license
5
+ // You may not use, copy, modify, or distribute this file except as that license permits.
6
+ // Disabling or circumventing the entitlement checks in @dbos-inc/dbos-sdk's src/enterprise.ts
7
+ // that gate it is a material breach of that license.
8
+ "use strict";
9
+ var __importDefault = (this && this.__importDefault) || function (mod) {
10
+ return (mod && mod.__esModule) ? mod : { "default": mod };
11
+ };
12
+ Object.defineProperty(exports, "__esModule", { value: true });
13
+ exports.S3ExternalStore = exports.FilesystemExternalStore = void 0;
14
+ const node_crypto_1 = require("node:crypto");
15
+ const promises_1 = __importDefault(require("node:fs/promises"));
16
+ const node_path_1 = __importDefault(require("node:path"));
17
+ const error_1 = require("@dbos-inc/dbos-sdk/internal/error");
18
+ const FILE_SUFFIX = '@';
19
+ const UPPER = /[A-Z]/g;
20
+ const PUT_ATTEMPTS = 5;
21
+ function errnoCode(e) {
22
+ return e?.code;
23
+ }
24
+ class FilesystemExternalStore {
25
+ #root;
26
+ storeID;
27
+ constructor(root, options = {}) {
28
+ this.#root = node_path_1.default.resolve(root);
29
+ this.storeID = options.storeID ?? `file:${this.#root}`;
30
+ }
31
+ filePath(key) {
32
+ const name = key.replace(UPPER, (c) => `^${c.toLowerCase()}`);
33
+ const file = node_path_1.default.join(this.#root, name);
34
+ const relative = node_path_1.default.relative(this.#root, file);
35
+ if (relative === '' || relative === '..' || relative.startsWith(`..${node_path_1.default.sep}`) || node_path_1.default.isAbsolute(relative)) {
36
+ throw new error_1.DBOSError(`External object key ${JSON.stringify(key)} escapes the store's root`);
37
+ }
38
+ return file + FILE_SUFFIX;
39
+ }
40
+ async put(key, data) {
41
+ const file = this.filePath(key);
42
+ const dir = node_path_1.default.dirname(file);
43
+ let handle;
44
+ let temp;
45
+ for (let attempts = 1;; attempts++) {
46
+ try {
47
+ await promises_1.default.mkdir(dir, { recursive: true });
48
+ temp = node_path_1.default.join(dir, `.upload-${(0, node_crypto_1.randomUUID)()}`);
49
+ handle = await promises_1.default.open(temp, 'wx', 0o600);
50
+ break;
51
+ }
52
+ catch (e) {
53
+ if (errnoCode(e) !== 'ENOENT' || attempts >= PUT_ATTEMPTS) {
54
+ throw e;
55
+ }
56
+ }
57
+ }
58
+ try {
59
+ try {
60
+ await handle.writeFile(data);
61
+ await handle.sync();
62
+ }
63
+ finally {
64
+ await handle.close();
65
+ }
66
+ await promises_1.default.rename(temp, file);
67
+ }
68
+ catch (e) {
69
+ await promises_1.default.rm(temp, { force: true });
70
+ throw e;
71
+ }
72
+ }
73
+ async get(key) {
74
+ try {
75
+ return await promises_1.default.readFile(this.filePath(key));
76
+ }
77
+ catch (e) {
78
+ if (errnoCode(e) === 'ENOENT') {
79
+ return undefined;
80
+ }
81
+ throw e;
82
+ }
83
+ }
84
+ async delete(keys) {
85
+ for (const key of keys) {
86
+ const file = this.filePath(key);
87
+ await promises_1.default.rm(file, { force: true });
88
+ for (let parent = node_path_1.default.dirname(file); parent !== this.#root; parent = node_path_1.default.dirname(parent)) {
89
+ try {
90
+ await promises_1.default.rmdir(parent);
91
+ }
92
+ catch {
93
+ break;
94
+ }
95
+ }
96
+ }
97
+ }
98
+ }
99
+ exports.FilesystemExternalStore = FilesystemExternalStore;
100
+ const S3_MISSING = new Set(['NoSuchKey', 'NotFound']);
101
+ function loadS3() {
102
+ try {
103
+ return {
104
+ s3: require('@aws-sdk/client-s3'),
105
+ storage: require('@aws-sdk/lib-storage'),
106
+ };
107
+ }
108
+ catch (e) {
109
+ throw new error_1.DBOSInitializationError('S3ExternalStore requires @aws-sdk/client-s3 and @aws-sdk/lib-storage. Install them with ' +
110
+ `\`npm install @aws-sdk/client-s3 @aws-sdk/lib-storage\`. Cause: ${e instanceof Error ? e.message.split('\n')[0] : String(e)}`);
111
+ }
112
+ }
113
+ class S3ExternalStore {
114
+ static deleteBatchSize = 1000;
115
+ #client;
116
+ #bucket;
117
+ #prefix;
118
+ #sdk;
119
+ storeID;
120
+ constructor(client, bucket, options = {}) {
121
+ this.#sdk = loadS3();
122
+ this.#client = client;
123
+ this.#bucket = bucket;
124
+ this.#prefix = (options.prefix ?? '').replace(/^\/+|\/+$/g, '');
125
+ this.storeID = options.storeID ?? (this.#prefix ? `s3://${bucket}/${this.#prefix}` : `s3://${bucket}`);
126
+ }
127
+ #objectKey(key) {
128
+ return this.#prefix ? `${this.#prefix}/${key}` : key;
129
+ }
130
+ async put(key, data) {
131
+ const params = { Bucket: this.#bucket, Key: this.#objectKey(key), Body: data };
132
+ const upload = new this.#sdk.storage.Upload({ client: this.#client, params, leavePartsOnError: true });
133
+ try {
134
+ await upload.done();
135
+ }
136
+ catch (e) {
137
+ if (upload.uploadId !== undefined) {
138
+ const abort = { Bucket: params.Bucket, Key: params.Key, UploadId: upload.uploadId };
139
+ await this.#client.send(new this.#sdk.s3.AbortMultipartUploadCommand(abort)).catch(() => undefined);
140
+ }
141
+ throw e;
142
+ }
143
+ }
144
+ async get(key) {
145
+ let response;
146
+ try {
147
+ response = await this.#client.send(new this.#sdk.s3.GetObjectCommand({ Bucket: this.#bucket, Key: this.#objectKey(key) }));
148
+ }
149
+ catch (e) {
150
+ const error = e;
151
+ if (S3_MISSING.has(error.name ?? '') || error.$metadata?.httpStatusCode === 404) {
152
+ return undefined;
153
+ }
154
+ throw e;
155
+ }
156
+ if (response.Body === undefined) {
157
+ throw new error_1.DBOSError(`S3 returned no body for ${this.#objectKey(key)}`);
158
+ }
159
+ return await response.Body.transformToByteArray();
160
+ }
161
+ async delete(keys) {
162
+ const batchSize = S3ExternalStore.deleteBatchSize;
163
+ for (let i = 0; i < keys.length; i += batchSize) {
164
+ const batch = keys.slice(i, i + batchSize);
165
+ const response = await this.#client.send(new this.#sdk.s3.DeleteObjectsCommand({
166
+ Bucket: this.#bucket,
167
+ Delete: { Objects: batch.map((k) => ({ Key: this.#objectKey(k) })), Quiet: true },
168
+ }));
169
+ const errors = response.Errors ?? [];
170
+ if (errors.length > 0) {
171
+ throw new error_1.DBOSError(`S3 failed to delete ${errors.length} external objects, first: ${JSON.stringify(errors[0])}`);
172
+ }
173
+ }
174
+ }
175
+ }
176
+ exports.S3ExternalStore = S3ExternalStore;
177
+ //# sourceMappingURL=external_stores.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"external_stores.js","sourceRoot":"","sources":["../../src/external_stores.ts"],"names":[],"mappings":"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"}
@@ -7,5 +7,8 @@
7
7
  // that gate it is a material breach of that license.
8
8
  export { AutoUpgradePass } from './auto_upgrade';
9
9
  export { ConductorWebsocket } from './conductor/conductor';
10
+ export { ExternalStorage } from './external_storage';
11
+ export { FilesystemExternalStore, S3ExternalStore, type S3ClientLike } from './external_stores';
10
12
  export { ShardedSystemDatabase } from './sharding';
13
+ export { Suspend } from './suspend';
11
14
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;AAAA,OAAO,EAAE,eAAe,EAAE,MAAM,gBAAgB,CAAC;AACjD,OAAO,EAAE,kBAAkB,EAAE,MAAM,uBAAuB,CAAC;AAC3D,OAAO,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AACrD,OAAO,EAAE,uBAAuB,EAAE,eAAe,EAAE,KAAK,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAChG,OAAO,EAAE,qBAAqB,EAAE,MAAM,YAAY,CAAC;AACnD,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC"}
package/dist/src/index.js CHANGED
@@ -7,11 +7,18 @@
7
7
  // that gate it is a material breach of that license.
8
8
  "use strict";
9
9
  Object.defineProperty(exports, "__esModule", { value: true });
10
- exports.ShardedSystemDatabase = exports.ConductorWebsocket = exports.AutoUpgradePass = void 0;
10
+ exports.Suspend = exports.ShardedSystemDatabase = exports.S3ExternalStore = exports.FilesystemExternalStore = exports.ExternalStorage = exports.ConductorWebsocket = exports.AutoUpgradePass = void 0;
11
11
  var auto_upgrade_1 = require("./auto_upgrade");
12
12
  Object.defineProperty(exports, "AutoUpgradePass", { enumerable: true, get: function () { return auto_upgrade_1.AutoUpgradePass; } });
13
13
  var conductor_1 = require("./conductor/conductor");
14
14
  Object.defineProperty(exports, "ConductorWebsocket", { enumerable: true, get: function () { return conductor_1.ConductorWebsocket; } });
15
+ var external_storage_1 = require("./external_storage");
16
+ Object.defineProperty(exports, "ExternalStorage", { enumerable: true, get: function () { return external_storage_1.ExternalStorage; } });
17
+ var external_stores_1 = require("./external_stores");
18
+ Object.defineProperty(exports, "FilesystemExternalStore", { enumerable: true, get: function () { return external_stores_1.FilesystemExternalStore; } });
19
+ Object.defineProperty(exports, "S3ExternalStore", { enumerable: true, get: function () { return external_stores_1.S3ExternalStore; } });
15
20
  var sharding_1 = require("./sharding");
16
21
  Object.defineProperty(exports, "ShardedSystemDatabase", { enumerable: true, get: function () { return sharding_1.ShardedSystemDatabase; } });
22
+ var suspend_1 = require("./suspend");
23
+ Object.defineProperty(exports, "Suspend", { enumerable: true, get: function () { return suspend_1.Suspend; } });
17
24
  //# sourceMappingURL=index.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,+CAAiD;AAAxC,+GAAA,eAAe,OAAA;AACxB,mDAA2D;AAAlD,+GAAA,kBAAkB,OAAA;AAC3B,uCAAmD;AAA1C,iHAAA,qBAAqB,OAAA"}
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":";;;;;;;;;;AAAA,+CAAiD;AAAxC,+GAAA,eAAe,OAAA;AACxB,mDAA2D;AAAlD,+GAAA,kBAAkB,OAAA;AAC3B,uDAAqD;AAA5C,mHAAA,eAAe,OAAA;AACxB,qDAAgG;AAAvF,0HAAA,uBAAuB,OAAA;AAAE,kHAAA,eAAe,OAAA;AACjD,uCAAmD;AAA1C,iHAAA,qBAAqB,OAAA;AAC9B,qCAAoC;AAA3B,kGAAA,OAAO,OAAA"}
@@ -6,6 +6,7 @@
6
6
  // Disabling or circumventing the entitlement checks in @dbos-inc/dbos-sdk's src/enterprise.ts
7
7
  // that gate it is a material breach of that license.
8
8
  import type { ClientBase, Pool } from 'pg';
9
+ import type { ExternalStore } from '@dbos-inc/dbos-sdk/internal/external_storage';
9
10
  import { type SystemDatabase } from '@dbos-inc/dbos-sdk/internal/system_database';
10
11
  export declare function retryOnSerializationError<T>(operation: () => Promise<T>, sysdb: SystemDatabase): Promise<T>;
11
12
  export declare function retentionLockKey(schemaName: string): bigint;
@@ -26,6 +27,7 @@ export declare function collectStatuses(sysdb: SystemDatabase, cutoffEpochTimest
26
27
  export declare function listTimedOutWorkflowIds(sysdb: SystemDatabase, cutoffEpochTimestampMs: number): Promise<[string, string | undefined][]>;
27
28
  export declare function garbageCollect(sysdb: SystemDatabase, cutoffEpochTimestampMs?: number | null, rowsThreshold?: number | null, options?: {
28
29
  batchSize?: number | null;
30
+ externalStores?: ExternalStore[];
29
31
  }): Promise<void>;
30
32
  export declare function globalTimeout(sysdb: SystemDatabase, cutoffEpochTimestampMs: number): Promise<void>;
31
33
  //# sourceMappingURL=retention.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"retention.d.ts","sourceRoot":"","sources":["../../src/retention.ts"],"names":[],"mappings":";;;;;;;AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAc,MAAM,IAAI,CAAC;AAGvD,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,6CAA6C,CAAC;AAgDrD,wBAAsB,yBAAyB,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CA0BjH;AAQD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE3D;AAGD,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAsC5C,qBAAa,aAAa;IAGZ,QAAQ,CAAC,SAAS,EAAE,MAAM;IAFtC,KAAK,SAA2B;gBAEX,SAAS,EAAE,MAAM;IAGhC,KAAK,CACT,MAAM,EAAE,UAAU,GAAG,IAAI,EACzB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,MAAM,EACvC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;CA+D/B;AAQD,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,GAAG,SAAS,CAAC,CA+BvD;AAoHD,wBAAsB,eAAe,CACnC,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,MAA8B,GACxC,OAAO,CAAC,MAAM,EAAE,CAAC,CA0CnB;AA8ED,wBAAsB,eAAe,CACnC,KAAK,EAAE,cAAc,EACrB,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,EACtC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,EAC7B,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GAC1C,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA+D7B;AAMD,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,cAAc,EACrB,sBAAsB,EAAE,MAAM,GAC7B,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC,CAoBzC;AAGD,wBAAsB,cAAc,CAClC,KAAK,EAAE,cAAc,EACrB,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,EACtC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,EAC7B,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GAC1C,OAAO,CAAC,IAAI,CAAC,CA6Bf;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKxG"}
1
+ {"version":3,"file":"retention.d.ts","sourceRoot":"","sources":["../../src/retention.ts"],"names":[],"mappings":";;;;;;;AAKA,OAAO,KAAK,EAAE,UAAU,EAAE,IAAI,EAAc,MAAM,IAAI,CAAC;AAIvD,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,8CAA8C,CAAC;AAClF,OAAO,EAML,KAAK,cAAc,EACpB,MAAM,6CAA6C,CAAC;AAgDrD,wBAAsB,yBAAyB,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,EAAE,KAAK,EAAE,cAAc,GAAG,OAAO,CAAC,CAAC,CAAC,CA0BjH;AAQD,wBAAgB,gBAAgB,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAE3D;AAGD,eAAO,MAAM,qBAAqB,QAAS,CAAC;AAsC5C,qBAAa,aAAa;IAGZ,QAAQ,CAAC,SAAS,EAAE,MAAM;IAFtC,KAAK,SAA2B;gBAEX,SAAS,EAAE,MAAM;IAGhC,KAAK,CACT,MAAM,EAAE,UAAU,GAAG,IAAI,EACzB,MAAM,EAAE,MAAM,EACd,IAAI,EAAE,MAAM,EACZ,QAAQ,EAAE,CAAC,MAAM,EAAE,OAAO,EAAE,KAAK,MAAM,EACvC,SAAS,EAAE,MAAM,EACjB,MAAM,EAAE,MAAM,GACb,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC;CA+D/B;AAQD,wBAAsB,oBAAoB,CACxC,KAAK,EAAE,cAAc,GACpB,OAAO,CAAC;IAAE,OAAO,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,CAAA;CAAE,GAAG,SAAS,CAAC,CA+BvD;AAoHD,wBAAsB,eAAe,CACnC,KAAK,EAAE,cAAc,EACrB,MAAM,EAAE,MAAM,EACd,SAAS,GAAE,MAA8B,GACxC,OAAO,CAAC,MAAM,EAAE,CAAC,CA0CnB;AA8ED,wBAAsB,eAAe,CACnC,KAAK,EAAE,cAAc,EACrB,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,EACtC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,EAC7B,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAA;CAAO,GAC1C,OAAO,CAAC,MAAM,GAAG,SAAS,CAAC,CA+D7B;AAMD,wBAAsB,uBAAuB,CAC3C,KAAK,EAAE,cAAc,EACrB,sBAAsB,EAAE,MAAM,GAC7B,OAAO,CAAC,CAAC,MAAM,EAAE,MAAM,GAAG,SAAS,CAAC,EAAE,CAAC,CAqBzC;AAGD,wBAAsB,cAAc,CAClC,KAAK,EAAE,cAAc,EACrB,sBAAsB,CAAC,EAAE,MAAM,GAAG,IAAI,EACtC,aAAa,CAAC,EAAE,MAAM,GAAG,IAAI,EAC7B,OAAO,GAAE;IAAE,SAAS,CAAC,EAAE,MAAM,GAAG,IAAI,CAAC;IAAC,cAAc,CAAC,EAAE,aAAa,EAAE,CAAA;CAAO,GAC5E,OAAO,CAAC,IAAI,CAAC,CAuCf;AAED,wBAAsB,aAAa,CAAC,KAAK,EAAE,cAAc,EAAE,sBAAsB,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAKxG"}
@@ -13,6 +13,7 @@ const dbos_executor_1 = require("@dbos-inc/dbos-sdk/internal/dbos-executor");
13
13
  const error_1 = require("@dbos-inc/dbos-sdk/internal/error");
14
14
  const shard_keys_1 = require("@dbos-inc/dbos-sdk/internal/shard_keys");
15
15
  const locks_1 = require("./locks");
16
+ const external_storage_1 = require("./external_storage");
16
17
  const system_database_1 = require("@dbos-inc/dbos-sdk/internal/system_database");
17
18
  const utils_1 = require("@dbos-inc/dbos-sdk/internal/utils");
18
19
  const workflow_1 = require("@dbos-inc/dbos-sdk/internal/workflow");
@@ -361,13 +362,14 @@ async function listTimedOutWorkflowIds(sysdb, cutoffEpochTimestampMs) {
361
362
  workflow_1.StatusString.PENDING,
362
363
  workflow_1.StatusString.ENQUEUED,
363
364
  workflow_1.StatusString.DELAYED,
365
+ workflow_1.StatusString.SUSPENDED,
364
366
  ];
365
367
  const scope = sysdb.appNameFilter('application_name', sysdb.appName, params);
366
368
  const key = sysdb.keyColumn(undefined);
367
369
  const { rows } = await sysdb.pool.query(`SELECT workflow_uuid, ${key ?? 'NULL'} AS shard_key
368
370
  FROM "${sysdb.schemaName}".workflow_status
369
371
  WHERE created_at <= $1
370
- AND status IN ($2, $3, $4)
372
+ AND status IN ($2, $3, $4, $5)
371
373
  AND ${scope}`, params);
372
374
  return rows.map((row) => [row.workflow_uuid, row.shard_key ?? undefined]);
373
375
  });
@@ -392,6 +394,14 @@ async function garbageCollect(sysdb, cutoffEpochTimestampMs, rowsThreshold, opti
392
394
  if (cutoff === undefined) {
393
395
  return;
394
396
  }
397
+ for (const store of options.externalStores ?? []) {
398
+ try {
399
+ await (0, external_storage_1.collectExternalObjects)(sysdb, store, cutoff);
400
+ }
401
+ catch (e) {
402
+ sysdb.logger.warn(`External object garbage collection failed for store ${store.storeID}: ${e instanceof Error ? e.message : String(e)}`);
403
+ }
404
+ }
395
405
  await collectPayloads(sysdb, cutoff, batchSize);
396
406
  }
397
407
  finally {