@syncular/server-cloudflare 0.0.1-91 → 0.0.1-95

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/r2.d.ts CHANGED
@@ -73,10 +73,18 @@ export interface BlobStorageAdapter {
73
73
  * Store blob data directly (for adapters that support direct storage).
74
74
  */
75
75
  put?(hash: string, data: Uint8Array, metadata?: Record<string, unknown>): Promise<void>;
76
+ /**
77
+ * Store blob data directly from a stream.
78
+ */
79
+ putStream?(hash: string, stream: ReadableStream<Uint8Array>, metadata?: Record<string, unknown>): Promise<void>;
76
80
  /**
77
81
  * Get blob data directly (for adapters that support direct retrieval).
78
82
  */
79
83
  get?(hash: string): Promise<Uint8Array | null>;
84
+ /**
85
+ * Get blob data directly as a stream.
86
+ */
87
+ getStream?(hash: string): Promise<ReadableStream<Uint8Array> | null>;
80
88
  }
81
89
  /**
82
90
  * Token signer interface for creating/verifying upload/download tokens.
package/dist/r2.d.ts.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"r2.d.ts","sourceRoot":"","sources":["../src/r2.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"r2.d.ts","sourceRoot":"","sources":["../src/r2.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAOH;;GAEG;AACH,MAAM,WAAW,qBAAqB;IACpC,wDAAwD;IACxD,IAAI,EAAE,MAAM,CAAC;IACb,4BAA4B;IAC5B,IAAI,EAAE,MAAM,CAAC;IACb,gBAAgB;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;GAEG;AACH,MAAM,WAAW,gBAAgB;IAC/B,2BAA2B;IAC3B,GAAG,EAAE,MAAM,CAAC;IACZ,kBAAkB;IAClB,MAAM,EAAE,KAAK,GAAG,MAAM,CAAC;IACvB,uBAAuB;IACvB,OAAO,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC;CAClC;AAED;;GAEG;AACH,MAAM,WAAW,uBAAuB;IACtC,mBAAmB;IACnB,IAAI,EAAE,MAAM,CAAC;IACb,gCAAgC;IAChC,SAAS,EAAE,MAAM,CAAC;CACnB;AAED;;;GAGG;AACH,MAAM,WAAW,kBAAkB;IACjC,yCAAyC;IACzC,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC;IAEtB;;OAEG;IACH,UAAU,CAAC,OAAO,EAAE,qBAAqB,GAAG,OAAO,CAAC,gBAAgB,CAAC,CAAC;IAEtE;;OAEG;IACH,YAAY,CAAC,OAAO,EAAE,uBAAuB,GAAG,OAAO,CAAC,MAAM,CAAC,CAAC;IAEhE;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC,CAAC;IAEvC;;OAEG;IACH,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAEpC;;OAEG;IACH,WAAW,CAAC,CACV,IAAI,EAAE,MAAM,GACX,OAAO,CAAC;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,QAAQ,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG,IAAI,CAAC,CAAC;IAEvD;;OAEG;IACH,GAAG,CAAC,CACF,IAAI,EAAE,MAAM,EACZ,IAAI,EAAE,UAAU,EAChB,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;OAEG;IACH,SAAS,CAAC,CACR,IAAI,EAAE,MAAM,EACZ,MAAM,EAAE,cAAc,CAAC,UAAU,CAAC,EAClC,QAAQ,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,GACjC,OAAO,CAAC,IAAI,CAAC,CAAC;IAEjB;;OAEG;IACH,GAAG,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,GAAG,IAAI,CAAC,CAAC;IAE/C;;OAEG;IACH,SAAS,CAAC,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,cAAc,CAAC,UAAU,CAAC,GAAG,IAAI,CAAC,CAAC;CACtE;AAED;;GAEG;AACH,MAAM,WAAW,eAAe;IAC9B;;;;;OAKG;IACH,IAAI,CACF,OAAO,EAAE;QAAE,IAAI,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAC;QAAC,SAAS,EAAE,MAAM,CAAA;KAAE,EAC3E,SAAS,EAAE,MAAM,GAChB,OAAO,CAAC,MAAM,CAAC,CAAC;IAEnB;;;OAGG;IACH,MAAM,CAAC,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;QAC7B,IAAI,EAAE,MAAM,CAAC;QACb,MAAM,EAAE,QAAQ,GAAG,UAAU,CAAC;QAC9B,SAAS,EAAE,MAAM,CAAC;KACnB,GAAG,IAAI,CAAC,CAAC;CACX;AAED;;GAEG;AACH,wBAAgB,qBAAqB,CAAC,MAAM,EAAE,MAAM,GAAG,eAAe,CAiDrE;AAQD,MAAM,WAAW,2BAA2B;IAC1C,wBAAwB;IACxB,MAAM,EAAE,QAAQ,CAAC;IACjB,wCAAwC;IACxC,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,8EAA8E;IAC9E,OAAO,EAAE,MAAM,CAAC;IAChB,qCAAqC;IACrC,WAAW,EAAE,eAAe,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;;;GAkBG;AACH,wBAAgB,0BAA0B,CACxC,OAAO,EAAE,2BAA2B,GACnC,kBAAkB,CAyNpB"}
package/dist/r2.js CHANGED
@@ -75,6 +75,86 @@ export function createR2BlobStorageAdapter(options) {
75
75
  const hex = hash.startsWith('sha256:') ? hash.slice(7) : hash;
76
76
  return `${keyPrefix}${hex}`;
77
77
  }
78
+ function resolveMimeType(metadata) {
79
+ return typeof metadata?.mimeType === 'string'
80
+ ? metadata.mimeType
81
+ : 'application/octet-stream';
82
+ }
83
+ function resolveChecksum(hash) {
84
+ return hash.startsWith('sha256:') ? hash.slice(7) : undefined;
85
+ }
86
+ function resolveContentLength(metadata) {
87
+ const candidates = [
88
+ metadata?.contentLength,
89
+ metadata?.byteLength,
90
+ metadata?.size,
91
+ ];
92
+ for (const candidate of candidates) {
93
+ if (typeof candidate !== 'number')
94
+ continue;
95
+ if (!Number.isFinite(candidate) || candidate < 0)
96
+ continue;
97
+ return candidate;
98
+ }
99
+ return undefined;
100
+ }
101
+ async function readStreamToBytes(stream) {
102
+ const reader = stream.getReader();
103
+ try {
104
+ const chunks = [];
105
+ let total = 0;
106
+ while (true) {
107
+ const { done, value } = await reader.read();
108
+ if (done)
109
+ break;
110
+ if (!value)
111
+ continue;
112
+ chunks.push(value);
113
+ total += value.length;
114
+ }
115
+ const out = new Uint8Array(total);
116
+ let offset = 0;
117
+ for (const chunk of chunks) {
118
+ out.set(chunk, offset);
119
+ offset += chunk.length;
120
+ }
121
+ return out;
122
+ }
123
+ finally {
124
+ reader.releaseLock();
125
+ }
126
+ }
127
+ async function putStreamInternal(hash, stream, metadata) {
128
+ const key = getKey(hash);
129
+ const mimeType = resolveMimeType(metadata);
130
+ const checksum = resolveChecksum(hash);
131
+ const contentLength = resolveContentLength(metadata);
132
+ if (typeof contentLength === 'number' && contentLength >= 0) {
133
+ const fixedLength = new FixedLengthStream(contentLength);
134
+ await Promise.all([
135
+ stream.pipeTo(fixedLength.writable),
136
+ bucket.put(key, fixedLength.readable, {
137
+ httpMetadata: { contentType: mimeType },
138
+ sha256: checksum,
139
+ }),
140
+ ]);
141
+ return;
142
+ }
143
+ const bytes = await readStreamToBytes(stream);
144
+ await bucket.put(key, bytes, {
145
+ httpMetadata: {
146
+ contentType: mimeType,
147
+ },
148
+ sha256: checksum,
149
+ });
150
+ }
151
+ async function getStreamInternal(hash) {
152
+ const key = getKey(hash);
153
+ const object = await bucket.get(key);
154
+ if (!object)
155
+ return null;
156
+ return object.body;
157
+ }
78
158
  return {
79
159
  name: 'r2',
80
160
  async signUpload(opts) {
@@ -117,22 +197,49 @@ export function createR2BlobStorageAdapter(options) {
117
197
  },
118
198
  async put(hash, data, metadata) {
119
199
  const key = getKey(hash);
120
- const mimeType = typeof metadata?.mimeType === 'string'
121
- ? metadata.mimeType
122
- : 'application/octet-stream';
200
+ const mimeType = resolveMimeType(metadata);
201
+ const checksum = resolveChecksum(hash);
123
202
  await bucket.put(key, data, {
124
203
  httpMetadata: {
125
204
  contentType: mimeType,
126
205
  },
127
- sha256: hash.startsWith('sha256:') ? hash.slice(7) : undefined,
206
+ sha256: checksum,
128
207
  });
129
208
  },
209
+ async putStream(hash, stream, metadata) {
210
+ await putStreamInternal(hash, stream, metadata);
211
+ },
130
212
  async get(hash) {
131
- const key = getKey(hash);
132
- const object = await bucket.get(key);
133
- if (!object)
213
+ const stream = await getStreamInternal(hash);
214
+ if (!stream)
134
215
  return null;
135
- return new Uint8Array(await object.arrayBuffer());
216
+ const reader = stream.getReader();
217
+ try {
218
+ const chunks = [];
219
+ let total = 0;
220
+ while (true) {
221
+ const { done, value } = await reader.read();
222
+ if (done)
223
+ break;
224
+ if (!value)
225
+ continue;
226
+ chunks.push(value);
227
+ total += value.length;
228
+ }
229
+ const out = new Uint8Array(total);
230
+ let offset = 0;
231
+ for (const chunk of chunks) {
232
+ out.set(chunk, offset);
233
+ offset += chunk.length;
234
+ }
235
+ return out;
236
+ }
237
+ finally {
238
+ reader.releaseLock();
239
+ }
240
+ },
241
+ async getStream(hash) {
242
+ return getStreamInternal(hash);
136
243
  },
137
244
  };
138
245
  }
package/dist/r2.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"r2.js","sourceRoot":"","sources":["../src/r2.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"r2.js","sourceRoot":"","sources":["../src/r2.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@syncular/server-cloudflare",
3
- "version": "0.0.1-91",
3
+ "version": "0.0.1-95",
4
4
  "description": "Cloudflare Workers adapter for the Syncular server",
5
5
  "license": "MIT",
6
6
  "author": "Benjamin Kniffler",
package/src/r2.ts CHANGED
@@ -92,10 +92,24 @@ export interface BlobStorageAdapter {
92
92
  metadata?: Record<string, unknown>
93
93
  ): Promise<void>;
94
94
 
95
+ /**
96
+ * Store blob data directly from a stream.
97
+ */
98
+ putStream?(
99
+ hash: string,
100
+ stream: ReadableStream<Uint8Array>,
101
+ metadata?: Record<string, unknown>
102
+ ): Promise<void>;
103
+
95
104
  /**
96
105
  * Get blob data directly (for adapters that support direct retrieval).
97
106
  */
