@pol-studios/powersync 1.0.7 → 1.0.11

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 (103) hide show
  1. package/README.md +933 -0
  2. package/dist/CacheSettingsManager-uz-kbnRH.d.ts +461 -0
  3. package/dist/attachments/index.d.ts +709 -6
  4. package/dist/attachments/index.js +133 -5
  5. package/dist/chunk-24RDMMCL.js +44 -0
  6. package/dist/chunk-24RDMMCL.js.map +1 -0
  7. package/dist/chunk-4TXTAEF2.js +2060 -0
  8. package/dist/chunk-4TXTAEF2.js.map +1 -0
  9. package/dist/chunk-63PXSPIN.js +358 -0
  10. package/dist/chunk-63PXSPIN.js.map +1 -0
  11. package/dist/chunk-654ERHA7.js +1 -0
  12. package/dist/{chunk-BREGB4WL.js → chunk-BRXQNASY.js} +287 -335
  13. package/dist/chunk-BRXQNASY.js.map +1 -0
  14. package/dist/{chunk-DHYUBVP7.js → chunk-CAB26E6F.js} +20 -9
  15. package/dist/chunk-CAB26E6F.js.map +1 -0
  16. package/dist/{chunk-H772V6XQ.js → chunk-CUCAYK7Z.js} +7 -43
  17. package/dist/chunk-CUCAYK7Z.js.map +1 -0
  18. package/dist/{chunk-4C3RY5SU.js → chunk-HWSNV45P.js} +76 -1
  19. package/dist/chunk-HWSNV45P.js.map +1 -0
  20. package/dist/{chunk-HFOFLW5F.js → chunk-KN2IZERF.js} +139 -6
  21. package/dist/chunk-KN2IZERF.js.map +1 -0
  22. package/dist/{chunk-UEYRTLKE.js → chunk-P4HZA6ZT.js} +20 -9
  23. package/dist/chunk-P4HZA6ZT.js.map +1 -0
  24. package/dist/chunk-T4AO7JIG.js +1 -0
  25. package/dist/{chunk-XQAJM2MW.js → chunk-VACPAAQZ.js} +33 -2
  26. package/dist/{chunk-XQAJM2MW.js.map → chunk-VACPAAQZ.js.map} +1 -1
  27. package/dist/{chunk-53WH2JJV.js → chunk-WN5ZJ3E2.js} +5 -8
  28. package/dist/chunk-WN5ZJ3E2.js.map +1 -0
  29. package/dist/chunk-XAEII4ZX.js +456 -0
  30. package/dist/chunk-XAEII4ZX.js.map +1 -0
  31. package/dist/chunk-XOY2CJ67.js +289 -0
  32. package/dist/chunk-XOY2CJ67.js.map +1 -0
  33. package/dist/chunk-YHTZ7VMV.js +1 -0
  34. package/dist/{chunk-MKD2VCX3.js → chunk-Z6VOBGTU.js} +8 -8
  35. package/dist/chunk-Z6VOBGTU.js.map +1 -0
  36. package/dist/chunk-ZM4ENYMF.js +230 -0
  37. package/dist/chunk-ZM4ENYMF.js.map +1 -0
  38. package/dist/connector/index.d.ts +56 -3
  39. package/dist/connector/index.js +8 -5
  40. package/dist/core/index.d.ts +12 -1
  41. package/dist/core/index.js +3 -2
  42. package/dist/error/index.js +0 -1
  43. package/dist/generator/cli.js +527 -0
  44. package/dist/generator/index.d.ts +168 -0
  45. package/dist/generator/index.js +370 -0
  46. package/dist/generator/index.js.map +1 -0
  47. package/dist/index.d.ts +12 -10
  48. package/dist/index.js +191 -29
  49. package/dist/index.native.d.ts +11 -9
  50. package/dist/index.native.js +191 -29
  51. package/dist/index.web.d.ts +11 -9
  52. package/dist/index.web.js +191 -29
  53. package/dist/maintenance/index.js +0 -1
  54. package/dist/platform/index.js +0 -2
  55. package/dist/platform/index.js.map +1 -1
  56. package/dist/platform/index.native.js +1 -2
  57. package/dist/platform/index.web.js +0 -1
  58. package/dist/pol-attachment-queue-BVAIueoP.d.ts +817 -0
  59. package/dist/provider/index.d.ts +38 -34
  60. package/dist/provider/index.js +11 -12
  61. package/dist/react/index.d.ts +372 -0
  62. package/dist/react/index.js +25 -0
  63. package/dist/storage/index.d.ts +3 -3
  64. package/dist/storage/index.js +22 -8
  65. package/dist/storage/index.native.d.ts +3 -3
  66. package/dist/storage/index.native.js +21 -7
  67. package/dist/storage/index.web.d.ts +3 -3
  68. package/dist/storage/index.web.js +21 -7
  69. package/dist/storage/upload/index.d.ts +7 -8
  70. package/dist/storage/upload/index.js +3 -3
  71. package/dist/storage/upload/index.native.d.ts +7 -8
  72. package/dist/storage/upload/index.native.js +4 -3
  73. package/dist/storage/upload/index.web.d.ts +1 -4
  74. package/dist/storage/upload/index.web.js +3 -3
  75. package/dist/supabase-connector-T9vHq_3i.d.ts +202 -0
  76. package/dist/sync/index.js +3 -3
  77. package/dist/{supabase-connector-qLm-WHkM.d.ts → types-B212hgfA.d.ts} +48 -170
  78. package/dist/{types-BVacP54t.d.ts → types-CyvBaAl8.d.ts} +12 -4
  79. package/dist/types-D0WcHrq6.d.ts +234 -0
  80. package/package.json +28 -4
  81. package/dist/CacheSettingsManager-1exbOC6S.d.ts +0 -261
  82. package/dist/chunk-4C3RY5SU.js.map +0 -1
  83. package/dist/chunk-53WH2JJV.js.map +0 -1
  84. package/dist/chunk-BREGB4WL.js.map +0 -1
  85. package/dist/chunk-DGUM43GV.js +0 -11
  86. package/dist/chunk-DHYUBVP7.js.map +0 -1
  87. package/dist/chunk-GKF7TOMT.js +0 -1
  88. package/dist/chunk-H772V6XQ.js.map +0 -1
  89. package/dist/chunk-HFOFLW5F.js.map +0 -1
  90. package/dist/chunk-KGSFAE5B.js +0 -1
  91. package/dist/chunk-LNL64IJZ.js +0 -1
  92. package/dist/chunk-MKD2VCX3.js.map +0 -1
  93. package/dist/chunk-UEYRTLKE.js.map +0 -1
  94. package/dist/chunk-WQ5MPAVC.js +0 -449
  95. package/dist/chunk-WQ5MPAVC.js.map +0 -1
  96. package/dist/chunk-ZEOKPWUC.js +0 -1165
  97. package/dist/chunk-ZEOKPWUC.js.map +0 -1
  98. package/dist/pol-attachment-queue-C7YNXXhK.d.ts +0 -676
  99. package/dist/types-Bgvx7-E8.d.ts +0 -187
  100. /package/dist/{chunk-DGUM43GV.js.map → chunk-654ERHA7.js.map} +0 -0
  101. /package/dist/{chunk-GKF7TOMT.js.map → chunk-T4AO7JIG.js.map} +0 -0
  102. /package/dist/{chunk-KGSFAE5B.js.map → chunk-YHTZ7VMV.js.map} +0 -0
  103. /package/dist/{chunk-LNL64IJZ.js.map → react/index.js.map} +0 -0
