syncorejs 0.2.3 → 0.2.4

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 (69) hide show
  1. package/dist/_vendor/core/cli.d.mts.map +1 -1
  2. package/dist/_vendor/core/cli.mjs +272 -7
  3. package/dist/_vendor/core/cli.mjs.map +1 -1
  4. package/dist/_vendor/core/index.d.mts +3 -3
  5. package/dist/_vendor/core/runtime/devtools.d.mts.map +1 -1
  6. package/dist/_vendor/core/runtime/devtools.mjs +131 -0
  7. package/dist/_vendor/core/runtime/devtools.mjs.map +1 -1
  8. package/dist/_vendor/core/runtime/functions.d.mts +3 -3
  9. package/dist/_vendor/core/runtime/functions.mjs.map +1 -1
  10. package/dist/_vendor/core/runtime/internal/engines/devtoolsEngine.mjs +1 -1
  11. package/dist/_vendor/core/runtime/internal/engines/devtoolsEngine.mjs.map +1 -1
  12. package/dist/_vendor/core/runtime/internal/engines/reactivityEngine.mjs +1 -1
  13. package/dist/_vendor/core/runtime/internal/engines/reactivityEngine.mjs.map +1 -1
  14. package/dist/_vendor/core/runtime/internal/engines/shared.mjs +5 -1
  15. package/dist/_vendor/core/runtime/internal/engines/shared.mjs.map +1 -1
  16. package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs +99 -13
  17. package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs.map +1 -1
  18. package/dist/_vendor/core/runtime/internal/runtimeKernel.mjs +38 -4
  19. package/dist/_vendor/core/runtime/internal/runtimeKernel.mjs.map +1 -1
  20. package/dist/_vendor/core/runtime/runtime.d.mts +65 -8
  21. package/dist/_vendor/core/runtime/runtime.d.mts.map +1 -1
  22. package/dist/_vendor/core/runtime/runtime.mjs.map +1 -1
  23. package/dist/_vendor/core/transport.d.mts.map +1 -1
  24. package/dist/_vendor/core/transport.mjs +30 -5
  25. package/dist/_vendor/core/transport.mjs.map +1 -1
  26. package/dist/_vendor/devtools-protocol/index.d.ts +75 -1
  27. package/dist/_vendor/devtools-protocol/index.d.ts.map +1 -1
  28. package/dist/_vendor/devtools-protocol/index.js.map +1 -1
  29. package/dist/_vendor/next/index.js +9 -1
  30. package/dist/_vendor/next/index.js.map +1 -1
  31. package/dist/_vendor/platform-expo/index.d.ts +1 -1
  32. package/dist/_vendor/platform-expo/index.d.ts.map +1 -1
  33. package/dist/_vendor/platform-expo/index.js +6 -1
  34. package/dist/_vendor/platform-expo/index.js.map +1 -1
  35. package/dist/_vendor/platform-node/index.d.mts +2 -1
  36. package/dist/_vendor/platform-node/index.d.mts.map +1 -1
  37. package/dist/_vendor/platform-node/index.mjs +27 -2
  38. package/dist/_vendor/platform-node/index.mjs.map +1 -1
  39. package/dist/_vendor/platform-node/ipc-react.mjs +4 -0
  40. package/dist/_vendor/platform-node/ipc-react.mjs.map +1 -1
  41. package/dist/_vendor/platform-web/external-change.d.ts +2 -2
  42. package/dist/_vendor/platform-web/external-change.js +2 -2
  43. package/dist/_vendor/platform-web/external-change.js.map +1 -1
  44. package/dist/_vendor/platform-web/index.d.ts +13 -10
  45. package/dist/_vendor/platform-web/index.d.ts.map +1 -1
  46. package/dist/_vendor/platform-web/index.js +66 -10
  47. package/dist/_vendor/platform-web/index.js.map +1 -1
  48. package/dist/_vendor/platform-web/indexeddb.d.ts +3 -3
  49. package/dist/_vendor/platform-web/indexeddb.js +3 -3
  50. package/dist/_vendor/platform-web/indexeddb.js.map +1 -1
  51. package/dist/_vendor/platform-web/opfs.d.ts +3 -1
  52. package/dist/_vendor/platform-web/opfs.d.ts.map +1 -1
  53. package/dist/_vendor/platform-web/opfs.js +29 -3
  54. package/dist/_vendor/platform-web/opfs.js.map +1 -1
  55. package/dist/_vendor/platform-web/persistence.d.ts +31 -1
  56. package/dist/_vendor/platform-web/persistence.d.ts.map +1 -1
  57. package/dist/_vendor/platform-web/persistence.js.map +1 -1
  58. package/dist/_vendor/platform-web/react.d.ts.map +1 -1
  59. package/dist/_vendor/platform-web/react.js +9 -1
  60. package/dist/_vendor/platform-web/react.js.map +1 -1
  61. package/dist/_vendor/react/index.d.ts +6 -5
  62. package/dist/_vendor/react/index.d.ts.map +1 -1
  63. package/dist/_vendor/react/index.js +6 -5
  64. package/dist/_vendor/react/index.js.map +1 -1
  65. package/dist/_vendor/svelte/index.d.ts +8 -6
  66. package/dist/_vendor/svelte/index.d.ts.map +1 -1
  67. package/dist/_vendor/svelte/index.js +7 -5
  68. package/dist/_vendor/svelte/index.js.map +1 -1
  69. package/package.json +1 -1
@@ -179,6 +179,14 @@ interface SyncoreDevtoolsCapabilities {
179
179
  mutate: boolean;
180
180
  importExport: boolean;
181
181
  };
