syncorejs 0.2.2 → 0.2.3

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 (140) hide show
  1. package/dist/_vendor/cli/app.d.mts.map +1 -1
  2. package/dist/_vendor/cli/app.mjs +8 -5
  3. package/dist/_vendor/cli/app.mjs.map +1 -1
  4. package/dist/_vendor/cli/context.mjs.map +1 -1
  5. package/dist/_vendor/cli/dev-session.mjs.map +1 -1
  6. package/dist/_vendor/cli/doctor.mjs.map +1 -1
  7. package/dist/_vendor/cli/errors.mjs.map +1 -1
  8. package/dist/_vendor/cli/help.mjs.map +1 -1
  9. package/dist/_vendor/cli/index.mjs +9 -2
  10. package/dist/_vendor/cli/index.mjs.map +1 -1
  11. package/dist/_vendor/cli/messages.mjs.map +1 -1
  12. package/dist/_vendor/cli/preflight.mjs.map +1 -1
  13. package/dist/_vendor/cli/project.mjs +20 -20
  14. package/dist/_vendor/cli/project.mjs.map +1 -1
  15. package/dist/_vendor/cli/render.mjs.map +1 -1
  16. package/dist/_vendor/cli/targets.mjs.map +1 -1
  17. package/dist/_vendor/core/cli.d.mts +8 -2
  18. package/dist/_vendor/core/cli.d.mts.map +1 -1
  19. package/dist/_vendor/core/cli.mjs +238 -64
  20. package/dist/_vendor/core/cli.mjs.map +1 -1
  21. package/dist/_vendor/core/devtools-auth.mjs.map +1 -1
  22. package/dist/_vendor/core/runtime/components.d.mts.map +1 -1
  23. package/dist/_vendor/core/runtime/components.mjs.map +1 -1
  24. package/dist/_vendor/core/runtime/devtools.d.mts.map +1 -1
  25. package/dist/_vendor/core/runtime/devtools.mjs +130 -23
  26. package/dist/_vendor/core/runtime/devtools.mjs.map +1 -1
  27. package/dist/_vendor/core/runtime/functions.d.mts +388 -6
  28. package/dist/_vendor/core/runtime/functions.d.mts.map +1 -1
  29. package/dist/_vendor/core/runtime/functions.mjs +72 -1
  30. package/dist/_vendor/core/runtime/functions.mjs.map +1 -1
  31. package/dist/_vendor/core/runtime/id.d.mts.map +1 -1
  32. package/dist/_vendor/core/runtime/id.mjs.map +1 -1
  33. package/dist/_vendor/core/runtime/internal/engines/devtoolsEngine.mjs +11 -5
  34. package/dist/_vendor/core/runtime/internal/engines/devtoolsEngine.mjs.map +1 -1
  35. package/dist/_vendor/core/runtime/internal/engines/executionEngine.mjs +123 -20
  36. package/dist/_vendor/core/runtime/internal/engines/executionEngine.mjs.map +1 -1
  37. package/dist/_vendor/core/runtime/internal/engines/reactivityEngine.mjs +56 -8
  38. package/dist/_vendor/core/runtime/internal/engines/reactivityEngine.mjs.map +1 -1
  39. package/dist/_vendor/core/runtime/internal/engines/schedulerEngine.mjs +49 -14
  40. package/dist/_vendor/core/runtime/internal/engines/schedulerEngine.mjs.map +1 -1
  41. package/dist/_vendor/core/runtime/internal/engines/schemaEngine.mjs +4 -7
  42. package/dist/_vendor/core/runtime/internal/engines/schemaEngine.mjs.map +1 -1
  43. package/dist/_vendor/core/runtime/internal/engines/shared.mjs +76 -1
  44. package/dist/_vendor/core/runtime/internal/engines/shared.mjs.map +1 -1
  45. package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs +1 -0
  46. package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs.map +1 -1
  47. package/dist/_vendor/core/runtime/internal/runtimeKernel.mjs +4 -3
  48. package/dist/_vendor/core/runtime/internal/runtimeKernel.mjs.map +1 -1
  49. package/dist/_vendor/core/runtime/internal/runtimeStatus.mjs.map +1 -1
  50. package/dist/_vendor/core/runtime/internal/systemMeta.mjs.map +1 -1
  51. package/dist/_vendor/core/runtime/internal/transactionCoordinator.mjs +4 -0
  52. package/dist/_vendor/core/runtime/internal/transactionCoordinator.mjs.map +1 -1
  53. package/dist/_vendor/core/runtime/runtime.d.mts +1040 -9
  54. package/dist/_vendor/core/runtime/runtime.d.mts.map +1 -1
  55. package/dist/_vendor/core/runtime/runtime.mjs +63 -0
  56. package/dist/_vendor/core/runtime/runtime.mjs.map +1 -1
  57. package/dist/_vendor/core/transport.d.mts +2 -0
  58. package/dist/_vendor/core/transport.d.mts.map +1 -1
  59. package/dist/_vendor/core/transport.mjs +33 -24
  60. package/dist/_vendor/core/transport.mjs.map +1 -1
  61. package/dist/_vendor/devtools-protocol/index.d.ts +149 -4
  62. package/dist/_vendor/devtools-protocol/index.d.ts.map +1 -1
  63. package/dist/_vendor/devtools-protocol/index.js.map +1 -1
  64. package/dist/_vendor/next/config.d.ts +3 -4
  65. package/dist/_vendor/next/config.d.ts.map +1 -1
  66. package/dist/_vendor/next/config.js +37 -19
  67. package/dist/_vendor/next/config.js.map +1 -1
  68. package/dist/_vendor/next/index.d.ts +109 -29
  69. package/dist/_vendor/next/index.d.ts.map +1 -1
  70. package/dist/_vendor/next/index.js +77 -17
  71. package/dist/_vendor/next/index.js.map +1 -1
  72. package/dist/_vendor/platform-expo/index.d.ts +146 -27
  73. package/dist/_vendor/platform-expo/index.d.ts.map +1 -1
  74. package/dist/_vendor/platform-expo/index.js +76 -10
  75. package/dist/_vendor/platform-expo/index.js.map +1 -1
  76. package/dist/_vendor/platform-expo/react.js.map +1 -1
  77. package/dist/_vendor/platform-expo/web-sqljs-wasm.js +16 -0
  78. package/dist/_vendor/platform-expo/web-sqljs-wasm.js.map +1 -0
  79. package/dist/_vendor/platform-node/index.d.mts +173 -9
  80. package/dist/_vendor/platform-node/index.d.mts.map +1 -1
  81. package/dist/_vendor/platform-node/index.mjs +225 -94
  82. package/dist/_vendor/platform-node/index.mjs.map +1 -1
  83. package/dist/_vendor/platform-node/ipc-react.mjs.map +1 -1
  84. package/dist/_vendor/platform-node/ipc.d.mts.map +1 -1
  85. package/dist/_vendor/platform-node/ipc.mjs.map +1 -1
  86. package/dist/_vendor/platform-web/external-change.d.ts +41 -0
  87. package/dist/_vendor/platform-web/external-change.d.ts.map +1 -1
  88. package/dist/_vendor/platform-web/external-change.js +30 -0
  89. package/dist/_vendor/platform-web/external-change.js.map +1 -1
  90. package/dist/_vendor/platform-web/index.d.ts +307 -35
  91. package/dist/_vendor/platform-web/index.d.ts.map +1 -1
  92. package/dist/_vendor/platform-web/index.js +189 -23
  93. package/dist/_vendor/platform-web/index.js.map +1 -1
  94. package/dist/_vendor/platform-web/indexeddb.d.ts +12 -0
  95. package/dist/_vendor/platform-web/indexeddb.d.ts.map +1 -1
  96. package/dist/_vendor/platform-web/indexeddb.js +10 -0
  97. package/dist/_vendor/platform-web/indexeddb.js.map +1 -1
  98. package/dist/_vendor/platform-web/opfs.d.ts +13 -0
  99. package/dist/_vendor/platform-web/opfs.d.ts.map +1 -1
  100. package/dist/_vendor/platform-web/opfs.js +12 -0
  101. package/dist/_vendor/platform-web/opfs.js.map +1 -1
  102. package/dist/_vendor/platform-web/persistence.d.ts +54 -0
  103. package/dist/_vendor/platform-web/persistence.d.ts.map +1 -1
  104. package/dist/_vendor/platform-web/persistence.js +15 -0
  105. package/dist/_vendor/platform-web/persistence.js.map +1 -1
  106. package/dist/_vendor/platform-web/react.d.ts +1 -2
  107. package/dist/_vendor/platform-web/react.d.ts.map +1 -1
  108. package/dist/_vendor/platform-web/react.js +2 -4
  109. package/dist/_vendor/platform-web/react.js.map +1 -1
  110. package/dist/_vendor/platform-web/sqljs.js +10 -1
  111. package/dist/_vendor/platform-web/sqljs.js.map +1 -1
  112. package/dist/_vendor/platform-web/web-sqljs-wasm.js +8 -0
  113. package/dist/_vendor/platform-web/web-sqljs-wasm.js.map +1 -0
  114. package/dist/_vendor/platform-web/worker.d.ts +60 -9
  115. package/dist/_vendor/platform-web/worker.d.ts.map +1 -1
  116. package/dist/_vendor/platform-web/worker.js +37 -4
  117. package/dist/_vendor/platform-web/worker.js.map +1 -1
  118. package/dist/_vendor/react/index.d.ts +196 -13
  119. package/dist/_vendor/react/index.d.ts.map +1 -1
  120. package/dist/_vendor/react/index.js +208 -17
  121. package/dist/_vendor/react/index.js.map +1 -1
  122. package/dist/_vendor/schema/definition.d.ts +129 -0
  123. package/dist/_vendor/schema/definition.d.ts.map +1 -1
  124. package/dist/_vendor/schema/definition.js +99 -0
  125. package/dist/_vendor/schema/definition.js.map +1 -1
  126. package/dist/_vendor/schema/planner.d.ts.map +1 -1
  127. package/dist/_vendor/schema/planner.js.map +1 -1
  128. package/dist/_vendor/schema/validators.d.ts +180 -4
  129. package/dist/_vendor/schema/validators.d.ts.map +1 -1
  130. package/dist/_vendor/schema/validators.js +35 -1
  131. package/dist/_vendor/schema/validators.js.map +1 -1
  132. package/dist/_vendor/svelte/index.d.ts +205 -7
  133. package/dist/_vendor/svelte/index.d.ts.map +1 -1
  134. package/dist/_vendor/svelte/index.js +199 -6
  135. package/dist/_vendor/svelte/index.js.map +1 -1
  136. package/dist/browser.d.ts.map +1 -1
  137. package/dist/cli.js +3 -1
  138. package/dist/cli.js.map +1 -1
  139. package/dist/index.d.ts +1 -1
  140. package/package.json +24 -21