@@ -1,449 +0,0 @@
1
- import {
2
- resolveBucketFromConfig
3
- } from "./chunk-MKD2VCX3.js";
4
-
5
- // src/utils/mimeTypes.ts
6
- var MIME_TYPES = {
7
- // Images
8
- jpg: "image/jpeg",
9
- jpeg: "image/jpeg",
10
- png: "image/png",
11
- gif: "image/gif",
12
- webp: "image/webp",
13
- heic: "image/heic",
14
- heif: "image/heic",
15
- svg: "image/svg+xml",
16
- bmp: "image/bmp",
17
- tiff: "image/tiff",
18
- tif: "image/tiff",
19
- ico: "image/x-icon",
20
- avif: "image/avif",
21
- // Videos
22
- mp4: "video/mp4",
23
- mov: "video/quicktime",
24
- avi: "video/x-msvideo",
25
- webm: "video/webm",
26
- mkv: "video/x-matroska",
27
- m4v: "video/x-m4v",
28
- "3gp": "video/3gpp",
29
- flv: "video/x-flv",
30
- // Audio
31
- mp3: "audio/mpeg",
32
- wav: "audio/wav",
33
- ogg: "audio/ogg",
34
- m4a: "audio/mp4",
35
- aac: "audio/aac",
36
- flac: "audio/flac",
37
- wma: "audio/x-ms-wma",
38
- // Documents
39
- pdf: "application/pdf",
40
- doc: "application/msword",
41
- docx: "application/vnd.openxmlformats-officedocument.wordprocessingml.document",
42
- xls: "application/vnd.ms-excel",
43
- xlsx: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
44
- ppt: "application/vnd.ms-powerpoint",
45
- pptx: "application/vnd.openxmlformats-officedocument.presentationml.presentation",
46
- txt: "text/plain",
47
- csv: "text/csv",
48
- rtf: "application/rtf",
49
- odt: "application/vnd.oasis.opendocument.text",
50
- ods: "application/vnd.oasis.opendocument.spreadsheet",
51
- odp: "application/vnd.oasis.opendocument.presentation",
52
- // Data formats
53
- json: "application/json",
54
- xml: "application/xml",
55
- yaml: "application/x-yaml",
56
- yml: "application/x-yaml",
57
- // Archives
58
- zip: "application/zip",
59
- rar: "application/vnd.rar",
60
- "7z": "application/x-7z-compressed",
61
- tar: "application/x-tar",
62
- gz: "application/gzip",
63
- // Code
64
- js: "text/javascript",
65
- ts: "text/typescript",
66
- jsx: "text/jsx",
67
- tsx: "text/tsx",
68
- css: "text/css",
69
- html: "text/html",
70
- htm: "text/html",
71
- md: "text/markdown",
72
- // Other
73
- woff: "font/woff",
74
- woff2: "font/woff2",
75
- ttf: "font/ttf",
76
- otf: "font/otf",
77
- eot: "application/vnd.ms-fontobject"
78
- };
79
- var DEFAULT_MIME_TYPE = "application/octet-stream";
80
- function getMimeType(extension) {
81
- if (!extension) {
82
- return DEFAULT_MIME_TYPE;
83
- }
84
- const ext = extension.replace(/^\./, "").toLowerCase();
85
- return MIME_TYPES[ext] ?? DEFAULT_MIME_TYPE;
86
- }
87
- function getMimeTypeFromPath(filePath) {
88
- if (!filePath) {
89
- return DEFAULT_MIME_TYPE;
90
- }
91
- const ext = filePath.split(".").pop();
92
- return getMimeType(ext);
93
- }
94
- function isImageMimeType(mimeType) {
95
- return mimeType.startsWith("image/");
96
- }
97
- function isVideoMimeType(mimeType) {
98
- return mimeType.startsWith("video/");
99
- }
100
- function isAudioMimeType(mimeType) {
101
- return mimeType.startsWith("audio/");
102
- }
103
- function isDocumentMimeType(mimeType) {
104
- return mimeType === "application/pdf" || mimeType.includes("wordprocessingml") || mimeType.includes("spreadsheetml") || mimeType.includes("presentationml") || mimeType.includes("msword") || mimeType.includes("ms-excel") || mimeType.includes("ms-powerpoint") || mimeType.includes("opendocument");
105
- }
106
- function getExtensionFromMimeType(mimeType) {
107
- for (const [ext, mime] of Object.entries(MIME_TYPES)) {
108
- if (mime === mimeType) {
109
- return ext;
110
- }
111
- }
112
- return void 0;
113
- }
114
-
115
- // src/storage/SupabaseStorageAdapter.ts
116
- var SupabaseStorageAdapter = class {
117
- client;
118
- bucketConfig;
119
- signedUrlExpiry;
120
- fileSystem;
121
- logger;
122
- constructor(options, fileSystem) {
123
- this.client = options.client;
124
- this.bucketConfig = options.bucketConfig;
125
- this.signedUrlExpiry = options.signedUrlExpiry ?? 60;
126
- this.fileSystem = fileSystem;
127
- this.logger = options.logger;
128
- }
129
- /**
130
- * Set the file system adapter (can be set after construction).
131
- */
132
- setFileSystem(fileSystem) {
133
- this.fileSystem = fileSystem;
134
- }
135
- /**
136
- * Resolve the storage bucket for a given file path.
137
- */
138
- resolveBucket(filePath) {
139
- return resolveBucketFromConfig(this.bucketConfig, filePath);
140
- }
141
- // ─── RemoteStorageAdapter Interface ─────────────────────────────────────────
142
- /**
143
- * Download a file from Supabase Storage to a local path.
144
- *
145
- * Uses the platform's streaming downloadFile method to avoid loading
146
- * the entire file into memory (prevents OOM on large files).
147
- */
148
- async download(remotePath, localPath) {
149
- if (!this.fileSystem) {
150
- throw new Error("FileSystem adapter not configured");
151
- }
152
- const signedUrl = await this.getDownloadUrl(remotePath);
153
- await this.fileSystem.downloadFile(signedUrl, localPath);
154
- }
155
- /**
156
- * Get a signed download URL for a remote file.
157
- */
158
- async getDownloadUrl(remotePath) {
159
- const bucket = this.resolveBucket(remotePath);
160
- const {
161
- data,
162
- error
163
- } = await this.client.storage.from(bucket).createSignedUrl(remotePath, this.signedUrlExpiry);
164
- if (error) {
165
- throw new Error(`Failed to create signed URL: ${error.message}`);
166
- }
167
- if (!data?.signedUrl) {
168
- throw new Error("Failed to create signed URL: No URL returned");
169
- }
170
- return data.signedUrl;
171
- }
172
- /**
173
- * Check if a file exists in remote storage.
174
- */
175
- async exists(remotePath) {
176
- const bucket = this.resolveBucket(remotePath);
177
- try {
178
- const pathParts = remotePath.split("/");
179
- const fileName = pathParts.pop();
180
- const directory = pathParts.join("/");
181
- const {
182
- data,
183
- error
184
- } = await this.client.storage.from(bucket).list(directory, {
185
- search: fileName,
186
- limit: 1
187
- });
188
- if (error) {
189
- return false;
190
- }
191
- return data?.some((file) => file.name === fileName) ?? false;
192
- } catch {
193
- return false;
194
- }
195
- }
196
- // ─── PowerSyncStorageAdapter Interface ──────────────────────────────────────
197
- /**
198
- * No-op for uploads. Use SupabaseUploadHandler for upload operations.
199
- *
200
- * Uploads are handled separately by the upload manager pipeline to support
201
- * background uploads and proper queue management.
202
- */
203
- async uploadFile(filename, _data, _options) {
204
- const message = "[SupabaseStorageAdapter] uploadFile called but uploads should be handled by SupabaseUploadHandler. File:";
205
- if (this.logger) {
206
- this.logger.warn(message, filename);
207
- } else {
208
- console.warn(message, filename);
209
- }
210
- }
211
- /**
212
- * Download a file from Supabase Storage and return as a Blob.
213
- *
214
- * Uses signed URL + fetch to download the file efficiently.
215
- * This method is required by the PowerSync attachments interface.
216
- *
217
- * Note: This loads the file into memory as a Blob. For very large files,
218
- * consider using download() to save directly to disk instead.
219
- */
220
- async downloadFile(filePath) {
221
- const signedUrl = await this.getDownloadUrl(filePath);
222
- const response = await fetch(signedUrl);
223
- if (!response.ok) {
224
- throw new Error(`Download failed with status ${response.status}: ${filePath}`);
225
- }
226
- const blob = await response.blob();
227
- if (!blob.type || blob.type === "application/octet-stream") {
228
- const mimeType = getMimeTypeFromPath(filePath);
229
- return new Blob([blob], {
230
- type: mimeType
231
- });
232
- }
233
- return blob;
234
- }
235
- /**
236
- * Write data to a local file.
237
- */
238
- async writeFile(fileURI, data, options) {
239
- if (!this.fileSystem) {
240
- throw new Error("FileSystem adapter not configured");
241
- }
242
- const encoding = options?.encoding ?? "utf8";
243
- const parentDir = fileURI.substring(0, fileURI.lastIndexOf("/"));
244
- if (parentDir) {
245
- await this.fileSystem.makeDirectory(parentDir, {
246
- intermediates: true
247
- });
248
- }
249
- await this.fileSystem.writeFile(fileURI, data, encoding);
250
- }
251
- /**
252
- * Read data from a local file.
253
- */
254
- async readFile(fileURI, options) {
255
- if (!this.fileSystem) {
256
- throw new Error("FileSystem adapter not configured");
257
- }
258
- const encoding = options?.encoding ?? "utf8";
259
- const content = await this.fileSystem.readFile(fileURI, encoding);
260
- if (encoding === "base64") {
261
- const binaryString = atob(content);
262
- const bytes = new Uint8Array(binaryString.length);
263
- for (let i = 0; i < binaryString.length; i++) {
264
- bytes[i] = binaryString.charCodeAt(i);
265
- }
266
- return bytes.buffer;
267
- }
268
- const encoder = new TextEncoder();
269
- return encoder.encode(content).buffer;
270
- }
271
- /**
272
- * Delete a local file.
273
- */
274
- async deleteFile(uri, _options) {
275
- if (!this.fileSystem) {
276
- throw new Error("FileSystem adapter not configured");
277
- }
278
- await this.fileSystem.deleteFile(uri);
279
- }
280
- /**
281
- * Check if a local file exists.
282
- */
283
- async fileExists(fileURI) {
284
- if (!this.fileSystem) {
285
- throw new Error("FileSystem adapter not configured");
286
- }
287
- const info = await this.fileSystem.getFileInfo(fileURI);
288
- return info?.exists ?? false;
289
- }
290
- /**
291
- * Create a directory.
292
- */
293
- async makeDir(uri) {
294
- if (!this.fileSystem) {
295
- throw new Error("FileSystem adapter not configured");
296
- }
297
- await this.fileSystem.makeDirectory(uri, {
298
- intermediates: true
299
- });
300
- }
301
- /**
302
- * Copy a file.
303
- */
304
- async copyFile(sourceUri, targetUri) {
305
- if (!this.fileSystem) {
306
- throw new Error("FileSystem adapter not configured");
307
- }
308
- await this.fileSystem.copyFile(sourceUri, targetUri);
309
- }
310
- /**
311
- * Get the user storage directory.
312
- */
313
- getUserStorageDirectory() {
314
- if (!this.fileSystem) {
315
- throw new Error("FileSystem adapter not configured");
316
- }
317
- return this.fileSystem.getDocumentsDirectory();
318
- }
319
- };
320
- function createSupabaseStorageAdapter(client, defaultBucket, fileSystem, options) {
321
- return new SupabaseStorageAdapter({
322
- client,
323
- bucketConfig: {
324
- defaultBucket,
325
- bucketMap: options?.bucketMap
326
- },
327
- signedUrlExpiry: options?.signedUrlExpiry,
328
- logger: options?.logger
329
- }, fileSystem);
330
- }
331
-
332
- // src/storage/cache/types.ts
333
- var DEFAULT_CACHE_SETTINGS = {
334
- maxCacheSizeMb: 5120,
335
- // 5 GB
336
- compressionQuality: 0.7
337
- // 70% quality
338
- };
339
-
340
- // src/storage/cache/CacheSettingsManager.ts
341
- var STORAGE_KEYS = {
342
- MAX_CACHE_SIZE_MB: "max-cache-size-mb",
343
- COMPRESSION_QUALITY: "compression-quality"
344
- };
345
- var CacheSettingsManager = class {
346
- storage;
347
- keyPrefix;
348
- defaults;
349
- constructor(storage, options) {
350
- this.storage = storage;
351
- this.keyPrefix = options?.storageKeyPrefix ?? "@pol-studios/cache";
352
- this.defaults = {
353
- ...DEFAULT_CACHE_SETTINGS,
354
- ...options?.defaults
355
- };
356
- }
357
- /**
358
- * Get the full storage key for a setting.
359
- */
360
- getKey(setting) {
361
- return `${this.keyPrefix}/${STORAGE_KEYS[setting]}`;
362
- }
363
- /**
364
- * Get all cache settings.
365
- */
366
- async getSettings() {
367
- const keys = [this.getKey("MAX_CACHE_SIZE_MB"), this.getKey("COMPRESSION_QUALITY")];
368
- const results = await this.storage.multiGet(keys);
369
- const sizeValue = results.find(([k]) => k === keys[0])?.[1];
370
- const qualityValue = results.find(([k]) => k === keys[1])?.[1];
371
- return {
372
- maxCacheSizeMb: sizeValue ? Number(sizeValue) : this.defaults.maxCacheSizeMb,
373
- compressionQuality: qualityValue ? Number(qualityValue) : this.defaults.compressionQuality
374
- };
375
- }
376
- /**
377
- * Get the maximum cache size in megabytes.
378
- * Returns 0 for unlimited.
379
- */
380
- async getMaxCacheSizeMb() {
381
- const value = await this.storage.getItem(this.getKey("MAX_CACHE_SIZE_MB"));
382
- return value ? Number(value) : this.defaults.maxCacheSizeMb;
383
- }
384
- /**
385
- * Set the maximum cache size in megabytes.
386
- * Use 0 for unlimited.
387
- *
388
- * @param mb - Maximum cache size in megabytes
389
- */
390
- async setMaxCacheSizeMb(mb) {
391
- if (mb < 0) {
392
- throw new Error("Cache size must be non-negative");
393
- }
394
- await this.storage.setItem(this.getKey("MAX_CACHE_SIZE_MB"), String(mb));
395
- }
396
- /**
397
- * Get the maximum cache size in bytes.
398
- * Returns Number.MAX_SAFE_INTEGER for unlimited.
399
- */
400
- async getMaxCacheSizeBytes() {
401
- const mb = await this.getMaxCacheSizeMb();
402
- return mb === 0 ? Number.MAX_SAFE_INTEGER : mb * 1024 * 1024;
403
- }
404
- /**
405
- * Get the compression quality (0.0 to 1.0).
406
- */
407
- async getCompressionQuality() {
408
- const value = await this.storage.getItem(this.getKey("COMPRESSION_QUALITY"));
409
- return value ? Number(value) : this.defaults.compressionQuality;
410
- }
411
- /**
412
- * Set the compression quality.
413
- *
414
- * @param quality - Compression quality (0.0 to 1.0)
415
- */
416
- async setCompressionQuality(quality) {
417
- if (quality < 0 || quality > 1) {
418
- throw new Error("Compression quality must be between 0 and 1");
419
- }
420
- await this.storage.setItem(this.getKey("COMPRESSION_QUALITY"), String(quality));
421
- }
422
- /**
423
- * Reset all settings to defaults.
424
- */
425
- async resetToDefaults() {
426
- await this.storage.multiSet([[this.getKey("MAX_CACHE_SIZE_MB"), String(this.defaults.maxCacheSizeMb)], [this.getKey("COMPRESSION_QUALITY"), String(this.defaults.compressionQuality)]]);
427
- }
428
- /**
429
- * Clear all stored settings.
430
- */
431
- async clear() {
432
- await Promise.all([this.storage.removeItem(this.getKey("MAX_CACHE_SIZE_MB")), this.storage.removeItem(this.getKey("COMPRESSION_QUALITY"))]);
433
- }
434
- };
435
-
436
- export {
437
- getMimeType,
438
- getMimeTypeFromPath,
439
- isImageMimeType,
440
- isVideoMimeType,
441
- isAudioMimeType,
442
- isDocumentMimeType,
443
- getExtensionFromMimeType,
444
- SupabaseStorageAdapter,
445
- createSupabaseStorageAdapter,
446
- DEFAULT_CACHE_SETTINGS,
447
- CacheSettingsManager
448
- };
449
- //# sourceMappingURL=chunk-WQ5MPAVC.js.map
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/utils/mimeTypes.ts","../src/storage/SupabaseStorageAdapter.ts","../src/storage/cache/types.ts","../src/storage/cache/CacheSettingsManager.ts"],"sourcesContent":["/**\n * MIME Type Utilities for @pol-studios/powersync\n *\n * Provides file extension to MIME type mapping for storage operations.\n */\n\n/**\n * MIME type mappings by file extension\n */\nconst MIME_TYPES: Record<string, string> = {\n // Images\n jpg: 'image/jpeg',\n jpeg: 'image/jpeg',\n png: 'image/png',\n gif: 'image/gif',\n webp: 'image/webp',\n heic: 'image/heic',\n heif: 'image/heic',\n svg: 'image/svg+xml',\n bmp: 'image/bmp',\n tiff: 'image/tiff',\n tif: 'image/tiff',\n ico: 'image/x-icon',\n avif: 'image/avif',\n // Videos\n mp4: 'video/mp4',\n mov: 'video/quicktime',\n avi: 'video/x-msvideo',\n webm: 'video/webm',\n mkv: 'video/x-matroska',\n m4v: 'video/x-m4v',\n '3gp': 'video/3gpp',\n flv: 'video/x-flv',\n // Audio\n mp3: 'audio/mpeg',\n wav: 'audio/wav',\n ogg: 'audio/ogg',\n m4a: 'audio/mp4',\n aac: 'audio/aac',\n flac: 'audio/flac',\n wma: 'audio/x-ms-wma',\n // Documents\n pdf: 'application/pdf',\n doc: 'application/msword',\n docx: 'application/vnd.openxmlformats-officedocument.wordprocessingml.document',\n xls: 'application/vnd.ms-excel',\n xlsx: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',\n ppt: 'application/vnd.ms-powerpoint',\n pptx: 'application/vnd.openxmlformats-officedocument.presentationml.presentation',\n txt: 'text/plain',\n csv: 'text/csv',\n rtf: 'application/rtf',\n odt: 'application/vnd.oasis.opendocument.text',\n ods: 'application/vnd.oasis.opendocument.spreadsheet',\n odp: 'application/vnd.oasis.opendocument.presentation',\n // Data formats\n json: 'application/json',\n xml: 'application/xml',\n yaml: 'application/x-yaml',\n yml: 'application/x-yaml',\n // Archives\n zip: 'application/zip',\n rar: 'application/vnd.rar',\n '7z': 'application/x-7z-compressed',\n tar: 'application/x-tar',\n gz: 'application/gzip',\n // Code\n js: 'text/javascript',\n ts: 'text/typescript',\n jsx: 'text/jsx',\n tsx: 'text/tsx',\n css: 'text/css',\n html: 'text/html',\n htm: 'text/html',\n md: 'text/markdown',\n // Other\n woff: 'font/woff',\n woff2: 'font/woff2',\n ttf: 'font/ttf',\n otf: 'font/otf',\n eot: 'application/vnd.ms-fontobject'\n};\n\n/**\n * Default MIME type for unknown file extensions\n */\nconst DEFAULT_MIME_TYPE = 'application/octet-stream';\n\n/**\n * Get MIME type from file extension.\n *\n * @param extension - File extension (with or without leading dot)\n * @returns MIME type string\n *\n * @example\n * ```typescript\n * getMimeType('jpg'); // 'image/jpeg'\n * getMimeType('.png'); // 'image/png'\n * getMimeType('unknown'); // 'application/octet-stream'\n * getMimeType(undefined); // 'application/octet-stream'\n * ```\n */\nexport function getMimeType(extension: string | undefined | null): string {\n if (!extension) {\n return DEFAULT_MIME_TYPE;\n }\n\n // Remove leading dot if present and convert to lowercase\n const ext = extension.replace(/^\\./, '').toLowerCase();\n return MIME_TYPES[ext] ?? DEFAULT_MIME_TYPE;\n}\n\n/**\n * Get MIME type from a file path or filename.\n *\n * @param filePath - Full file path or filename\n * @returns MIME type string\n *\n * @example\n * ```typescript\n * getMimeTypeFromPath('/path/to/image.jpg'); // 'image/jpeg'\n * getMimeTypeFromPath('document.pdf'); // 'application/pdf'\n * getMimeTypeFromPath('file-without-extension'); // 'application/octet-stream'\n * ```\n */\nexport function getMimeTypeFromPath(filePath: string | undefined | null): string {\n if (!filePath) {\n return DEFAULT_MIME_TYPE;\n }\n const ext = filePath.split('.').pop();\n return getMimeType(ext);\n}\n\n/**\n * Check if a MIME type represents an image.\n */\nexport function isImageMimeType(mimeType: string): boolean {\n return mimeType.startsWith('image/');\n}\n\n/**\n * Check if a MIME type represents a video.\n */\nexport function isVideoMimeType(mimeType: string): boolean {\n return mimeType.startsWith('video/');\n}\n\n/**\n * Check if a MIME type represents audio.\n */\nexport function isAudioMimeType(mimeType: string): boolean {\n return mimeType.startsWith('audio/');\n}\n\n/**\n * Check if a MIME type represents a document (PDF, Office, etc.).\n */\nexport function isDocumentMimeType(mimeType: string): boolean {\n return mimeType === 'application/pdf' || mimeType.includes('wordprocessingml') || mimeType.includes('spreadsheetml') || mimeType.includes('presentationml') || mimeType.includes('msword') || mimeType.includes('ms-excel') || mimeType.includes('ms-powerpoint') || mimeType.includes('opendocument');\n}\n\n/**\n * Get file extension from MIME type (reverse lookup).\n * Returns the most common extension for the given MIME type.\n *\n * @param mimeType - MIME type string\n * @returns File extension without leading dot, or undefined if unknown\n */\nexport function getExtensionFromMimeType(mimeType: string): string | undefined {\n // Find the first matching extension\n for (const [ext, mime] of Object.entries(MIME_TYPES)) {\n if (mime === mimeType) {\n return ext;\n }\n }\n return undefined;\n}","/**\n * Supabase Storage Adapter for @pol-studios/powersync\n *\n * Provides attachment storage operations using Supabase Storage with\n * platform-agnostic file system operations via PlatformAdapter.\n *\n * Key features:\n * - Memory-efficient downloads using signed URLs + native file system\n * - Multi-bucket support via BucketConfig/BucketResolver\n * - Platform-agnostic via FileSystemAdapter interface\n * - Compatible with PowerSync attachments interface\n */\n\nimport type { FileSystemAdapter, LoggerAdapter } from '../platform/types';\nimport type { RemoteStorageAdapter, SupabaseStorageAdapterOptions, BucketConfig, PowerSyncStorageAdapter } from './types';\nimport { resolveBucketFromConfig } from './types';\nimport { getMimeTypeFromPath } from '../utils/mimeTypes';\n\n/**\n * Supabase Storage adapter for attachment downloads and local file operations.\n *\n * Uses PlatformAdapter's fileSystem for I/O operations to remain platform-agnostic.\n *\n * IMPORTANT: This adapter downloads files using signed URLs + platform file system\n * operations to avoid loading entire files into memory. This prevents OOM crashes\n * on large files that occurred with the previous blob-based approach.\n *\n * @example\n * ```typescript\n * const adapter = new SupabaseStorageAdapter(\n * {\n * client: supabaseClient,\n * bucketConfig: {\n * defaultBucket: 'attachments',\n * bucketMap: new Map([['avatars/', 'user-avatars']]),\n * },\n * },\n * platform.fileSystem\n * );\n *\n * // Download to local path\n * await adapter.download('photos/image.jpg', '/local/path/image.jpg');\n *\n * // Get signed URL for direct access\n * const url = await adapter.getDownloadUrl('photos/image.jpg');\n * ```\n */\nexport class SupabaseStorageAdapter implements RemoteStorageAdapter, PowerSyncStorageAdapter {\n private client: any;\n private bucketConfig: BucketConfig;\n private signedUrlExpiry: number;\n private fileSystem?: FileSystemAdapter;\n private logger?: LoggerAdapter;\n constructor(options: SupabaseStorageAdapterOptions, fileSystem?: FileSystemAdapter) {\n this.client = options.client;\n this.bucketConfig = options.bucketConfig;\n this.signedUrlExpiry = options.signedUrlExpiry ?? 60;\n this.fileSystem = fileSystem;\n this.logger = options.logger;\n }\n\n /**\n * Set the file system adapter (can be set after construction).\n */\n setFileSystem(fileSystem: FileSystemAdapter): void {\n this.fileSystem = fileSystem;\n }\n\n /**\n * Resolve the storage bucket for a given file path.\n */\n resolveBucket(filePath: string): string {\n return resolveBucketFromConfig(this.bucketConfig, filePath);\n }\n\n // ─── RemoteStorageAdapter Interface ─────────────────────────────────────────\n\n /**\n * Download a file from Supabase Storage to a local path.\n *\n * Uses the platform's streaming downloadFile method to avoid loading\n * the entire file into memory (prevents OOM on large files).\n */\n async download(remotePath: string, localPath: string): Promise<void> {\n if (!this.fileSystem) {\n throw new Error('FileSystem adapter not configured');\n }\n const signedUrl = await this.getDownloadUrl(remotePath);\n\n // Use the platform's streaming download method\n // This writes directly to disk without loading the entire file into memory\n await this.fileSystem.downloadFile(signedUrl, localPath);\n }\n\n /**\n * Get a signed download URL for a remote file.\n */\n async getDownloadUrl(remotePath: string): Promise<string> {\n const bucket = this.resolveBucket(remotePath);\n const {\n data,\n error\n } = await this.client.storage.from(bucket).createSignedUrl(remotePath, this.signedUrlExpiry);\n if (error) {\n throw new Error(`Failed to create signed URL: ${error.message}`);\n }\n if (!data?.signedUrl) {\n throw new Error('Failed to create signed URL: No URL returned');\n }\n return data.signedUrl;\n }\n\n /**\n * Check if a file exists in remote storage.\n */\n async exists(remotePath: string): Promise<boolean> {\n const bucket = this.resolveBucket(remotePath);\n try {\n // Use list with a specific path prefix to check existence\n const pathParts = remotePath.split('/');\n const fileName = pathParts.pop();\n const directory = pathParts.join('/');\n const {\n data,\n error\n } = await this.client.storage.from(bucket).list(directory, {\n search: fileName,\n limit: 1\n });\n if (error) {\n return false;\n }\n return data?.some((file: {\n name: string;\n }) => file.name === fileName) ?? false;\n } catch {\n return false;\n }\n }\n\n // ─── PowerSyncStorageAdapter Interface ──────────────────────────────────────\n\n /**\n * No-op for uploads. Use SupabaseUploadHandler for upload operations.\n *\n * Uploads are handled separately by the upload manager pipeline to support\n * background uploads and proper queue management.\n */\n async uploadFile(filename: string, _data: ArrayBuffer, _options?: {\n mediaType?: string;\n }): Promise<void> {\n const message = '[SupabaseStorageAdapter] uploadFile called but uploads should be handled by SupabaseUploadHandler. File:';\n if (this.logger) {\n this.logger.warn(message, filename);\n } else {\n console.warn(message, filename);\n }\n }\n\n /**\n * Download a file from Supabase Storage and return as a Blob.\n *\n * Uses signed URL + fetch to download the file efficiently.\n * This method is required by the PowerSync attachments interface.\n *\n * Note: This loads the file into memory as a Blob. For very large files,\n * consider using download() to save directly to disk instead.\n */\n async downloadFile(filePath: string): Promise<Blob> {\n const signedUrl = await this.getDownloadUrl(filePath);\n const response = await fetch(signedUrl);\n if (!response.ok) {\n throw new Error(`Download failed with status ${response.status}: ${filePath}`);\n }\n const blob = await response.blob();\n\n // If the blob doesn't have a type, set it based on file extension\n if (!blob.type || blob.type === 'application/octet-stream') {\n const mimeType = getMimeTypeFromPath(filePath);\n return new Blob([blob], {\n type: mimeType\n });\n }\n return blob;\n }\n\n /**\n * Write data to a local file.\n */\n async writeFile(fileURI: string, data: string, options?: {\n encoding?: 'utf8' | 'base64';\n }): Promise<void> {\n if (!this.fileSystem) {\n throw new Error('FileSystem adapter not configured');\n }\n const encoding = options?.encoding ?? 'utf8';\n\n // Ensure parent directory exists\n const parentDir = fileURI.substring(0, fileURI.lastIndexOf('/'));\n if (parentDir) {\n await this.fileSystem.makeDirectory(parentDir, {\n intermediates: true\n });\n }\n await this.fileSystem.writeFile(fileURI, data, encoding);\n }\n\n /**\n * Read data from a local file.\n */\n async readFile(fileURI: string, options?: {\n encoding?: 'utf8' | 'base64';\n mediaType?: string;\n }): Promise<ArrayBuffer> {\n if (!this.fileSystem) {\n throw new Error('FileSystem adapter not configured');\n }\n const encoding = options?.encoding ?? 'utf8';\n const content = await this.fileSystem.readFile(fileURI, encoding);\n if (encoding === 'base64') {\n // Decode base64 to ArrayBuffer\n const binaryString = atob(content);\n const bytes = new Uint8Array(binaryString.length);\n for (let i = 0; i < binaryString.length; i++) {\n bytes[i] = binaryString.charCodeAt(i);\n }\n return bytes.buffer;\n }\n\n // For utf8, encode to ArrayBuffer\n const encoder = new TextEncoder();\n return encoder.encode(content).buffer;\n }\n\n /**\n * Delete a local file.\n */\n async deleteFile(uri: string, _options?: {\n filename?: string;\n }): Promise<void> {\n if (!this.fileSystem) {\n throw new Error('FileSystem adapter not configured');\n }\n await this.fileSystem.deleteFile(uri);\n }\n\n /**\n * Check if a local file exists.\n */\n async fileExists(fileURI: string): Promise<boolean> {\n if (!this.fileSystem) {\n throw new Error('FileSystem adapter not configured');\n }\n const info = await this.fileSystem.getFileInfo(fileURI);\n return info?.exists ?? false;\n }\n\n /**\n * Create a directory.\n */\n async makeDir(uri: string): Promise<void> {\n if (!this.fileSystem) {\n throw new Error('FileSystem adapter not configured');\n }\n await this.fileSystem.makeDirectory(uri, {\n intermediates: true\n });\n }\n\n /**\n * Copy a file.\n */\n async copyFile(sourceUri: string, targetUri: string): Promise<void> {\n if (!this.fileSystem) {\n throw new Error('FileSystem adapter not configured');\n }\n await this.fileSystem.copyFile(sourceUri, targetUri);\n }\n\n /**\n * Get the user storage directory.\n */\n getUserStorageDirectory(): string {\n if (!this.fileSystem) {\n throw new Error('FileSystem adapter not configured');\n }\n return this.fileSystem.getDocumentsDirectory();\n }\n}\n\n/**\n * Create a SupabaseStorageAdapter with simplified configuration.\n *\n * @example\n * ```typescript\n * const adapter = createSupabaseStorageAdapter(\n * supabaseClient,\n * 'attachments',\n * platform.fileSystem\n * );\n * ```\n */\nexport function createSupabaseStorageAdapter(client: any, defaultBucket: string, fileSystem?: FileSystemAdapter, options?: {\n bucketMap?: Map<string, string>;\n signedUrlExpiry?: number;\n logger?: LoggerAdapter;\n}): SupabaseStorageAdapter {\n return new SupabaseStorageAdapter({\n client,\n bucketConfig: {\n defaultBucket,\n bucketMap: options?.bucketMap\n },\n signedUrlExpiry: options?.signedUrlExpiry,\n logger: options?.logger\n }, fileSystem);\n}","/**\n * Cache Settings Types for @pol-studios/powersync\n *\n * Defines types for cache configuration storage.\n * Note: UI-specific options (labels, descriptions) should be defined in the app.\n */\n\n/**\n * Cache settings stored via AsyncStorageAdapter.\n */\nexport interface CacheSettings {\n /**\n * Maximum cache size in megabytes.\n * A value of 0 indicates unlimited cache size.\n */\n maxCacheSizeMb: number;\n\n /**\n * Compression quality for cached images (0.0 to 1.0).\n * Higher values mean better quality but larger file sizes.\n */\n compressionQuality: number;\n}\n\n/**\n * Options for creating a CacheSettingsManager.\n */\nexport interface CacheSettingsManagerOptions {\n /**\n * Prefix for storage keys.\n * Useful for namespacing when multiple apps share storage.\n * @default '@pol-studios/cache'\n */\n storageKeyPrefix?: string;\n\n /**\n * Default values for cache settings.\n */\n defaults?: Partial<CacheSettings>;\n}\n\n/**\n * Default cache settings values.\n */\nexport const DEFAULT_CACHE_SETTINGS: CacheSettings = {\n maxCacheSizeMb: 5120,\n // 5 GB\n compressionQuality: 0.7 // 70% quality\n};","/**\n * Cache Settings Manager for @pol-studios/powersync\n *\n * Manages persistence of cache settings via AsyncStorageAdapter.\n * Uses platform-agnostic storage interface for cross-platform support.\n */\n\nimport type { AsyncStorageAdapter } from '../../platform/types';\nimport type { CacheSettings, CacheSettingsManagerOptions } from './types';\nimport { DEFAULT_CACHE_SETTINGS } from './types';\n\n/**\n * Storage keys used by the cache settings manager.\n */\nconst STORAGE_KEYS = {\n MAX_CACHE_SIZE_MB: 'max-cache-size-mb',\n COMPRESSION_QUALITY: 'compression-quality'\n} as const;\n\n/**\n * Manages cache settings persistence using AsyncStorageAdapter.\n *\n * @example\n * ```typescript\n * const manager = new CacheSettingsManager(platform.storage, {\n * storageKeyPrefix: '@myapp/cache',\n * defaults: { maxCacheSizeMb: 2048 },\n * });\n *\n * const settings = await manager.getSettings();\n * await manager.setMaxCacheSizeMb(1024);\n * ```\n */\nexport class CacheSettingsManager {\n private storage: AsyncStorageAdapter;\n private keyPrefix: string;\n private defaults: CacheSettings;\n constructor(storage: AsyncStorageAdapter, options?: CacheSettingsManagerOptions) {\n this.storage = storage;\n this.keyPrefix = options?.storageKeyPrefix ?? '@pol-studios/cache';\n this.defaults = {\n ...DEFAULT_CACHE_SETTINGS,\n ...options?.defaults\n };\n }\n\n /**\n * Get the full storage key for a setting.\n */\n private getKey(setting: keyof typeof STORAGE_KEYS): string {\n return `${this.keyPrefix}/${STORAGE_KEYS[setting]}`;\n }\n\n /**\n * Get all cache settings.\n */\n async getSettings(): Promise<CacheSettings> {\n const keys = [this.getKey('MAX_CACHE_SIZE_MB'), this.getKey('COMPRESSION_QUALITY')];\n const results = await this.storage.multiGet(keys);\n\n // Build settings object from stored values or defaults\n const sizeValue = results.find(([k]) => k === keys[0])?.[1];\n const qualityValue = results.find(([k]) => k === keys[1])?.[1];\n return {\n maxCacheSizeMb: sizeValue ? Number(sizeValue) : this.defaults.maxCacheSizeMb,\n compressionQuality: qualityValue ? Number(qualityValue) : this.defaults.compressionQuality\n };\n }\n\n /**\n * Get the maximum cache size in megabytes.\n * Returns 0 for unlimited.\n */\n async getMaxCacheSizeMb(): Promise<number> {\n const value = await this.storage.getItem(this.getKey('MAX_CACHE_SIZE_MB'));\n return value ? Number(value) : this.defaults.maxCacheSizeMb;\n }\n\n /**\n * Set the maximum cache size in megabytes.\n * Use 0 for unlimited.\n *\n * @param mb - Maximum cache size in megabytes\n */\n async setMaxCacheSizeMb(mb: number): Promise<void> {\n if (mb < 0) {\n throw new Error('Cache size must be non-negative');\n }\n await this.storage.setItem(this.getKey('MAX_CACHE_SIZE_MB'), String(mb));\n }\n\n /**\n * Get the maximum cache size in bytes.\n * Returns Number.MAX_SAFE_INTEGER for unlimited.\n */\n async getMaxCacheSizeBytes(): Promise<number> {\n const mb = await this.getMaxCacheSizeMb();\n return mb === 0 ? Number.MAX_SAFE_INTEGER : mb * 1024 * 1024;\n }\n\n /**\n * Get the compression quality (0.0 to 1.0).\n */\n async getCompressionQuality(): Promise<number> {\n const value = await this.storage.getItem(this.getKey('COMPRESSION_QUALITY'));\n return value ? Number(value) : this.defaults.compressionQuality;\n }\n\n /**\n * Set the compression quality.\n *\n * @param quality - Compression quality (0.0 to 1.0)\n */\n async setCompressionQuality(quality: number): Promise<void> {\n if (quality < 0 || quality > 1) {\n throw new Error('Compression quality must be between 0 and 1');\n }\n await this.storage.setItem(this.getKey('COMPRESSION_QUALITY'), String(quality));\n }\n\n /**\n * Reset all settings to defaults.\n */\n async resetToDefaults(): Promise<void> {\n await this.storage.multiSet([[this.getKey('MAX_CACHE_SIZE_MB'), String(this.defaults.maxCacheSizeMb)], [this.getKey('COMPRESSION_QUALITY'), String(this.defaults.compressionQuality)]]);\n }\n\n /**\n * Clear all stored settings.\n */\n async clear(): Promise<void> {\n await Promise.all([this.storage.removeItem(this.getKey('MAX_CACHE_SIZE_MB')), this.storage.removeItem(this.getKey('COMPRESSION_QUALITY'))]);\n }\n}"],"mappings":"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","names":[]}