98
107
  get?(hash: string): Promise<Uint8Array | null>;
108
+
109
+ /**
110
+ * Get blob data directly as a stream.
111
+ */
112
+ getStream?(hash: string): Promise<ReadableStream<Uint8Array> | null>;
99
113
  }
100
114
 
101
115
  /**
@@ -228,6 +242,99 @@ export function createR2BlobStorageAdapter(
228
242
  return `${keyPrefix}${hex}`;
229
243
  }
230
244
 
245
+ function resolveMimeType(metadata?: Record<string, unknown>): string {
246
+ return typeof metadata?.mimeType === 'string'
247
+ ? metadata.mimeType
248
+ : 'application/octet-stream';
249
+ }
250
+
251
+ function resolveChecksum(hash: string): string | undefined {
252
+ return hash.startsWith('sha256:') ? hash.slice(7) : undefined;
253
+ }
254
+
255
+ function resolveContentLength(
256
+ metadata?: Record<string, unknown>
257
+ ): number | undefined {
258
+ const candidates = [
259
+ metadata?.contentLength,
260
+ metadata?.byteLength,
261
+ metadata?.size,
262
+ ];
263
+ for (const candidate of candidates) {
264
+ if (typeof candidate !== 'number') continue;
265
+ if (!Number.isFinite(candidate) || candidate < 0) continue;
266
+ return candidate;
267
+ }
268
+ return undefined;
269
+ }
270
+
271
+ async function readStreamToBytes(
272
+ stream: ReadableStream<Uint8Array>
273
+ ): Promise<Uint8Array> {
274
+ const reader = stream.getReader();
275
+ try {
276
+ const chunks: Uint8Array[] = [];
277
+ let total = 0;
278
+ while (true) {
279
+ const { done, value } = await reader.read();
280
+ if (done) break;
281
+ if (!value) continue;
282
+ chunks.push(value);
283
+ total += value.length;
284
+ }
285
+
286
+ const out = new Uint8Array(total);
287
+ let offset = 0;
288
+ for (const chunk of chunks) {
289
+ out.set(chunk, offset);
290
+ offset += chunk.length;
291
+ }
292
+ return out;
293
+ } finally {
294
+ reader.releaseLock();
295
+ }
296
+ }
297
+
298
+ async function putStreamInternal(
299
+ hash: string,
300
+ stream: ReadableStream<Uint8Array>,
301
+ metadata?: Record<string, unknown>
302
+ ): Promise<void> {
303
+ const key = getKey(hash);
304
+ const mimeType = resolveMimeType(metadata);
305
+ const checksum = resolveChecksum(hash);
306
+ const contentLength = resolveContentLength(metadata);
307
+
308
+ if (typeof contentLength === 'number' && contentLength >= 0) {
309
+ const fixedLength = new FixedLengthStream(contentLength);
310
+ await Promise.all([
311
+ stream.pipeTo(fixedLength.writable),
312
+ bucket.put(key, fixedLength.readable, {
313
+ httpMetadata: { contentType: mimeType },
314
+ sha256: checksum,
315
+ }),
316
+ ]);
317
+ return;
318
+ }
319
+
320
+ const bytes = await readStreamToBytes(stream);
321
+ await bucket.put(key, bytes, {
322
+ httpMetadata: {
323
+ contentType: mimeType,
324
+ },
325
+ sha256: checksum,
326
+ });
327
+ }
328
+
329
+ async function getStreamInternal(
330
+ hash: string
331
+ ): Promise<ReadableStream<Uint8Array> | null> {
332
+ const key = getKey(hash);
333
+ const object = await bucket.get(key);
334
+ if (!object) return null;
335
+ return object.body as ReadableStream<Uint8Array> | null;
336
+ }
337
+
231
338
  return {
232
339
  name: 'r2',
233
340
 
@@ -291,25 +398,53 @@ export function createR2BlobStorageAdapter(
291
398
  metadata?: Record<string, unknown>
292
399
  ): Promise<void> {
293
400
  const key = getKey(hash);
294
- const mimeType =
295
- typeof metadata?.mimeType === 'string'
296
- ? metadata.mimeType
297
- : 'application/octet-stream';
298
-
401
+ const mimeType = resolveMimeType(metadata);
402
+ const checksum = resolveChecksum(hash);
299
403
  await bucket.put(key, data, {
300
404
  httpMetadata: {
301
405
  contentType: mimeType,
302
406
  },
303
- sha256: hash.startsWith('sha256:') ? hash.slice(7) : undefined,
407
+ sha256: checksum,
304
408
  });
305
409
  },
306
410
 
411
+ async putStream(
412
+ hash: string,
413
+ stream: ReadableStream<Uint8Array>,
414
+ metadata?: Record<string, unknown>
415
+ ): Promise<void> {
416
+ await putStreamInternal(hash, stream, metadata);
417
+ },
418
+
307
419
  async get(hash: string): Promise<Uint8Array | null> {
308
- const key = getKey(hash);
309
- const object = await bucket.get(key);
310
- if (!object) return null;
420
+ const stream = await getStreamInternal(hash);
421
+ if (!stream) return null;
422
+
423
+ const reader = stream.getReader();
424
+ try {
425
+ const chunks: Uint8Array[] = [];
426
+ let total = 0;
427
+ while (true) {
428
+ const { done, value } = await reader.read();
429
+ if (done) break;
430
+ if (!value) continue;
431
+ chunks.push(value);
432
+ total += value.length;
433
+ }
434
+ const out = new Uint8Array(total);
435
+ let offset = 0;
436
+ for (const chunk of chunks) {
437
+ out.set(chunk, offset);
438
+ offset += chunk.length;
439
+ }
440
+ return out;
441
+ } finally {
442
+ reader.releaseLock();
443
+ }
444
+ },
311
445
 
312
- return new Uint8Array(await object.arrayBuffer());
446
+ async getStream(hash: string): Promise<ReadableStream<Uint8Array> | null> {
447
+ return getStreamInternal(hash);
313
448
  },
314
449
  };
315
450
  }