@@ -1 +1 @@
1
- {"version":3,"file":"config.js","names":[],"sources":["../src/config.ts"],"sourcesContent":["const WORKER_NAME = \"syncore-worker\";\n\nfunction joinAppWorkerPath(dir: string) {\n return `${dir.replace(/[\\\\/]$/, \"\")}/app/syncore.worker`;\n}\n\n/**\n * Wrap a Next config with the settings Syncore needs for SQL.js and worker assets.\n *\n * This enables async WebAssembly support and, for non-exported apps, adds a\n * long-lived cache header for `sql-wasm.wasm`. It also configures webpack to\n * bundle the syncore worker as a separate entry point.\n */\nexport function withSyncoreNext<TConfig extends Record<string, unknown>>(\n config: TConfig\n): TConfig {\n const baseConfig = config as Record<string, unknown>;\n const isStaticExport = baseConfig.output === \"export\";\n const headers = (baseConfig.headers ?? []) as Array<Record<string, unknown>>;\n const userWebpack =\n typeof baseConfig.webpack === \"function\"\n ? (baseConfig.webpack as (\n config: Record<string, unknown>,\n context: unknown\n ) => Record<string, unknown>)\n : undefined;\n const userHeaders =\n typeof baseConfig.headers === \"function\"\n ? (baseConfig.headers as () =>\n | Array<Record<string, unknown>>\n | Promise<Array<Record<string, unknown>>>)\n : undefined;\n const syncoreHeaders = {\n source: \"/sql-wasm.wasm\",\n headers: [\n {\n key: \"Cache-Control\",\n value: \"public, max-age=31536000, immutable\"\n }\n ]\n };\n\n const nextConfig: Record<string, unknown> = {\n ...config,\n webpack(currentConfig: Record<string, unknown>, context: unknown) {\n const nextConfig = { ...currentConfig };\n const experiments = (nextConfig.experiments ?? {}) as Record<\n string,\n unknown\n >;\n nextConfig.experiments = {\n ...experiments,\n asyncWebAssembly: true\n };\n\n type WebpackContext = {\n dev?: boolean;\n isServer: boolean;\n nextRuntime?: string;\n dir: string;\n };\n const ctx = context as WebpackContext | undefined;\n if (\n isStaticExport &&\n ctx &&\n !ctx.dev &&\n !ctx.isServer &&\n ctx.nextRuntime !== \"edge\"\n ) {\n const entry =\n (nextConfig.entry as () => Promise<Record<string, unknown>>) ??\n (async () => ({}));\n const workerPath = joinAppWorkerPath(ctx.dir);\n nextConfig.entry = async () => {\n const entries = await entry();\n return {\n ...entries,\n [WORKER_NAME]: {\n import: workerPath,\n filename: \"static/chunks/[name].js\"\n }\n };\n };\n }\n\n if (userWebpack) {\n return userWebpack(nextConfig, context);\n }\n\n return nextConfig;\n }\n };\n\n if (!isStaticExport || userHeaders) {\n nextConfig.headers = async () => {\n const resolvedHeaders = userHeaders ? await userHeaders() : headers;\n return isStaticExport\n ? resolvedHeaders\n : [...resolvedHeaders, syncoreHeaders];\n };\n }\n\n return nextConfig as TConfig;\n}\n\nexport function getSyncoreWorkerUrl(): string {\n return `/_next/static/chunks/${WORKER_NAME}.js`;\n}\n\n/**\n * Create the default worker URL used by the Next integration.\n */\nexport function createSyncoreNextWorkerUrl(\n relativePath = \"./syncore.worker.js\"\n) {\n return new URL(relativePath, import.meta.url);\n}\n"],"mappings":";AAAA,MAAM,cAAc;AAEpB,SAAS,kBAAkB,KAAa;AACtC,QAAO,GAAG,IAAI,QAAQ,UAAU,GAAG,CAAC;;;;;;;;;AAUtC,SAAgB,gBACd,QACS;CACT,MAAM,aAAa;CACnB,MAAM,iBAAiB,WAAW,WAAW;CAC7C,MAAM,UAAW,WAAW,WAAW,EAAE;CACzC,MAAM,cACJ,OAAO,WAAW,YAAY,aACzB,WAAW,UAIZ,KAAA;CACN,MAAM,cACJ,OAAO,WAAW,YAAY,aACzB,WAAW,UAGZ,KAAA;CACN,MAAM,iBAAiB;EACrB,QAAQ;EACR,SAAS,CACP;GACE,KAAK;GACL,OAAO;GACR,CACF;EACF;CAED,MAAM,aAAsC;EAC1C,GAAG;EACH,QAAQ,eAAwC,SAAkB;GAChE,MAAM,aAAa,EAAE,GAAG,eAAe;AAKvC,cAAW,cAAc;IACvB,GALmB,WAAW,eAAe,EAAE;IAM/C,kBAAkB;IACnB;GAQD,MAAM,MAAM;AACZ,OACE,kBACA,OACA,CAAC,IAAI,OACL,CAAC,IAAI,YACL,IAAI,gBAAgB,QACpB;IACA,MAAM,QACH,WAAW,UACX,aAAa,EAAE;IAClB,MAAM,aAAa,kBAAkB,IAAI,IAAI;AAC7C,eAAW,QAAQ,YAAY;AAE7B,YAAO;MACL,GAFc,MAAM,OAAO;OAG1B,cAAc;OACb,QAAQ;OACR,UAAU;OACX;MACF;;;AAIL,OAAI,YACF,QAAO,YAAY,YAAY,QAAQ;AAGzC,UAAO;;EAEV;AAED,KAAI,CAAC,kBAAkB,YACrB,YAAW,UAAU,YAAY;EAC/B,MAAM,kBAAkB,cAAc,MAAM,aAAa,GAAG;AAC5D,SAAO,iBACH,kBACA,CAAC,GAAG,iBAAiB,eAAe;;AAI5C,QAAO;;AAGT,SAAgB,sBAA8B;AAC5C,QAAO,wBAAwB,YAAY;;;;;AAM7C,SAAgB,2BACd,eAAe,uBACf;AACA,QAAO,IAAI,IAAI,cAAc,OAAO,KAAK,IAAI"}
1
+ {"version":3,"file":"config.js","names":[],"sources":["../src/config.ts"],"sourcesContent":["const WORKER_NAME = \"syncore-worker\";\n\nfunction joinAppWorkerPath(dir: string) {\n return `${dir.replace(/[\\\\/]$/, \"\")}/app/syncore.worker`;\n}\n\n/**\n * Wrap a Next config with the settings Syncore needs for worker assets.\n *\n * This enables async WebAssembly support and configures webpack to bundle the\n * syncore worker as a separate entry point.\n */\nexport function withSyncoreNext<TConfig extends Record<string, unknown>>(\n config: TConfig\n): TConfig {\n const baseConfig = config as Record<string, unknown>;\n const isStaticExport = baseConfig.output === \"export\";\n const userWebpack =\n typeof baseConfig.webpack === \"function\"\n ? (baseConfig.webpack as (\n config: Record<string, unknown>,\n context: unknown\n ) => Record<string, unknown>)\n : undefined;\n const userTranspilePackages = Array.isArray(baseConfig.transpilePackages)\n ? baseConfig.transpilePackages\n : [];\n const internalScope = `${String.fromCharCode(64)}syncore/`;\n const syncoreTranspilePackages = [\n \"syncorejs\",\n `${internalScope}core`,\n `${internalScope}schema`,\n `${internalScope}react`,\n `${internalScope}platform-web`,\n `${internalScope}next`\n ];\n\n const nextConfig: Record<string, unknown> = {\n ...config,\n transpilePackages: Array.from(\n new Set([...userTranspilePackages, ...syncoreTranspilePackages])\n ),\n webpack(currentConfig: Record<string, unknown>, context: unknown) {\n const nextConfig = { ...currentConfig };\n const experiments = (nextConfig.experiments ?? {}) as Record<\n string,\n unknown\n >;\n nextConfig.experiments = {\n ...experiments,\n asyncWebAssembly: true\n };\n const resolve = (nextConfig.resolve ?? {}) as Record<string, unknown>;\n nextConfig.resolve = {\n ...resolve,\n extensionAlias: {\n ...((resolve.extensionAlias ?? {}) as Record<string, unknown>),\n \".js\": [\".ts\", \".tsx\", \".js\"],\n \".mjs\": [\".mts\", \".mjs\"]\n }\n };\n const moduleConfig = (nextConfig.module ?? {}) as Record<string, unknown>;\n const rules = Array.isArray(moduleConfig.rules) ? moduleConfig.rules : [];\n nextConfig.module = {\n ...moduleConfig,\n rules: [\n {\n test: /\\.wasm$/,\n type: \"asset/resource\"\n },\n ...rules\n ]\n };\n\n type WebpackContext = {\n dev?: boolean;\n isServer: boolean;\n nextRuntime?: string;\n dir: string;\n };\n const ctx = context as WebpackContext | undefined;\n if (\n isStaticExport &&\n ctx &&\n !ctx.dev &&\n !ctx.isServer &&\n ctx.nextRuntime !== \"edge\"\n ) {\n const entry =\n (nextConfig.entry as () => Promise<Record<string, unknown>>) ??\n (async () => ({}));\n const workerPath = joinAppWorkerPath(ctx.dir);\n nextConfig.entry = async () => {\n const entries = await entry();\n return {\n ...entries,\n [WORKER_NAME]: {\n import: workerPath,\n filename: \"static/chunks/[name].js\"\n }\n };\n };\n }\n\n if (userWebpack) {\n return userWebpack(nextConfig, context);\n }\n\n return nextConfig;\n }\n };\n\n return nextConfig as TConfig;\n}\n\nexport function getSyncoreWorkerUrl(): string {\n return `/_next/static/chunks/${WORKER_NAME}.js`;\n}\n\n/**\n * Create the default worker URL used by the Next integration.\n */\nexport function createSyncoreNextWorkerUrl(\n relativePath = \"./syncore.worker.js\"\n) {\n return new URL(relativePath, import.meta.url);\n}\n"],"mappings":";AAAA,MAAM,cAAc;AAEpB,SAAS,kBAAkB,KAAa;CACtC,OAAO,GAAG,IAAI,QAAQ,UAAU,EAAE,EAAE;AACtC;;;;;;;AAQA,SAAgB,gBACd,QACS;CACT,MAAM,aAAa;CACnB,MAAM,iBAAiB,WAAW,WAAW;CAC7C,MAAM,cACJ,OAAO,WAAW,YAAY,aACzB,WAAW,UAIZ,KAAA;CACN,MAAM,wBAAwB,MAAM,QAAQ,WAAW,iBAAiB,IACpE,WAAW,oBACX,CAAC;CACL,MAAM,gBAAgB,GAAG,OAAO,aAAa,EAAE,EAAE;CACjD,MAAM,2BAA2B;EAC/B;EACA,GAAG,cAAc;EACjB,GAAG,cAAc;EACjB,GAAG,cAAc;EACjB,GAAG,cAAc;EACjB,GAAG,cAAc;CACnB;CA6EA,OAAO;EA1EL,GAAG;EACH,mBAAmB,MAAM,KACvB,IAAI,IAAI,CAAC,GAAG,uBAAuB,GAAG,wBAAwB,CAAC,CACjE;EACA,QAAQ,eAAwC,SAAkB;GAChE,MAAM,aAAa,EAAE,GAAG,cAAc;GAKtC,WAAW,cAAc;IACvB,GALmB,WAAW,eAAe,CAAC;IAM9C,kBAAkB;GACpB;GACA,MAAM,UAAW,WAAW,WAAW,CAAC;GACxC,WAAW,UAAU;IACnB,GAAG;IACH,gBAAgB;KACd,GAAK,QAAQ,kBAAkB,CAAC;KAChC,OAAO;MAAC;MAAO;MAAQ;KAAK;KAC5B,QAAQ,CAAC,QAAQ,MAAM;IACzB;GACF;GACA,MAAM,eAAgB,WAAW,UAAU,CAAC;GAC5C,MAAM,QAAQ,MAAM,QAAQ,aAAa,KAAK,IAAI,aAAa,QAAQ,CAAC;GACxE,WAAW,SAAS;IAClB,GAAG;IACH,OAAO,CACL;KACE,MAAM;KACN,MAAM;IACR,GACA,GAAG,KACL;GACF;GAQA,MAAM,MAAM;GACZ,IACE,kBACA,OACA,CAAC,IAAI,OACL,CAAC,IAAI,YACL,IAAI,gBAAgB,QACpB;IACA,MAAM,QACH,WAAW,UACX,aAAa,CAAC;IACjB,MAAM,aAAa,kBAAkB,IAAI,GAAG;IAC5C,WAAW,QAAQ,YAAY;KAE7B,OAAO;MACL,GAAG,MAFiB,MAAM;OAGzB,cAAc;OACb,QAAQ;OACR,UAAU;MACZ;KACF;IACF;GACF;GAEA,IAAI,aACF,OAAO,YAAY,YAAY,OAAO;GAGxC,OAAO;EACT;CAGc;AAClB;AAEA,SAAgB,sBAA8B;CAC5C,OAAO,wBAAwB,YAAY;AAC7C;;;;AAKA,SAAgB,2BACd,eAAe,uBACf;CACA,OAAO,IAAI,IAAI,cAAc,OAAO,KAAK,GAAG;AAC9C"}
@@ -1,63 +1,141 @@
1
1
  import { createSyncoreNextWorkerUrl, getSyncoreWorkerUrl } from "./config.js";