182
+ storage?: {
183
+ browse: boolean;
184
+ download: boolean;
185
+ readRange?: boolean;
186
+ delete: boolean;
187
+ maxPreviewBytes?: number;
188
+ reason?: string;
189
+ };
182
190
  scheduler?: {
183
191
  read: boolean;
184
192
  edit: boolean;
@@ -301,6 +309,23 @@ type SyncoreDevtoolsCommandPayload = {
301
309
  } | {
302
310
  kind: "sql.write";
303
311
  query: string;
312
+ } | {
313
+ kind: "storage.list";
314
+ limit?: number;
315
+ offset?: number;
316
+ search?: string;
317
+ } | {
318
+ kind: "storage.access.create";
319
+ id: string;
320
+ purpose: "preview" | "download";
321
+ } | {
322
+ kind: "storage.readRange";
323
+ id: string;
324
+ offset: number;
325
+ length: number;
326
+ } | {
327
+ kind: "storage.delete";
328
+ id: string;
304
329
  } | {
305
330
  kind: "scheduler.cancel";
306
331
  jobId: string;
@@ -333,6 +358,11 @@ type SyncoreDevtoolsSubscriptionPayload = {
333
358
  kind: "scheduler.jobs";
334
359
  } | {
335
360
  kind: "functions.catalog";
361
+ } | {
362
+ kind: "storage.list";
363
+ limit?: number;
364
+ offset?: number;
365
+ search?: string;
336
366
  } | {
337
367
  kind: "sql.watch";
338
368
  query: string;
@@ -378,6 +408,35 @@ type SyncoreDevtoolsCommandResultPayload = {
378
408
  rowsAffected: number;
379
409
  error?: string;
380
410
  invalidationScopes: string[];
411
+ } | {
412
+ kind: "storage.list.result";
413
+ entries: StorageEntry[];
414
+ totalCount: number;
415
+ offset: number;
416
+ hasMore: boolean;
417
+ error?: string;
418
+ } | {
419
+ kind: "storage.access.create.result";
420
+ entry?: StorageEntry;
421
+ url?: string;
422
+ expiresAt?: number;
423
+ supportsRange?: boolean;
424
+ maxPreviewBytes?: number;
425
+ error?: string;
426
+ } | {
427
+ kind: "storage.readRange.result";
428
+ entry?: StorageEntry;
429
+ offset: number;
430
+ bytesRead: number;
431
+ done: boolean;
432
+ supportsRange: boolean;
433
+ base64?: string;
434
+ error?: string;
435
+ } | {
436
+ kind: "storage.delete.result";
437
+ success: boolean;
438
+ deleted: boolean;
439
+ error?: string;
381
440
  } | {
382
441
  kind: "scheduler.cancel.result";
383
442
  success: boolean;
@@ -417,6 +476,13 @@ type SyncoreDevtoolsSubscriptionResultPayload = {
417
476
  } | {
418
477
  kind: "functions.catalog.result";
419
478
  functions: FunctionDefinition[];
479
+ } | {
480
+ kind: "storage.list.result";
481
+ entries: StorageEntry[];
482
+ totalCount: number;
483
+ offset: number;
484
+ hasMore: boolean;
485
+ error?: string;
420
486
  } | {
421
487
  kind: "sql.watch.result";
422
488
  columns: string[];
@@ -461,6 +527,14 @@ interface TableIndex {
461
527
  fields: string[];
462
528
  unique: boolean;
463
529
  }
530
+ interface StorageEntry {
531
+ id: string;
532
+ createdAt: number;
533
+ fileName?: string;
534
+ contentType?: string;
535
+ size: number;
536
+ path: string;
537
+ }
464
538
  interface SchedulerJob {
465
539
  id: string;
466
540
  functionName: string;
@@ -516,5 +590,5 @@ type SchedulerMisfirePolicy = {
516
590
  windowMs: number;
517
591
  };
518
592
  //#endregion
519
- export { DataFilter, DevtoolsPreview, DocumentChangePreview, ExecutionTrace, FunctionDefinition, InvalidationCause, SYNCORE_DEVTOOLS_MAX_SUPPORTED_PROTOCOL_VERSION, SYNCORE_DEVTOOLS_MIN_SUPPORTED_PROTOCOL_VERSION, SYNCORE_DEVTOOLS_PROTOCOL_VERSION, SchedulerJob, SchedulerMisfirePolicy, SchedulerRecurringDailySchedule, SchedulerRecurringIntervalSchedule, SchedulerRecurringSchedule, SchedulerRecurringWeeklySchedule, SyncoreActiveQueryInfo, SyncoreDevtoolsCapabilities, SyncoreDevtoolsClientMessage, SyncoreDevtoolsCommand, SyncoreDevtoolsCommandPayload, SyncoreDevtoolsCommandResultPayload, SyncoreDevtoolsEvent, SyncoreDevtoolsEventOrigin, SyncoreDevtoolsExternalChangeEvent, SyncoreDevtoolsMessage, SyncoreDevtoolsSubscribe, SyncoreDevtoolsSubscriptionPayload, SyncoreDevtoolsSubscriptionResultPayload, SyncoreDevtoolsUnsubscribe, SyncoreRuntimeSummary, TableField, TableIndex, TableSchema, VersionHandshake, createBasePublicId, createPublicId, createPublicRuntimeId, createPublicTargetId, isCompatibleVersionHandshake };
593
+ export { DataFilter, DevtoolsPreview, DocumentChangePreview, ExecutionTrace, FunctionDefinition, InvalidationCause, SYNCORE_DEVTOOLS_MAX_SUPPORTED_PROTOCOL_VERSION, SYNCORE_DEVTOOLS_MIN_SUPPORTED_PROTOCOL_VERSION, SYNCORE_DEVTOOLS_PROTOCOL_VERSION, SchedulerJob, SchedulerMisfirePolicy, SchedulerRecurringDailySchedule, SchedulerRecurringIntervalSchedule, SchedulerRecurringSchedule, SchedulerRecurringWeeklySchedule, StorageEntry, SyncoreActiveQueryInfo, SyncoreDevtoolsCapabilities, SyncoreDevtoolsClientMessage, SyncoreDevtoolsCommand, SyncoreDevtoolsCommandPayload, SyncoreDevtoolsCommandResultPayload, SyncoreDevtoolsEvent, SyncoreDevtoolsEventOrigin, SyncoreDevtoolsExternalChangeEvent, SyncoreDevtoolsMessage, SyncoreDevtoolsSubscribe, SyncoreDevtoolsSubscriptionPayload, SyncoreDevtoolsSubscriptionResultPayload, SyncoreDevtoolsUnsubscribe, SyncoreRuntimeSummary, TableField, TableIndex, TableSchema, VersionHandshake, createBasePublicId, createPublicId, createPublicRuntimeId, createPublicTargetId, isCompatibleVersionHandshake };
520
594
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";KAAY,0BAAA;AAAA,cAEC,iCAAA;AAAA,cACA,+CAAA;AAAA,cACA,+CAAA;AAAA,UAEI,gBAAA;EACf,eAAA;EACA,2BAAA;EACA,2BAAA;EACA,cAAA;AAAA;AAAA,iBAGc,4BAAA,CACd,SAAA,EAAW,IAAI,CACb,gBAAA;AAAA,KAcC,wBAAA;EACH,SAAA;EACA,SAAA;EACA,QAAA;EACA,MAAA,GAAS,0BAA0B;AAAA;AAAA,KAGzB,eAAA;EAEN,IAAA;EACA,KAAA;EACA,SAAA;EACA,IAAA;AAAA;EAGA,IAAA;EACA,OAAA;EACA,SAAA;AAAA;AAAA,UAGW,qBAAA;EACf,KAAA;EACA,EAAA;EACA,SAAA;EACA,MAAA;EACA,aAAA,GAAgB,eAAA;EAChB,YAAA,GAAe,eAAe;AAAA;AAAA,UAGf,iBAAA;EACf,WAAA;EACA,MAAA;EACA,aAAA;EACA,aAAA;AAAA;AAAA,UAGe,cAAA;EACf,WAAA;EACA,iBAAA;EACA,IAAA;EACA,YAAA;EACA,WAAA,GAAc,eAAA;EACd,aAAA,GAAgB,eAAA;EAChB,KAAA;EACA,UAAA;EACA,WAAA;EACA,aAAA;EACA,uBAAA,GAA0B,qBAAA;EAC1B,mBAAA;EACA,cAAA;AAAA;AAAA,KAGU,oBAAA,IACP,wBAAA;EACC,IAAA;EACA,QAAA;AAAA,MAED,wBAAA;EACC,IAAA;AAAA,MAED,wBAAA;EACC,IAAA;EACA,OAAA;EACA,YAAA;EACA,aAAA;EACA,aAAA;EACA,YAAA;EACA,UAAA;EACA,WAAA;EACA,iBAAA;EACA,WAAA,GAAc,eAAA;EACd,aAAA,GAAgB,eAAA;EAChB,UAAA;AAAA,MAED,wBAAA;EACC,IAAA;EACA,OAAA;EACA,aAAA;EACA,aAAA;EACA,MAAA;EACA,mBAAA;EACA,aAAA;EACA,aAAA;EACA,gBAAA;AAAA,MAED,wBAAA;EACC,IAAA;EACA,UAAA;EACA,YAAA;EACA,aAAA;EACA,aAAA;EACA,aAAA;EACA,UAAA;EACA,WAAA;EACA,iBAAA;EACA,WAAA,GAAc,eAAA;EACd,aAAA,GAAgB,eAAA;EAChB,WAAA;EACA,aAAA;EACA,uBAAA,GAA0B,qBAAA;EAC1B,mBAAA;AAAA,MAED,wBAAA;EACC,IAAA;EACA,QAAA;EACA,YAAA;EACA,aAAA;EACA,aAAA;EACA,UAAA;EACA,KAAA;EACA,WAAA;EACA,iBAAA;EACA,WAAA,GAAc,eAAA;EACd,aAAA,GAAgB,eAAA;EAChB,WAAA;EACA,aAAA;EACA,uBAAA,GAA0B,qBAAA;EAC1B,mBAAA;AAAA,MAED,wBAAA;EACC,IAAA;EACA,cAAA;EACA,WAAA;EACA,aAAA,GAAgB,KAAA;IACd,KAAA;IACA,WAAA;IACA,YAAA;IACA,YAAA;IACA,WAAA,GAAc,eAAA;IACd,aAAA,GAAgB,eAAA;IAChB,KAAA;IACA,UAAA;EAAA;AAAA,MAGH,wBAAA;EACC,IAAA;EACA,SAAA;EACA,aAAA;EACA,SAAA;AAAA,MAED,wBAAA;EACC,IAAA;EACA,KAAA;EACA,OAAA;AAAA;AAAA,UAGW,sBAAA;EACf,EAAA;EACA,YAAA;EACA,IAAA,GAAO,MAAM;EACb,SAAA;EACA,KAAA;EACA,aAAA;EACA,aAAA;EACA,cAAA;EACA,SAAA;AAAA;AAAA,UAGe,qBAAA;EACf,SAAA;EACA,QAAA;EACA,OAAA;EACA,MAAA;EACA,YAAA;EACA,UAAA;EACA,WAAA;EACA,eAAA;EACA,aAAA;EACA,eAAA;EACA,eAAA;EACA,YAAA,GAAe,2BAA2B;EAC1C,WAAA;EACA,gBAAA;EACA,gBAAA;AAAA;AAAA,UAGe,2BAAA;EACf,GAAA;IACE,IAAA;IACA,KAAA;IACA,IAAA;IACA,MAAA;EAAA;EAEF,IAAA;IACE,MAAA;IACA,MAAA;IACA,YAAA;EAAA;EAEF,SAAA;IACE,IAAA;IACA,IAAA;EAAA;AAAA;AAAA,UAIa,kCAAA;EACf,QAAA;EACA,KAAA;EACA,MAAA;EACA,SAAA;EACA,QAAA;EACA,aAAA;EACA,aAAA;EACA,UAAA;AAAA;AAAA,iBAGc,kBAAA,CAAmB,KAAa;AAAA,iBAIhC,cAAA,CACd,GAAA,UACA,IAAA,EAAM,QAAQ;AAAA,iBAKA,qBAAA,CACd,SAAA,UACA,UAAA,GAAa,QAAQ;AAAA,iBAOP,oBAAA,CACd,SAAA,UACA,UAAA,EAAY,QAAQ;AAAA,KAsDV,sBAAA;EAEN,IAAA;EACA,eAAA;EACA,2BAAA;EACA,2BAAA;EACA,cAAA;EACA,SAAA;EACA,QAAA;EACA,OAAA;EACA,MAAA;EACA,YAAA;EACA,UAAA;EACA,WAAA;EACA,eAAA;EACA,aAAA;EACA,eAAA;EACA,eAAA;EACA,YAAA,GAAe,2BAAA;AAAA;EAEf,IAAA;EAAe,KAAA,EAAO,oBAAA;AAAA;EAEtB,IAAA;EACA,SAAA;EACA,MAAA,EAAQ,oBAAA;AAAA;EAER,IAAA;AAAA;EACA,IAAA;AAAA;EAEA,IAAA;EACA,SAAA;EACA,SAAA;EACA,OAAA,EAAS,mCAAA;AAAA;EAGT,IAAA;EACA,cAAA;EACA,SAAA;EACA,OAAA,EAAS,wCAAA;AAAA;EAGT,IAAA;EACA,cAAA;EACA,SAAA;EACA,KAAA;AAAA;EAGA,IAAA;EACA,SAAA;EACA,eAAA;EACA,KAAA,EAAO,kCAAA;AAAA;AAAA,UAOI,sBAAA;EACf,IAAA;EACA,SAAA;EACA,eAAA;EACA,OAAA,EAAS,6BAA6B;AAAA;AAAA,UAGvB,wBAAA;EACf,IAAA;EACA,cAAA;EACA,eAAA;EACA,OAAA,EAAS,kCAAkC;AAAA;AAAA,UAG5B,0BAAA;EACf,IAAA;EACA,cAAA;EACA,eAAA;AAAA;AAAA,KAGU,4BAAA;EACN,IAAA;AAAA,IACF,sBAAA,GACA,wBAAA,GACA,0BAAA;AAAA,KAEQ,6BAAA;EAGN,IAAA;EACA,YAAA;EACA,YAAA;EACA,IAAA,EAAM,MAAA;AAAA;EAEN,IAAA;EAAqB,KAAA;EAAe,QAAA,EAAU,MAAA;AAAA;EAE9C,IAAA;EACA,KAAA;EACA,EAAA;EACA,MAAA,EAAQ,MAAA;AAAA;EAER,IAAA;EAAqB,KAAA;EAAe,EAAA;AAAA;EACpC,IAAA;EAAqB,MAAA;AAAA;EAErB,IAAA;EACA,KAAA;EACA,MAAA;EACA,KAAA;EACA,MAAA;AAAA;EAGA,IAAA;EAAkB,KAAA;AAAA;EAClB,IAAA;EAAmB,KAAA;AAAA;EAEnB,IAAA;EAA0B,KAAA;AAAA;EAE1B,IAAA;EACA,KAAA;EACA,QAAA,GAAW,0BAAA;EACX,IAAA,EAAM,MAAA;EACN,aAAA,GAAgB,sBAAA;EAChB,KAAA;AAAA;AAAA,KAGM,kCAAA;EACN,IAAA;AAAA;EACA,IAAA;AAAA;EACA,IAAA;AAAA;EAEA,IAAA;EACA,YAAA;EACA,YAAA;EACA,IAAA,EAAM,MAAA;AAAA;EAGN,IAAA;EACA,KAAA;EACA,OAAA,GAAU,UAAU;EACpB,KAAA;EACA,MAAA;AAAA;EAEA,IAAA;AAAA;EACA,IAAA;AAAA;EACA,IAAA;EAAmB,KAAA;AAAA;AAAA,UAER,UAAA;EACf,KAAA;EACA,QAAA;EASA,KAAA;AAAA;AAAA,KAOU,mCAAA;EAEN,IAAA;EACA,MAAA;EACA,KAAA;EACA,UAAA;AAAA;EAGA,IAAA;EACA,OAAA;EACA,EAAA;EACA,KAAA;AAAA;EAGA,IAAA;EACA,MAAA,EAAQ,KAAA;IACN,IAAA;IACA,IAAA,EAAM,MAAA;IACN,UAAA;EAAA;EAEF,KAAA;AAAA;EAGA,IAAA;EACA,KAAA;EACA,IAAA,EAAM,MAAA;EACN,UAAA;EACA,MAAA;EACA,OAAA;EACA,KAAA;AAAA;EAGA,IAAA;EACA,OAAA;EACA,IAAA;EACA,KAAA;AAAA;EAGA,IAAA;EACA,YAAA;EACA,KAAA;EACA,kBAAA;AAAA;EAGA,IAAA;EACA,OAAA;EACA,SAAA;EACA,KAAA;AAAA;EAGA,IAAA;EACA,OAAA;EACA,OAAA;EACA,KAAA;EACA,GAAA,GAAM,YAAA;AAAA;EAEN,IAAA;EAAe,OAAA;AAAA;AAAA,KAET,wCAAA;EACN,IAAA;EAAgC,OAAA,EAAS,qBAAA;AAAA;EAEzC,IAAA;EACA,aAAA,EAAe,sBAAA;AAAA;EAGf,IAAA;EACA,MAAA;EACA,KAAA;AAAA;EAEA,IAAA;EAA8B,MAAA,EAAQ,WAAA;AAAA;EAEtC,IAAA;EACA,IAAA,EAAM,MAAA;EACN,UAAA;EACA,MAAA;AAAA;EAEA,IAAA;EAA+B,IAAA,EAAM,YAAA;AAAA;EACrC,IAAA;EAAkC,SAAA,EAAW,kBAAA;AAAA;EAE7C,IAAA;EACA,OAAA;EACA,IAAA;EACA,cAAA;AAAA;AAAA,UAOW,kBAAA;EACf,IAAA;EACA,IAAA;EACA,IAAA;EACA,UAAA;EACA,SAAA;EACA,iBAAA;EACA,KAAA;EACA,aAAA;EACA,aAAA;EACA,UAAA;EACA,SAAA;EApLE;EAsLF,IAAA,GAAO,MAAA;EArLqB;EAuL5B,OAAA,GAAU,MAAM;AAAA;AAAA,UAGD,WAAA;EACf,IAAA;EACA,WAAA;EACA,KAAA;EACA,aAAA;EACA,aAAA;EACA,MAAA,EAAQ,UAAA;EACR,OAAA,EAAS,UAAU;EACnB,aAAA;AAAA;AAAA,UAGe,UAAA;EACf,IAAA;EACA,IAAA;EACA,QAAA;EACA,cAAA;AAAA;AAAA,UAGe,UAAA;EACf,IAAA;EACA,MAAA;EACA,MAAA;AAAA;AAAA,UAGe,YAAA;EACf,EAAA;EACA,YAAA;EACA,KAAA;EACA,aAAA;EACA,aAAA;EACA,IAAA,EAAM,MAAA;EACN,WAAA;EACA,KAAA;EACA,MAAA;EACA,WAAA;EACA,MAAA;EACA,KAAA;EACA,UAAA;EACA,aAAA;EACA,QAAA,GAAW,0BAAA;EACX,aAAA;EACA,aAAA,GAAgB,sBAAA;EAChB,QAAA;EACA,SAAA;EACA,SAAA;EApMI;EAsMJ,YAAA;AAAA;AAAA,UAGe,kCAAA;EACf,IAAA;EACA,OAAA;EACA,OAAA;EACA,KAAA;AAAA;AAAA,UAGe,+BAAA;EACf,IAAA;EACA,IAAA;EACA,MAAA;EACA,QAAA;AAAA;AAAA,UAGe,gCAAA;EACf,IAAA;EACA,SAAA;EAQA,IAAA;EACA,MAAA;EACA,QAAA;AAAA;AAAA,KAGU,0BAAA,GACR,kCAAA,GACA,+BAAA,GACA,gCAAA;AAAA,KAEQ,sBAAA;EACN,IAAA;AAAA;EACA,IAAA;AAAA;EACA,IAAA;AAAA;EACA,IAAA;EAAkB,QAAA;AAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["export type SyncoreDevtoolsEventOrigin = \"runtime\" | \"dashboard\";\n\nexport const SYNCORE_DEVTOOLS_PROTOCOL_VERSION = 1;\nexport const SYNCORE_DEVTOOLS_MIN_SUPPORTED_PROTOCOL_VERSION = 1;\nexport const SYNCORE_DEVTOOLS_MAX_SUPPORTED_PROTOCOL_VERSION = 1;\n\nexport interface VersionHandshake {\n protocolVersion: number;\n minSupportedProtocolVersion: number;\n maxSupportedProtocolVersion: number;\n runtimeVersion?: string;\n}\n\nexport function isCompatibleVersionHandshake(\n handshake: Pick<\n VersionHandshake,\n \"protocolVersion\" | \"minSupportedProtocolVersion\" | \"maxSupportedProtocolVersion\"\n >\n): boolean {\n return (\n handshake.maxSupportedProtocolVersion >=\n SYNCORE_DEVTOOLS_MIN_SUPPORTED_PROTOCOL_VERSION &&\n handshake.minSupportedProtocolVersion <=\n SYNCORE_DEVTOOLS_MAX_SUPPORTED_PROTOCOL_VERSION &&\n handshake.protocolVersion >= handshake.minSupportedProtocolVersion &&\n handshake.protocolVersion <= handshake.maxSupportedProtocolVersion\n );\n}\n\ntype SyncoreDevtoolsEventBase = {\n runtimeId: string;\n timestamp: number;\n sequence?: number;\n origin?: SyncoreDevtoolsEventOrigin;\n};\n\nexport type DevtoolsPreview =\n | {\n kind: \"value\";\n value: unknown;\n truncated?: boolean;\n note?: string;\n }\n | {\n kind: \"error\";\n message: string;\n truncated?: boolean;\n };\n\nexport interface DocumentChangePreview {\n table: string;\n id: string;\n operation: \"insert\" | \"patch\" | \"replace\" | \"delete\";\n fields?: string[];\n beforePreview?: DevtoolsPreview;\n afterPreview?: DevtoolsPreview;\n}\n\nexport interface InvalidationCause {\n executionId?: string;\n reason: string;\n changedScopes: string[];\n matchedScopes: string[];\n}\n\nexport interface ExecutionTrace {\n executionId: string;\n parentExecutionId?: string;\n kind: \"query\" | \"mutation\" | \"action\" | \"scheduler\" | \"dashboard\";\n functionName?: string;\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n error?: string;\n readScopes?: string[];\n writeScopes?: string[];\n changedScopes?: string[];\n changedDocumentsPreview?: DocumentChangePreview[];\n invalidatedQueryIds?: string[];\n schedulerJobId?: string;\n}\n\nexport type SyncoreDevtoolsEvent =\n | (SyncoreDevtoolsEventBase & {\n type: \"runtime.connected\";\n platform: string;\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"runtime.disconnected\";\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"query.executed\";\n queryId: string;\n functionName: string;\n componentPath?: string;\n componentName?: string;\n dependencies: string[];\n durationMs: number;\n executionId?: string;\n parentExecutionId?: string;\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n readScopes?: string[];\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"query.invalidated\";\n queryId: string;\n componentPath?: string;\n componentName?: string;\n reason: string;\n causedByExecutionId?: string;\n changedScopes?: string[];\n matchedScopes?: string[];\n rerunExecutionId?: string;\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"mutation.committed\";\n mutationId: string;\n functionName: string;\n componentPath?: string;\n componentName?: string;\n changedTables: string[];\n durationMs: number;\n executionId?: string;\n parentExecutionId?: string;\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n writeScopes?: string[];\n changedScopes?: string[];\n changedDocumentsPreview?: DocumentChangePreview[];\n invalidatedQueryIds?: string[];\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"action.completed\";\n actionId: string;\n functionName: string;\n componentPath?: string;\n componentName?: string;\n durationMs: number;\n error?: string;\n executionId?: string;\n parentExecutionId?: string;\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n writeScopes?: string[];\n changedScopes?: string[];\n changedDocumentsPreview?: DocumentChangePreview[];\n invalidatedQueryIds?: string[];\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"scheduler.tick\";\n executedJobIds: string[];\n executionId?: string;\n jobExecutions?: Array<{\n jobId: string;\n executionId?: string;\n functionName: string;\n functionType: \"mutation\" | \"action\";\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n error?: string;\n durationMs?: number;\n }>;\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"storage.updated\";\n storageId: string;\n componentPath?: string;\n operation: \"put\" | \"delete\";\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"log\";\n level: \"info\" | \"warn\" | \"error\";\n message: string;\n });\n\nexport interface SyncoreActiveQueryInfo {\n id: string;\n functionName: string;\n args?: Record<string, unknown>;\n consumers?: number;\n owner?: \"root\" | \"component\";\n componentPath?: string;\n componentName?: string;\n dependencyKeys: string[];\n lastRunAt: number;\n}\n\nexport interface SyncoreRuntimeSummary {\n runtimeId: string;\n platform: string;\n appName?: string;\n origin?: string;\n sessionLabel?: string;\n targetKind?: \"client\" | \"project\";\n runtimeRole?: \"app\" | \"project-target\";\n storageProtocol?: string;\n databaseLabel?: string;\n dataSourceAlias?: string;\n storageIdentity?: string;\n capabilities?: SyncoreDevtoolsCapabilities;\n connectedAt: number;\n activeQueryCount: number;\n recentEventCount: number;\n}\n\nexport interface SyncoreDevtoolsCapabilities {\n sql?: {\n read: boolean;\n write: boolean;\n live: boolean;\n reason?: string;\n };\n data?: {\n browse: boolean;\n mutate: boolean;\n importExport: boolean;\n };\n scheduler?: {\n read: boolean;\n edit: boolean;\n };\n}\n\nexport interface SyncoreDevtoolsExternalChangeEvent {\n sourceId: string;\n scope: \"database\" | \"storage\" | \"all\";\n reason: \"commit\" | \"storage-put\" | \"storage-delete\" | \"reconcile\";\n timestamp: number;\n revision?: string;\n changedScopes?: string[];\n changedTables?: string[];\n storageIds?: string[];\n}\n\nexport function createBasePublicId(input: string): string {\n return stablePublicId(input, 0);\n}\n\nexport function createPublicId(\n key: string,\n keys: Iterable<string>\n): string {\n return createPublicIdWithFormatter(key, keys, stablePublicId);\n}\n\nexport function createPublicRuntimeId(\n runtimeId: string,\n runtimeIds?: Iterable<string>\n): string {\n return runtimeIds\n ? createPublicIdWithFormatter(runtimeId, runtimeIds, stableRuntimePublicId)\n : stableRuntimePublicId(runtimeId, 0);\n}\n\nexport function createPublicTargetId(\n targetKey: string,\n targetKeys: Iterable<string>\n): string {\n return createPublicId(targetKey, targetKeys);\n}\n\nfunction createPublicIdWithFormatter(\n key: string,\n keys: Iterable<string>,\n formatPublicId: (input: string, salt: number) => string\n): string {\n const used = new Set<string>();\n for (const existingKey of [...keys].sort()) {\n let attempt = 0;\n while (true) {\n const candidate = formatPublicId(existingKey, attempt);\n if (existingKey === key && !used.has(candidate)) {\n return candidate;\n }\n if (!used.has(candidate)) {\n used.add(candidate);\n break;\n }\n attempt += 1;\n }\n }\n return formatPublicId(key, 0);\n}\n\nfunction stablePublicId(input: string, salt: number): string {\n const value = stableHash(input, salt) % 100000;\n return value.toString().padStart(5, \"0\");\n}\n\nfunction stableRuntimePublicId(input: string, salt: number): string {\n const value = stableHash(input, salt);\n const letter = String.fromCharCode(65 + (value % 26));\n const digits = Math.floor(value / 26) % 1000;\n return `${letter}${digits.toString().padStart(3, \"0\")}`;\n}\n\nfunction stableHash(input: string, salt: number): number {\n const hashInput = salt === 0 ? input : `${input}#${salt}`;\n let hash = 2166136261;\n for (let index = 0; index < hashInput.length; index += 1) {\n hash ^= hashInput.charCodeAt(index);\n hash = Math.imul(hash, 16777619);\n }\n return hash >>> 0;\n}\n\n/* ------------------------------------------------------------------ */\n/* Runtime → Dashboard messages */\n/* ------------------------------------------------------------------ */\n\nexport type SyncoreDevtoolsMessage =\n | {\n type: \"hello\";\n protocolVersion?: number;\n minSupportedProtocolVersion?: number;\n maxSupportedProtocolVersion?: number;\n runtimeVersion?: string;\n runtimeId: string;\n platform: string;\n appName?: string;\n origin?: string;\n sessionLabel?: string;\n targetKind?: \"client\" | \"project\";\n runtimeRole?: \"app\" | \"project-target\";\n storageProtocol?: string;\n databaseLabel?: string;\n dataSourceAlias?: string;\n storageIdentity?: string;\n capabilities?: SyncoreDevtoolsCapabilities;\n }\n | { type: \"event\"; event: SyncoreDevtoolsEvent }\n | {\n type: \"event.batch\";\n runtimeId: string;\n events: SyncoreDevtoolsEvent[];\n }\n | { type: \"ping\" }\n | { type: \"pong\" }\n | {\n type: \"command.result\";\n commandId: string;\n runtimeId: string;\n payload: SyncoreDevtoolsCommandResultPayload;\n }\n | {\n type: \"subscription.data\";\n subscriptionId: string;\n runtimeId: string;\n payload: SyncoreDevtoolsSubscriptionResultPayload;\n }\n | {\n type: \"subscription.error\";\n subscriptionId: string;\n runtimeId: string;\n error: string;\n }\n | {\n type: \"external.change\";\n runtimeId: string;\n storageIdentity: string;\n event: SyncoreDevtoolsExternalChangeEvent;\n };\n\n/* ------------------------------------------------------------------ */\n/* Dashboard → Runtime requests */\n/* ------------------------------------------------------------------ */\n\nexport interface SyncoreDevtoolsCommand {\n type: \"command\";\n commandId: string;\n targetRuntimeId: string;\n payload: SyncoreDevtoolsCommandPayload;\n}\n\nexport interface SyncoreDevtoolsSubscribe {\n type: \"subscribe\";\n subscriptionId: string;\n targetRuntimeId: string;\n payload: SyncoreDevtoolsSubscriptionPayload;\n}\n\nexport interface SyncoreDevtoolsUnsubscribe {\n type: \"unsubscribe\";\n subscriptionId: string;\n targetRuntimeId: string;\n}\n\nexport type SyncoreDevtoolsClientMessage =\n | { type: \"ping\" }\n | SyncoreDevtoolsCommand\n | SyncoreDevtoolsSubscribe\n | SyncoreDevtoolsUnsubscribe;\n\nexport type SyncoreDevtoolsCommandPayload =\n /* Functions */\n | {\n kind: \"fn.run\";\n functionName: string;\n functionType: \"query\" | \"mutation\" | \"action\";\n args: Record<string, unknown>;\n }\n | { kind: \"data.insert\"; table: string; document: Record<string, unknown> }\n | {\n kind: \"data.patch\";\n table: string;\n id: string;\n fields: Record<string, unknown>;\n }\n | { kind: \"data.delete\"; table: string; id: string }\n | { kind: \"data.export\"; tables?: string[] }\n | {\n kind: \"data.referenceOptions\";\n table: string;\n search?: string;\n limit?: number;\n offset?: number;\n }\n /* SQL */\n | { kind: \"sql.read\"; query: string }\n | { kind: \"sql.write\"; query: string }\n /* Scheduler */\n | { kind: \"scheduler.cancel\"; jobId: string }\n | {\n kind: \"scheduler.update\";\n jobId: string;\n schedule?: SchedulerRecurringSchedule;\n args: Record<string, unknown>;\n misfirePolicy?: SchedulerMisfirePolicy;\n runAt?: number;\n };\n\nexport type SyncoreDevtoolsSubscriptionPayload =\n | { kind: \"runtime.summary\" }\n | { kind: \"runtime.activeQueries\" }\n | { kind: \"schema.tables\" }\n | {\n kind: \"fn.watch\";\n functionName: string;\n functionType: \"query\";\n args: Record<string, unknown>;\n }\n | {\n kind: \"data.table\";\n table: string;\n filters?: DataFilter[];\n limit?: number;\n cursor?: string;\n }\n | { kind: \"scheduler.jobs\" }\n | { kind: \"functions.catalog\" }\n | { kind: \"sql.watch\"; query: string };\n\nexport interface DataFilter {\n field: string;\n operator:\n | \"eq\"\n | \"neq\"\n | \"gt\"\n | \"gte\"\n | \"lt\"\n | \"lte\"\n | \"contains\"\n | \"startsWith\";\n value: unknown;\n}\n\n/* ------------------------------------------------------------------ */\n/* Response payloads */\n/* ------------------------------------------------------------------ */\n\nexport type SyncoreDevtoolsCommandResultPayload =\n | {\n kind: \"fn.run.result\";\n result?: unknown;\n error?: string;\n durationMs: number;\n }\n | {\n kind: \"data.mutate.result\";\n success: boolean;\n id?: string;\n error?: string;\n }\n | {\n kind: \"data.export.result\";\n tables: Array<{\n name: string;\n rows: Record<string, unknown>[];\n totalCount: number;\n }>;\n error?: string;\n }\n | {\n kind: \"data.referenceOptions.result\";\n table: string;\n rows: Record<string, unknown>[];\n totalCount: number;\n offset: number;\n hasMore: boolean;\n error?: string;\n }\n | {\n kind: \"sql.read.result\";\n columns: string[];\n rows: unknown[][];\n error?: string;\n }\n | {\n kind: \"sql.write.result\";\n rowsAffected: number;\n error?: string;\n invalidationScopes: string[];\n }\n | {\n kind: \"scheduler.cancel.result\";\n success: boolean;\n cancelled: boolean;\n error?: string;\n }\n | {\n kind: \"scheduler.update.result\";\n success: boolean;\n updated: boolean;\n error?: string;\n job?: SchedulerJob;\n }\n | { kind: \"error\"; message: string };\n\nexport type SyncoreDevtoolsSubscriptionResultPayload =\n | { kind: \"runtime.summary.result\"; summary: SyncoreRuntimeSummary }\n | {\n kind: \"runtime.activeQueries.result\";\n activeQueries: SyncoreActiveQueryInfo[];\n }\n | {\n kind: \"fn.watch.result\";\n result?: unknown;\n error?: string;\n }\n | { kind: \"schema.tables.result\"; tables: TableSchema[] }\n | {\n kind: \"data.table.result\";\n rows: Record<string, unknown>[];\n totalCount: number;\n cursor?: string;\n }\n | { kind: \"scheduler.jobs.result\"; jobs: SchedulerJob[] }\n | { kind: \"functions.catalog.result\"; functions: FunctionDefinition[] }\n | {\n kind: \"sql.watch.result\";\n columns: string[];\n rows: unknown[][];\n observedTables: string[];\n };\n\n/* ------------------------------------------------------------------ */\n/* Shared data shapes */\n/* ------------------------------------------------------------------ */\n\nexport interface FunctionDefinition {\n name: string;\n type: \"query\" | \"mutation\" | \"action\";\n file?: string;\n modulePath?: string;\n namespace?: string;\n metadataAvailable?: boolean;\n owner?: \"root\" | \"component\";\n componentPath?: string;\n componentName?: string;\n visibility?: \"public\" | \"internal\";\n localName?: string;\n /** Argument validator schema (JSON Schema-like), if available */\n args?: Record<string, unknown>;\n /** Return validator schema, if available */\n returns?: Record<string, unknown>;\n}\n\nexport interface TableSchema {\n name: string;\n displayName?: string;\n owner?: \"root\" | \"component\";\n componentPath?: string;\n componentName?: string;\n fields: TableField[];\n indexes: TableIndex[];\n documentCount: number;\n}\n\nexport interface TableField {\n name: string;\n type: string;\n optional: boolean;\n referenceTable?: string;\n}\n\nexport interface TableIndex {\n name: string;\n fields: string[];\n unique: boolean;\n}\n\nexport interface SchedulerJob {\n id: string;\n functionName: string;\n owner?: \"root\" | \"component\";\n componentPath?: string;\n componentName?: string;\n args: Record<string, unknown>;\n scheduledAt: number;\n runAt: number;\n status: \"pending\" | \"running\" | \"completed\" | \"failed\" | \"cancelled\";\n completedAt?: number;\n result?: unknown;\n error?: string;\n durationMs?: number;\n recurringName?: string;\n schedule?: SchedulerRecurringSchedule;\n scheduleLabel?: string;\n misfirePolicy?: SchedulerMisfirePolicy;\n timezone?: string;\n lastRunAt?: number;\n updatedAt?: number;\n /** Compatibility label for older UI code. */\n cronSchedule?: string;\n}\n\nexport interface SchedulerRecurringIntervalSchedule {\n type: \"interval\";\n seconds?: number;\n minutes?: number;\n hours?: number;\n}\n\nexport interface SchedulerRecurringDailySchedule {\n type: \"daily\";\n hour: number;\n minute: number;\n timezone?: string;\n}\n\nexport interface SchedulerRecurringWeeklySchedule {\n type: \"weekly\";\n dayOfWeek:\n | \"sunday\"\n | \"monday\"\n | \"tuesday\"\n | \"wednesday\"\n | \"thursday\"\n | \"friday\"\n | \"saturday\";\n hour: number;\n minute: number;\n timezone?: string;\n}\n\nexport type SchedulerRecurringSchedule =\n | SchedulerRecurringIntervalSchedule\n | SchedulerRecurringDailySchedule\n | SchedulerRecurringWeeklySchedule;\n\nexport type SchedulerMisfirePolicy =\n | { type: \"catch_up\" }\n | { type: \"skip\" }\n | { type: \"run_once_if_missed\" }\n | { type: \"windowed\"; windowMs: number };\n"],"mappings":";AAEA,MAAa,oCAAoC;AACjD,MAAa,kDAAkD;AAC/D,MAAa,kDAAkD;AAS/D,SAAgB,6BACd,WAIS;CACT,OACE,UAAU,+BAAA,KAEV,UAAU,+BAAA,KAEV,UAAU,mBAAmB,UAAU,+BACvC,UAAU,mBAAmB,UAAU;AAE3C;AA+MA,SAAgB,mBAAmB,OAAuB;CACxD,OAAO,eAAe,OAAO,CAAC;AAChC;AAEA,SAAgB,eACd,KACA,MACQ;CACR,OAAO,4BAA4B,KAAK,MAAM,cAAc;AAC9D;AAEA,SAAgB,sBACd,WACA,YACQ;CACR,OAAO,aACH,4BAA4B,WAAW,YAAY,qBAAqB,IACxE,sBAAsB,WAAW,CAAC;AACxC;AAEA,SAAgB,qBACd,WACA,YACQ;CACR,OAAO,eAAe,WAAW,UAAU;AAC7C;AAEA,SAAS,4BACP,KACA,MACA,gBACQ;CACR,MAAM,uBAAO,IAAI,IAAY;CAC7B,KAAK,MAAM,eAAe,CAAC,GAAG,IAAI,EAAE,KAAK,GAAG;EAC1C,IAAI,UAAU;EACd,OAAO,MAAM;GACX,MAAM,YAAY,eAAe,aAAa,OAAO;GACrD,IAAI,gBAAgB,OAAO,CAAC,KAAK,IAAI,SAAS,GAC5C,OAAO;GAET,IAAI,CAAC,KAAK,IAAI,SAAS,GAAG;IACxB,KAAK,IAAI,SAAS;IAClB;GACF;GACA,WAAW;EACb;CACF;CACA,OAAO,eAAe,KAAK,CAAC;AAC9B;AAEA,SAAS,eAAe,OAAe,MAAsB;CAE3D,QADc,WAAW,OAAO,IAAI,IAAI,KAC3B,SAAS,EAAE,SAAS,GAAG,GAAG;AACzC;AAEA,SAAS,sBAAsB,OAAe,MAAsB;CAClE,MAAM,QAAQ,WAAW,OAAO,IAAI;CAGpC,OAAO,GAFQ,OAAO,aAAa,KAAM,QAAQ,EAElC,KADA,KAAK,MAAM,QAAQ,EAAE,IAAI,KACd,SAAS,EAAE,SAAS,GAAG,GAAG;AACtD;AAEA,SAAS,WAAW,OAAe,MAAsB;CACvD,MAAM,YAAY,SAAS,IAAI,QAAQ,GAAG,MAAM,GAAG;CACnD,IAAI,OAAO;CACX,KAAK,IAAI,QAAQ,GAAG,QAAQ,UAAU,QAAQ,SAAS,GAAG;EACxD,QAAQ,UAAU,WAAW,KAAK;EAClC,OAAO,KAAK,KAAK,MAAM,QAAQ;CACjC;CACA,OAAO,SAAS;AAClB"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["export type SyncoreDevtoolsEventOrigin = \"runtime\" | \"dashboard\";\n\nexport const SYNCORE_DEVTOOLS_PROTOCOL_VERSION = 1;\nexport const SYNCORE_DEVTOOLS_MIN_SUPPORTED_PROTOCOL_VERSION = 1;\nexport const SYNCORE_DEVTOOLS_MAX_SUPPORTED_PROTOCOL_VERSION = 1;\n\nexport interface VersionHandshake {\n protocolVersion: number;\n minSupportedProtocolVersion: number;\n maxSupportedProtocolVersion: number;\n runtimeVersion?: string;\n}\n\nexport function isCompatibleVersionHandshake(\n handshake: Pick<\n VersionHandshake,\n | \"protocolVersion\"\n | \"minSupportedProtocolVersion\"\n | \"maxSupportedProtocolVersion\"\n >\n): boolean {\n return (\n handshake.maxSupportedProtocolVersion >=\n SYNCORE_DEVTOOLS_MIN_SUPPORTED_PROTOCOL_VERSION &&\n handshake.minSupportedProtocolVersion <=\n SYNCORE_DEVTOOLS_MAX_SUPPORTED_PROTOCOL_VERSION &&\n handshake.protocolVersion >= handshake.minSupportedProtocolVersion &&\n handshake.protocolVersion <= handshake.maxSupportedProtocolVersion\n );\n}\n\ntype SyncoreDevtoolsEventBase = {\n runtimeId: string;\n timestamp: number;\n sequence?: number;\n origin?: SyncoreDevtoolsEventOrigin;\n};\n\nexport type DevtoolsPreview =\n | {\n kind: \"value\";\n value: unknown;\n truncated?: boolean;\n note?: string;\n }\n | {\n kind: \"error\";\n message: string;\n truncated?: boolean;\n };\n\nexport interface DocumentChangePreview {\n table: string;\n id: string;\n operation: \"insert\" | \"patch\" | \"replace\" | \"delete\";\n fields?: string[];\n beforePreview?: DevtoolsPreview;\n afterPreview?: DevtoolsPreview;\n}\n\nexport interface InvalidationCause {\n executionId?: string;\n reason: string;\n changedScopes: string[];\n matchedScopes: string[];\n}\n\nexport interface ExecutionTrace {\n executionId: string;\n parentExecutionId?: string;\n kind: \"query\" | \"mutation\" | \"action\" | \"scheduler\" | \"dashboard\";\n functionName?: string;\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n error?: string;\n readScopes?: string[];\n writeScopes?: string[];\n changedScopes?: string[];\n changedDocumentsPreview?: DocumentChangePreview[];\n invalidatedQueryIds?: string[];\n schedulerJobId?: string;\n}\n\nexport type SyncoreDevtoolsEvent =\n | (SyncoreDevtoolsEventBase & {\n type: \"runtime.connected\";\n platform: string;\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"runtime.disconnected\";\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"query.executed\";\n queryId: string;\n functionName: string;\n componentPath?: string;\n componentName?: string;\n dependencies: string[];\n durationMs: number;\n executionId?: string;\n parentExecutionId?: string;\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n readScopes?: string[];\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"query.invalidated\";\n queryId: string;\n componentPath?: string;\n componentName?: string;\n reason: string;\n causedByExecutionId?: string;\n changedScopes?: string[];\n matchedScopes?: string[];\n rerunExecutionId?: string;\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"mutation.committed\";\n mutationId: string;\n functionName: string;\n componentPath?: string;\n componentName?: string;\n changedTables: string[];\n durationMs: number;\n executionId?: string;\n parentExecutionId?: string;\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n writeScopes?: string[];\n changedScopes?: string[];\n changedDocumentsPreview?: DocumentChangePreview[];\n invalidatedQueryIds?: string[];\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"action.completed\";\n actionId: string;\n functionName: string;\n componentPath?: string;\n componentName?: string;\n durationMs: number;\n error?: string;\n executionId?: string;\n parentExecutionId?: string;\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n writeScopes?: string[];\n changedScopes?: string[];\n changedDocumentsPreview?: DocumentChangePreview[];\n invalidatedQueryIds?: string[];\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"scheduler.tick\";\n executedJobIds: string[];\n executionId?: string;\n jobExecutions?: Array<{\n jobId: string;\n executionId?: string;\n functionName: string;\n functionType: \"mutation\" | \"action\";\n argsPreview?: DevtoolsPreview;\n resultPreview?: DevtoolsPreview;\n error?: string;\n durationMs?: number;\n }>;\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"storage.updated\";\n storageId: string;\n componentPath?: string;\n operation: \"put\" | \"delete\";\n })\n | (SyncoreDevtoolsEventBase & {\n type: \"log\";\n level: \"info\" | \"warn\" | \"error\";\n message: string;\n });\n\nexport interface SyncoreActiveQueryInfo {\n id: string;\n functionName: string;\n args?: Record<string, unknown>;\n consumers?: number;\n owner?: \"root\" | \"component\";\n componentPath?: string;\n componentName?: string;\n dependencyKeys: string[];\n lastRunAt: number;\n}\n\nexport interface SyncoreRuntimeSummary {\n runtimeId: string;\n platform: string;\n appName?: string;\n origin?: string;\n sessionLabel?: string;\n targetKind?: \"client\" | \"project\";\n runtimeRole?: \"app\" | \"project-target\";\n storageProtocol?: string;\n databaseLabel?: string;\n dataSourceAlias?: string;\n storageIdentity?: string;\n capabilities?: SyncoreDevtoolsCapabilities;\n connectedAt: number;\n activeQueryCount: number;\n recentEventCount: number;\n}\n\nexport interface SyncoreDevtoolsCapabilities {\n sql?: {\n read: boolean;\n write: boolean;\n live: boolean;\n reason?: string;\n };\n data?: {\n browse: boolean;\n mutate: boolean;\n importExport: boolean;\n };\n storage?: {\n browse: boolean;\n download: boolean;\n readRange?: boolean;\n delete: boolean;\n maxPreviewBytes?: number;\n reason?: string;\n };\n scheduler?: {\n read: boolean;\n edit: boolean;\n };\n}\n\nexport interface SyncoreDevtoolsExternalChangeEvent {\n sourceId: string;\n scope: \"database\" | \"storage\" | \"all\";\n reason: \"commit\" | \"storage-put\" | \"storage-delete\" | \"reconcile\";\n timestamp: number;\n revision?: string;\n changedScopes?: string[];\n changedTables?: string[];\n storageIds?: string[];\n}\n\nexport function createBasePublicId(input: string): string {\n return stablePublicId(input, 0);\n}\n\nexport function createPublicId(key: string, keys: Iterable<string>): string {\n return createPublicIdWithFormatter(key, keys, stablePublicId);\n}\n\nexport function createPublicRuntimeId(\n runtimeId: string,\n runtimeIds?: Iterable<string>\n): string {\n return runtimeIds\n ? createPublicIdWithFormatter(runtimeId, runtimeIds, stableRuntimePublicId)\n : stableRuntimePublicId(runtimeId, 0);\n}\n\nexport function createPublicTargetId(\n targetKey: string,\n targetKeys: Iterable<string>\n): string {\n return createPublicId(targetKey, targetKeys);\n}\n\nfunction createPublicIdWithFormatter(\n key: string,\n keys: Iterable<string>,\n formatPublicId: (input: string, salt: number) => string\n): string {\n const used = new Set<string>();\n for (const existingKey of [...keys].sort()) {\n let attempt = 0;\n while (true) {\n const candidate = formatPublicId(existingKey, attempt);\n if (existingKey === key && !used.has(candidate)) {\n return candidate;\n }\n if (!used.has(candidate)) {\n used.add(candidate);\n break;\n }\n attempt += 1;\n }\n }\n return formatPublicId(key, 0);\n}\n\nfunction stablePublicId(input: string, salt: number): string {\n const value = stableHash(input, salt) % 100000;\n return value.toString().padStart(5, \"0\");\n}\n\nfunction stableRuntimePublicId(input: string, salt: number): string {\n const value = stableHash(input, salt);\n const letter = String.fromCharCode(65 + (value % 26));\n const digits = Math.floor(value / 26) % 1000;\n return `${letter}${digits.toString().padStart(3, \"0\")}`;\n}\n\nfunction stableHash(input: string, salt: number): number {\n const hashInput = salt === 0 ? input : `${input}#${salt}`;\n let hash = 2166136261;\n for (let index = 0; index < hashInput.length; index += 1) {\n hash ^= hashInput.charCodeAt(index);\n hash = Math.imul(hash, 16777619);\n }\n return hash >>> 0;\n}\n\n/* ------------------------------------------------------------------ */\n/* Runtime → Dashboard messages */\n/* ------------------------------------------------------------------ */\n\nexport type SyncoreDevtoolsMessage =\n | {\n type: \"hello\";\n protocolVersion?: number;\n minSupportedProtocolVersion?: number;\n maxSupportedProtocolVersion?: number;\n runtimeVersion?: string;\n runtimeId: string;\n platform: string;\n appName?: string;\n origin?: string;\n sessionLabel?: string;\n targetKind?: \"client\" | \"project\";\n runtimeRole?: \"app\" | \"project-target\";\n storageProtocol?: string;\n databaseLabel?: string;\n dataSourceAlias?: string;\n storageIdentity?: string;\n capabilities?: SyncoreDevtoolsCapabilities;\n }\n | { type: \"event\"; event: SyncoreDevtoolsEvent }\n | {\n type: \"event.batch\";\n runtimeId: string;\n events: SyncoreDevtoolsEvent[];\n }\n | { type: \"ping\" }\n | { type: \"pong\" }\n | {\n type: \"command.result\";\n commandId: string;\n runtimeId: string;\n payload: SyncoreDevtoolsCommandResultPayload;\n }\n | {\n type: \"subscription.data\";\n subscriptionId: string;\n runtimeId: string;\n payload: SyncoreDevtoolsSubscriptionResultPayload;\n }\n | {\n type: \"subscription.error\";\n subscriptionId: string;\n runtimeId: string;\n error: string;\n }\n | {\n type: \"external.change\";\n runtimeId: string;\n storageIdentity: string;\n event: SyncoreDevtoolsExternalChangeEvent;\n };\n\n/* ------------------------------------------------------------------ */\n/* Dashboard → Runtime requests */\n/* ------------------------------------------------------------------ */\n\nexport interface SyncoreDevtoolsCommand {\n type: \"command\";\n commandId: string;\n targetRuntimeId: string;\n payload: SyncoreDevtoolsCommandPayload;\n}\n\nexport interface SyncoreDevtoolsSubscribe {\n type: \"subscribe\";\n subscriptionId: string;\n targetRuntimeId: string;\n payload: SyncoreDevtoolsSubscriptionPayload;\n}\n\nexport interface SyncoreDevtoolsUnsubscribe {\n type: \"unsubscribe\";\n subscriptionId: string;\n targetRuntimeId: string;\n}\n\nexport type SyncoreDevtoolsClientMessage =\n | { type: \"ping\" }\n | SyncoreDevtoolsCommand\n | SyncoreDevtoolsSubscribe\n | SyncoreDevtoolsUnsubscribe;\n\nexport type SyncoreDevtoolsCommandPayload =\n /* Functions */\n | {\n kind: \"fn.run\";\n functionName: string;\n functionType: \"query\" | \"mutation\" | \"action\";\n args: Record<string, unknown>;\n }\n | { kind: \"data.insert\"; table: string; document: Record<string, unknown> }\n | {\n kind: \"data.patch\";\n table: string;\n id: string;\n fields: Record<string, unknown>;\n }\n | { kind: \"data.delete\"; table: string; id: string }\n | { kind: \"data.export\"; tables?: string[] }\n | {\n kind: \"data.referenceOptions\";\n table: string;\n search?: string;\n limit?: number;\n offset?: number;\n }\n /* SQL */\n | { kind: \"sql.read\"; query: string }\n | { kind: \"sql.write\"; query: string }\n /* Storage */\n | {\n kind: \"storage.list\";\n limit?: number;\n offset?: number;\n search?: string;\n }\n | {\n kind: \"storage.access.create\";\n id: string;\n purpose: \"preview\" | \"download\";\n }\n | {\n kind: \"storage.readRange\";\n id: string;\n offset: number;\n length: number;\n }\n | { kind: \"storage.delete\"; id: string }\n /* Scheduler */\n | { kind: \"scheduler.cancel\"; jobId: string }\n | {\n kind: \"scheduler.update\";\n jobId: string;\n schedule?: SchedulerRecurringSchedule;\n args: Record<string, unknown>;\n misfirePolicy?: SchedulerMisfirePolicy;\n runAt?: number;\n };\n\nexport type SyncoreDevtoolsSubscriptionPayload =\n | { kind: \"runtime.summary\" }\n | { kind: \"runtime.activeQueries\" }\n | { kind: \"schema.tables\" }\n | {\n kind: \"fn.watch\";\n functionName: string;\n functionType: \"query\";\n args: Record<string, unknown>;\n }\n | {\n kind: \"data.table\";\n table: string;\n filters?: DataFilter[];\n limit?: number;\n cursor?: string;\n }\n | { kind: \"scheduler.jobs\" }\n | { kind: \"functions.catalog\" }\n | {\n kind: \"storage.list\";\n limit?: number;\n offset?: number;\n search?: string;\n }\n | { kind: \"sql.watch\"; query: string };\n\nexport interface DataFilter {\n field: string;\n operator:\n | \"eq\"\n | \"neq\"\n | \"gt\"\n | \"gte\"\n | \"lt\"\n | \"lte\"\n | \"contains\"\n | \"startsWith\";\n value: unknown;\n}\n\n/* ------------------------------------------------------------------ */\n/* Response payloads */\n/* ------------------------------------------------------------------ */\n\nexport type SyncoreDevtoolsCommandResultPayload =\n | {\n kind: \"fn.run.result\";\n result?: unknown;\n error?: string;\n durationMs: number;\n }\n | {\n kind: \"data.mutate.result\";\n success: boolean;\n id?: string;\n error?: string;\n }\n | {\n kind: \"data.export.result\";\n tables: Array<{\n name: string;\n rows: Record<string, unknown>[];\n totalCount: number;\n }>;\n error?: string;\n }\n | {\n kind: \"data.referenceOptions.result\";\n table: string;\n rows: Record<string, unknown>[];\n totalCount: number;\n offset: number;\n hasMore: boolean;\n error?: string;\n }\n | {\n kind: \"sql.read.result\";\n columns: string[];\n rows: unknown[][];\n error?: string;\n }\n | {\n kind: \"sql.write.result\";\n rowsAffected: number;\n error?: string;\n invalidationScopes: string[];\n }\n | {\n kind: \"storage.list.result\";\n entries: StorageEntry[];\n totalCount: number;\n offset: number;\n hasMore: boolean;\n error?: string;\n }\n | {\n kind: \"storage.access.create.result\";\n entry?: StorageEntry;\n url?: string;\n expiresAt?: number;\n supportsRange?: boolean;\n maxPreviewBytes?: number;\n error?: string;\n }\n | {\n kind: \"storage.readRange.result\";\n entry?: StorageEntry;\n offset: number;\n bytesRead: number;\n done: boolean;\n supportsRange: boolean;\n base64?: string;\n error?: string;\n }\n | {\n kind: \"storage.delete.result\";\n success: boolean;\n deleted: boolean;\n error?: string;\n }\n | {\n kind: \"scheduler.cancel.result\";\n success: boolean;\n cancelled: boolean;\n error?: string;\n }\n | {\n kind: \"scheduler.update.result\";\n success: boolean;\n updated: boolean;\n error?: string;\n job?: SchedulerJob;\n }\n | { kind: \"error\"; message: string };\n\nexport type SyncoreDevtoolsSubscriptionResultPayload =\n | { kind: \"runtime.summary.result\"; summary: SyncoreRuntimeSummary }\n | {\n kind: \"runtime.activeQueries.result\";\n activeQueries: SyncoreActiveQueryInfo[];\n }\n | {\n kind: \"fn.watch.result\";\n result?: unknown;\n error?: string;\n }\n | { kind: \"schema.tables.result\"; tables: TableSchema[] }\n | {\n kind: \"data.table.result\";\n rows: Record<string, unknown>[];\n totalCount: number;\n cursor?: string;\n }\n | { kind: \"scheduler.jobs.result\"; jobs: SchedulerJob[] }\n | { kind: \"functions.catalog.result\"; functions: FunctionDefinition[] }\n | {\n kind: \"storage.list.result\";\n entries: StorageEntry[];\n totalCount: number;\n offset: number;\n hasMore: boolean;\n error?: string;\n }\n | {\n kind: \"sql.watch.result\";\n columns: string[];\n rows: unknown[][];\n observedTables: string[];\n };\n\n/* ------------------------------------------------------------------ */\n/* Shared data shapes */\n/* ------------------------------------------------------------------ */\n\nexport interface FunctionDefinition {\n name: string;\n type: \"query\" | \"mutation\" | \"action\";\n file?: string;\n modulePath?: string;\n namespace?: string;\n metadataAvailable?: boolean;\n owner?: \"root\" | \"component\";\n componentPath?: string;\n componentName?: string;\n visibility?: \"public\" | \"internal\";\n localName?: string;\n /** Argument validator schema (JSON Schema-like), if available */\n args?: Record<string, unknown>;\n /** Return validator schema, if available */\n returns?: Record<string, unknown>;\n}\n\nexport interface TableSchema {\n name: string;\n displayName?: string;\n owner?: \"root\" | \"component\";\n componentPath?: string;\n componentName?: string;\n fields: TableField[];\n indexes: TableIndex[];\n documentCount: number;\n}\n\nexport interface TableField {\n name: string;\n type: string;\n optional: boolean;\n referenceTable?: string;\n}\n\nexport interface TableIndex {\n name: string;\n fields: string[];\n unique: boolean;\n}\n\nexport interface StorageEntry {\n id: string;\n createdAt: number;\n fileName?: string;\n contentType?: string;\n size: number;\n path: string;\n}\n\nexport interface SchedulerJob {\n id: string;\n functionName: string;\n owner?: \"root\" | \"component\";\n componentPath?: string;\n componentName?: string;\n args: Record<string, unknown>;\n scheduledAt: number;\n runAt: number;\n status: \"pending\" | \"running\" | \"completed\" | \"failed\" | \"cancelled\";\n completedAt?: number;\n result?: unknown;\n error?: string;\n durationMs?: number;\n recurringName?: string;\n schedule?: SchedulerRecurringSchedule;\n scheduleLabel?: string;\n misfirePolicy?: SchedulerMisfirePolicy;\n timezone?: string;\n lastRunAt?: number;\n updatedAt?: number;\n /** Compatibility label for older UI code. */\n cronSchedule?: string;\n}\n\nexport interface SchedulerRecurringIntervalSchedule {\n type: \"interval\";\n seconds?: number;\n minutes?: number;\n hours?: number;\n}\n\nexport interface SchedulerRecurringDailySchedule {\n type: \"daily\";\n hour: number;\n minute: number;\n timezone?: string;\n}\n\nexport interface SchedulerRecurringWeeklySchedule {\n type: \"weekly\";\n dayOfWeek:\n | \"sunday\"\n | \"monday\"\n | \"tuesday\"\n | \"wednesday\"\n | \"thursday\"\n | \"friday\"\n | \"saturday\";\n hour: number;\n minute: number;\n timezone?: string;\n}\n\nexport type SchedulerRecurringSchedule =\n | SchedulerRecurringIntervalSchedule\n | SchedulerRecurringDailySchedule\n | SchedulerRecurringWeeklySchedule;\n\nexport type SchedulerMisfirePolicy =\n | { type: \"catch_up\" }\n | { type: \"skip\" }\n | { type: \"run_once_if_missed\" }\n | { type: \"windowed\"; windowMs: number };\n"],"mappings":";AAEA,MAAa,oCAAoC;AACjD,MAAa,kDAAkD;AAC/D,MAAa,kDAAkD;AAS/D,SAAgB,6BACd,WAMS;CACT,OACE,UAAU,+BAAA,KAEV,UAAU,+BAAA,KAEV,UAAU,mBAAmB,UAAU,+BACvC,UAAU,mBAAmB,UAAU;AAE3C;AAuNA,SAAgB,mBAAmB,OAAuB;CACxD,OAAO,eAAe,OAAO,CAAC;AAChC;AAEA,SAAgB,eAAe,KAAa,MAAgC;CAC1E,OAAO,4BAA4B,KAAK,MAAM,cAAc;AAC9D;AAEA,SAAgB,sBACd,WACA,YACQ;CACR,OAAO,aACH,4BAA4B,WAAW,YAAY,qBAAqB,IACxE,sBAAsB,WAAW,CAAC;AACxC;AAEA,SAAgB,qBACd,WACA,YACQ;CACR,OAAO,eAAe,WAAW,UAAU;AAC7C;AAEA,SAAS,4BACP,KACA,MACA,gBACQ;CACR,MAAM,uBAAO,IAAI,IAAY;CAC7B,KAAK,MAAM,eAAe,CAAC,GAAG,IAAI,EAAE,KAAK,GAAG;EAC1C,IAAI,UAAU;EACd,OAAO,MAAM;GACX,MAAM,YAAY,eAAe,aAAa,OAAO;GACrD,IAAI,gBAAgB,OAAO,CAAC,KAAK,IAAI,SAAS,GAC5C,OAAO;GAET,IAAI,CAAC,KAAK,IAAI,SAAS,GAAG;IACxB,KAAK,IAAI,SAAS;IAClB;GACF;GACA,WAAW;EACb;CACF;CACA,OAAO,eAAe,KAAK,CAAC;AAC9B;AAEA,SAAS,eAAe,OAAe,MAAsB;CAE3D,QADc,WAAW,OAAO,IAAI,IAAI,KAC3B,SAAS,EAAE,SAAS,GAAG,GAAG;AACzC;AAEA,SAAS,sBAAsB,OAAe,MAAsB;CAClE,MAAM,QAAQ,WAAW,OAAO,IAAI;CAGpC,OAAO,GAFQ,OAAO,aAAa,KAAM,QAAQ,EAElC,KADA,KAAK,MAAM,QAAQ,EAAE,IAAI,KACd,SAAS,EAAE,SAAS,GAAG,GAAG;AACtD;AAEA,SAAS,WAAW,OAAe,MAAsB;CACvD,MAAM,YAAY,SAAS,IAAI,QAAQ,GAAG,MAAM,GAAG;CACnD,IAAI,OAAO;CACX,KAAK,IAAI,QAAQ,GAAG,QAAQ,UAAU,QAAQ,SAAS,GAAG;EACxD,QAAQ,UAAU,WAAW,KAAK;EAClC,OAAO,KAAK,KAAK,MAAM,QAAQ;CACjC;CACA,OAAO,SAAS;AAClB"}
@@ -116,7 +116,11 @@ function SyncoreNextProvider({ children, createWorker, serviceWorkerUrl, workerU
116
116
  const resolvedWorkerUrl = typeof workerUrl === "string" ? workerUrl : workerUrl?.toString();
117
117
  const bootingClient = useMemo(() => createUnavailableSyncoreClient({
118
118
  kind: "starting",
119
- reason: "booting"
119
+ reason: "booting",
120
+ capabilities: { storage: {
121
+ available: false,
122
+ reason: "Syncore worker is booting."
123
+ } }
120
124
  }), []);
121
125
  const [client, setClient] = useState(bootingClient);
122
126
  useEffect(() => {
@@ -134,6 +138,10 @@ function SyncoreNextProvider({ children, createWorker, serviceWorkerUrl, workerU
134
138
  setClient(createUnavailableSyncoreClient({
135
139
  kind: "unavailable",
136
140
  reason: "worker-unavailable",
141
+ capabilities: { storage: {
142
+ available: false,
143
+ reason: "Syncore worker is unavailable."
144
+ } },
137
145
  ...error instanceof Error ? { error } : {}
138
146
  }));
139
147
  }
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.tsx"],"sourcesContent":["import {\n createUnavailableSyncoreClient,\n type SyncoreClient\n} from \"@syncore/core\";\nimport {\n createManagedWebWorkerClient,\n createSyncoreWebWorkerClient,\n type ManagedWebWorkerClient\n} from \"@syncore/platform-web\";\nimport { SyncoreProvider } from \"@syncore/react\";\nimport {\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode\n} from \"react\";\nimport { getSyncoreWorkerUrl } from \"./config.js\";\n\nexport { getSyncoreWorkerUrl } from \"./config.js\";\nexport { createSyncoreNextWorkerUrl } from \"./config.js\";\n\n/**\n * Shared configuration options for the Syncore Next.js integration.\n *\n * Accepted by both {@link SyncoreNextProvider} and\n * {@link registerSyncoreServiceWorker}.\n */\nexport interface SyncoreNextOptions {\n /**\n * URL of the Next PWA service worker. Defaults to `\"/sw.js\"` (the path\n * emitted by `next-pwa` or `@ducanh2912/next-pwa`).\n */\n serviceWorkerUrl?: string;\n\n /**\n * Public path to the compiled Syncore worker asset. Defaults to\n * `\"/syncore.worker.js\"`. Override if your build tool emits the worker to a\n * different path.\n */\n workerAssetUrl?: string;\n}\n\n/**\n * Handle returned by {@link registerSyncoreServiceWorker}.\n */\nexport interface SyncoreServiceWorkerRegistration {\n /** Unregister the installed service worker. */\n unregister(): Promise<boolean>;\n\n /**\n * Instruct the browser to check for a new service worker version. Useful\n * for implementing an “Update available” prompt.\n */\n update(): Promise<ServiceWorkerRegistration>;\n}\n\n/**\n * Register the Syncore PWA service worker in a Next.js app.\n *\n * Call this once at app startup (e.g. in your root layout’s `useEffect`, or in\n * `instrumentation.ts` with `\"use client\"`). Returns `null` on the server or\n * when the browser does not support service workers.\n *\n * ```ts\n * // app/layout.tsx (client component)\n * import { registerSyncoreServiceWorker } from \"syncorejs/next\";\n *\n * useEffect(() => {\n * registerSyncoreServiceWorker({ serviceWorkerUrl: \"/sw.js\" });\n * }, []);\n * ```\n *\n * @param options - Optional configuration. Defaults to `\"/sw.js\"`.\n * @returns A {@link SyncoreServiceWorkerRegistration} handle, or `null` on\n * the server / when unsupported.\n */\nexport async function registerSyncoreServiceWorker(\n options?: SyncoreNextOptions\n): Promise<SyncoreServiceWorkerRegistration | null> {\n if (typeof window === \"undefined\" || !(\"serviceWorker\" in navigator)) {\n return null;\n }\n\n const registration = await navigator.serviceWorker.register(\n options?.serviceWorkerUrl ?? \"/sw.js\"\n );\n\n return {\n unregister: () => registration.unregister(),\n update: () => registration.update()\n };\n}\n\n/**\n * Create a worker-backed Syncore client for a Next.js app.\n *\n * The client communicates with a Syncore runtime running inside a `Worker`.\n * The worker runs the SQLite engine and all function handlers off the main\n * thread so the UI stays responsive.\n *\n * In most cases you should use {@link SyncoreNextProvider} instead, which\n * manages the client lifecycle automatically. Use `createNextSyncoreClient`\n * directly only when you need to control the client lifecycle yourself (e.g.\n * in testing harnesses or custom providers).\n *\n * ```ts\n * const managedClient = createNextSyncoreClient({\n * workerAssetUrl: \"/syncore.worker.js\",\n * });\n *\n * // Later:\n * managedClient.dispose();\n * ```\n */\nexport function createNextSyncoreClient(options: {\n /**\n * Custom worker factory function. Useful in tests (supply a `Worker` backed\n * by a mock or in-process runtime) or when using Next’s App Router dev-mode\n * bundling where `new Worker(new URL(...))` must be used inside the component.\n */\n createWorker?: () => Worker;\n\n /** Explicit module URL for an already-public worker script. */\n workerUrl?: URL | string;\n\n /** Public asset path for the compiled worker file. Defaults to `\"/syncore.worker.js\"`. */\n workerAssetUrl?: string;\n}): ManagedWebWorkerClient {\n if (options.createWorker) {\n return createManagedWebWorkerClient({\n createWorker: options.createWorker\n });\n }\n\n return createSyncoreWebWorkerClient({\n workerUrl:\n options.workerUrl ?? options.workerAssetUrl ?? \"/syncore.worker.js\"\n });\n}\n\n/**\n * React component that registers a PWA service worker as a side-effect.\n *\n * Renders its `children` immediately (no loading state) and registers the\n * service worker asynchronously. Safe to render on the server — the\n * registration effect only runs in browsers that support service workers.\n *\n * ```tsx\n * <SyncoreServiceWorker serviceWorkerUrl=\"/sw.js\" onRegistered={console.log}>\n * <App />\n * </SyncoreServiceWorker>\n * ```\n */\nexport function SyncoreServiceWorker({\n children,\n serviceWorkerUrl,\n onRegistered\n}: {\n children: ReactNode;\n /** URL of the service worker script. Defaults to `\"/sw.js\"`. */\n serviceWorkerUrl?: string;\n /** Called after the service worker is successfully registered. */\n onRegistered?: (registration: ServiceWorkerRegistration) => void;\n}) {\n useEffect(() => {\n void (async () => {\n if (typeof window === \"undefined\" || !(\"serviceWorker\" in navigator)) {\n return;\n }\n const registration = await navigator.serviceWorker.register(\n serviceWorkerUrl ?? \"/sw.js\"\n );\n onRegistered?.(registration);\n })();\n }, [onRegistered, serviceWorkerUrl]);\n\n return children;\n}\n\n/**\n * Root provider that wires a worker-backed Syncore runtime into a Next.js\n * React tree.\n *\n * Place this at the top of your App Router layout. It spawns the Syncore\n * worker on mount, exposes the client via React context (accessible with\n * `useSyncore()`), and optionally registers the PWA service worker.\n *\n * ```tsx\n * // app/layout.tsx\n * import { SyncoreNextProvider } from \"syncorejs/next\";\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html>\n * <body>\n * <SyncoreNextProvider\n * createWorker={() => new Worker(\n * new URL(\"../syncore.worker.ts\", import.meta.url)\n * )}\n * >\n * {children}\n * </SyncoreNextProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n */\nexport function SyncoreNextProvider({\n children,\n createWorker,\n serviceWorkerUrl,\n workerUrl,\n workerAssetUrl\n}: {\n /** The React subtree that should receive the Syncore client. */\n children: ReactNode;\n\n /**\n * Factory function that creates the Syncore `Worker`. Required in Next App\n * Router dev mode because `new Worker(new URL(..., import.meta.url))` must\n * be called inside the module to be bundled correctly.\n */\n createWorker?: () => Worker;\n\n /** URL of the PWA service worker script. Omit to skip service worker registration. */\n serviceWorkerUrl?: string;\n\n /** Explicit module URL for an already-public worker asset. */\n workerUrl?: URL | string;\n\n /** Public asset path for the compiled worker file. Defaults to `\"/syncore.worker.js\"`. */\n workerAssetUrl?: string;\n}) {\n const createWorkerRef = useRef(createWorker);\n createWorkerRef.current = createWorker;\n const resolvedWorkerUrl =\n typeof workerUrl === \"string\" ? workerUrl : workerUrl?.toString();\n const bootingClient = useMemo(\n () =>\n createUnavailableSyncoreClient({\n kind: \"starting\",\n reason: \"booting\"\n }),\n []\n );\n const [client, setClient] = useState<SyncoreClient>(bootingClient);\n\n useEffect(() => {\n let managedClient: ManagedWebWorkerClient | undefined;\n\n setClient(bootingClient);\n\n try {\n const workerFactory = createWorkerRef.current;\n managedClient = createNextSyncoreClient({\n ...(workerFactory\n ? {\n createWorker: () => workerFactory()\n }\n : {}),\n ...(resolvedWorkerUrl\n ? {\n workerUrl:\n process.env.NODE_ENV === \"production\"\n ? getSyncoreWorkerUrl()\n : resolvedWorkerUrl\n }\n : {}),\n ...(workerAssetUrl ? { workerAssetUrl } : {})\n });\n setClient(managedClient.client);\n } catch (error) {\n setClient(\n createUnavailableSyncoreClient({\n kind: \"unavailable\",\n reason: \"worker-unavailable\",\n ...(error instanceof Error ? { error } : {})\n })\n );\n }\n\n return () => {\n managedClient?.dispose();\n };\n }, [bootingClient, resolvedWorkerUrl, workerAssetUrl]);\n\n return (\n <SyncoreServiceWorker {...(serviceWorkerUrl ? { serviceWorkerUrl } : {})}>\n <SyncoreProvider client={client}>{children}</SyncoreProvider>\n </SyncoreServiceWorker>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA6EA,eAAsB,6BACpB,SACkD;CAClD,IAAI,OAAO,WAAW,eAAe,EAAE,mBAAmB,YACxD,OAAO;CAGT,MAAM,eAAe,MAAM,UAAU,cAAc,SACjD,SAAS,oBAAoB,QAC/B;CAEA,OAAO;EACL,kBAAkB,aAAa,WAAW;EAC1C,cAAc,aAAa,OAAO;CACpC;AACF;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,wBAAwB,SAab;CACzB,IAAI,QAAQ,cACV,OAAO,6BAA6B,EAClC,cAAc,QAAQ,aACxB,CAAC;CAGH,OAAO,6BAA6B,EAClC,WACE,QAAQ,aAAa,QAAQ,kBAAkB,qBACnD,CAAC;AACH;;;;;;;;;;;;;;AAeA,SAAgB,qBAAqB,EACnC,UACA,kBACA,gBAOC;CACD,gBAAgB;EACd,CAAM,YAAY;GAChB,IAAI,OAAO,WAAW,eAAe,EAAE,mBAAmB,YACxD;GAEF,MAAM,eAAe,MAAM,UAAU,cAAc,SACjD,oBAAoB,QACtB;GACA,eAAe,YAAY;EAC7B,GAAG;CACL,GAAG,CAAC,cAAc,gBAAgB,CAAC;CAEnC,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,SAAgB,oBAAoB,EAClC,UACA,cACA,kBACA,WACA,kBAoBC;CACD,MAAM,kBAAkB,OAAO,YAAY;CAC3C,gBAAgB,UAAU;CAC1B,MAAM,oBACJ,OAAO,cAAc,WAAW,YAAY,WAAW,SAAS;CAClE,MAAM,gBAAgB,cAElB,+BAA+B;EAC7B,MAAM;EACN,QAAQ;CACV,CAAC,GACH,CAAC,CACH;CACA,MAAM,CAAC,QAAQ,aAAa,SAAwB,aAAa;CAEjE,gBAAgB;EACd,IAAI;EAEJ,UAAU,aAAa;EAEvB,IAAI;GACF,MAAM,gBAAgB,gBAAgB;GACtC,gBAAgB,wBAAwB;IACtC,GAAI,gBACA,EACE,oBAAoB,cAAc,EACpC,IACA,CAAC;IACL,GAAI,oBACA,EACE,WACE,QAAQ,IAAI,aAAa,eACrB,oBAAoB,IACpB,kBACR,IACA,CAAC;IACL,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC;GAC7C,CAAC;GACD,UAAU,cAAc,MAAM;EAChC,SAAS,OAAO;GACd,UACE,+BAA+B;IAC7B,MAAM;IACN,QAAQ;IACR,GAAI,iBAAiB,QAAQ,EAAE,MAAM,IAAI,CAAC;GAC5C,CAAC,CACH;EACF;EAEA,aAAa;GACX,eAAe,QAAQ;EACzB;CACF,GAAG;EAAC;EAAe;EAAmB;CAAc,CAAC;CAErD,OACE,oBAAC,sBAAD;EAAsB,GAAK,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;YACpE,oBAAC,iBAAD;GAAyB;GAAS;EAA0B,CAAA;CACxC,CAAA;AAE1B"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.tsx"],"sourcesContent":["import {\n createUnavailableSyncoreClient,\n type SyncoreClient\n} from \"@syncore/core\";\nimport {\n createManagedWebWorkerClient,\n createSyncoreWebWorkerClient,\n type ManagedWebWorkerClient\n} from \"@syncore/platform-web\";\nimport { SyncoreProvider } from \"@syncore/react\";\nimport {\n useEffect,\n useMemo,\n useRef,\n useState,\n type ReactNode\n} from \"react\";\nimport { getSyncoreWorkerUrl } from \"./config.js\";\n\nexport { getSyncoreWorkerUrl } from \"./config.js\";\nexport { createSyncoreNextWorkerUrl } from \"./config.js\";\n\n/**\n * Shared configuration options for the Syncore Next.js integration.\n *\n * Accepted by both {@link SyncoreNextProvider} and\n * {@link registerSyncoreServiceWorker}.\n */\nexport interface SyncoreNextOptions {\n /**\n * URL of the Next PWA service worker. Defaults to `\"/sw.js\"` (the path\n * emitted by `next-pwa` or `@ducanh2912/next-pwa`).\n */\n serviceWorkerUrl?: string;\n\n /**\n * Public path to the compiled Syncore worker asset. Defaults to\n * `\"/syncore.worker.js\"`. Override if your build tool emits the worker to a\n * different path.\n */\n workerAssetUrl?: string;\n}\n\n/**\n * Handle returned by {@link registerSyncoreServiceWorker}.\n */\nexport interface SyncoreServiceWorkerRegistration {\n /** Unregister the installed service worker. */\n unregister(): Promise<boolean>;\n\n /**\n * Instruct the browser to check for a new service worker version. Useful\n * for implementing an “Update available” prompt.\n */\n update(): Promise<ServiceWorkerRegistration>;\n}\n\n/**\n * Register the Syncore PWA service worker in a Next.js app.\n *\n * Call this once at app startup (e.g. in your root layout’s `useEffect`, or in\n * `instrumentation.ts` with `\"use client\"`). Returns `null` on the server or\n * when the browser does not support service workers.\n *\n * ```ts\n * // app/layout.tsx (client component)\n * import { registerSyncoreServiceWorker } from \"syncorejs/next\";\n *\n * useEffect(() => {\n * registerSyncoreServiceWorker({ serviceWorkerUrl: \"/sw.js\" });\n * }, []);\n * ```\n *\n * @param options - Optional configuration. Defaults to `\"/sw.js\"`.\n * @returns A {@link SyncoreServiceWorkerRegistration} handle, or `null` on\n * the server / when unsupported.\n */\nexport async function registerSyncoreServiceWorker(\n options?: SyncoreNextOptions\n): Promise<SyncoreServiceWorkerRegistration | null> {\n if (typeof window === \"undefined\" || !(\"serviceWorker\" in navigator)) {\n return null;\n }\n\n const registration = await navigator.serviceWorker.register(\n options?.serviceWorkerUrl ?? \"/sw.js\"\n );\n\n return {\n unregister: () => registration.unregister(),\n update: () => registration.update()\n };\n}\n\n/**\n * Create a worker-backed Syncore client for a Next.js app.\n *\n * The client communicates with a Syncore runtime running inside a `Worker`.\n * The worker runs the SQLite engine and all function handlers off the main\n * thread so the UI stays responsive.\n *\n * In most cases you should use {@link SyncoreNextProvider} instead, which\n * manages the client lifecycle automatically. Use `createNextSyncoreClient`\n * directly only when you need to control the client lifecycle yourself (e.g.\n * in testing harnesses or custom providers).\n *\n * ```ts\n * const managedClient = createNextSyncoreClient({\n * workerAssetUrl: \"/syncore.worker.js\",\n * });\n *\n * // Later:\n * managedClient.dispose();\n * ```\n */\nexport function createNextSyncoreClient(options: {\n /**\n * Custom worker factory function. Useful in tests (supply a `Worker` backed\n * by a mock or in-process runtime) or when using Next’s App Router dev-mode\n * bundling where `new Worker(new URL(...))` must be used inside the component.\n */\n createWorker?: () => Worker;\n\n /** Explicit module URL for an already-public worker script. */\n workerUrl?: URL | string;\n\n /** Public asset path for the compiled worker file. Defaults to `\"/syncore.worker.js\"`. */\n workerAssetUrl?: string;\n}): ManagedWebWorkerClient {\n if (options.createWorker) {\n return createManagedWebWorkerClient({\n createWorker: options.createWorker\n });\n }\n\n return createSyncoreWebWorkerClient({\n workerUrl:\n options.workerUrl ?? options.workerAssetUrl ?? \"/syncore.worker.js\"\n });\n}\n\n/**\n * React component that registers a PWA service worker as a side-effect.\n *\n * Renders its `children` immediately (no loading state) and registers the\n * service worker asynchronously. Safe to render on the server — the\n * registration effect only runs in browsers that support service workers.\n *\n * ```tsx\n * <SyncoreServiceWorker serviceWorkerUrl=\"/sw.js\" onRegistered={console.log}>\n * <App />\n * </SyncoreServiceWorker>\n * ```\n */\nexport function SyncoreServiceWorker({\n children,\n serviceWorkerUrl,\n onRegistered\n}: {\n children: ReactNode;\n /** URL of the service worker script. Defaults to `\"/sw.js\"`. */\n serviceWorkerUrl?: string;\n /** Called after the service worker is successfully registered. */\n onRegistered?: (registration: ServiceWorkerRegistration) => void;\n}) {\n useEffect(() => {\n void (async () => {\n if (typeof window === \"undefined\" || !(\"serviceWorker\" in navigator)) {\n return;\n }\n const registration = await navigator.serviceWorker.register(\n serviceWorkerUrl ?? \"/sw.js\"\n );\n onRegistered?.(registration);\n })();\n }, [onRegistered, serviceWorkerUrl]);\n\n return children;\n}\n\n/**\n * Root provider that wires a worker-backed Syncore runtime into a Next.js\n * React tree.\n *\n * Place this at the top of your App Router layout. It spawns the Syncore\n * worker on mount, exposes the client via React context (accessible with\n * `useSyncore()`), and optionally registers the PWA service worker.\n *\n * ```tsx\n * // app/layout.tsx\n * import { SyncoreNextProvider } from \"syncorejs/next\";\n *\n * export default function RootLayout({ children }) {\n * return (\n * <html>\n * <body>\n * <SyncoreNextProvider\n * createWorker={() => new Worker(\n * new URL(\"../syncore.worker.ts\", import.meta.url)\n * )}\n * >\n * {children}\n * </SyncoreNextProvider>\n * </body>\n * </html>\n * );\n * }\n * ```\n */\nexport function SyncoreNextProvider({\n children,\n createWorker,\n serviceWorkerUrl,\n workerUrl,\n workerAssetUrl\n}: {\n /** The React subtree that should receive the Syncore client. */\n children: ReactNode;\n\n /**\n * Factory function that creates the Syncore `Worker`. Required in Next App\n * Router dev mode because `new Worker(new URL(..., import.meta.url))` must\n * be called inside the module to be bundled correctly.\n */\n createWorker?: () => Worker;\n\n /** URL of the PWA service worker script. Omit to skip service worker registration. */\n serviceWorkerUrl?: string;\n\n /** Explicit module URL for an already-public worker asset. */\n workerUrl?: URL | string;\n\n /** Public asset path for the compiled worker file. Defaults to `\"/syncore.worker.js\"`. */\n workerAssetUrl?: string;\n}) {\n const createWorkerRef = useRef(createWorker);\n createWorkerRef.current = createWorker;\n const resolvedWorkerUrl =\n typeof workerUrl === \"string\" ? workerUrl : workerUrl?.toString();\n const bootingClient = useMemo(\n () =>\n createUnavailableSyncoreClient({\n kind: \"starting\",\n reason: \"booting\",\n capabilities: {\n storage: { available: false, reason: \"Syncore worker is booting.\" }\n }\n }),\n []\n );\n const [client, setClient] = useState<SyncoreClient>(bootingClient);\n\n useEffect(() => {\n let managedClient: ManagedWebWorkerClient | undefined;\n\n setClient(bootingClient);\n\n try {\n const workerFactory = createWorkerRef.current;\n managedClient = createNextSyncoreClient({\n ...(workerFactory\n ? {\n createWorker: () => workerFactory()\n }\n : {}),\n ...(resolvedWorkerUrl\n ? {\n workerUrl:\n process.env.NODE_ENV === \"production\"\n ? getSyncoreWorkerUrl()\n : resolvedWorkerUrl\n }\n : {}),\n ...(workerAssetUrl ? { workerAssetUrl } : {})\n });\n setClient(managedClient.client);\n } catch (error) {\n setClient(\n createUnavailableSyncoreClient({\n kind: \"unavailable\",\n reason: \"worker-unavailable\",\n capabilities: {\n storage: {\n available: false,\n reason: \"Syncore worker is unavailable.\"\n }\n },\n ...(error instanceof Error ? { error } : {})\n })\n );\n }\n\n return () => {\n managedClient?.dispose();\n };\n }, [bootingClient, resolvedWorkerUrl, workerAssetUrl]);\n\n return (\n <SyncoreServiceWorker {...(serviceWorkerUrl ? { serviceWorkerUrl } : {})}>\n <SyncoreProvider client={client}>{children}</SyncoreProvider>\n </SyncoreServiceWorker>\n );\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;AA6EA,eAAsB,6BACpB,SACkD;CAClD,IAAI,OAAO,WAAW,eAAe,EAAE,mBAAmB,YACxD,OAAO;CAGT,MAAM,eAAe,MAAM,UAAU,cAAc,SACjD,SAAS,oBAAoB,QAC/B;CAEA,OAAO;EACL,kBAAkB,aAAa,WAAW;EAC1C,cAAc,aAAa,OAAO;CACpC;AACF;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,wBAAwB,SAab;CACzB,IAAI,QAAQ,cACV,OAAO,6BAA6B,EAClC,cAAc,QAAQ,aACxB,CAAC;CAGH,OAAO,6BAA6B,EAClC,WACE,QAAQ,aAAa,QAAQ,kBAAkB,qBACnD,CAAC;AACH;;;;;;;;;;;;;;AAeA,SAAgB,qBAAqB,EACnC,UACA,kBACA,gBAOC;CACD,gBAAgB;EACd,CAAM,YAAY;GAChB,IAAI,OAAO,WAAW,eAAe,EAAE,mBAAmB,YACxD;GAEF,MAAM,eAAe,MAAM,UAAU,cAAc,SACjD,oBAAoB,QACtB;GACA,eAAe,YAAY;EAC7B,GAAG;CACL,GAAG,CAAC,cAAc,gBAAgB,CAAC;CAEnC,OAAO;AACT;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,SAAgB,oBAAoB,EAClC,UACA,cACA,kBACA,WACA,kBAoBC;CACD,MAAM,kBAAkB,OAAO,YAAY;CAC3C,gBAAgB,UAAU;CAC1B,MAAM,oBACJ,OAAO,cAAc,WAAW,YAAY,WAAW,SAAS;CAClE,MAAM,gBAAgB,cAElB,+BAA+B;EAC7B,MAAM;EACN,QAAQ;EACR,cAAc,EACZ,SAAS;GAAE,WAAW;GAAO,QAAQ;EAA6B,EACpE;CACF,CAAC,GACH,CAAC,CACH;CACA,MAAM,CAAC,QAAQ,aAAa,SAAwB,aAAa;CAEjE,gBAAgB;EACd,IAAI;EAEJ,UAAU,aAAa;EAEvB,IAAI;GACF,MAAM,gBAAgB,gBAAgB;GACtC,gBAAgB,wBAAwB;IACtC,GAAI,gBACA,EACE,oBAAoB,cAAc,EACpC,IACA,CAAC;IACL,GAAI,oBACA,EACE,WACE,QAAQ,IAAI,aAAa,eACrB,oBAAoB,IACpB,kBACR,IACA,CAAC;IACL,GAAI,iBAAiB,EAAE,eAAe,IAAI,CAAC;GAC7C,CAAC;GACD,UAAU,cAAc,MAAM;EAChC,SAAS,OAAO;GACd,UACE,+BAA+B;IAC7B,MAAM;IACN,QAAQ;IACR,cAAc,EACZ,SAAS;KACP,WAAW;KACX,QAAQ;IACV,EACF;IACA,GAAI,iBAAiB,QAAQ,EAAE,MAAM,IAAI,CAAC;GAC5C,CAAC,CACH;EACF;EAEA,aAAa;GACX,eAAe,QAAQ;EACzB;CACF,GAAG;EAAC;EAAe;EAAmB;CAAc,CAAC;CAErD,OACE,oBAAC,sBAAD;EAAsB,GAAK,mBAAmB,EAAE,iBAAiB,IAAI,CAAC;YACpE,oBAAC,iBAAD;GAAyB;GAAS;EAA0B,CAAA;CACxC,CAAA;AAE1B"}
@@ -131,7 +131,7 @@ interface ExpoSyncoreBootstrap<TSchema extends ExpoSyncoreSchema = ExpoSyncoreSc
131
131
  * Create a Syncore runtime for Expo (React Native and Expo web) backed by
132
132
  * `expo-sqlite` on native platforms and SQL.js on web.
133
133
  *
134
- * Returns an unstarted {@link SyncoreRuntime}. Call `await runtime.start()`
134
+ * Returns an unstarted SyncoreRuntime. Call `await runtime.start()`
135
135
  * before using the client:
136
136
  *
137
137
  * ```ts
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;KA6BY,iBAAA,iBACM,gBAAA,GAAmB,gBAAA,IACjC,OAAA;;AAFJ;;;;;;;;;;;;;AAEW;AAsBX;;;;;UAAiB,wBAAA,iBACC,iBAAA,GAAoB,iBAAA;EASH;EANjC,MAAA,EAAQ,OAAA;EAY2B;;;;EANnC,SAAA,EAAW,qBAAA,CAAsB,OAAA;EAmDtB;;;;EA7CX,UAAA,GAAa,qBAAA,CAAsB,OAAA;EA6DiB;;;;EAvDpD,YAAA,GAAe,mBAAA;EAlBP;;;;EAwBR,MAAA,GAAS,gBAAA;EAZI;EAeb,OAAA,GAAU,qBAAA;EATV;;;;EAeA,YAAA;EANU;;;;EAYV,iBAAA;EAkBA;;;;EAZA,oBAAA;EAqBuB;;;;EAfvB,QAAA;EAkCc;;AAAgB;AAiBhC;EA7CE,QAAA,GAAW,YAAA;EA6CwB;EA1CnC,SAAA,GAAY,gBAAA;EA2CwB;;;;EArCpC,oBAAA,GAAuB,2BAAA;EAmDf;;;;;EA5CR,qBAAA,GAAwB,4BAAA;EA8BY;;;;EAxBpC,OAAA;EAkCa;;;;EA5Bb,UAAA,IAAc,QAAA;AAAA;;AAsCE;AAuBlB;;;;;;;;;;;;UA5CiB,oBAAA,iBACC,iBAAA,GAAoB,iBAAA;EA8CF;EA3ClC,UAAA;EA4CC;;;AAAsB;EAtCvB,SAAA,IAAa,OAAA,CACX,UAAA,CAAW,cAAA,CAAe,OAAA;EAiHS;EA7GrC,IAAA,IAAQ,OAAA;EA8GQ;;;;EAxGhB,KAAA,IAAS,OAAA;AAAA;;;;;;;AAyGuB;AA0BlC;;;;;;;;;;;;;iBA5GgB,wBAAA,iBACE,iBAAA,CAAA,CAEhB,OAAA,EAAS,wBAAA,CAAyB,OAAA,IACjC,cAAA,CAAe,OAAA;;;;;AA4Ga;AAgD/B;;;;;;;iBAhFgB,uBAAA,iBACE,iBAAA,CAAA,CAChB,OAAA,EAAS,cAAA,CAAe,OAAA,4BAAQ,aAAA;;;;;;;;;;;;;;;;;;;;;;;iBA0BlB,0BAAA,iBACE,iBAAA,CAAA,CAEhB,OAAA,EAAS,wBAAA,CAAyB,OAAA,IACjC,oBAAA,CAAqB,OAAA;;;;cAgDX,gBAAA,YAA4B,gBAAA;EAAA,QAO7B,QAAA;EAAA,QANF,gBAAA;EAAA,QACA,MAAA;EAAA,iBACS,YAAA;EAAA,iBACA,iBAAA;cAGP,QAAA,EAAU,cAAA,EAClB,OAAA;IACE,YAAA;IACA,iBAAA;EAAA;EAOE,IAAA,CAAK,GAAA,WAAc,OAAA;EAKnB,GAAA,CACJ,GAAA,UACA,MAAA,eACC,OAAA;IAAU,OAAA;IAAiB,eAAA;EAAA;EASxB,GAAA,GAAA,CAAO,GAAA,UAAa,MAAA,eAAyB,OAAA,CAAQ,CAAA;EASrD,GAAA,GAAA,CAAO,GAAA,UAAa,MAAA,eAAyB,OAAA,CAAQ,CAAA;EAKrD,eAAA,GAAA,CAAmB,QAAA,QAAgB,OAAA,CAAQ,CAAA,IAAK,OAAA,CAAQ,CAAA;EAoBxD,aAAA,GAAA,CAAiB,IAAA,UAAc,QAAA,QAAgB,OAAA,CAAQ,CAAA,IAAK,OAAA,CAAQ,CAAA;EAkBpE,KAAA,CAAA,GAAS,OAAA;EAAA,QAQP,UAAA;EAMF,MAAA,CAAA,GAAU,OAAA;AAAA;;;;cAuCL,sBAAA,YAAkC,qBAAA;EAAA,iBAC5B,aAAA;cAEL,oBAAA;EAON,GAAA,CAAI,EAAA,UAAY,KAAA,EAAO,iBAAA,GAAoB,OAAA,CAAQ,aAAA;EAenD,GAAA,CAAI,EAAA,WAAa,OAAA,CAAQ,aAAA;EAazB,IAAA,CAAK,EAAA,WAAa,OAAA,CAAQ,UAAA;EAQ1B,MAAA,CAAO,EAAA,WAAa,OAAA;AAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":";;;;KA6BY,iBAAA,iBACM,gBAAA,GAAmB,gBAAA,IACjC,OAAA;;AAFJ;;;;;;;;;;;;;AAEW;AAsBX;;;;;UAAiB,wBAAA,iBACC,iBAAA,GAAoB,iBAAA;EASH;EANjC,MAAA,EAAQ,OAAA;EAY2B;;;;EANnC,SAAA,EAAW,qBAAA,CAAsB,OAAA;EAmDtB;;;;EA7CX,UAAA,GAAa,qBAAA,CAAsB,OAAA;EA6DiB;;;;EAvDpD,YAAA,GAAe,mBAAA;EAlBP;;;;EAwBR,MAAA,GAAS,gBAAA;EAZI;EAeb,OAAA,GAAU,qBAAA;EATV;;;;EAeA,YAAA;EANU;;;;EAYV,iBAAA;EAkBA;;;;EAZA,oBAAA;EAqBuB;;;;EAfvB,QAAA;EAkCc;;AAAgB;AAiBhC;EA7CE,QAAA,GAAW,YAAA;EA6CwB;EA1CnC,SAAA,GAAY,gBAAA;EA2CwB;;;;EArCpC,oBAAA,GAAuB,2BAAA;EAmDf;;;;;EA5CR,qBAAA,GAAwB,4BAAA;EA8BY;;;;EAxBpC,OAAA;EAkCa;;;;EA5Bb,UAAA,IAAc,QAAA;AAAA;;AAsCE;AAuBlB;;;;;;;;;;;;UA5CiB,oBAAA,iBACC,iBAAA,GAAoB,iBAAA;EA8CF;EA3ClC,UAAA;EA4CC;;;AAAsB;EAtCvB,SAAA,IAAa,OAAA,CACX,UAAA,CAAW,cAAA,CAAe,OAAA;EAwHS;EApHrC,IAAA,IAAQ,OAAA;EAqHQ;;;;EA/GhB,KAAA,IAAS,OAAA;AAAA;;;;;;;AAgHuB;AA0BlC;;;;;;;;;;;;;iBAnHgB,wBAAA,iBACE,iBAAA,CAAA,CAEhB,OAAA,EAAS,wBAAA,CAAyB,OAAA,IACjC,cAAA,CAAe,OAAA;;;;;AAmHa;AAgD/B;;;;;;;iBAhFgB,uBAAA,iBACE,iBAAA,CAAA,CAChB,OAAA,EAAS,cAAA,CAAe,OAAA,4BAAQ,aAAA;;;;;;;;;;;;;;;;;;;;;;;iBA0BlB,0BAAA,iBACE,iBAAA,CAAA,CAEhB,OAAA,EAAS,wBAAA,CAAyB,OAAA,IACjC,oBAAA,CAAqB,OAAA;;;;cAgDX,gBAAA,YAA4B,gBAAA;EAAA,QAO7B,QAAA;EAAA,QANF,gBAAA;EAAA,QACA,MAAA;EAAA,iBACS,YAAA;EAAA,iBACA,iBAAA;cAGP,QAAA,EAAU,cAAA,EAClB,OAAA;IACE,YAAA;IACA,iBAAA;EAAA;EAOE,IAAA,CAAK,GAAA,WAAc,OAAA;EAKnB,GAAA,CACJ,GAAA,UACA,MAAA,eACC,OAAA;IAAU,OAAA;IAAiB,eAAA;EAAA;EASxB,GAAA,GAAA,CAAO,GAAA,UAAa,MAAA,eAAyB,OAAA,CAAQ,CAAA;EASrD,GAAA,GAAA,CAAO,GAAA,UAAa,MAAA,eAAyB,OAAA,CAAQ,CAAA;EAKrD,eAAA,GAAA,CAAmB,QAAA,QAAgB,OAAA,CAAQ,CAAA,IAAK,OAAA,CAAQ,CAAA;EAoBxD,aAAA,GAAA,CAAiB,IAAA,UAAc,QAAA,QAAgB,OAAA,CAAQ,CAAA,IAAK,OAAA,CAAQ,CAAA;EAkBpE,KAAA,CAAA,GAAS,OAAA;EAAA,QAQP,UAAA;EAMF,MAAA,CAAA,GAAU,OAAA;AAAA;;;;cAuCL,sBAAA,YAAkC,qBAAA;EAAA,iBAC5B,aAAA;cAEL,oBAAA;EAON,GAAA,CAAI,EAAA,UAAY,KAAA,EAAO,iBAAA,GAAoB,OAAA,CAAQ,aAAA;EAenD,GAAA,CAAI,EAAA,WAAa,OAAA,CAAQ,aAAA;EAazB,IAAA,CAAK,EAAA,WAAa,OAAA,CAAQ,UAAA;EAQ1B,MAAA,CAAO,EAAA,WAAa,OAAA;AAAA"}
@@ -7,7 +7,7 @@ import { BroadcastChannelExternalChangeSignal, createDefaultSyncChannelName, cre
7
7
  * Create a Syncore runtime for Expo (React Native and Expo web) backed by
8
8
  * `expo-sqlite` on native platforms and SQL.js on web.
9
9
  *
10
- * Returns an unstarted {@link SyncoreRuntime}. Call `await runtime.start()`
10
+ * Returns an unstarted SyncoreRuntime. Call `await runtime.start()`
11
11
  * before using the client:
12
12
  *
13
13
  * ```ts
@@ -43,6 +43,11 @@ function createExpoSyncoreRuntime(options) {
43
43
  ...isWebEnvironment && options.externalChangeApplier ? { externalChangeApplier: options.externalChangeApplier } : isWebEnvironment && webExternalChangeApplier ? { externalChangeApplier: webExternalChangeApplier } : {},
44
44
  platform: options.platform ?? "expo",
45
45
  ...options.capabilities ? { capabilities: options.capabilities } : {},
46
+ runtimeCapabilities: { storage: {
47
+ available: true,
48
+ protocol: "file",
49
+ supportsRange: false
50
+ } },
46
51
  ...options.devtools ? { devtools: options.devtools } : {},
47
52
  ...options.scheduler ? { scheduler: options.scheduler } : {}
48
53
  });
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/// <reference path=\"./assets.d.ts\" />\n\nimport { Directory, File, Paths } from \"expo-file-system\";\nimport {\n defaultDatabaseDirectory,\n openDatabaseSync,\n type SQLiteDatabase\n} from \"expo-sqlite\";\nimport {\n type ImpactScope,\n type DevtoolsSink,\n type SyncoreExternalChangeApplier,\n type SyncoreExternalChangeSignal,\n SyncoreRuntime,\n type SchedulerOptions,\n type SyncoreCapabilities,\n type SyncoreDataModel,\n type SyncoreRuntimeOptions,\n type SyncoreSqlDriver,\n type SyncoreStorageAdapter,\n type StorageObject,\n type StorageWriteInput\n} from \"@syncore/core\";\nimport {\n BroadcastChannelExternalChangeSignal,\n createDefaultSyncChannelName,\n createWebSyncoreRuntime\n} from \"@syncore/platform-web\";\n\nexport type ExpoSyncoreSchema<\n TSchema extends SyncoreDataModel = SyncoreDataModel\n> = TSchema;\n\n/**\n * Options for {@link createExpoSyncoreRuntime}.\n *\n * On native (iOS/Android) Syncore uses `expo-sqlite` and `expo-file-system`\n * automatically. When the same app is served on web (via `expo-router` or\n * Metro’s web bundler) it falls back to the SQL.js + OPFS web stack instead.\n *\n * At minimum supply `schema` and `functions`. Everything else has platform\n * defaults.\n *\n * ```ts\n * const runtime = createExpoSyncoreRuntime({\n * schema,\n * functions,\n * databaseName: \"app.db\",\n * storageDirectoryName: \"app-storage\",\n * });\n * await runtime.start();\n * ```\n */\nexport interface CreateExpoRuntimeOptions<\n TSchema extends ExpoSyncoreSchema = ExpoSyncoreSchema\n> {\n /** The data model that defines the available tables and indexes. */\n schema: TSchema;\n\n /**\n * The registered function map. Use the `functions` export from\n * `syncore/_generated/functions.ts`.\n */\n functions: SyncoreRuntimeOptions<TSchema>[\"functions\"];\n\n /**\n * Resolved Syncore component instances. Only required when your app\n * installs Syncore component packages.\n */\n components?: SyncoreRuntimeOptions<TSchema>[\"components\"];\n\n /**\n * Platform capabilities injected into `ctx.capabilities` inside function\n * handlers.\n */\n capabilities?: SyncoreCapabilities;\n\n /**\n * Custom SQL driver. Defaults to an `ExpoSqliteDriver` backed by\n * `expo-sqlite`.\n */\n driver?: SyncoreSqlDriver;\n\n /** Custom file/blob storage adapter. Defaults to `ExpoFileStorageAdapter`. */\n storage?: SyncoreStorageAdapter;\n\n /**\n * SQLite database filename (e.g. `\"app.db\"`). Defaults to `\"syncore.db\"`.\n * The file is created inside the app-local documents directory on device.\n */\n databaseName?: string;\n\n /**\n * Absolute path to the directory where the SQLite file is stored.\n * Defaults to `expo-sqlite`’s `defaultDatabaseDirectory`.\n */\n databaseDirectory?: string;\n\n /**\n * Name of the sub-directory inside the app’s documents folder used for\n * blob/file storage. Defaults to `\"syncore-storage\"`.\n */\n storageDirectoryName?: string;\n\n /**\n * Platform label reported to devtools. Defaults to `\"expo\"`. Override to\n * `\"expo-web\"` when running on web.\n */\n platform?: string;\n\n /**\n * Devtools event sink. Omit to disable devtools. On-device devtools\n * connections require pointing to your development machine’s IP address.\n */\n devtools?: DevtoolsSink;\n\n /** Scheduler configuration for background and recurring jobs. */\n scheduler?: SchedulerOptions;\n\n /**\n * External change signal used to keep multiple in-process instances in sync.\n * On web, defaults to a `BroadcastChannel`-based signal automatically.\n */\n externalChangeSignal?: SyncoreExternalChangeSignal;\n\n /**\n * External change applier used when change events arrive from other tabs or\n * processes. On web with `ExpoSqliteDriver`, defaults to\n * `ExpoWebExternalChangeApplier` automatically.\n */\n externalChangeApplier?: SyncoreExternalChangeApplier;\n\n /**\n * Direct URL to the SQL.js `.wasm` binary. Only needed when the app runs on\n * web and the default CDN URL is unreachable.\n */\n wasmUrl?: string;\n\n /**\n * Resolver for SQL.js support files (`.wasm`, `.worker.js`). Equivalent to\n * the `locateFile` option in `initSqlJs()`. Only used on web.\n */\n locateFile?: (fileName: string) => string;\n}\n\n/**\n * A reusable, lazily-started Expo Syncore runtime handle.\n *\n * Created by {@link createExpoSyncoreBootstrap}. The bootstrap defers actual\n * runtime startup until the first call to `getClient()` and keeps a single\n * instance alive across React Navigation reloads.\n *\n * ```ts\n * const bootstrap = createExpoSyncoreBootstrap({ schema, functions });\n *\n * // In your root component:\n * const client = await bootstrap.getClient();\n * ```\n */\nexport interface ExpoSyncoreBootstrap<\n TSchema extends ExpoSyncoreSchema = ExpoSyncoreSchema\n> {\n /** @deprecated Access the runtime via `getClient()` instead. */\n getRuntime(): never;\n\n /**\n * Start the runtime on first call, then return the same client on subsequent\n * calls. Safe to call from multiple places concurrently.\n */\n getClient(): Promise<\n ReturnType<SyncoreRuntime<TSchema>[\"createClient\"]>\n >;\n\n /** Stop the running runtime instance if one is active. */\n stop(): Promise<void>;\n\n /**\n * Stop and discard the current runtime so the next `getClient()` call\n * creates a fresh one. Useful after a full app reset or database migration.\n */\n reset(): Promise<void>;\n}\n\n/**\n * Create a Syncore runtime for Expo (React Native and Expo web) backed by\n * `expo-sqlite` on native platforms and SQL.js on web.\n *\n * Returns an unstarted {@link SyncoreRuntime}. Call `await runtime.start()`\n * before using the client:\n *\n * ```ts\n * import { createExpoSyncoreRuntime } from \"syncorejs/expo\";\n * import schema from \"./syncore/schema\";\n * import { functions } from \"./syncore/_generated/functions\";\n *\n * const runtime = createExpoSyncoreRuntime({ schema, functions });\n * await runtime.start();\n * const client = runtime.createClient();\n * ```\n *\n * For managed lifecycle in React components, prefer\n * {@link createExpoSyncoreBootstrap} instead.\n */\nexport function createExpoSyncoreRuntime<\n TSchema extends ExpoSyncoreSchema\n>(\n options: CreateExpoRuntimeOptions<TSchema>\n): SyncoreRuntime<TSchema> {\n const databaseDirectory =\n options.databaseDirectory ??\n (typeof defaultDatabaseDirectory === \"string\"\n ? defaultDatabaseDirectory\n : undefined);\n const driver =\n options.driver ??\n new ExpoSqliteDriver(\n openDatabaseSync(\n options.databaseName ?? \"syncore.db\",\n undefined,\n databaseDirectory\n ),\n {\n databaseName: options.databaseName ?? \"syncore.db\",\n ...(databaseDirectory ? { databaseDirectory } : {})\n }\n );\n const storage =\n options.storage ??\n new ExpoFileStorageAdapter(\n options.storageDirectoryName ?? \"syncore-storage\"\n );\n const isWebEnvironment =\n typeof window !== \"undefined\" && typeof document !== \"undefined\";\n const webExternalChangeSignal =\n isWebEnvironment && !options.externalChangeSignal\n ? new BroadcastChannelExternalChangeSignal({\n channelName: createDefaultSyncChannelName(\n options.databaseName ?? \"syncore.db\"\n )\n })\n : undefined;\n const webExternalChangeApplier =\n isWebEnvironment &&\n !options.externalChangeApplier &&\n driver instanceof ExpoSqliteDriver\n ? new ExpoWebExternalChangeApplier(driver)\n : undefined;\n\n return new SyncoreRuntime({\n schema: options.schema,\n functions: options.functions,\n ...(options.components ? { components: options.components } : {}),\n driver,\n storage,\n ...(isWebEnvironment && options.externalChangeSignal\n ? { externalChangeSignal: options.externalChangeSignal }\n : isWebEnvironment && webExternalChangeSignal\n ? { externalChangeSignal: webExternalChangeSignal }\n : {}),\n ...(isWebEnvironment && options.externalChangeApplier\n ? { externalChangeApplier: options.externalChangeApplier }\n : isWebEnvironment && webExternalChangeApplier\n ? { externalChangeApplier: webExternalChangeApplier }\n : {}),\n platform: options.platform ?? \"expo\",\n ...(options.capabilities ? { capabilities: options.capabilities } : {}),\n ...(options.devtools ? { devtools: options.devtools } : {}),\n ...(options.scheduler ? { scheduler: options.scheduler } : {})\n });\n}\n\n/**\n * Create a same-process Syncore client directly from a started Expo runtime.\n *\n * Prefer this in scripts or non-component code. For React component trees,\n * use {@link createExpoSyncoreBootstrap} instead to get automatic lifecycle\n * management.\n *\n * ```ts\n * const client = createExpoSyncoreClient(runtime);\n * await client.mutation(api.todos.create, { text: \"Buy milk\" });\n * ```\n */\nexport function createExpoSyncoreClient<\n TSchema extends ExpoSyncoreSchema\n>(runtime: SyncoreRuntime<TSchema>) {\n return runtime.createClient();\n}\n\n/**\n * Create a reusable Expo bootstrap that lazily starts the local runtime the\n * first time a client is requested.\n *\n * The bootstrap keeps a single runtime instance alive across component\n * remounts and safely handles concurrent `getClient()` calls.\n *\n * ```ts\n * // app/_layout.tsx\n * import { createExpoSyncoreBootstrap } from \"syncorejs/expo\";\n * import schema from \"../syncore/schema\";\n * import { functions } from \"../syncore/_generated/functions\";\n *\n * export const syncoreBootstrap = createExpoSyncoreBootstrap({\n * schema,\n * functions,\n * });\n *\n * // Later in SyncoreProvider:\n * const client = await syncoreBootstrap.getClient();\n * ```\n */\nexport function createExpoSyncoreBootstrap<\n TSchema extends ExpoSyncoreSchema\n>(\n options: CreateExpoRuntimeOptions<TSchema>\n): ExpoSyncoreBootstrap<TSchema> {\n let runtime: SyncoreRuntime<TSchema> | null = null;\n let started: Promise<\n ReturnType<SyncoreRuntime<TSchema>[\"createClient\"]>\n > | null = null;\n\n const ensureRuntime = async () => {\n runtime ??= isWebEnvironment()\n ? await createExpoWebSyncoreRuntime(options)\n : createExpoSyncoreRuntime(options);\n return runtime;\n };\n\n return {\n getRuntime() {\n throw new Error(\n \"createExpoSyncoreBootstrap().getRuntime() is not available synchronously. Use getClient() instead.\"\n );\n },\n async getClient() {\n if (!started) {\n started = ensureRuntime().then((activeRuntime) =>\n activeRuntime.start().then(() => activeRuntime.createClient())\n );\n }\n return started;\n },\n async stop() {\n if (!runtime) {\n return;\n }\n await runtime.stop();\n runtime = null;\n started = null;\n },\n async reset() {\n if (runtime) {\n await runtime.stop();\n }\n runtime = null;\n started = null;\n }\n };\n}\n\n/**\n * Syncore SQL driver implementation backed by `expo-sqlite`.\n */\nexport class ExpoSqliteDriver implements SyncoreSqlDriver {\n private transactionDepth = 0;\n private closed = false;\n private readonly databaseName: string;\n private readonly databaseDirectory: string | undefined;\n\n constructor(\n private database: SQLiteDatabase,\n options?: {\n databaseName?: string;\n databaseDirectory?: string;\n }\n ) {\n this.databaseName = options?.databaseName ?? \"syncore.db\";\n this.databaseDirectory = options?.databaseDirectory;\n }\n\n async exec(sql: string): Promise<void> {\n this.ensureOpen();\n await this.database.execAsync(sql);\n }\n\n async run(\n sql: string,\n params: unknown[] = []\n ): Promise<{ changes: number; lastInsertRowid?: number | string }> {\n this.ensureOpen();\n const result = await this.database.runAsync(sql, normalizeParams(params));\n return {\n changes: result.changes,\n lastInsertRowid: result.lastInsertRowId\n };\n }\n\n async get<T>(sql: string, params: unknown[] = []): Promise<T | undefined> {\n this.ensureOpen();\n const row = await this.database.getFirstAsync<T>(\n sql,\n normalizeParams(params)\n );\n return row ?? undefined;\n }\n\n async all<T>(sql: string, params: unknown[] = []): Promise<T[]> {\n this.ensureOpen();\n return this.database.getAllAsync<T>(sql, normalizeParams(params));\n }\n\n async withTransaction<T>(callback: () => Promise<T>): Promise<T> {\n this.ensureOpen();\n if (this.transactionDepth > 0) {\n return this.withSavepoint(`nested_${this.transactionDepth}`, callback);\n }\n\n this.transactionDepth += 1;\n await this.database.execAsync(\"BEGIN IMMEDIATE\");\n try {\n const result = await callback();\n await this.database.execAsync(\"COMMIT\");\n return result;\n } catch (error) {\n await this.database.execAsync(\"ROLLBACK\");\n throw error;\n } finally {\n this.transactionDepth -= 1;\n }\n }\n\n async withSavepoint<T>(name: string, callback: () => Promise<T>): Promise<T> {\n this.ensureOpen();\n const safeName = name.replaceAll(/[^a-zA-Z0-9_]/g, \"_\");\n this.transactionDepth += 1;\n await this.database.execAsync(`SAVEPOINT ${safeName}`);\n try {\n const result = await callback();\n await this.database.execAsync(`RELEASE SAVEPOINT ${safeName}`);\n return result;\n } catch (error) {\n await this.database.execAsync(`ROLLBACK TO SAVEPOINT ${safeName}`);\n await this.database.execAsync(`RELEASE SAVEPOINT ${safeName}`);\n throw error;\n } finally {\n this.transactionDepth -= 1;\n }\n }\n\n async close(): Promise<void> {\n if (this.closed) {\n return;\n }\n await this.database.closeAsync();\n this.closed = true;\n }\n\n private ensureOpen(): void {\n if (this.closed) {\n throw new Error(\"The Expo SQLite driver is already closed.\");\n }\n }\n\n async reopen(): Promise<void> {\n this.ensureOpen();\n await this.database.closeAsync();\n this.database = openDatabaseSync(\n this.databaseName,\n undefined,\n this.databaseDirectory\n );\n }\n}\n\nclass ExpoWebExternalChangeApplier implements SyncoreExternalChangeApplier {\n constructor(private readonly driver: ExpoSqliteDriver) {}\n\n async applyExternalChange(event: {\n scope: \"database\" | \"storage\" | \"all\";\n changedScopes?: ImpactScope[];\n changedTables?: string[];\n storageIds?: string[];\n }) {\n if (event.scope === \"database\" || event.scope === \"all\") {\n await this.driver.reopen();\n }\n return {\n databaseChanged: event.scope === \"database\" || event.scope === \"all\",\n storageChanged: event.scope === \"storage\" || event.scope === \"all\",\n changedScopes:\n event.changedScopes ??\n ([\n ...(event.changedTables ?? []).map((tableName) => `table:${tableName}`),\n ...(event.storageIds ?? []).map((storageId) => `storage:${storageId}`)\n ] as ImpactScope[])\n };\n }\n}\n\n/**\n * Syncore file/blob storage backed by the Expo file system.\n */\nexport class ExpoFileStorageAdapter implements SyncoreStorageAdapter {\n private readonly rootDirectory: Directory;\n\n constructor(storageDirectoryName: string) {\n this.rootDirectory = new Directory(Paths.document, storageDirectoryName);\n if (!this.rootDirectory.exists) {\n this.rootDirectory.create({ idempotent: true, intermediates: true });\n }\n }\n\n async put(id: string, input: StorageWriteInput): Promise<StorageObject> {\n const file = new File(this.rootDirectory, id);\n if (!file.exists) {\n file.create({ intermediates: true, overwrite: true });\n }\n const bytes = normalizeBinary(input.data);\n file.write(bytes);\n return {\n id,\n path: file.uri,\n size: bytes.byteLength,\n contentType: input.contentType ?? null\n };\n }\n\n async get(id: string): Promise<StorageObject | null> {\n const file = new File(this.rootDirectory, id);\n if (!file.exists) {\n return null;\n }\n return {\n id,\n path: file.uri,\n size: file.size,\n contentType: file.type || null\n };\n }\n\n async read(id: string): Promise<Uint8Array | null> {\n const file = new File(this.rootDirectory, id);\n if (!file.exists) {\n return null;\n }\n return file.bytes();\n }\n\n async delete(id: string): Promise<void> {\n const file = new File(this.rootDirectory, id);\n if (file.exists) {\n file.delete();\n }\n }\n}\n\nfunction normalizeParams(\n values: unknown[]\n): Array<string | number | Uint8Array | null> {\n return values.map((value) => {\n if (typeof value === \"boolean\") {\n return value ? 1 : 0;\n }\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n value instanceof Uint8Array\n ) {\n return value;\n }\n if (value instanceof ArrayBuffer) {\n return new Uint8Array(value);\n }\n return JSON.stringify(value);\n });\n}\n\nfunction normalizeBinary(data: StorageWriteInput[\"data\"]): Uint8Array {\n if (typeof data === \"string\") {\n return new TextEncoder().encode(data);\n }\n if (data instanceof Uint8Array) {\n return data;\n }\n return new Uint8Array(data);\n}\n\nasync function createExpoWebSyncoreRuntime<TSchema extends ExpoSyncoreSchema>(\n options: CreateExpoRuntimeOptions<TSchema>\n): Promise<SyncoreRuntime<TSchema>> {\n const wasmUrl =\n options.wasmUrl ??\n (options.locateFile\n ? undefined\n : await resolveDefaultExpoWebSqlJsWasmUrl());\n\n return createWebSyncoreRuntime({\n schema: options.schema,\n functions: options.functions,\n ...(options.components ? { components: options.components } : {}),\n ...(options.capabilities ? { capabilities: options.capabilities } : {}),\n databaseName: options.databaseName ?? \"syncore.db\",\n storageNamespace: options.storageDirectoryName ?? \"syncore-storage\",\n ...(wasmUrl ? { wasmUrl } : {}),\n ...(options.locateFile ? { locateFile: options.locateFile } : {}),\n platform: options.platform ?? \"expo-web\",\n ...(options.devtools !== undefined ? { devtools: options.devtools } : {}),\n ...(options.scheduler ? { scheduler: options.scheduler } : {})\n });\n}\n\nasync function resolveDefaultExpoWebSqlJsWasmUrl(): Promise<\n string | undefined\n> {\n const module = await import(\"./web-sqljs-wasm.js\");\n return module.resolveDefaultExpoWebSqlJsWasmUrl();\n}\n\nfunction isWebEnvironment(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["/// <reference path=\"./assets.d.ts\" />\n\nimport { Directory, File, Paths } from \"expo-file-system\";\nimport {\n defaultDatabaseDirectory,\n openDatabaseSync,\n type SQLiteDatabase\n} from \"expo-sqlite\";\nimport {\n type ImpactScope,\n type DevtoolsSink,\n type SyncoreExternalChangeApplier,\n type SyncoreExternalChangeSignal,\n SyncoreRuntime,\n type SchedulerOptions,\n type SyncoreCapabilities,\n type SyncoreDataModel,\n type SyncoreRuntimeOptions,\n type SyncoreSqlDriver,\n type SyncoreStorageAdapter,\n type StorageObject,\n type StorageWriteInput\n} from \"@syncore/core\";\nimport {\n BroadcastChannelExternalChangeSignal,\n createDefaultSyncChannelName,\n createWebSyncoreRuntime\n} from \"@syncore/platform-web\";\n\nexport type ExpoSyncoreSchema<\n TSchema extends SyncoreDataModel = SyncoreDataModel\n> = TSchema;\n\n/**\n * Options for {@link createExpoSyncoreRuntime}.\n *\n * On native (iOS/Android) Syncore uses `expo-sqlite` and `expo-file-system`\n * automatically. When the same app is served on web (via `expo-router` or\n * Metro’s web bundler) it falls back to the SQL.js + OPFS web stack instead.\n *\n * At minimum supply `schema` and `functions`. Everything else has platform\n * defaults.\n *\n * ```ts\n * const runtime = createExpoSyncoreRuntime({\n * schema,\n * functions,\n * databaseName: \"app.db\",\n * storageDirectoryName: \"app-storage\",\n * });\n * await runtime.start();\n * ```\n */\nexport interface CreateExpoRuntimeOptions<\n TSchema extends ExpoSyncoreSchema = ExpoSyncoreSchema\n> {\n /** The data model that defines the available tables and indexes. */\n schema: TSchema;\n\n /**\n * The registered function map. Use the `functions` export from\n * `syncore/_generated/functions.ts`.\n */\n functions: SyncoreRuntimeOptions<TSchema>[\"functions\"];\n\n /**\n * Resolved Syncore component instances. Only required when your app\n * installs Syncore component packages.\n */\n components?: SyncoreRuntimeOptions<TSchema>[\"components\"];\n\n /**\n * Platform capabilities injected into `ctx.capabilities` inside function\n * handlers.\n */\n capabilities?: SyncoreCapabilities;\n\n /**\n * Custom SQL driver. Defaults to an `ExpoSqliteDriver` backed by\n * `expo-sqlite`.\n */\n driver?: SyncoreSqlDriver;\n\n /** Custom file/blob storage adapter. Defaults to `ExpoFileStorageAdapter`. */\n storage?: SyncoreStorageAdapter;\n\n /**\n * SQLite database filename (e.g. `\"app.db\"`). Defaults to `\"syncore.db\"`.\n * The file is created inside the app-local documents directory on device.\n */\n databaseName?: string;\n\n /**\n * Absolute path to the directory where the SQLite file is stored.\n * Defaults to `expo-sqlite`’s `defaultDatabaseDirectory`.\n */\n databaseDirectory?: string;\n\n /**\n * Name of the sub-directory inside the app’s documents folder used for\n * blob/file storage. Defaults to `\"syncore-storage\"`.\n */\n storageDirectoryName?: string;\n\n /**\n * Platform label reported to devtools. Defaults to `\"expo\"`. Override to\n * `\"expo-web\"` when running on web.\n */\n platform?: string;\n\n /**\n * Devtools event sink. Omit to disable devtools. On-device devtools\n * connections require pointing to your development machine’s IP address.\n */\n devtools?: DevtoolsSink;\n\n /** Scheduler configuration for background and recurring jobs. */\n scheduler?: SchedulerOptions;\n\n /**\n * External change signal used to keep multiple in-process instances in sync.\n * On web, defaults to a `BroadcastChannel`-based signal automatically.\n */\n externalChangeSignal?: SyncoreExternalChangeSignal;\n\n /**\n * External change applier used when change events arrive from other tabs or\n * processes. On web with `ExpoSqliteDriver`, defaults to\n * `ExpoWebExternalChangeApplier` automatically.\n */\n externalChangeApplier?: SyncoreExternalChangeApplier;\n\n /**\n * Direct URL to the SQL.js `.wasm` binary. Only needed when the app runs on\n * web and the default CDN URL is unreachable.\n */\n wasmUrl?: string;\n\n /**\n * Resolver for SQL.js support files (`.wasm`, `.worker.js`). Equivalent to\n * the `locateFile` option in `initSqlJs()`. Only used on web.\n */\n locateFile?: (fileName: string) => string;\n}\n\n/**\n * A reusable, lazily-started Expo Syncore runtime handle.\n *\n * Created by {@link createExpoSyncoreBootstrap}. The bootstrap defers actual\n * runtime startup until the first call to `getClient()` and keeps a single\n * instance alive across React Navigation reloads.\n *\n * ```ts\n * const bootstrap = createExpoSyncoreBootstrap({ schema, functions });\n *\n * // In your root component:\n * const client = await bootstrap.getClient();\n * ```\n */\nexport interface ExpoSyncoreBootstrap<\n TSchema extends ExpoSyncoreSchema = ExpoSyncoreSchema\n> {\n /** @deprecated Access the runtime via `getClient()` instead. */\n getRuntime(): never;\n\n /**\n * Start the runtime on first call, then return the same client on subsequent\n * calls. Safe to call from multiple places concurrently.\n */\n getClient(): Promise<\n ReturnType<SyncoreRuntime<TSchema>[\"createClient\"]>\n >;\n\n /** Stop the running runtime instance if one is active. */\n stop(): Promise<void>;\n\n /**\n * Stop and discard the current runtime so the next `getClient()` call\n * creates a fresh one. Useful after a full app reset or database migration.\n */\n reset(): Promise<void>;\n}\n\n/**\n * Create a Syncore runtime for Expo (React Native and Expo web) backed by\n * `expo-sqlite` on native platforms and SQL.js on web.\n *\n * Returns an unstarted SyncoreRuntime. Call `await runtime.start()`\n * before using the client:\n *\n * ```ts\n * import { createExpoSyncoreRuntime } from \"syncorejs/expo\";\n * import schema from \"./syncore/schema\";\n * import { functions } from \"./syncore/_generated/functions\";\n *\n * const runtime = createExpoSyncoreRuntime({ schema, functions });\n * await runtime.start();\n * const client = runtime.createClient();\n * ```\n *\n * For managed lifecycle in React components, prefer\n * {@link createExpoSyncoreBootstrap} instead.\n */\nexport function createExpoSyncoreRuntime<\n TSchema extends ExpoSyncoreSchema\n>(\n options: CreateExpoRuntimeOptions<TSchema>\n): SyncoreRuntime<TSchema> {\n const databaseDirectory =\n options.databaseDirectory ??\n (typeof defaultDatabaseDirectory === \"string\"\n ? defaultDatabaseDirectory\n : undefined);\n const driver =\n options.driver ??\n new ExpoSqliteDriver(\n openDatabaseSync(\n options.databaseName ?? \"syncore.db\",\n undefined,\n databaseDirectory\n ),\n {\n databaseName: options.databaseName ?? \"syncore.db\",\n ...(databaseDirectory ? { databaseDirectory } : {})\n }\n );\n const storage =\n options.storage ??\n new ExpoFileStorageAdapter(\n options.storageDirectoryName ?? \"syncore-storage\"\n );\n const isWebEnvironment =\n typeof window !== \"undefined\" && typeof document !== \"undefined\";\n const webExternalChangeSignal =\n isWebEnvironment && !options.externalChangeSignal\n ? new BroadcastChannelExternalChangeSignal({\n channelName: createDefaultSyncChannelName(\n options.databaseName ?? \"syncore.db\"\n )\n })\n : undefined;\n const webExternalChangeApplier =\n isWebEnvironment &&\n !options.externalChangeApplier &&\n driver instanceof ExpoSqliteDriver\n ? new ExpoWebExternalChangeApplier(driver)\n : undefined;\n\n return new SyncoreRuntime({\n schema: options.schema,\n functions: options.functions,\n ...(options.components ? { components: options.components } : {}),\n driver,\n storage,\n ...(isWebEnvironment && options.externalChangeSignal\n ? { externalChangeSignal: options.externalChangeSignal }\n : isWebEnvironment && webExternalChangeSignal\n ? { externalChangeSignal: webExternalChangeSignal }\n : {}),\n ...(isWebEnvironment && options.externalChangeApplier\n ? { externalChangeApplier: options.externalChangeApplier }\n : isWebEnvironment && webExternalChangeApplier\n ? { externalChangeApplier: webExternalChangeApplier }\n : {}),\n platform: options.platform ?? \"expo\",\n ...(options.capabilities ? { capabilities: options.capabilities } : {}),\n runtimeCapabilities: {\n storage: {\n available: true,\n protocol: \"file\",\n supportsRange: false\n }\n },\n ...(options.devtools ? { devtools: options.devtools } : {}),\n ...(options.scheduler ? { scheduler: options.scheduler } : {})\n });\n}\n\n/**\n * Create a same-process Syncore client directly from a started Expo runtime.\n *\n * Prefer this in scripts or non-component code. For React component trees,\n * use {@link createExpoSyncoreBootstrap} instead to get automatic lifecycle\n * management.\n *\n * ```ts\n * const client = createExpoSyncoreClient(runtime);\n * await client.mutation(api.todos.create, { text: \"Buy milk\" });\n * ```\n */\nexport function createExpoSyncoreClient<\n TSchema extends ExpoSyncoreSchema\n>(runtime: SyncoreRuntime<TSchema>) {\n return runtime.createClient();\n}\n\n/**\n * Create a reusable Expo bootstrap that lazily starts the local runtime the\n * first time a client is requested.\n *\n * The bootstrap keeps a single runtime instance alive across component\n * remounts and safely handles concurrent `getClient()` calls.\n *\n * ```ts\n * // app/_layout.tsx\n * import { createExpoSyncoreBootstrap } from \"syncorejs/expo\";\n * import schema from \"../syncore/schema\";\n * import { functions } from \"../syncore/_generated/functions\";\n *\n * export const syncoreBootstrap = createExpoSyncoreBootstrap({\n * schema,\n * functions,\n * });\n *\n * // Later in SyncoreProvider:\n * const client = await syncoreBootstrap.getClient();\n * ```\n */\nexport function createExpoSyncoreBootstrap<\n TSchema extends ExpoSyncoreSchema\n>(\n options: CreateExpoRuntimeOptions<TSchema>\n): ExpoSyncoreBootstrap<TSchema> {\n let runtime: SyncoreRuntime<TSchema> | null = null;\n let started: Promise<\n ReturnType<SyncoreRuntime<TSchema>[\"createClient\"]>\n > | null = null;\n\n const ensureRuntime = async () => {\n runtime ??= isWebEnvironment()\n ? await createExpoWebSyncoreRuntime(options)\n : createExpoSyncoreRuntime(options);\n return runtime;\n };\n\n return {\n getRuntime() {\n throw new Error(\n \"createExpoSyncoreBootstrap().getRuntime() is not available synchronously. Use getClient() instead.\"\n );\n },\n async getClient() {\n if (!started) {\n started = ensureRuntime().then((activeRuntime) =>\n activeRuntime.start().then(() => activeRuntime.createClient())\n );\n }\n return started;\n },\n async stop() {\n if (!runtime) {\n return;\n }\n await runtime.stop();\n runtime = null;\n started = null;\n },\n async reset() {\n if (runtime) {\n await runtime.stop();\n }\n runtime = null;\n started = null;\n }\n };\n}\n\n/**\n * Syncore SQL driver implementation backed by `expo-sqlite`.\n */\nexport class ExpoSqliteDriver implements SyncoreSqlDriver {\n private transactionDepth = 0;\n private closed = false;\n private readonly databaseName: string;\n private readonly databaseDirectory: string | undefined;\n\n constructor(\n private database: SQLiteDatabase,\n options?: {\n databaseName?: string;\n databaseDirectory?: string;\n }\n ) {\n this.databaseName = options?.databaseName ?? \"syncore.db\";\n this.databaseDirectory = options?.databaseDirectory;\n }\n\n async exec(sql: string): Promise<void> {\n this.ensureOpen();\n await this.database.execAsync(sql);\n }\n\n async run(\n sql: string,\n params: unknown[] = []\n ): Promise<{ changes: number; lastInsertRowid?: number | string }> {\n this.ensureOpen();\n const result = await this.database.runAsync(sql, normalizeParams(params));\n return {\n changes: result.changes,\n lastInsertRowid: result.lastInsertRowId\n };\n }\n\n async get<T>(sql: string, params: unknown[] = []): Promise<T | undefined> {\n this.ensureOpen();\n const row = await this.database.getFirstAsync<T>(\n sql,\n normalizeParams(params)\n );\n return row ?? undefined;\n }\n\n async all<T>(sql: string, params: unknown[] = []): Promise<T[]> {\n this.ensureOpen();\n return this.database.getAllAsync<T>(sql, normalizeParams(params));\n }\n\n async withTransaction<T>(callback: () => Promise<T>): Promise<T> {\n this.ensureOpen();\n if (this.transactionDepth > 0) {\n return this.withSavepoint(`nested_${this.transactionDepth}`, callback);\n }\n\n this.transactionDepth += 1;\n await this.database.execAsync(\"BEGIN IMMEDIATE\");\n try {\n const result = await callback();\n await this.database.execAsync(\"COMMIT\");\n return result;\n } catch (error) {\n await this.database.execAsync(\"ROLLBACK\");\n throw error;\n } finally {\n this.transactionDepth -= 1;\n }\n }\n\n async withSavepoint<T>(name: string, callback: () => Promise<T>): Promise<T> {\n this.ensureOpen();\n const safeName = name.replaceAll(/[^a-zA-Z0-9_]/g, \"_\");\n this.transactionDepth += 1;\n await this.database.execAsync(`SAVEPOINT ${safeName}`);\n try {\n const result = await callback();\n await this.database.execAsync(`RELEASE SAVEPOINT ${safeName}`);\n return result;\n } catch (error) {\n await this.database.execAsync(`ROLLBACK TO SAVEPOINT ${safeName}`);\n await this.database.execAsync(`RELEASE SAVEPOINT ${safeName}`);\n throw error;\n } finally {\n this.transactionDepth -= 1;\n }\n }\n\n async close(): Promise<void> {\n if (this.closed) {\n return;\n }\n await this.database.closeAsync();\n this.closed = true;\n }\n\n private ensureOpen(): void {\n if (this.closed) {\n throw new Error(\"The Expo SQLite driver is already closed.\");\n }\n }\n\n async reopen(): Promise<void> {\n this.ensureOpen();\n await this.database.closeAsync();\n this.database = openDatabaseSync(\n this.databaseName,\n undefined,\n this.databaseDirectory\n );\n }\n}\n\nclass ExpoWebExternalChangeApplier implements SyncoreExternalChangeApplier {\n constructor(private readonly driver: ExpoSqliteDriver) {}\n\n async applyExternalChange(event: {\n scope: \"database\" | \"storage\" | \"all\";\n changedScopes?: ImpactScope[];\n changedTables?: string[];\n storageIds?: string[];\n }) {\n if (event.scope === \"database\" || event.scope === \"all\") {\n await this.driver.reopen();\n }\n return {\n databaseChanged: event.scope === \"database\" || event.scope === \"all\",\n storageChanged: event.scope === \"storage\" || event.scope === \"all\",\n changedScopes:\n event.changedScopes ??\n ([\n ...(event.changedTables ?? []).map((tableName) => `table:${tableName}`),\n ...(event.storageIds ?? []).map((storageId) => `storage:${storageId}`)\n ] as ImpactScope[])\n };\n }\n}\n\n/**\n * Syncore file/blob storage backed by the Expo file system.\n */\nexport class ExpoFileStorageAdapter implements SyncoreStorageAdapter {\n private readonly rootDirectory: Directory;\n\n constructor(storageDirectoryName: string) {\n this.rootDirectory = new Directory(Paths.document, storageDirectoryName);\n if (!this.rootDirectory.exists) {\n this.rootDirectory.create({ idempotent: true, intermediates: true });\n }\n }\n\n async put(id: string, input: StorageWriteInput): Promise<StorageObject> {\n const file = new File(this.rootDirectory, id);\n if (!file.exists) {\n file.create({ intermediates: true, overwrite: true });\n }\n const bytes = normalizeBinary(input.data);\n file.write(bytes);\n return {\n id,\n path: file.uri,\n size: bytes.byteLength,\n contentType: input.contentType ?? null\n };\n }\n\n async get(id: string): Promise<StorageObject | null> {\n const file = new File(this.rootDirectory, id);\n if (!file.exists) {\n return null;\n }\n return {\n id,\n path: file.uri,\n size: file.size,\n contentType: file.type || null\n };\n }\n\n async read(id: string): Promise<Uint8Array | null> {\n const file = new File(this.rootDirectory, id);\n if (!file.exists) {\n return null;\n }\n return file.bytes();\n }\n\n async delete(id: string): Promise<void> {\n const file = new File(this.rootDirectory, id);\n if (file.exists) {\n file.delete();\n }\n }\n}\n\nfunction normalizeParams(\n values: unknown[]\n): Array<string | number | Uint8Array | null> {\n return values.map((value) => {\n if (typeof value === \"boolean\") {\n return value ? 1 : 0;\n }\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n value instanceof Uint8Array\n ) {\n return value;\n }\n if (value instanceof ArrayBuffer) {\n return new Uint8Array(value);\n }\n return JSON.stringify(value);\n });\n}\n\nfunction normalizeBinary(data: StorageWriteInput[\"data\"]): Uint8Array {\n if (typeof data === \"string\") {\n return new TextEncoder().encode(data);\n }\n if (data instanceof Uint8Array) {\n return data;\n }\n return new Uint8Array(data);\n}\n\nasync function createExpoWebSyncoreRuntime<TSchema extends ExpoSyncoreSchema>(\n options: CreateExpoRuntimeOptions<TSchema>\n): Promise<SyncoreRuntime<TSchema>> {\n const wasmUrl =\n options.wasmUrl ??\n (options.locateFile\n ? undefined\n : await resolveDefaultExpoWebSqlJsWasmUrl());\n\n return createWebSyncoreRuntime({\n schema: options.schema,\n functions: options.functions,\n ...(options.components ? { components: options.components } : {}),\n ...(options.capabilities ? { capabilities: options.capabilities } : {}),\n databaseName: options.databaseName ?? \"syncore.db\",\n storageNamespace: options.storageDirectoryName ?? \"syncore-storage\",\n ...(wasmUrl ? { wasmUrl } : {}),\n ...(options.locateFile ? { locateFile: options.locateFile } : {}),\n platform: options.platform ?? \"expo-web\",\n ...(options.devtools !== undefined ? { devtools: options.devtools } : {}),\n ...(options.scheduler ? { scheduler: options.scheduler } : {})\n });\n}\n\nasync function resolveDefaultExpoWebSqlJsWasmUrl(): Promise<\n string | undefined\n> {\n const module = await import(\"./web-sqljs-wasm.js\");\n return module.resolveDefaultExpoWebSqlJsWasmUrl();\n}\n\nfunction isWebEnvironment(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n"],"mappings":"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"}
@@ -53,6 +53,7 @@ declare class NodeFileStorageAdapter implements SyncoreStorageAdapter {
53
53
  put(id: string, input: StorageWriteInput): Promise<StorageObject>;
54
54
  get(id: string): Promise<StorageObject | null>;
55
55
  read(id: string): Promise<Uint8Array | null>;
56
+ readRange(id: string, offset: number, length: number): Promise<Uint8Array | null>;
56
57
  delete(id: string): Promise<void>;
57
58
  list(): Promise<StorageObject[]>;
58
59
  }
@@ -246,7 +247,7 @@ interface CreateSyncoreRendererWindowClientOptions {
246
247
  * ```
247
248
  *
248
249
  * @param options - Configuration object. See {@link CreateNodeRuntimeOptions}.
249
- * @returns A configured (but not yet started) {@link SyncoreRuntime}. Call
250
+ * @returns A configured (but not yet started) SyncoreRuntime. Call
250
251
  * `await runtime.start()` before using the client.
251
252
  */
252
253
  declare function createNodeSyncoreRuntime<TSchema extends NodeSyncoreSchema>(options: CreateNodeRuntimeOptions<TSchema>): SyncoreRuntime<TSchema>;
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":"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"}
1
+ {"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":"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"}
@@ -1,5 +1,5 @@
1
1
  import { SyncoreRendererClient, attachNodeIpcRuntime, createNodeIpcMessageEndpoint, createRendererSyncoreBridgeClient, createRendererSyncoreClient, createRendererSyncoreWindowClient, installSyncoreWindowBridge } from "./ipc.mjs";
2
- import { mkdir, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
2
+ import { mkdir, open, readFile, readdir, rm, stat, writeFile } from "node:fs/promises";
3
3
  import { createHash } from "node:crypto";
4
4
  import { mkdirSync, readFileSync, writeFileSync } from "node:fs";
5
5
  import path from "node:path";
@@ -142,6 +142,19 @@ var NodeFileStorageAdapter = class {
142
142
  return null;
143
143
  }
144
144
  }
145
+ async readRange(id, offset, length) {
146
+ let handle;
147
+ try {
148
+ handle = await open(this.filePath(id), "r");
149
+ const buffer = Buffer.alloc(Math.max(length, 0));
150
+ const result = await handle.read(buffer, 0, buffer.byteLength, Math.max(offset, 0));
151
+ return buffer.subarray(0, result.bytesRead);
152
+ } catch {
153
+ return null;
154
+ } finally {
155
+ await handle?.close();
156
+ }
157
+ }
145
158
  async delete(id) {
146
159
  await rm(this.filePath(id), { force: true });
147
160
  }
@@ -288,7 +301,7 @@ function resolvePersistedDataSourceAlias(storageDirectory, storageIdentity) {
288
301
  * ```
289
302
  *
290
303
  * @param options - Configuration object. See {@link CreateNodeRuntimeOptions}.
291
- * @returns A configured (but not yet started) {@link SyncoreRuntime}. Call
304
+ * @returns A configured (but not yet started) SyncoreRuntime. Call
292
305
  * `await runtime.start()` before using the client.
293
306
  */
294
307
  function createNodeSyncoreRuntime(options) {
@@ -313,6 +326,11 @@ function createNodeSyncoreRuntime(options) {
313
326
  ...options.components ? { components: options.components } : {},
314
327
  driver: new NodeSqliteDriver(options.databasePath),
315
328
  storage: new NodeFileStorageAdapter(options.storageDirectory),
329
+ runtimeCapabilities: { storage: {
330
+ available: true,
331
+ protocol: "file",
332
+ supportsRange: true
333
+ } },
316
334
  platform: options.platform ?? "node"
317
335
  };
318
336
  if (options.capabilities) runtimeOptions.capabilities = options.capabilities;
@@ -635,6 +653,13 @@ function createNodeDevtoolsCapabilities() {
635
653
  mutate: true,
636
654
  importExport: true
637
655
  },
656
+ storage: {
657
+ browse: true,
658
+ download: true,
659
+ readRange: true,
660
+ delete: true,
661
+ maxPreviewBytes: 8e4
662
+ },
638
663
  scheduler: {
639
664
  read: true,
640
665
  edit: true