syncorejs 0.2.2 → 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.
- package/dist/_vendor/cli/app.d.mts.map +1 -1
- package/dist/_vendor/cli/app.mjs +8 -5
- package/dist/_vendor/cli/app.mjs.map +1 -1
- package/dist/_vendor/cli/context.mjs.map +1 -1
- package/dist/_vendor/cli/dev-session.mjs.map +1 -1
- package/dist/_vendor/cli/doctor.mjs.map +1 -1
- package/dist/_vendor/cli/errors.mjs.map +1 -1
- package/dist/_vendor/cli/help.mjs.map +1 -1
- package/dist/_vendor/cli/index.mjs +9 -2
- package/dist/_vendor/cli/index.mjs.map +1 -1
- package/dist/_vendor/cli/messages.mjs.map +1 -1
- package/dist/_vendor/cli/preflight.mjs.map +1 -1
- package/dist/_vendor/cli/project.mjs +20 -20
- package/dist/_vendor/cli/project.mjs.map +1 -1
- package/dist/_vendor/cli/render.mjs.map +1 -1
- package/dist/_vendor/cli/targets.mjs.map +1 -1
- package/dist/_vendor/core/cli.d.mts +8 -2
- package/dist/_vendor/core/cli.d.mts.map +1 -1
- package/dist/_vendor/core/cli.mjs +510 -71
- package/dist/_vendor/core/cli.mjs.map +1 -1
- package/dist/_vendor/core/devtools-auth.mjs.map +1 -1
- package/dist/_vendor/core/index.d.mts +3 -3
- package/dist/_vendor/core/runtime/components.d.mts.map +1 -1
- package/dist/_vendor/core/runtime/components.mjs.map +1 -1
- package/dist/_vendor/core/runtime/devtools.d.mts.map +1 -1
- package/dist/_vendor/core/runtime/devtools.mjs +261 -23
- package/dist/_vendor/core/runtime/devtools.mjs.map +1 -1
- package/dist/_vendor/core/runtime/functions.d.mts +388 -6
- package/dist/_vendor/core/runtime/functions.d.mts.map +1 -1
- package/dist/_vendor/core/runtime/functions.mjs +72 -1
- package/dist/_vendor/core/runtime/functions.mjs.map +1 -1
- package/dist/_vendor/core/runtime/id.d.mts.map +1 -1
- package/dist/_vendor/core/runtime/id.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/engines/devtoolsEngine.mjs +12 -6
- package/dist/_vendor/core/runtime/internal/engines/devtoolsEngine.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/engines/executionEngine.mjs +123 -20
- package/dist/_vendor/core/runtime/internal/engines/executionEngine.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/engines/reactivityEngine.mjs +56 -8
- package/dist/_vendor/core/runtime/internal/engines/reactivityEngine.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/engines/schedulerEngine.mjs +49 -14
- package/dist/_vendor/core/runtime/internal/engines/schedulerEngine.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/engines/schemaEngine.mjs +4 -7
- package/dist/_vendor/core/runtime/internal/engines/schemaEngine.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/engines/shared.mjs +81 -2
- package/dist/_vendor/core/runtime/internal/engines/shared.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs +100 -13
- package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/runtimeKernel.mjs +42 -7
- package/dist/_vendor/core/runtime/internal/runtimeKernel.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/runtimeStatus.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/systemMeta.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/transactionCoordinator.mjs +4 -0
- package/dist/_vendor/core/runtime/internal/transactionCoordinator.mjs.map +1 -1
- package/dist/_vendor/core/runtime/runtime.d.mts +1100 -12
- package/dist/_vendor/core/runtime/runtime.d.mts.map +1 -1
- package/dist/_vendor/core/runtime/runtime.mjs +63 -0
- package/dist/_vendor/core/runtime/runtime.mjs.map +1 -1
- package/dist/_vendor/core/transport.d.mts +2 -0
- package/dist/_vendor/core/transport.d.mts.map +1 -1
- package/dist/_vendor/core/transport.mjs +61 -27
- package/dist/_vendor/core/transport.mjs.map +1 -1
- package/dist/_vendor/devtools-protocol/index.d.ts +223 -4
- package/dist/_vendor/devtools-protocol/index.d.ts.map +1 -1
- package/dist/_vendor/devtools-protocol/index.js.map +1 -1
- package/dist/_vendor/next/config.d.ts +3 -4
- package/dist/_vendor/next/config.d.ts.map +1 -1
- package/dist/_vendor/next/config.js +37 -19
- package/dist/_vendor/next/config.js.map +1 -1
- package/dist/_vendor/next/index.d.ts +109 -29
- package/dist/_vendor/next/index.d.ts.map +1 -1
- package/dist/_vendor/next/index.js +86 -18
- package/dist/_vendor/next/index.js.map +1 -1
- package/dist/_vendor/platform-expo/index.d.ts +146 -27
- package/dist/_vendor/platform-expo/index.d.ts.map +1 -1
- package/dist/_vendor/platform-expo/index.js +81 -10
- package/dist/_vendor/platform-expo/index.js.map +1 -1
- package/dist/_vendor/platform-expo/react.js.map +1 -1
- package/dist/_vendor/platform-expo/web-sqljs-wasm.js +16 -0
- package/dist/_vendor/platform-expo/web-sqljs-wasm.js.map +1 -0
- package/dist/_vendor/platform-node/index.d.mts +174 -9
- package/dist/_vendor/platform-node/index.d.mts.map +1 -1
- package/dist/_vendor/platform-node/index.mjs +251 -95
- package/dist/_vendor/platform-node/index.mjs.map +1 -1
- package/dist/_vendor/platform-node/ipc-react.mjs +4 -0
- package/dist/_vendor/platform-node/ipc-react.mjs.map +1 -1
- package/dist/_vendor/platform-node/ipc.d.mts.map +1 -1
- package/dist/_vendor/platform-node/ipc.mjs.map +1 -1
- package/dist/_vendor/platform-web/external-change.d.ts +41 -0
- package/dist/_vendor/platform-web/external-change.d.ts.map +1 -1
- package/dist/_vendor/platform-web/external-change.js +30 -0
- package/dist/_vendor/platform-web/external-change.js.map +1 -1
- package/dist/_vendor/platform-web/index.d.ts +312 -37
- package/dist/_vendor/platform-web/index.d.ts.map +1 -1
- package/dist/_vendor/platform-web/index.js +247 -25
- package/dist/_vendor/platform-web/index.js.map +1 -1
- package/dist/_vendor/platform-web/indexeddb.d.ts +12 -0
- package/dist/_vendor/platform-web/indexeddb.d.ts.map +1 -1
- package/dist/_vendor/platform-web/indexeddb.js +10 -0
- package/dist/_vendor/platform-web/indexeddb.js.map +1 -1
- package/dist/_vendor/platform-web/opfs.d.ts +16 -1
- package/dist/_vendor/platform-web/opfs.d.ts.map +1 -1
- package/dist/_vendor/platform-web/opfs.js +41 -3
- package/dist/_vendor/platform-web/opfs.js.map +1 -1
- package/dist/_vendor/platform-web/persistence.d.ts +85 -1
- package/dist/_vendor/platform-web/persistence.d.ts.map +1 -1
- package/dist/_vendor/platform-web/persistence.js +15 -0
- package/dist/_vendor/platform-web/persistence.js.map +1 -1
- package/dist/_vendor/platform-web/react.d.ts +1 -2
- package/dist/_vendor/platform-web/react.d.ts.map +1 -1
- package/dist/_vendor/platform-web/react.js +11 -5
- package/dist/_vendor/platform-web/react.js.map +1 -1
- package/dist/_vendor/platform-web/sqljs.js +10 -1
- package/dist/_vendor/platform-web/sqljs.js.map +1 -1
- package/dist/_vendor/platform-web/web-sqljs-wasm.js +8 -0
- package/dist/_vendor/platform-web/web-sqljs-wasm.js.map +1 -0
- package/dist/_vendor/platform-web/worker.d.ts +60 -9
- package/dist/_vendor/platform-web/worker.d.ts.map +1 -1
- package/dist/_vendor/platform-web/worker.js +37 -4
- package/dist/_vendor/platform-web/worker.js.map +1 -1
- package/dist/_vendor/react/index.d.ts +197 -13
- package/dist/_vendor/react/index.d.ts.map +1 -1
- package/dist/_vendor/react/index.js +209 -17
- package/dist/_vendor/react/index.js.map +1 -1
- package/dist/_vendor/schema/definition.d.ts +129 -0
- package/dist/_vendor/schema/definition.d.ts.map +1 -1
- package/dist/_vendor/schema/definition.js +99 -0
- package/dist/_vendor/schema/definition.js.map +1 -1
- package/dist/_vendor/schema/planner.d.ts.map +1 -1
- package/dist/_vendor/schema/planner.js.map +1 -1
- package/dist/_vendor/schema/validators.d.ts +180 -4
- package/dist/_vendor/schema/validators.d.ts.map +1 -1
- package/dist/_vendor/schema/validators.js +35 -1
- package/dist/_vendor/schema/validators.js.map +1 -1
- package/dist/_vendor/svelte/index.d.ts +207 -7
- package/dist/_vendor/svelte/index.d.ts.map +1 -1
- package/dist/_vendor/svelte/index.js +201 -6
- package/dist/_vendor/svelte/index.js.map +1 -1
- package/dist/browser.d.ts.map +1 -1
- package/dist/cli.js +3 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.d.ts +1 -1
- package/package.json +24 -21
|
@@ -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
|
|
7
|
+
* Options for {@link createExpoSyncoreRuntime}.
|
|
9
8
|
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
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
|
|
27
|
+
/** The data model that defines the available tables and indexes. */
|
|
15
28
|
schema: TSchema;
|
|
16
|
-
/**
|
|
29
|
+
/**
|
|
30
|
+
* The registered function map. Use the `functions` export from
|
|
31
|
+
* `syncore/_generated/functions.ts`.
|
|
32
|
+
*/
|
|
17
33
|
functions: SyncoreRuntimeOptions<TSchema>["functions"];
|
|
18
|
-
/**
|
|
34
|
+
/**
|
|
35
|
+
* Resolved Syncore component instances. Only required when your app
|
|
36
|
+
* installs Syncore component packages.
|
|
37
|
+
*/
|
|
19
38
|
components?: SyncoreRuntimeOptions<TSchema>["components"];
|
|
20
|
-
/**
|
|
39
|
+
/**
|
|
40
|
+
* Platform capabilities injected into `ctx.capabilities` inside function
|
|
41
|
+
* handlers.
|
|
42
|
+
*/
|
|
21
43
|
capabilities?: SyncoreCapabilities;
|
|
22
|
-
/**
|
|
44
|
+
/**
|
|
45
|
+
* Custom SQL driver. Defaults to an `ExpoSqliteDriver` backed by
|
|
46
|
+
* `expo-sqlite`.
|
|
47
|
+
*/
|
|
23
48
|
driver?: SyncoreSqlDriver;
|
|
24
|
-
/**
|
|
49
|
+
/** Custom file/blob storage adapter. Defaults to `ExpoFileStorageAdapter`. */
|
|
25
50
|
storage?: SyncoreStorageAdapter;
|
|
26
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
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
|
-
/**
|
|
76
|
+
/** Scheduler configuration for background and recurring jobs. */
|
|
37
77
|
scheduler?: SchedulerOptions;
|
|
38
|
-
/**
|
|
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
|
-
/**
|
|
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
|
|
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
|
-
/**
|
|
115
|
+
/** @deprecated Access the runtime via `getClient()` instead. */
|
|
48
116
|
getRuntime(): never;
|
|
49
|
-
/**
|
|
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
|
|
122
|
+
/** Stop the running runtime instance if one is active. */
|
|
52
123
|
stop(): Promise<void>;
|
|
53
|
-
/**
|
|
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
|
|
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 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>):
|
|
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
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../src/index.ts"],"mappings":"
|
|
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"}
|
|
@@ -1,10 +1,27 @@
|
|
|
1
1
|
import { Directory, File, Paths } from "expo-file-system";
|
|
2
2
|
import { defaultDatabaseDirectory, openDatabaseSync } from "expo-sqlite";
|
|
3
3
|
import { SyncoreRuntime } from "../core/index.mjs";
|
|
4
|
-
import { BroadcastChannelExternalChangeSignal, createDefaultSyncChannelName } from "../platform-web/index.js";
|
|
4
|
+
import { BroadcastChannelExternalChangeSignal, createDefaultSyncChannelName, createWebSyncoreRuntime } from "../platform-web/index.js";
|
|
5
5
|
//#region src/index.ts
|
|
6
6
|
/**
|
|
7
|
-
* Create
|
|
7
|
+
* Create a Syncore runtime for Expo (React Native and Expo web) backed by
|
|
8
|
+
* `expo-sqlite` on native platforms and SQL.js on web.
|
|
9
|
+
*
|
|
10
|
+
* Returns an unstarted SyncoreRuntime. Call `await runtime.start()`
|
|
11
|
+
* before using the client:
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* import { createExpoSyncoreRuntime } from "syncorejs/expo";
|
|
15
|
+
* import schema from "./syncore/schema";
|
|
16
|
+
* import { functions } from "./syncore/_generated/functions";
|
|
17
|
+
*
|
|
18
|
+
* const runtime = createExpoSyncoreRuntime({ schema, functions });
|
|
19
|
+
* await runtime.start();
|
|
20
|
+
* const client = runtime.createClient();
|
|
21
|
+
* ```
|
|
22
|
+
*
|
|
23
|
+
* For managed lifecycle in React components, prefer
|
|
24
|
+
* {@link createExpoSyncoreBootstrap} instead.
|
|
8
25
|
*/
|
|
9
26
|
function createExpoSyncoreRuntime(options) {
|
|
10
27
|
const databaseDirectory = options.databaseDirectory ?? (typeof defaultDatabaseDirectory === "string" ? defaultDatabaseDirectory : void 0);
|
|
@@ -26,24 +43,57 @@ function createExpoSyncoreRuntime(options) {
|
|
|
26
43
|
...isWebEnvironment && options.externalChangeApplier ? { externalChangeApplier: options.externalChangeApplier } : isWebEnvironment && webExternalChangeApplier ? { externalChangeApplier: webExternalChangeApplier } : {},
|
|
27
44
|
platform: options.platform ?? "expo",
|
|
28
45
|
...options.capabilities ? { capabilities: options.capabilities } : {},
|
|
46
|
+
runtimeCapabilities: { storage: {
|
|
47
|
+
available: true,
|
|
48
|
+
protocol: "file",
|
|
49
|
+
supportsRange: false
|
|
50
|
+
} },
|
|
29
51
|
...options.devtools ? { devtools: options.devtools } : {},
|
|
30
52
|
...options.scheduler ? { scheduler: options.scheduler } : {}
|
|
31
53
|
});
|
|
32
54
|
}
|
|
33
55
|
/**
|
|
34
|
-
* Create a same-process Syncore client from a started Expo runtime.
|
|
56
|
+
* Create a same-process Syncore client directly from a started Expo runtime.
|
|
57
|
+
*
|
|
58
|
+
* Prefer this in scripts or non-component code. For React component trees,
|
|
59
|
+
* use {@link createExpoSyncoreBootstrap} instead to get automatic lifecycle
|
|
60
|
+
* management.
|
|
61
|
+
*
|
|
62
|
+
* ```ts
|
|
63
|
+
* const client = createExpoSyncoreClient(runtime);
|
|
64
|
+
* await client.mutation(api.todos.create, { text: "Buy milk" });
|
|
65
|
+
* ```
|
|
35
66
|
*/
|
|
36
67
|
function createExpoSyncoreClient(runtime) {
|
|
37
68
|
return runtime.createClient();
|
|
38
69
|
}
|
|
39
70
|
/**
|
|
40
|
-
* Create a reusable Expo bootstrap that lazily starts the local runtime
|
|
71
|
+
* Create a reusable Expo bootstrap that lazily starts the local runtime the
|
|
72
|
+
* first time a client is requested.
|
|
73
|
+
*
|
|
74
|
+
* The bootstrap keeps a single runtime instance alive across component
|
|
75
|
+
* remounts and safely handles concurrent `getClient()` calls.
|
|
76
|
+
*
|
|
77
|
+
* ```ts
|
|
78
|
+
* // app/_layout.tsx
|
|
79
|
+
* import { createExpoSyncoreBootstrap } from "syncorejs/expo";
|
|
80
|
+
* import schema from "../syncore/schema";
|
|
81
|
+
* import { functions } from "../syncore/_generated/functions";
|
|
82
|
+
*
|
|
83
|
+
* export const syncoreBootstrap = createExpoSyncoreBootstrap({
|
|
84
|
+
* schema,
|
|
85
|
+
* functions,
|
|
86
|
+
* });
|
|
87
|
+
*
|
|
88
|
+
* // Later in SyncoreProvider:
|
|
89
|
+
* const client = await syncoreBootstrap.getClient();
|
|
90
|
+
* ```
|
|
41
91
|
*/
|
|
42
92
|
function createExpoSyncoreBootstrap(options) {
|
|
43
93
|
let runtime = null;
|
|
44
94
|
let started = null;
|
|
45
|
-
const ensureRuntime = () => {
|
|
46
|
-
runtime ??= createExpoSyncoreRuntime(options);
|
|
95
|
+
const ensureRuntime = async () => {
|
|
96
|
+
runtime ??= isWebEnvironment() ? await createExpoWebSyncoreRuntime(options) : createExpoSyncoreRuntime(options);
|
|
47
97
|
return runtime;
|
|
48
98
|
};
|
|
49
99
|
return {
|
|
@@ -51,10 +101,7 @@ function createExpoSyncoreBootstrap(options) {
|
|
|
51
101
|
throw new Error("createExpoSyncoreBootstrap().getRuntime() is not available synchronously. Use getClient() instead.");
|
|
52
102
|
},
|
|
53
103
|
async getClient() {
|
|
54
|
-
if (!started)
|
|
55
|
-
const activeRuntime = ensureRuntime();
|
|
56
|
-
started = activeRuntime.start().then(() => activeRuntime.createClient());
|
|
57
|
-
}
|
|
104
|
+
if (!started) started = ensureRuntime().then((activeRuntime) => activeRuntime.start().then(() => activeRuntime.createClient()));
|
|
58
105
|
return started;
|
|
59
106
|
},
|
|
60
107
|
async stop() {
|
|
@@ -74,6 +121,7 @@ function createExpoSyncoreBootstrap(options) {
|
|
|
74
121
|
* Syncore SQL driver implementation backed by `expo-sqlite`.
|
|
75
122
|
*/
|
|
76
123
|
var ExpoSqliteDriver = class {
|
|
124
|
+
database;
|
|
77
125
|
transactionDepth = 0;
|
|
78
126
|
closed = false;
|
|
79
127
|
databaseName;
|
|
@@ -151,6 +199,7 @@ var ExpoSqliteDriver = class {
|
|
|
151
199
|
}
|
|
152
200
|
};
|
|
153
201
|
var ExpoWebExternalChangeApplier = class {
|
|
202
|
+
driver;
|
|
154
203
|
constructor(driver) {
|
|
155
204
|
this.driver = driver;
|
|
156
205
|
}
|
|
@@ -223,6 +272,28 @@ function normalizeBinary(data) {
|
|
|
223
272
|
if (data instanceof Uint8Array) return data;
|
|
224
273
|
return new Uint8Array(data);
|
|
225
274
|
}
|
|
275
|
+
async function createExpoWebSyncoreRuntime(options) {
|
|
276
|
+
const wasmUrl = options.wasmUrl ?? (options.locateFile ? void 0 : await resolveDefaultExpoWebSqlJsWasmUrl());
|
|
277
|
+
return createWebSyncoreRuntime({
|
|
278
|
+
schema: options.schema,
|
|
279
|
+
functions: options.functions,
|
|
280
|
+
...options.components ? { components: options.components } : {},
|
|
281
|
+
...options.capabilities ? { capabilities: options.capabilities } : {},
|
|
282
|
+
databaseName: options.databaseName ?? "syncore.db",
|
|
283
|
+
storageNamespace: options.storageDirectoryName ?? "syncore-storage",
|
|
284
|
+
...wasmUrl ? { wasmUrl } : {},
|
|
285
|
+
...options.locateFile ? { locateFile: options.locateFile } : {},
|
|
286
|
+
platform: options.platform ?? "expo-web",
|
|
287
|
+
...options.devtools !== void 0 ? { devtools: options.devtools } : {},
|
|
288
|
+
...options.scheduler ? { scheduler: options.scheduler } : {}
|
|
289
|
+
});
|
|
290
|
+
}
|
|
291
|
+
async function resolveDefaultExpoWebSqlJsWasmUrl() {
|
|
292
|
+
return (await import("./web-sqljs-wasm.js")).resolveDefaultExpoWebSqlJsWasmUrl();
|
|
293
|
+
}
|
|
294
|
+
function isWebEnvironment() {
|
|
295
|
+
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
296
|
+
}
|
|
226
297
|
//#endregion
|
|
227
298
|
export { ExpoFileStorageAdapter, ExpoSqliteDriver, createExpoSyncoreBootstrap, createExpoSyncoreClient, createExpoSyncoreRuntime };
|
|
228
299
|
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../src/index.ts"],"sourcesContent":["import { 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} from \"@syncore/platform-web\";\n\nexport type ExpoSyncoreSchema<\n TSchema extends SyncoreDataModel = SyncoreDataModel\n> = TSchema;\n\n/**\n * Options for constructing an Expo Syncore runtime.\n *\n * Use this when you want Syncore to persist locally with `expo-sqlite` and the\n * Expo file system.\n */\nexport interface CreateExpoRuntimeOptions<\n TSchema extends ExpoSyncoreSchema = ExpoSyncoreSchema\n> {\n /** The schema for the local Syncore app. */\n schema: TSchema;\n\n /** The generated function registry for the local Syncore app. */\n functions: SyncoreRuntimeOptions<TSchema>[\"functions\"];\n\n /** Optional resolved installed components for the local Syncore app. */\n components?: SyncoreRuntimeOptions<TSchema>[\"components\"];\n\n /** Optional platform capabilities exposed to function handlers. */\n capabilities?: SyncoreCapabilities;\n\n /** Optional custom SQL driver. Defaults to `expo-sqlite`. */\n driver?: SyncoreSqlDriver;\n\n /** Optional custom file/blob storage adapter. */\n storage?: SyncoreStorageAdapter;\n\n /** The SQLite database filename to open locally. */\n databaseName?: string;\n\n /** Optional directory for the SQLite database file. */\n databaseDirectory?: string;\n\n /** Directory name used for local file/blob storage. */\n storageDirectoryName?: string;\n\n /** Optional runtime platform label shown in devtools snapshots. */\n platform?: string;\n\n /** Optional devtools sink used during development. */\n devtools?: DevtoolsSink;\n\n /** Optional scheduler configuration for jobs and recurring work. */\n scheduler?: SchedulerOptions;\n\n /** Optional shared signal used to synchronize browser instances. */\n externalChangeSignal?: SyncoreExternalChangeSignal;\n\n /** Optional applier used to reconcile browser-side external changes. */\n externalChangeApplier?: SyncoreExternalChangeApplier;\n}\n\n/**\n * A reusable bootstrap that lazily creates, starts, and stops an Expo Syncore runtime.\n */\nexport interface ExpoSyncoreBootstrap<\n TSchema extends ExpoSyncoreSchema = ExpoSyncoreSchema\n> {\n /** Synchronous access is unavailable; use `getClient()` instead. */\n getRuntime(): never;\n\n /** Start the runtime if needed and return a ready client. */\n getClient(): Promise<\n ReturnType<SyncoreRuntime<TSchema>[\"createClient\"]>\n >;\n\n /** Stop the current runtime instance if one exists. */\n stop(): Promise<void>;\n\n /** Fully discard the runtime so the next call recreates it. */\n reset(): Promise<void>;\n}\n\n/**\n * Create an Expo Syncore runtime backed by `expo-sqlite` and local file storage.\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 from a started Expo runtime.\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.\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 = () => {\n runtime ??= 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 const activeRuntime = ensureRuntime();\n started = activeRuntime\n .start()\n .then(() => activeRuntime.createClient());\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"],"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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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"react.js","names":[],"sources":["../src/react.tsx"],"sourcesContent":["import { createDeferredSyncoreClient } from \"@syncore/core\";\nimport { useEffect, useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { SyncoreProvider } from \"@syncore/react\";\nimport type { SyncoreClient } from \"@syncore/core\";\nimport type { ExpoSyncoreBootstrap } from \"./index.js\";\n\ntype ExpoSyncoreClient = SyncoreClient;\n\n/**\n * Props for {@link SyncoreExpoProvider}.\n */\nexport interface SyncoreExpoProviderProps {\n /** The bootstrap created with `createExpoSyncoreBootstrap`. */\n bootstrap: ExpoSyncoreBootstrap;\n\n /** The React subtree that should receive the Syncore client. */\n children: ReactNode;\n\n /** Optional fallback content rendered while the local runtime starts. */\n fallback?: ReactNode;\n}\n\n/**\n * Start an Expo Syncore bootstrap and provide its client to React descendants.\n */\nexport function SyncoreExpoProvider({\n bootstrap,\n children,\n fallback = null\n}: SyncoreExpoProviderProps): ReactNode {\n const client = useMemo(\n () =>\n createDeferredSyncoreClient({\n loadClient: () => bootstrap.getClient(),\n initialStatus: {\n kind: \"starting\",\n reason: \"booting\"\n },\n failureReason: \"runtime-unavailable\"\n }) as ExpoSyncoreClient,\n [bootstrap]\n );\n\n useEffect(() => {\n return () => {\n void bootstrap.stop();\n };\n }, [bootstrap]);\n\n return <SyncoreProvider client={client}>{children ?? fallback}</SyncoreProvider>;\n}\n"],"mappings":";;;;;;;;AA0BA,SAAgB,oBAAoB,EAClC,WACA,UACA,WAAW,QAC2B;CACtC,MAAM,SAAS,cAEX,4BAA4B;EAC1B,kBAAkB,UAAU,
|
|
1
|
+
{"version":3,"file":"react.js","names":[],"sources":["../src/react.tsx"],"sourcesContent":["import { createDeferredSyncoreClient } from \"@syncore/core\";\nimport { useEffect, useMemo } from \"react\";\nimport type { ReactNode } from \"react\";\nimport { SyncoreProvider } from \"@syncore/react\";\nimport type { SyncoreClient } from \"@syncore/core\";\nimport type { ExpoSyncoreBootstrap } from \"./index.js\";\n\ntype ExpoSyncoreClient = SyncoreClient;\n\n/**\n * Props for {@link SyncoreExpoProvider}.\n */\nexport interface SyncoreExpoProviderProps {\n /** The bootstrap created with `createExpoSyncoreBootstrap`. */\n bootstrap: ExpoSyncoreBootstrap;\n\n /** The React subtree that should receive the Syncore client. */\n children: ReactNode;\n\n /** Optional fallback content rendered while the local runtime starts. */\n fallback?: ReactNode;\n}\n\n/**\n * Start an Expo Syncore bootstrap and provide its client to React descendants.\n */\nexport function SyncoreExpoProvider({\n bootstrap,\n children,\n fallback = null\n}: SyncoreExpoProviderProps): ReactNode {\n const client = useMemo(\n () =>\n createDeferredSyncoreClient({\n loadClient: () => bootstrap.getClient(),\n initialStatus: {\n kind: \"starting\",\n reason: \"booting\"\n },\n failureReason: \"runtime-unavailable\"\n }) as ExpoSyncoreClient,\n [bootstrap]\n );\n\n useEffect(() => {\n return () => {\n void bootstrap.stop();\n };\n }, [bootstrap]);\n\n return <SyncoreProvider client={client}>{children ?? fallback}</SyncoreProvider>;\n}\n"],"mappings":";;;;;;;;AA0BA,SAAgB,oBAAoB,EAClC,WACA,UACA,WAAW,QAC2B;CACtC,MAAM,SAAS,cAEX,4BAA4B;EAC1B,kBAAkB,UAAU,UAAU;EACtC,eAAe;GACb,MAAM;GACN,QAAQ;EACV;EACA,eAAe;CACjB,CAAC,GACH,CAAC,SAAS,CACZ;CAEA,gBAAgB;EACd,aAAa;GACX,UAAe,KAAK;EACtB;CACF,GAAG,CAAC,SAAS,CAAC;CAEd,OAAO,oBAAC,iBAAD;EAAyB;YAAS,YAAY;CAA0B,CAAA;AACjF"}
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
import sqlWasmAsset from "sql.js/dist/sql-wasm.wasm";
|
|
2
|
+
//#region src/web-sqljs-wasm.ts
|
|
3
|
+
function resolveDefaultExpoWebSqlJsWasmUrl() {
|
|
4
|
+
return normalizeAssetUrl(sqlWasmAsset);
|
|
5
|
+
}
|
|
6
|
+
function normalizeAssetUrl(asset) {
|
|
7
|
+
if (typeof asset === "string") return asset;
|
|
8
|
+
if (!asset || typeof asset !== "object") return;
|
|
9
|
+
const record = asset;
|
|
10
|
+
if (typeof record.uri === "string") return record.uri;
|
|
11
|
+
return normalizeAssetUrl(record.default);
|
|
12
|
+
}
|
|
13
|
+
//#endregion
|
|
14
|
+
export { resolveDefaultExpoWebSqlJsWasmUrl };
|
|
15
|
+
|
|
16
|
+
//# sourceMappingURL=web-sqljs-wasm.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"web-sqljs-wasm.js","names":[],"sources":["../src/web-sqljs-wasm.ts"],"sourcesContent":["import sqlWasmAsset from \"sql.js/dist/sql-wasm.wasm\";\n\nexport function resolveDefaultExpoWebSqlJsWasmUrl(): string | undefined {\n return normalizeAssetUrl(sqlWasmAsset);\n}\n\nfunction normalizeAssetUrl(asset: unknown): string | undefined {\n if (typeof asset === \"string\") {\n return asset;\n }\n\n if (!asset || typeof asset !== \"object\") {\n return undefined;\n }\n\n const record = asset as {\n default?: unknown;\n uri?: unknown;\n };\n\n if (typeof record.uri === \"string\") {\n return record.uri;\n }\n\n return normalizeAssetUrl(record.default);\n}\n"],"mappings":";;AAEA,SAAgB,oCAAwD;CACtE,OAAO,kBAAkB,YAAY;AACvC;AAEA,SAAS,kBAAkB,OAAoC;CAC7D,IAAI,OAAO,UAAU,UACnB,OAAO;CAGT,IAAI,CAAC,SAAS,OAAO,UAAU,UAC7B;CAGF,MAAM,SAAS;CAKf,IAAI,OAAO,OAAO,QAAQ,UACxB,OAAO,OAAO;CAGhB,OAAO,kBAAkB,OAAO,OAAO;AACzC"}
|