2
2
  import { ManagedWebWorkerClient } from "../platform-web/index.d.ts";
3
3
  import { ReactNode } from "react";
4
- import * as react_jsx_runtime0 from "react/jsx-runtime";
5
4
 
6
5
  //#region src/index.d.ts
6
+ /**
7
+ * Shared configuration options for the Syncore Next.js integration.
8
+ *
9
+ * Accepted by both {@link SyncoreNextProvider} and
10
+ * {@link registerSyncoreServiceWorker}.
11
+ */
7
12
  interface SyncoreNextOptions {
8
- /** Optional service worker URL used to cache the application shell. */
13
+ /**
14
+ * URL of the Next PWA service worker. Defaults to `"/sw.js"` (the path
15
+ * emitted by `next-pwa` or `@ducanh2912/next-pwa`).
16
+ */
9
17
  serviceWorkerUrl?: string;
10
- /** Optional URL for the `sql.js` wasm asset. */
11
- wasmAssetUrl?: string;
12
- /** Optional URL for the worker asset used by the local Syncore runtime. */
18
+ /**
19
+ * Public path to the compiled Syncore worker asset. Defaults to
20
+ * `"/syncore.worker.js"`. Override if your build tool emits the worker to a
21
+ * different path.
22
+ */
13
23
  workerAssetUrl?: string;
14
24
  }
