@syncular/server 0.0.6-159 → 0.0.6-167
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/blobs/adapters/database.d.ts +26 -9
- package/dist/blobs/adapters/database.d.ts.map +1 -1
- package/dist/blobs/adapters/database.js +65 -21
- package/dist/blobs/adapters/database.js.map +1 -1
- package/dist/blobs/manager.d.ts +60 -3
- package/dist/blobs/manager.d.ts.map +1 -1
- package/dist/blobs/manager.js +227 -56
- package/dist/blobs/manager.js.map +1 -1
- package/dist/blobs/migrate.d.ts.map +1 -1
- package/dist/blobs/migrate.js +16 -8
- package/dist/blobs/migrate.js.map +1 -1
- package/dist/blobs/types.d.ts +4 -0
- package/dist/blobs/types.d.ts.map +1 -1
- package/dist/dialect/helpers.d.ts +3 -0
- package/dist/dialect/helpers.d.ts.map +1 -1
- package/dist/dialect/helpers.js +17 -0
- package/dist/dialect/helpers.js.map +1 -1
- package/dist/handlers/collection.d.ts +0 -2
- package/dist/handlers/collection.d.ts.map +1 -1
- package/dist/handlers/collection.js +5 -56
- package/dist/handlers/collection.js.map +1 -1
- package/dist/handlers/create-handler.d.ts +0 -4
- package/dist/handlers/create-handler.d.ts.map +1 -1
- package/dist/handlers/create-handler.js +6 -34
- package/dist/handlers/create-handler.js.map +1 -1
- package/dist/notify.d.ts.map +1 -1
- package/dist/notify.js +13 -37
- package/dist/notify.js.map +1 -1
- package/dist/proxy/collection.d.ts +0 -2
- package/dist/proxy/collection.d.ts.map +1 -1
- package/dist/proxy/collection.js +2 -17
- package/dist/proxy/collection.js.map +1 -1
- package/dist/proxy/handler.d.ts +1 -1
- package/dist/proxy/handler.d.ts.map +1 -1
- package/dist/proxy/handler.js +1 -2
- package/dist/proxy/handler.js.map +1 -1
- package/dist/proxy/index.d.ts +1 -1
- package/dist/proxy/index.d.ts.map +1 -1
- package/dist/proxy/index.js +1 -1
- package/dist/proxy/index.js.map +1 -1
- package/dist/proxy/oplog.d.ts.map +1 -1
- package/dist/proxy/oplog.js +1 -7
- package/dist/proxy/oplog.js.map +1 -1
- package/dist/prune.d.ts.map +1 -1
- package/dist/prune.js +1 -13
- package/dist/prune.js.map +1 -1
- package/dist/pull.d.ts.map +1 -1
- package/dist/pull.js +186 -54
- package/dist/pull.js.map +1 -1
- package/dist/push.d.ts +1 -1
- package/dist/push.d.ts.map +1 -1
- package/dist/push.js +9 -36
- package/dist/push.js.map +1 -1
- package/dist/snapshot-chunks/db-metadata.d.ts +18 -0
- package/dist/snapshot-chunks/db-metadata.d.ts.map +1 -1
- package/dist/snapshot-chunks/db-metadata.js +71 -23
- package/dist/snapshot-chunks/db-metadata.js.map +1 -1
- package/dist/snapshot-chunks.d.ts +5 -1
- package/dist/snapshot-chunks.d.ts.map +1 -1
- package/dist/snapshot-chunks.js +14 -1
- package/dist/snapshot-chunks.js.map +1 -1
- package/dist/stats.d.ts.map +1 -1
- package/dist/stats.js +1 -13
- package/dist/stats.js.map +1 -1
- package/dist/subscriptions/resolve.d.ts +1 -1
- package/dist/subscriptions/resolve.d.ts.map +1 -1
- package/dist/subscriptions/resolve.js +3 -16
- package/dist/subscriptions/resolve.js.map +1 -1
- package/dist/sync.d.ts.map +1 -1
- package/dist/sync.js +2 -4
- package/dist/sync.js.map +1 -1
- package/package.json +2 -2
- package/src/blobs/adapters/database.test.ts +7 -0
- package/src/blobs/adapters/database.ts +119 -39
- package/src/blobs/manager.ts +339 -53
- package/src/blobs/migrate.ts +16 -8
- package/src/blobs/types.ts +4 -0
- package/src/dialect/helpers.ts +19 -0
- package/src/handlers/collection.ts +17 -86
- package/src/handlers/create-handler.ts +9 -44
- package/src/notify.ts +15 -40
- package/src/proxy/collection.ts +5 -27
- package/src/proxy/handler.ts +2 -2
- package/src/proxy/index.ts +0 -2
- package/src/proxy/oplog.ts +1 -9
- package/src/prune.ts +1 -12
- package/src/pull.ts +280 -105
- package/src/push.ts +14 -43
- package/src/snapshot-chunks/db-metadata.ts +107 -27
- package/src/snapshot-chunks.ts +18 -0
- package/src/stats.ts +1 -12
- package/src/subscriptions/resolve.ts +4 -20
- package/src/sync.ts +6 -6
|
@@ -13,23 +13,37 @@ import type { SyncBlobsDb } from '../types';
|
|
|
13
13
|
*/
|
|
14
14
|
export interface BlobTokenSigner {
|
|
15
15
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
18
|
-
* @param expiresIn Expiration time in seconds
|
|
19
|
-
* @returns A signed token string
|
|
16
|
+
* Token payload for upload/download authorization.
|
|
17
|
+
* Upload tokens are bound to hash + expected byte size.
|
|
20
18
|
*/
|
|
21
19
|
sign(payload: {
|
|
22
20
|
hash: string;
|
|
23
|
-
|
|
21
|
+
partitionId: string;
|
|
22
|
+
action: 'upload';
|
|
23
|
+
size: number;
|
|
24
|
+
expiresAt: number;
|
|
25
|
+
} | {
|
|
26
|
+
hash: string;
|
|
27
|
+
partitionId: string;
|
|
28
|
+
action: 'download';
|
|
24
29
|
expiresAt: number;
|
|
25
30
|
}, expiresIn: number): Promise<string>;
|
|
26
31
|
/**
|
|
27
|
-
*
|
|
28
|
-
* @
|
|
32
|
+
* Sign a token for blob upload/download authorization.
|
|
33
|
+
* @param payload The data to sign
|
|
34
|
+
* @param expiresIn Expiration time in seconds
|
|
35
|
+
* @returns A signed token string
|
|
29
36
|
*/
|
|
30
37
|
verify(token: string): Promise<{
|
|
31
38
|
hash: string;
|
|
32
|
-
|
|
39
|
+
partitionId: string;
|
|
40
|
+
action: 'upload';
|
|
41
|
+
size: number;
|
|
42
|
+
expiresAt: number;
|
|
43
|
+
} | {
|
|
44
|
+
hash: string;
|
|
45
|
+
partitionId: string;
|
|
46
|
+
action: 'download';
|
|
33
47
|
expiresAt: number;
|
|
34
48
|
} | null>;
|
|
35
49
|
}
|
|
@@ -66,6 +80,7 @@ export declare function createDatabaseBlobStorageAdapter<DB extends SyncBlobsDb>
|
|
|
66
80
|
* Called by the server routes when handling direct uploads.
|
|
67
81
|
*/
|
|
68
82
|
export declare function storeBlobInDatabase<DB extends SyncBlobsDb>(db: Kysely<DB>, args: {
|
|
83
|
+
partitionId: string;
|
|
69
84
|
hash: string;
|
|
70
85
|
size: number;
|
|
71
86
|
mimeType: string;
|
|
@@ -75,7 +90,9 @@ export declare function storeBlobInDatabase<DB extends SyncBlobsDb>(db: Kysely<D
|
|
|
75
90
|
* Read a blob from the database.
|
|
76
91
|
* Called by the server routes when handling direct downloads.
|
|
77
92
|
*/
|
|
78
|
-
export declare function readBlobFromDatabase<DB extends SyncBlobsDb>(db: Kysely<DB>, hash: string
|
|
93
|
+
export declare function readBlobFromDatabase<DB extends SyncBlobsDb>(db: Kysely<DB>, hash: string, options?: {
|
|
94
|
+
partitionId?: string;
|
|
95
|
+
}): Promise<{
|
|
79
96
|
body: Uint8Array;
|
|
80
97
|
mimeType: string;
|
|
81
98
|
size: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/blobs/adapters/database.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAIV,kBAAkB,EACnB,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"database.d.ts","sourceRoot":"","sources":["../../../src/blobs/adapters/database.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAIV,kBAAkB,EACnB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,KAAK,MAAM,EAAO,MAAM,QAAQ,CAAC;AAC1C,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAE5C;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;OAGG;IACH,IAAI,CACF,OAAO,EACH;QACE,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,QAAQ,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,GACD;QACE,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,UAAU,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,EACL,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnB;;;;;OAKG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAC1B;QACE,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,QAAQ,CAAC;QACjB,IAAI,EAAE,MAAM,CAAC;QACb,SAAS,EAAE,MAAM,CAAC;KACnB,GACD;QACE,IAAI,EAAE,MAAM,CAAC;QACb,WAAW,EAAE,MAAM,CAAC;QACpB,MAAM,EAAE,UAAU,CAAC;QACnB,SAAS,EAAE,MAAM,CAAC;KACnB,GACD,IAAI,CACP,CAAC;CACH;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAoFrE;AAoBD,MAAM,WAAW,iCAAiC,CAChD,EAAE,SAAS,WAAW,GAAG,WAAW;IAEpC,+BAA+B;IAC/B,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IACf,8EAA8E;IAC9E,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,WAAW,EAAE,eAAe,CAAC;CAC9B;AAED;;;;;;;;;;;;;;GAcG;AACH,wBAAgB,gCAAgC,CAAC,EAAE,SAAS,WAAW,EACrE,OAAO,EAAE,iCAAiC,CAAC,EAAE,CAAC,GAC7C,kBAAkB,CA6HpB;AAED;;;GAGG;AACH,wBAAsB,mBAAmB,CAAC,EAAE,SAAS,WAAW,EAC9D,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,IAAI,EAAE;IACJ,WAAW,EAAE,MAAM,CAAC;IACpB,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,IAAI,EAAE,UAAU,CAAC;CAClB,GACA,OAAO,CAAC,IAAI,CAAC,CAoBf;AAED;;;GAGG;AACH,wBAAsB,oBAAoB,CAAC,EAAE,SAAS,WAAW,EAC/D,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,EACd,IAAI,EAAE,MAAM,EACZ,OAAO,CAAC,EAAE;IAAE,WAAW,CAAC,EAAE,MAAM,CAAA;CAAE,GACjC,OAAO,CAAC;IAAE,IAAI,EAAE,UAAU,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG,IAAI,CAAC,CAqBtE"}
|
|
@@ -5,6 +5,7 @@
|
|
|
5
5
|
* Since there's no external service, this adapter generates signed tokens that allow
|
|
6
6
|
* uploads/downloads through the server's blob routes.
|
|
7
7
|
*/
|
|
8
|
+
import { resolveUrlFromBase } from '@syncular/core';
|
|
8
9
|
import { sql } from 'kysely';
|
|
9
10
|
/**
|
|
10
11
|
* Create a simple HMAC-based token signer.
|
|
@@ -41,10 +42,36 @@ export function createHmacTokenSigner(secret) {
|
|
|
41
42
|
if (!isValidSig)
|
|
42
43
|
return null;
|
|
43
44
|
try {
|
|
44
|
-
const
|
|
45
|
-
if (
|
|
45
|
+
const parsed = JSON.parse(atob(dataB64));
|
|
46
|
+
if (typeof parsed.hash !== 'string')
|
|
46
47
|
return null;
|
|
47
|
-
|
|
48
|
+
if (typeof parsed.partitionId !== 'string')
|
|
49
|
+
return null;
|
|
50
|
+
if (typeof parsed.expiresAt !== 'number')
|
|
51
|
+
return null;
|
|
52
|
+
if (Date.now() > parsed.expiresAt)
|
|
53
|
+
return null;
|
|
54
|
+
if (parsed.action === 'download') {
|
|
55
|
+
return {
|
|
56
|
+
hash: parsed.hash,
|
|
57
|
+
partitionId: parsed.partitionId,
|
|
58
|
+
action: 'download',
|
|
59
|
+
expiresAt: parsed.expiresAt,
|
|
60
|
+
};
|
|
61
|
+
}
|
|
62
|
+
if (parsed.action === 'upload' &&
|
|
63
|
+
typeof parsed.size === 'number' &&
|
|
64
|
+
Number.isFinite(parsed.size) &&
|
|
65
|
+
parsed.size >= 0) {
|
|
66
|
+
return {
|
|
67
|
+
hash: parsed.hash,
|
|
68
|
+
partitionId: parsed.partitionId,
|
|
69
|
+
action: 'upload',
|
|
70
|
+
size: parsed.size,
|
|
71
|
+
expiresAt: parsed.expiresAt,
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
return null;
|
|
48
75
|
}
|
|
49
76
|
catch {
|
|
50
77
|
return null;
|
|
@@ -86,15 +113,22 @@ function hexToBuffer(hex) {
|
|
|
86
113
|
*/
|
|
87
114
|
export function createDatabaseBlobStorageAdapter(options) {
|
|
88
115
|
const { db, baseUrl, tokenSigner } = options;
|
|
89
|
-
|
|
90
|
-
const normalizedBaseUrl = baseUrl.replace(/\/$/, '');
|
|
116
|
+
const resolvePartitionId = (partitionId) => partitionId ?? 'default';
|
|
91
117
|
return {
|
|
92
118
|
name: 'database',
|
|
93
119
|
async signUpload(opts) {
|
|
120
|
+
const partitionId = resolvePartitionId(opts.partitionId);
|
|
94
121
|
const expiresAt = Date.now() + opts.expiresIn * 1000;
|
|
95
|
-
const token = await tokenSigner.sign({
|
|
122
|
+
const token = await tokenSigner.sign({
|
|
123
|
+
hash: opts.hash,
|
|
124
|
+
partitionId,
|
|
125
|
+
action: 'upload',
|
|
126
|
+
size: opts.size,
|
|
127
|
+
expiresAt,
|
|
128
|
+
}, opts.expiresIn);
|
|
96
129
|
// URL points to server's blob upload endpoint
|
|
97
|
-
const
|
|
130
|
+
const uploadPath = `/blobs/${encodeURIComponent(opts.hash)}/upload?token=${encodeURIComponent(token)}`;
|
|
131
|
+
const url = resolveUrlFromBase(baseUrl, uploadPath);
|
|
98
132
|
return {
|
|
99
133
|
url,
|
|
100
134
|
method: 'PUT',
|
|
@@ -105,30 +139,34 @@ export function createDatabaseBlobStorageAdapter(options) {
|
|
|
105
139
|
};
|
|
106
140
|
},
|
|
107
141
|
async signDownload(opts) {
|
|
142
|
+
const partitionId = resolvePartitionId(opts.partitionId);
|
|
108
143
|
const expiresAt = Date.now() + opts.expiresIn * 1000;
|
|
109
|
-
const token = await tokenSigner.sign({ hash: opts.hash, action: 'download', expiresAt }, opts.expiresIn);
|
|
110
|
-
return
|
|
144
|
+
const token = await tokenSigner.sign({ hash: opts.hash, partitionId, action: 'download', expiresAt }, opts.expiresIn);
|
|
145
|
+
return resolveUrlFromBase(baseUrl, `/blobs/${encodeURIComponent(opts.hash)}/download?token=${encodeURIComponent(token)}`);
|
|
111
146
|
},
|
|
112
|
-
async exists(hash) {
|
|
147
|
+
async exists(hash, options) {
|
|
148
|
+
const partitionId = resolvePartitionId(options?.partitionId);
|
|
113
149
|
const rowResult = await sql `
|
|
114
150
|
select hash
|
|
115
151
|
from ${sql.table('sync_blobs')}
|
|
116
|
-
where hash = ${hash}
|
|
152
|
+
where partition_id = ${partitionId} and hash = ${hash}
|
|
117
153
|
limit 1
|
|
118
154
|
`.execute(db);
|
|
119
155
|
return rowResult.rows.length > 0;
|
|
120
156
|
},
|
|
121
|
-
async delete(hash) {
|
|
157
|
+
async delete(hash, options) {
|
|
158
|
+
const partitionId = resolvePartitionId(options?.partitionId);
|
|
122
159
|
await sql `
|
|
123
160
|
delete from ${sql.table('sync_blobs')}
|
|
124
|
-
where hash = ${hash}
|
|
161
|
+
where partition_id = ${partitionId} and hash = ${hash}
|
|
125
162
|
`.execute(db);
|
|
126
163
|
},
|
|
127
|
-
async getMetadata(hash) {
|
|
164
|
+
async getMetadata(hash, options) {
|
|
165
|
+
const partitionId = resolvePartitionId(options?.partitionId);
|
|
128
166
|
const rowResult = await sql `
|
|
129
167
|
select size, mime_type
|
|
130
168
|
from ${sql.table('sync_blobs')}
|
|
131
|
-
where hash = ${hash}
|
|
169
|
+
where partition_id = ${partitionId} and hash = ${hash}
|
|
132
170
|
limit 1
|
|
133
171
|
`.execute(db);
|
|
134
172
|
const row = rowResult.rows[0];
|
|
@@ -139,19 +177,22 @@ export function createDatabaseBlobStorageAdapter(options) {
|
|
|
139
177
|
mimeType: row.mime_type,
|
|
140
178
|
};
|
|
141
179
|
},
|
|
142
|
-
async put(hash, data, metadata) {
|
|
180
|
+
async put(hash, data, metadata, options) {
|
|
181
|
+
const partitionId = resolvePartitionId(options?.partitionId);
|
|
143
182
|
const mimeType = typeof metadata?.mimeType === 'string'
|
|
144
183
|
? metadata.mimeType
|
|
145
184
|
: 'application/octet-stream';
|
|
146
185
|
await storeBlobInDatabase(db, {
|
|
186
|
+
partitionId,
|
|
147
187
|
hash,
|
|
148
188
|
size: data.length,
|
|
149
189
|
mimeType,
|
|
150
190
|
body: data,
|
|
151
191
|
});
|
|
152
192
|
},
|
|
153
|
-
async get(hash) {
|
|
154
|
-
const
|
|
193
|
+
async get(hash, options) {
|
|
194
|
+
const partitionId = resolvePartitionId(options?.partitionId);
|
|
195
|
+
const result = await readBlobFromDatabase(db, hash, { partitionId });
|
|
155
196
|
return result?.body ?? null;
|
|
156
197
|
},
|
|
157
198
|
};
|
|
@@ -163,6 +204,7 @@ export function createDatabaseBlobStorageAdapter(options) {
|
|
|
163
204
|
export async function storeBlobInDatabase(db, args) {
|
|
164
205
|
await sql `
|
|
165
206
|
insert into ${sql.table('sync_blobs')} (
|
|
207
|
+
partition_id,
|
|
166
208
|
hash,
|
|
167
209
|
size,
|
|
168
210
|
mime_type,
|
|
@@ -170,24 +212,26 @@ export async function storeBlobInDatabase(db, args) {
|
|
|
170
212
|
created_at
|
|
171
213
|
)
|
|
172
214
|
values (
|
|
215
|
+
${args.partitionId},
|
|
173
216
|
${args.hash},
|
|
174
217
|
${args.size},
|
|
175
218
|
${args.mimeType},
|
|
176
219
|
${args.body},
|
|
177
220
|
${new Date().toISOString()}
|
|
178
221
|
)
|
|
179
|
-
on conflict (hash) do nothing
|
|
222
|
+
on conflict (partition_id, hash) do nothing
|
|
180
223
|
`.execute(db);
|
|
181
224
|
}
|
|
182
225
|
/**
|
|
183
226
|
* Read a blob from the database.
|
|
184
227
|
* Called by the server routes when handling direct downloads.
|
|
185
228
|
*/
|
|
186
|
-
export async function readBlobFromDatabase(db, hash) {
|
|
229
|
+
export async function readBlobFromDatabase(db, hash, options) {
|
|
230
|
+
const partitionId = options?.partitionId ?? 'default';
|
|
187
231
|
const rowResult = await sql `
|
|
188
232
|
select body, mime_type, size
|
|
189
233
|
from ${sql.table('sync_blobs')}
|
|
190
|
-
where hash = ${hash}
|
|
234
|
+
where partition_id = ${partitionId} and hash = ${hash}
|
|
191
235
|
limit 1
|
|
192
236
|
`.execute(db);
|
|
193
237
|
const row = rowResult.rows[0];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/blobs/adapters/database.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAQH,OAAO,EAAe,GAAG,EAAE,MAAM,QAAQ,CAAC;
|
|
1
|
+
{"version":3,"file":"database.js","sourceRoot":"","sources":["../../../src/blobs/adapters/database.ts"],"names":[],"mappings":"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"}
|
package/dist/blobs/manager.d.ts
CHANGED
|
@@ -16,17 +16,60 @@ export interface BlobManagerOptions<DB extends SyncBlobUploadsDb = SyncBlobUploa
|
|
|
16
16
|
defaultExpiresIn?: number;
|
|
17
17
|
/** How long incomplete uploads are kept before cleanup. Default: 86400 (24 hours) */
|
|
18
18
|
uploadTtlSeconds?: number;
|
|
19
|
+
/** Optional cleanup throughput tuning knobs. */
|
|
20
|
+
cleanupTuning?: BlobCleanupTuning;
|
|
19
21
|
}
|
|
22
|
+
export interface BlobCleanupTuning {
|
|
23
|
+
/** Cleanup select/delete batch size. Default: 250 */
|
|
24
|
+
batchSize?: number;
|
|
25
|
+
/** Max concurrent storage deletes during cleanup. Default: 8 */
|
|
26
|
+
storageDeleteConcurrency?: number;
|
|
27
|
+
/** Max concurrent reference checks for completed uploads. Default: 16 */
|
|
28
|
+
referenceCheckConcurrency?: number;
|
|
29
|
+
}
|
|
30
|
+
export declare const BLOB_CLEANUP_TUNING_PRESETS: {
|
|
31
|
+
readonly server: {
|
|
32
|
+
readonly batchSize: 500;
|
|
33
|
+
readonly storageDeleteConcurrency: 16;
|
|
34
|
+
readonly referenceCheckConcurrency: 24;
|
|
35
|
+
};
|
|
36
|
+
readonly edge: {
|
|
37
|
+
readonly batchSize: 100;
|
|
38
|
+
readonly storageDeleteConcurrency: 4;
|
|
39
|
+
readonly referenceCheckConcurrency: 8;
|
|
40
|
+
};
|
|
41
|
+
};
|
|
20
42
|
export interface InitiateUploadOptions {
|
|
21
43
|
hash: string;
|
|
22
44
|
size: number;
|
|
23
45
|
mimeType: string;
|
|
24
46
|
actorId: string;
|
|
47
|
+
partitionId?: string;
|
|
25
48
|
}
|
|
26
49
|
export interface GetDownloadUrlOptions {
|
|
27
50
|
hash: string;
|
|
28
51
|
/** Optional: verify actor has access to this blob via a scope check */
|
|
29
52
|
actorId?: string;
|
|
53
|
+
partitionId?: string;
|
|
54
|
+
}
|
|
55
|
+
export interface CompleteUploadOptions {
|
|
56
|
+
/**
|
|
57
|
+
* Optional actor identity to authorize upload completion.
|
|
58
|
+
* When provided, only the initiating actor may mark an upload complete.
|
|
59
|
+
*/
|
|
60
|
+
actorId?: string;
|
|
61
|
+
partitionId?: string;
|
|
62
|
+
}
|
|
63
|
+
export interface BlobUploadRecord {
|
|
64
|
+
partitionId: string;
|
|
65
|
+
hash: string;
|
|
66
|
+
size: number;
|
|
67
|
+
mimeType: string;
|
|
68
|
+
status: 'pending' | 'complete';
|
|
69
|
+
actorId: string;
|
|
70
|
+
createdAt: string;
|
|
71
|
+
expiresAt: string;
|
|
72
|
+
completedAt: string | null;
|
|
30
73
|
}
|
|
31
74
|
/**
|
|
32
75
|
* Create a blob manager for handling server-side blob operations.
|
|
@@ -50,7 +93,7 @@ export declare function createBlobManager<DB extends SyncBlobUploadsDb>(options:
|
|
|
50
93
|
*
|
|
51
94
|
* Verifies the blob exists in storage and marks the upload as complete.
|
|
52
95
|
*/
|
|
53
|
-
completeUpload(hash: string): Promise<{
|
|
96
|
+
completeUpload(hash: string, options?: CompleteUploadOptions | undefined): Promise<{
|
|
54
97
|
ok: boolean;
|
|
55
98
|
metadata?: {
|
|
56
99
|
hash: string;
|
|
@@ -77,10 +120,18 @@ export declare function createBlobManager<DB extends SyncBlobUploadsDb>(options:
|
|
|
77
120
|
uploadComplete: boolean;
|
|
78
121
|
};
|
|
79
122
|
}>;
|
|
123
|
+
/**
|
|
124
|
+
* Get upload record for a blob hash, including pending uploads.
|
|
125
|
+
*/
|
|
126
|
+
getUploadRecord(hash: string, options?: {
|
|
127
|
+
partitionId?: string | undefined;
|
|
128
|
+
} | undefined): Promise<BlobUploadRecord | null>;
|
|
80
129
|
/**
|
|
81
130
|
* Get blob metadata without generating a download URL.
|
|
82
131
|
*/
|
|
83
|
-
getMetadata(hash: string
|
|
132
|
+
getMetadata(hash: string, options?: {
|
|
133
|
+
partitionId?: string | undefined;
|
|
134
|
+
} | undefined): Promise<{
|
|
84
135
|
hash: string;
|
|
85
136
|
size: number;
|
|
86
137
|
mimeType: string;
|
|
@@ -91,7 +142,9 @@ export declare function createBlobManager<DB extends SyncBlobUploadsDb>(options:
|
|
|
91
142
|
/**
|
|
92
143
|
* Check if a blob exists and is complete.
|
|
93
144
|
*/
|
|
94
|
-
exists(hash: string
|
|
145
|
+
exists(hash: string, options?: {
|
|
146
|
+
partitionId?: string | undefined;
|
|
147
|
+
} | undefined): Promise<boolean>;
|
|
95
148
|
/**
|
|
96
149
|
* Clean up expired/orphaned uploads.
|
|
97
150
|
*
|
|
@@ -104,6 +157,8 @@ export declare function createBlobManager<DB extends SyncBlobUploadsDb>(options:
|
|
|
104
157
|
isReferenced?: ((hash: string) => Promise<boolean>) | undefined;
|
|
105
158
|
/** Delete from storage too (not just tracking table) */
|
|
106
159
|
deleteFromStorage?: boolean | undefined;
|
|
160
|
+
/** Optional partition filter for cleanup */
|
|
161
|
+
partitionId?: string | undefined;
|
|
107
162
|
} | undefined): Promise<{
|
|
108
163
|
deleted: number;
|
|
109
164
|
}>;
|
|
@@ -120,6 +175,8 @@ export interface BlobCleanupSchedulerOptions {
|
|
|
120
175
|
deleteFromStorage?: boolean;
|
|
121
176
|
/** Optional: Check if a blob hash is referenced by any row */
|
|
122
177
|
isReferenced?: (hash: string) => Promise<boolean>;
|
|
178
|
+
/** Optional partition to scope cleanup. Defaults to "default". */
|
|
179
|
+
partitionId?: string;
|
|
123
180
|
/** Optional: Called after each cleanup run */
|
|
124
181
|
onCleanup?: (result: {
|
|
125
182
|
deleted: number;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/blobs/manager.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAEV,kBAAkB,EAGnB,MAAM,gBAAgB,CAAC;AAExB,OAAO,EAAE,KAAK,MAAM,EAAO,MAAM,QAAQ,CAAC;AAC1C,OAAO,KAAK,EAAE,iBAAiB,EAAE,MAAM,SAAS,CAAC;AAMjD,MAAM,WAAW,kBAAkB,CACjC,EAAE,SAAS,iBAAiB,GAAG,iBAAiB;IAEhD,6CAA6C;IAC7C,EAAE,EAAE,MAAM,CAAC,EAAE,CAAC,CAAC;IACf,+CAA+C;IAC/C,OAAO,EAAE,kBAAkB,CAAC;IAC5B,0EAA0E;IAC1E,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,qFAAqF;IACrF,gBAAgB,CAAC,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"manager.d.ts","sourceRoot":"","sources":["../../src/blobs/manager.ts"],"names":[],"mappings":"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"}
|