15
25
  /**
16
- * The result of registering the Syncore service worker in a Next app.
26
+ * Handle returned by {@link registerSyncoreServiceWorker}.
17
27
  */
18
28
  interface SyncoreServiceWorkerRegistration {
19
29
  /** Unregister the installed service worker. */
20
30
  unregister(): Promise<boolean>;
21
- /** Ask the browser to check for an updated service worker. */
31
+ /**
32
+ * Instruct the browser to check for a new service worker version. Useful
33
+ * for implementing an “Update available” prompt.
34
+ */
22
35
  update(): Promise<ServiceWorkerRegistration>;
23
36
  }
24
37
  /**
25
- * Register the Syncore service worker used by the Next integration.
38
+ * Register the Syncore PWA service worker in a Next.js app.
39
+ *
40
+ * Call this once at app startup (e.g. in your root layout’s `useEffect`, or in
41
+ * `instrumentation.ts` with `"use client"`). Returns `null` on the server or
42
+ * when the browser does not support service workers.
43
+ *
44
+ * ```ts
45
+ * // app/layout.tsx (client component)
46
+ * import { registerSyncoreServiceWorker } from "syncorejs/next";
47
+ *
48
+ * useEffect(() => {
49
+ * registerSyncoreServiceWorker({ serviceWorkerUrl: "/sw.js" });
50
+ * }, []);
51
+ * ```
52
+ *
53
+ * @param options - Optional configuration. Defaults to `"/sw.js"`.
54
+ * @returns A {@link SyncoreServiceWorkerRegistration} handle, or `null` on
55
+ * the server / when unsupported.
26
56
  */
27
57
  declare function registerSyncoreServiceWorker(options?: SyncoreNextOptions): Promise<SyncoreServiceWorkerRegistration | null>;
28
58
  /**
29
- * Resolve the public URL used by SQL.js to load its wasm file in a Next app.
30
- */
31
- declare function resolveSqlJsWasmUrl(options?: SyncoreNextOptions): string;
32
- /**
33
- * Create a worker-backed Syncore client for a Next app.
59
+ * Create a worker-backed Syncore client for a Next.js app.
60
+ *
61
+ * The client communicates with a Syncore runtime running inside a `Worker`.
62
+ * The worker runs the SQLite engine and all function handlers off the main
63
+ * thread so the UI stays responsive.
64
+ *
65
+ * In most cases you should use {@link SyncoreNextProvider} instead, which
66
+ * manages the client lifecycle automatically. Use `createNextSyncoreClient`
67
+ * directly only when you need to control the client lifecycle yourself (e.g.
68
+ * in testing harnesses or custom providers).
69
+ *
70
+ * ```ts
71
+ * const managedClient = createNextSyncoreClient({
72
+ * workerAssetUrl: "/syncore.worker.js",
73
+ * });
74
+ *
75
+ * // Later:
76
+ * managedClient.dispose();
77
+ * ```
34
78
  */
35
79
  declare function createNextSyncoreClient(options: {
36
80
  /**
37
- * Optional custom worker factory for tests or framework-specific worker
38
- * bundling patterns such as Next App Router development.
81
+ * Custom worker factory function. Useful in tests (supply a `Worker` backed
82
+ * by a mock or in-process runtime) or when using Next’s App Router dev-mode
83
+ * bundling where `new Worker(new URL(...))` must be used inside the component.
39
84
  */
40
- createWorker?: () => Worker; /** Optional explicit module URL for an already-public worker asset. */
41
- workerUrl?: URL | string; /** Optional public worker asset path for production builds. */
85
+ createWorker?: () => Worker; /** Explicit module URL for an already-public worker script. */
86
+ workerUrl?: URL | string; /** Public asset path for the compiled worker file. Defaults to `"/syncore.worker.js"`. */
42
87
  workerAssetUrl?: string;
43
88
  }): ManagedWebWorkerClient;
44
89
  /**
45
- * Register a service worker while rendering a React subtree.
90
+ * React component that registers a PWA service worker as a side-effect.
91
+ *
92
+ * Renders its `children` immediately (no loading state) and registers the
93
+ * service worker asynchronously. Safe to render on the server — the
94
+ * registration effect only runs in browsers that support service workers.
95
+ *
96
+ * ```tsx
97
+ * <SyncoreServiceWorker serviceWorkerUrl="/sw.js" onRegistered={console.log}>
98
+ * <App />
99
+ * </SyncoreServiceWorker>
100
+ * ```
46
101
  */
47
102
  declare function SyncoreServiceWorker({
48
103
  children,
49
104
  serviceWorkerUrl,
50
105
  onRegistered
51
106
  }: {
52
- children: ReactNode;
53
- serviceWorkerUrl?: string;
107
+ children: ReactNode; /** URL of the service worker script. Defaults to `"/sw.js"`. */
108
+ serviceWorkerUrl?: string; /** Called after the service worker is successfully registered. */
54
109
  onRegistered?: (registration: ServiceWorkerRegistration) => void;
55
110
  }): ReactNode;
56
111
  /**
57
- * Provides a worker-backed Syncore client to a Next React tree.
112
+ * Root provider that wires a worker-backed Syncore runtime into a Next.js
113
+ * React tree.
114
+ *
115
+ * Place this at the top of your App Router layout. It spawns the Syncore
116
+ * worker on mount, exposes the client via React context (accessible with
117
+ * `useSyncore()`), and optionally registers the PWA service worker.
118
+ *
119
+ * ```tsx
120
+ * // app/layout.tsx
121
+ * import { SyncoreNextProvider } from "syncorejs/next";
58
122
  *
59
- * This is the shortest recommended integration for App Router pages that run
60
- * fully local in the browser.
123
+ * export default function RootLayout({ children }) {
124
+ * return (
125
+ * <html>
126
+ * <body>
127
+ * <SyncoreNextProvider
128
+ * createWorker={() => new Worker(
129
+ * new URL("../syncore.worker.ts", import.meta.url)
130
+ * )}
131
+ * >
132
+ * {children}
133
+ * </SyncoreNextProvider>
134
+ * </body>
135
+ * </html>
136
+ * );
137
+ * }
138
+ * ```
61
139
  */
62
140
  declare function SyncoreNextProvider({
63
141
  children,
@@ -68,13 +146,15 @@ declare function SyncoreNextProvider({
68
146
  }: {
69
147
  /** The React subtree that should receive the Syncore client. */children: ReactNode;
70
148
  /**
71
- * Optional custom worker factory for tests or Next colocated worker modules.
149
+ * Factory function that creates the Syncore `Worker`. Required in Next App
150
+ * Router dev mode because `new Worker(new URL(..., import.meta.url))` must
151
+ * be called inside the module to be bundled correctly.
72
152
  */
73
- createWorker?: () => Worker; /** Optional service worker URL used to cache the application shell. */
74
- serviceWorkerUrl?: string; /** Optional explicit module URL for an already-public worker asset. */
75
- workerUrl?: URL | string; /** Optional public worker asset path for production builds. */
153
+ createWorker?: () => Worker; /** URL of the PWA service worker script. Omit to skip service worker registration. */
154
+ serviceWorkerUrl?: string; /** Explicit module URL for an already-public worker asset. */
155
+ workerUrl?: URL | string; /** Public asset path for the compiled worker file. Defaults to `"/syncore.worker.js"`. */
76
156
  workerAssetUrl?: string;
77
- }): react_jsx_runtime0.JSX.Element;
157
+ }): import("react/jsx-runtime").JSX.Element;
78
158
  //#endregion
79
- export { SyncoreNextOptions, SyncoreNextProvider, SyncoreServiceWorker, SyncoreServiceWorkerRegistration, createNextSyncoreClient, createSyncoreNextWorkerUrl, getSyncoreWorkerUrl, registerSyncoreServiceWorker, resolveSqlJsWasmUrl };
159
+ export { SyncoreNextOptions, SyncoreNextProvider, SyncoreServiceWorker, SyncoreServiceWorkerRegistration, createNextSyncoreClient, createSyncoreNextWorkerUrl, getSyncoreWorkerUrl, registerSyncoreServiceWorker };
80
160
  //# sourceMappingURL=index.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.tsx"],"mappings":";;;;;;UAsBiB,kBAAA;;EAEf,gBAAA;EAFiC;EAKjC,YAAA;EALiC;EAQjC,cAAA;AAAA;;;;UAMe,gCAAA;EAAgC;EAE/C,UAAA,IAAc,OAAA;EAAA;EAGd,MAAA,IAAU,OAAA,CAAQ,yBAAA;AAAA;;;;iBAME,4BAAA,CACpB,OAAA,GAAU,kBAAA,GACT,OAAA,CAAQ,gCAAA;;;;iBAkBK,mBAAA,CAAoB,OAAA,GAAU,kBAAA;;AApB9C;;iBA2BgB,uBAAA,CAAwB,OAAA;EA1B5B;;;;EA+BV,YAAA,SAAqB,MAAA,EA/BX;EAkCV,SAAA,GAAY,GAAA,WAjCX;EAoCD,cAAA;AAAA,IACE,sBAAA;;AAnBJ;;iBAmCgB,oBAAA,CAAA;EACd,QAAA;EACA,gBAAA;EACA;AAAA;EAEA,QAAA,EAAU,SAAA;EACV,gBAAA;EACA,YAAA,IAAgB,YAAA,EAAc,yBAAA;AAAA,IAC/B,SAAA;;;;;;;iBAsBe,mBAAA,CAAA;EACd,QAAA;EACA,YAAA;EACA,gBAAA;EACA,SAAA;EACA;AAAA;EA1DqB,gEA6DrB,QAAA,EAAU,SAAA;EA1DE;;;EA+DZ,YAAA,SAAqB,MAAA,EA3DG;EA8DxB,gBAAA,WA9Cc;EAiDd,SAAA,GAAY,GAAA;EAGZ,cAAA;AAAA,IACD,kBAAA,CAAA,GAAA,CAAA,OAAA"}
1
+ {"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.tsx"],"mappings":";;;;;;AA4BA;;;;AAYgB;UAZC,kBAAA;EAkBgC;;;;EAb/C,gBAAA;EAqBiB;;;;;EAdjB,cAAc;AAAA;;AAc6B;AAuB7C;UA/BiB,gCAAA;;EAEf,UAAA,IAAc,OAAA;EA+BL;;;;EAzBT,MAAA,IAAU,OAAA,CAAQ,yBAAA;AAAA;;;;AAyBuB;AAoC3C;;;;;;;;;;;;;;;;iBAtCsB,4BAAA,CACpB,OAAA,GAAU,kBAAA,GACT,OAAA,CAAQ,gCAAA;AA2EX;;;;;;;;;;;;;;;;;;;;;AAAA,iBAvCgB,uBAAA,CAAwB,OAAA;EAgDtB;;;AACjB;AA6CD;EAxFE,YAAA,SAAqB,MAAA;EAGrB,SAAA,GAAY,GAAA,WAuFZ;EApFA,cAAA;AAAA,IACE,sBAAA;;;;;;;;;;;;;;iBA0BY,oBAAA,CAAA;EACd,QAAA;EACA,gBAAA;EACA;AAAA;EAEA,QAAA,EAAU,SAAA,EAuDV;EArDA,gBAAA,WAwDU;EAtDV,YAAA,IAAgB,YAAA,EAAc,yBAAA;AAAA,IAC/B,SAAA;;;;;;;;AAsEA;;;;;;;;;;;;;;;;;;;;;;iBAzBe,mBAAA,CAAA;EACd,QAAA;EACA,YAAA;EACA,gBAAA;EACA,SAAA;EACA;AAAA;kEAGA,QAAA,EAAU,SAAA;;;;;;EAOV,YAAA,SAAqB,MAAA;EAGrB,gBAAA;EAGA,SAAA,GAAY,GAAA;EAGZ,cAAA;AAAA,gCACD,GAAA,CAAA,OAAA"}
@@ -6,7 +6,24 @@ import { useEffect, useMemo, useRef, useState } from "react";
6
6
  import { jsx } from "react/jsx-runtime";
7
7
  //#region src/index.tsx
8
8
  /**
9
- * Register the Syncore service worker used by the Next integration.
9
+ * Register the Syncore PWA service worker in a Next.js app.
10
+ *
11
+ * Call this once at app startup (e.g. in your root layout’s `useEffect`, or in
12
+ * `instrumentation.ts` with `"use client"`). Returns `null` on the server or
13
+ * when the browser does not support service workers.
14
+ *
15
+ * ```ts
16
+ * // app/layout.tsx (client component)
17
+ * import { registerSyncoreServiceWorker } from "syncorejs/next";
18
+ *
19
+ * useEffect(() => {
20
+ * registerSyncoreServiceWorker({ serviceWorkerUrl: "/sw.js" });
21
+ * }, []);
22
+ * ```
23
+ *
24
+ * @param options - Optional configuration. Defaults to `"/sw.js"`.
25
+ * @returns A {@link SyncoreServiceWorkerRegistration} handle, or `null` on
26
+ * the server / when unsupported.
10
27
  */
11
28
  async function registerSyncoreServiceWorker(options) {
12
29
  if (typeof window === "undefined" || !("serviceWorker" in navigator)) return null;
@@ -17,20 +34,42 @@ async function registerSyncoreServiceWorker(options) {
17
34
  };
18
35
  }
19
36
  /**
20
- * Resolve the public URL used by SQL.js to load its wasm file in a Next app.
21
- */
22
- function resolveSqlJsWasmUrl(options) {
23
- return options?.wasmAssetUrl ?? "/sql-wasm.wasm";
24
- }
25
- /**
26
- * Create a worker-backed Syncore client for a Next app.
37
+ * Create a worker-backed Syncore client for a Next.js app.
38
+ *
39
+ * The client communicates with a Syncore runtime running inside a `Worker`.
40
+ * The worker runs the SQLite engine and all function handlers off the main
41
+ * thread so the UI stays responsive.
42
+ *
43
+ * In most cases you should use {@link SyncoreNextProvider} instead, which
44
+ * manages the client lifecycle automatically. Use `createNextSyncoreClient`
45
+ * directly only when you need to control the client lifecycle yourself (e.g.
46
+ * in testing harnesses or custom providers).
47
+ *
48
+ * ```ts
49
+ * const managedClient = createNextSyncoreClient({
50
+ * workerAssetUrl: "/syncore.worker.js",
51
+ * });
52
+ *
53
+ * // Later:
54
+ * managedClient.dispose();
55
+ * ```
27
56
  */
28
57
  function createNextSyncoreClient(options) {
29
58
  if (options.createWorker) return createManagedWebWorkerClient({ createWorker: options.createWorker });
30
59
  return createSyncoreWebWorkerClient({ workerUrl: options.workerUrl ?? options.workerAssetUrl ?? "/syncore.worker.js" });
31
60
  }
32
61
  /**
33
- * Register a service worker while rendering a React subtree.
62
+ * React component that registers a PWA service worker as a side-effect.
63
+ *
64
+ * Renders its `children` immediately (no loading state) and registers the
65
+ * service worker asynchronously. Safe to render on the server — the
66
+ * registration effect only runs in browsers that support service workers.
67
+ *
68
+ * ```tsx
69
+ * <SyncoreServiceWorker serviceWorkerUrl="/sw.js" onRegistered={console.log}>
70
+ * <App />
71
+ * </SyncoreServiceWorker>
72
+ * ```
34
73
  */
35
74
  function SyncoreServiceWorker({ children, serviceWorkerUrl, onRegistered }) {
36
75
  useEffect(() => {
@@ -43,10 +82,33 @@ function SyncoreServiceWorker({ children, serviceWorkerUrl, onRegistered }) {
43
82
  return children;
44
83
  }
45
84
  /**
46
- * Provides a worker-backed Syncore client to a Next React tree.
85
+ * Root provider that wires a worker-backed Syncore runtime into a Next.js
86
+ * React tree.
87
+ *
88
+ * Place this at the top of your App Router layout. It spawns the Syncore
89
+ * worker on mount, exposes the client via React context (accessible with
90
+ * `useSyncore()`), and optionally registers the PWA service worker.
91
+ *
92
+ * ```tsx
93
+ * // app/layout.tsx
94
+ * import { SyncoreNextProvider } from "syncorejs/next";
47
95
  *
48
- * This is the shortest recommended integration for App Router pages that run
49
- * fully local in the browser.
96
+ * export default function RootLayout({ children }) {
97
+ * return (
98
+ * <html>
99
+ * <body>
100
+ * <SyncoreNextProvider
101
+ * createWorker={() => new Worker(
102
+ * new URL("../syncore.worker.ts", import.meta.url)
103
+ * )}
104
+ * >
105
+ * {children}
106
+ * </SyncoreNextProvider>
107
+ * </body>
108
+ * </html>
109
+ * );
110
+ * }
111
+ * ```
50
112
  */
51
113
  function SyncoreNextProvider({ children, createWorker, serviceWorkerUrl, workerUrl, workerAssetUrl }) {
52
114
  const createWorkerRef = useRef(createWorker);
@@ -58,7 +120,6 @@ function SyncoreNextProvider({ children, createWorker, serviceWorkerUrl, workerU
58
120
  }), []);
59
121
  const [client, setClient] = useState(bootingClient);
60
122
  useEffect(() => {
61
- let disposed = false;
62
123
  let managedClient;
63
124
  setClient(bootingClient);
64
125
  try {
@@ -68,16 +129,15 @@ function SyncoreNextProvider({ children, createWorker, serviceWorkerUrl, workerU
68
129
  ...resolvedWorkerUrl ? { workerUrl: process.env.NODE_ENV === "production" ? getSyncoreWorkerUrl() : resolvedWorkerUrl } : {},
69
130
  ...workerAssetUrl ? { workerAssetUrl } : {}
70
131
  });
71
- if (!disposed) setClient(managedClient.client);
132
+ setClient(managedClient.client);
72
133
  } catch (error) {
73
- if (!disposed) setClient(createUnavailableSyncoreClient({
134
+ setClient(createUnavailableSyncoreClient({
74
135
  kind: "unavailable",
75
136
  reason: "worker-unavailable",
76
137
  ...error instanceof Error ? { error } : {}
77
138
  }));
78
139
  }
79
140
  return () => {
80
- disposed = true;
81
141
  managedClient?.dispose();
82
142
  };
83
143
  }, [
@@ -94,6 +154,6 @@ function SyncoreNextProvider({ children, createWorker, serviceWorkerUrl, workerU
94
154
  });
95
155
  }
96
156
  //#endregion
97
- export { SyncoreNextProvider, SyncoreServiceWorker, createNextSyncoreClient, createSyncoreNextWorkerUrl, getSyncoreWorkerUrl, registerSyncoreServiceWorker, resolveSqlJsWasmUrl };
157
+ export { SyncoreNextProvider, SyncoreServiceWorker, createNextSyncoreClient, createSyncoreNextWorkerUrl, getSyncoreWorkerUrl, registerSyncoreServiceWorker };
98
158
 
99
159
  //# sourceMappingURL=index.js.map
@@ -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\nexport interface SyncoreNextOptions {\n /** Optional service worker URL used to cache the application shell. */\n serviceWorkerUrl?: string;\n\n /** Optional URL for the `sql.js` wasm asset. */\n wasmAssetUrl?: string;\n\n /** Optional URL for the worker asset used by the local Syncore runtime. */\n workerAssetUrl?: string;\n}\n\n/**\n * The result of registering the Syncore service worker in a Next app.\n */\nexport interface SyncoreServiceWorkerRegistration {\n /** Unregister the installed service worker. */\n unregister(): Promise<boolean>;\n\n /** Ask the browser to check for an updated service worker. */\n update(): Promise<ServiceWorkerRegistration>;\n}\n\n/**\n * Register the Syncore service worker used by the Next integration.\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 * Resolve the public URL used by SQL.js to load its wasm file in a Next app.\n */\nexport function resolveSqlJsWasmUrl(options?: SyncoreNextOptions): string {\n return options?.wasmAssetUrl ?? \"/sql-wasm.wasm\";\n}\n\n/**\n * Create a worker-backed Syncore client for a Next app.\n */\nexport function createNextSyncoreClient(options: {\n /**\n * Optional custom worker factory for tests or framework-specific worker\n * bundling patterns such as Next App Router development.\n */\n createWorker?: () => Worker;\n\n /** Optional explicit module URL for an already-public worker asset. */\n workerUrl?: URL | string;\n\n /** Optional public worker asset path for production builds. */\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 * Register a service worker while rendering a React subtree.\n */\nexport function SyncoreServiceWorker({\n children,\n serviceWorkerUrl,\n onRegistered\n}: {\n children: ReactNode;\n serviceWorkerUrl?: string;\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 * Provides a worker-backed Syncore client to a Next React tree.\n *\n * This is the shortest recommended integration for App Router pages that run\n * fully local in the browser.\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 * Optional custom worker factory for tests or Next colocated worker modules.\n */\n createWorker?: () => Worker;\n\n /** Optional service worker URL used to cache the application shell. */\n serviceWorkerUrl?: string;\n\n /** Optional explicit module URL for an already-public worker asset. */\n workerUrl?: URL | string;\n\n /** Optional public worker asset path for production builds. */\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 disposed = false;\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 if (!disposed) {\n setClient(managedClient.client);\n }\n } catch (error) {\n if (!disposed) {\n setClient(\n createUnavailableSyncoreClient({\n kind: \"unavailable\",\n reason: \"worker-unavailable\",\n ...(error instanceof Error ? { error } : {})\n })\n );\n }\n }\n\n return () => {\n disposed = true;\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":";;;;;;;;;;AA+CA,eAAsB,6BACpB,SACkD;AAClD,KAAI,OAAO,WAAW,eAAe,EAAE,mBAAmB,WACxD,QAAO;CAGT,MAAM,eAAe,MAAM,UAAU,cAAc,SACjD,SAAS,oBAAoB,SAC9B;AAED,QAAO;EACL,kBAAkB,aAAa,YAAY;EAC3C,cAAc,aAAa,QAAQ;EACpC;;;;;AAMH,SAAgB,oBAAoB,SAAsC;AACxE,QAAO,SAAS,gBAAgB;;;;;AAMlC,SAAgB,wBAAwB,SAYb;AACzB,KAAI,QAAQ,aACV,QAAO,6BAA6B,EAClC,cAAc,QAAQ,cACvB,CAAC;AAGJ,QAAO,6BAA6B,EAClC,WACE,QAAQ,aAAa,QAAQ,kBAAkB,sBAClD,CAAC;;;;;AAMJ,SAAgB,qBAAqB,EACnC,UACA,kBACA,gBAKC;AACD,iBAAgB;AACd,GAAM,YAAY;AAChB,OAAI,OAAO,WAAW,eAAe,EAAE,mBAAmB,WACxD;GAEF,MAAM,eAAe,MAAM,UAAU,cAAc,SACjD,oBAAoB,SACrB;AACD,kBAAe,aAAa;MAC1B;IACH,CAAC,cAAc,iBAAiB,CAAC;AAEpC,QAAO;;;;;;;;AAST,SAAgB,oBAAoB,EAClC,UACA,cACA,kBACA,WACA,kBAkBC;CACD,MAAM,kBAAkB,OAAO,aAAa;AAC5C,iBAAgB,UAAU;CAC1B,MAAM,oBACJ,OAAO,cAAc,WAAW,YAAY,WAAW,UAAU;CACnE,MAAM,gBAAgB,cAElB,+BAA+B;EAC7B,MAAM;EACN,QAAQ;EACT,CAAC,EACJ,EAAE,CACH;CACD,MAAM,CAAC,QAAQ,aAAa,SAAwB,cAAc;AAElE,iBAAgB;EACd,IAAI,WAAW;EACf,IAAI;AAEJ,YAAU,cAAc;AAExB,MAAI;GACF,MAAM,gBAAgB,gBAAgB;AACtC,mBAAgB,wBAAwB;IACtC,GAAI,gBACA,EACE,oBAAoB,eAAe,EACpC,GACD,EAAE;IACN,GAAI,oBACA,EACE,WACE,QAAQ,IAAI,aAAa,eACrB,qBAAqB,GACrB,mBACP,GACD,EAAE;IACN,GAAI,iBAAiB,EAAE,gBAAgB,GAAG,EAAE;IAC7C,CAAC;AACF,OAAI,CAAC,SACH,WAAU,cAAc,OAAO;WAE1B,OAAO;AACd,OAAI,CAAC,SACH,WACE,+BAA+B;IAC7B,MAAM;IACN,QAAQ;IACR,GAAI,iBAAiB,QAAQ,EAAE,OAAO,GAAG,EAAE;IAC5C,CAAC,CACH;;AAIL,eAAa;AACX,cAAW;AACX,kBAAe,SAAS;;IAEzB;EAAC;EAAe;EAAmB;EAAe,CAAC;AAEtD,QACE,oBAAC,sBAAD;EAAsB,GAAK,mBAAmB,EAAE,kBAAkB,GAAG,EAAE;YACrE,oBAAC,iBAAD;GAAyB;GAAS;GAA2B,CAAA;EACxC,CAAA"}
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,68 +1,187 @@
1
1
  import { SQLiteDatabase } from "expo-sqlite";
2
- import * as _syncore_core0 from "../core/index.d.mts";
3
2
  import { DevtoolsSink, SchedulerOptions, StorageObject, StorageWriteInput, SyncoreCapabilities, SyncoreDataModel, SyncoreExternalChangeApplier, SyncoreExternalChangeSignal, SyncoreRuntime, SyncoreRuntimeOptions, SyncoreSqlDriver, SyncoreStorageAdapter } from "../core/index.d.mts";
4
3
 
5
4
  //#region src/index.d.ts
6
5
  type ExpoSyncoreSchema<TSchema extends SyncoreDataModel = SyncoreDataModel> = TSchema;
7
6
  /**
8
- * Options for constructing an Expo Syncore runtime.
7
+ * Options for {@link createExpoSyncoreRuntime}.
9
8
  *
10
- * Use this when you want Syncore to persist locally with `expo-sqlite` and the
11
- * Expo file system.
9
+ * On native (iOS/Android) Syncore uses `expo-sqlite` and `expo-file-system`
10
+ * automatically. When the same app is served on web (via `expo-router` or
11
+ * Metro’s web bundler) it falls back to the SQL.js + OPFS web stack instead.
12
+ *
13
+ * At minimum supply `schema` and `functions`. Everything else has platform
14
+ * defaults.
15
+ *
16
+ * ```ts
17
+ * const runtime = createExpoSyncoreRuntime({
18
+ * schema,
19
+ * functions,
20
+ * databaseName: "app.db",
21
+ * storageDirectoryName: "app-storage",
22
+ * });
23
+ * await runtime.start();
24
+ * ```
12
25
  */
13
26
  interface CreateExpoRuntimeOptions<TSchema extends ExpoSyncoreSchema = ExpoSyncoreSchema> {
14
- /** The schema for the local Syncore app. */
27
+ /** The data model that defines the available tables and indexes. */
15
28
  schema: TSchema;
16
- /** The generated function registry for the local Syncore app. */
29
+ /**
30
+ * The registered function map. Use the `functions` export from
31
+ * `syncore/_generated/functions.ts`.
32
+ */
17
33
  functions: SyncoreRuntimeOptions<TSchema>["functions"];
18
- /** Optional resolved installed components for the local Syncore app. */
34
+ /**
35
+ * Resolved Syncore component instances. Only required when your app
36
+ * installs Syncore component packages.
37
+ */
19
38
  components?: SyncoreRuntimeOptions<TSchema>["components"];
20
- /** Optional platform capabilities exposed to function handlers. */
39
+ /**
40
+ * Platform capabilities injected into `ctx.capabilities` inside function
41
+ * handlers.
42
+ */
21
43
  capabilities?: SyncoreCapabilities;
22
- /** Optional custom SQL driver. Defaults to `expo-sqlite`. */
44
+ /**
45
+ * Custom SQL driver. Defaults to an `ExpoSqliteDriver` backed by
46
+ * `expo-sqlite`.
47
+ */
23
48
  driver?: SyncoreSqlDriver;
24
- /** Optional custom file/blob storage adapter. */
49
+ /** Custom file/blob storage adapter. Defaults to `ExpoFileStorageAdapter`. */
25
50
  storage?: SyncoreStorageAdapter;
26
- /** The SQLite database filename to open locally. */
51
+ /**
52
+ * SQLite database filename (e.g. `"app.db"`). Defaults to `"syncore.db"`.
53
+ * The file is created inside the app-local documents directory on device.
54
+ */
27
55
  databaseName?: string;
28
- /** Optional directory for the SQLite database file. */
56
+ /**
57
+ * Absolute path to the directory where the SQLite file is stored.
58
+ * Defaults to `expo-sqlite`’s `defaultDatabaseDirectory`.
59
+ */
29
60
  databaseDirectory?: string;
30
- /** Directory name used for local file/blob storage. */
61
+ /**
62
+ * Name of the sub-directory inside the app’s documents folder used for
63
+ * blob/file storage. Defaults to `"syncore-storage"`.
64
+ */
31
65
  storageDirectoryName?: string;
32
- /** Optional runtime platform label shown in devtools snapshots. */
66
+ /**
67
+ * Platform label reported to devtools. Defaults to `"expo"`. Override to
68
+ * `"expo-web"` when running on web.
69
+ */
33
70
  platform?: string;
34
- /** Optional devtools sink used during development. */
71
+ /**
72
+ * Devtools event sink. Omit to disable devtools. On-device devtools
73
+ * connections require pointing to your development machine’s IP address.
74
+ */
35
75
  devtools?: DevtoolsSink;
36
- /** Optional scheduler configuration for jobs and recurring work. */
76
+ /** Scheduler configuration for background and recurring jobs. */
37
77
  scheduler?: SchedulerOptions;
38
- /** Optional shared signal used to synchronize browser instances. */
78
+ /**
79
+ * External change signal used to keep multiple in-process instances in sync.
80
+ * On web, defaults to a `BroadcastChannel`-based signal automatically.
81
+ */
39
82
  externalChangeSignal?: SyncoreExternalChangeSignal;
40
- /** Optional applier used to reconcile browser-side external changes. */
83
+ /**
84
+ * External change applier used when change events arrive from other tabs or
85
+ * processes. On web with `ExpoSqliteDriver`, defaults to
86
+ * `ExpoWebExternalChangeApplier` automatically.
87
+ */
41
88
  externalChangeApplier?: SyncoreExternalChangeApplier;
89
+ /**
90
+ * Direct URL to the SQL.js `.wasm` binary. Only needed when the app runs on
91
+ * web and the default CDN URL is unreachable.
92
+ */
93
+ wasmUrl?: string;
94
+ /**
95
+ * Resolver for SQL.js support files (`.wasm`, `.worker.js`). Equivalent to
96
+ * the `locateFile` option in `initSqlJs()`. Only used on web.
97
+ */
98
+ locateFile?: (fileName: string) => string;
42
99
  }
43
100
  /**
44
- * A reusable bootstrap that lazily creates, starts, and stops an Expo Syncore runtime.
101
+ * A reusable, lazily-started Expo Syncore runtime handle.
102
+ *
103
+ * Created by {@link createExpoSyncoreBootstrap}. The bootstrap defers actual
104
+ * runtime startup until the first call to `getClient()` and keeps a single
105
+ * instance alive across React Navigation reloads.
106
+ *
107
+ * ```ts
108
+ * const bootstrap = createExpoSyncoreBootstrap({ schema, functions });
109
+ *
110
+ * // In your root component:
111
+ * const client = await bootstrap.getClient();
112
+ * ```
45
113
  */
46
114
  interface ExpoSyncoreBootstrap<TSchema extends ExpoSyncoreSchema = ExpoSyncoreSchema> {
47
- /** Synchronous access is unavailable; use `getClient()` instead. */
115
+ /** @deprecated Access the runtime via `getClient()` instead. */
48
116
  getRuntime(): never;
49
- /** Start the runtime if needed and return a ready client. */
117
+ /**
118
+ * Start the runtime on first call, then return the same client on subsequent
119
+ * calls. Safe to call from multiple places concurrently.
120
+ */
50
121
  getClient(): Promise<ReturnType<SyncoreRuntime<TSchema>["createClient"]>>;
51
- /** Stop the current runtime instance if one exists. */
122
+ /** Stop the running runtime instance if one is active. */
52
123
  stop(): Promise<void>;
53
- /** Fully discard the runtime so the next call recreates it. */
124
+ /**
125
+ * Stop and discard the current runtime so the next `getClient()` call
126
+ * creates a fresh one. Useful after a full app reset or database migration.
127
+ */
54
128
  reset(): Promise<void>;
55
129
  }
56
130
  /**
57
- * Create an Expo Syncore runtime backed by `expo-sqlite` and local file storage.
131
+ * Create a Syncore runtime for Expo (React Native and Expo web) backed by
132
+ * `expo-sqlite` on native platforms and SQL.js on web.
133
+ *
134
+ * Returns an unstarted {@link SyncoreRuntime}. Call `await runtime.start()`
135
+ * before using the client:
136
+ *
137
+ * ```ts
138
+ * import { createExpoSyncoreRuntime } from "syncorejs/expo";
139
+ * import schema from "./syncore/schema";
140
+ * import { functions } from "./syncore/_generated/functions";
141
+ *
142
+ * const runtime = createExpoSyncoreRuntime({ schema, functions });
143
+ * await runtime.start();
144
+ * const client = runtime.createClient();
145
+ * ```
146
+ *
147
+ * For managed lifecycle in React components, prefer
148
+ * {@link createExpoSyncoreBootstrap} instead.
58
149
  */
59
150
  declare function createExpoSyncoreRuntime<TSchema extends ExpoSyncoreSchema>(options: CreateExpoRuntimeOptions<TSchema>): SyncoreRuntime<TSchema>;
60
151
  /**
61
- * Create a same-process Syncore client from a started Expo runtime.
152
+ * Create a same-process Syncore client directly from a started Expo runtime.
153
+ *
154
+ * Prefer this in scripts or non-component code. For React component trees,
155
+ * use {@link createExpoSyncoreBootstrap} instead to get automatic lifecycle
156
+ * management.
157
+ *
158
+ * ```ts
159
+ * const client = createExpoSyncoreClient(runtime);
160
+ * await client.mutation(api.todos.create, { text: "Buy milk" });
161
+ * ```
62
162
  */
63
- declare function createExpoSyncoreClient<TSchema extends ExpoSyncoreSchema>(runtime: SyncoreRuntime<TSchema>): _syncore_core0.SyncoreClient;
163
+ declare function createExpoSyncoreClient<TSchema extends ExpoSyncoreSchema>(runtime: SyncoreRuntime<TSchema>): import("../core/index.d.mts").SyncoreClient;
64
164
  /**
65
- * Create a reusable Expo bootstrap that lazily starts the local runtime.
165
+ * Create a reusable Expo bootstrap that lazily starts the local runtime the
166
+ * first time a client is requested.
167
+ *
168
+ * The bootstrap keeps a single runtime instance alive across component
169
+ * remounts and safely handles concurrent `getClient()` calls.
170
+ *
171
+ * ```ts
172
+ * // app/_layout.tsx
173
+ * import { createExpoSyncoreBootstrap } from "syncorejs/expo";
174
+ * import schema from "../syncore/schema";
175
+ * import { functions } from "../syncore/_generated/functions";
176
+ *
177
+ * export const syncoreBootstrap = createExpoSyncoreBootstrap({
178
+ * schema,
179
+ * functions,
180
+ * });
181
+ *
182
+ * // Later in SyncoreProvider:
183
+ * const client = await syncoreBootstrap.getClient();
184
+ * ```
66
185
  */
67
186
  declare function createExpoSyncoreBootstrap<TSchema extends ExpoSyncoreSchema>(options: CreateExpoRuntimeOptions<TSchema>): ExpoSyncoreBootstrap<TSchema>;
68
187
  /**