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.
- 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 +238 -64
- package/dist/_vendor/core/cli.mjs.map +1 -1
- package/dist/_vendor/core/devtools-auth.mjs.map +1 -1
- 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 +130 -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 +11 -5
- 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 +76 -1
- package/dist/_vendor/core/runtime/internal/engines/shared.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs +1 -0
- package/dist/_vendor/core/runtime/internal/engines/storageEngine.mjs.map +1 -1
- package/dist/_vendor/core/runtime/internal/runtimeKernel.mjs +4 -3
- 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 +1040 -9
- 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 +33 -24
- package/dist/_vendor/core/transport.mjs.map +1 -1
- package/dist/_vendor/devtools-protocol/index.d.ts +149 -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 +77 -17
- 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 +76 -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 +173 -9
- package/dist/_vendor/platform-node/index.d.mts.map +1 -1
- package/dist/_vendor/platform-node/index.mjs +225 -94
- package/dist/_vendor/platform-node/index.mjs.map +1 -1
- 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 +307 -35
- package/dist/_vendor/platform-web/index.d.ts.map +1 -1
- package/dist/_vendor/platform-web/index.js +189 -23
- 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 +13 -0
- package/dist/_vendor/platform-web/opfs.d.ts.map +1 -1
- package/dist/_vendor/platform-web/opfs.js +12 -0
- package/dist/_vendor/platform-web/opfs.js.map +1 -1
- package/dist/_vendor/platform-web/persistence.d.ts +54 -0
- 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 +2 -4
- 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 +196 -13
- package/dist/_vendor/react/index.d.ts.map +1 -1
- package/dist/_vendor/react/index.js +208 -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 +205 -7
- package/dist/_vendor/svelte/index.d.ts.map +1 -1
- package/dist/_vendor/svelte/index.js +199 -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 +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;EAiHS;EA7GrC,IAAA,IAAQ,OAAA;EA8GQ;;;;EAxGhB,KAAA,IAAS,OAAA;AAAA;;;;;;;AAyGuB;AA0BlC;;;;;;;;;;;;;iBA5GgB,wBAAA,iBACE,iBAAA,CAAA,CAEhB,OAAA,EAAS,wBAAA,CAAyB,OAAA,IACjC,cAAA,CAAe,OAAA;;;;;AA4Ga;AAgD/B;;;;;;;iBAhFgB,uBAAA,iBACE,iBAAA,CAAA,CAChB,OAAA,EAAS,cAAA,CAAe,OAAA,4BAAQ,aAAA;;;;;;;;;;;;;;;;;;;;;;;iBA0BlB,0BAAA,iBACE,iBAAA,CAAA,CAEhB,OAAA,EAAS,wBAAA,CAAyB,OAAA,IACjC,oBAAA,CAAqB,OAAA;;;;cAgDX,gBAAA,YAA4B,gBAAA;EAAA,QAO7B,QAAA;EAAA,QANF,gBAAA;EAAA,QACA,MAAA;EAAA,iBACS,YAAA;EAAA,iBACA,iBAAA;cAGP,QAAA,EAAU,cAAA,EAClB,OAAA;IACE,YAAA;IACA,iBAAA;EAAA;EAOE,IAAA,CAAK,GAAA,WAAc,OAAA;EAKnB,GAAA,CACJ,GAAA,UACA,MAAA,eACC,OAAA;IAAU,OAAA;IAAiB,eAAA;EAAA;EASxB,GAAA,GAAA,CAAO,GAAA,UAAa,MAAA,eAAyB,OAAA,CAAQ,CAAA;EASrD,GAAA,GAAA,CAAO,GAAA,UAAa,MAAA,eAAyB,OAAA,CAAQ,CAAA;EAKrD,eAAA,GAAA,CAAmB,QAAA,QAAgB,OAAA,CAAQ,CAAA,IAAK,OAAA,CAAQ,CAAA;EAoBxD,aAAA,GAAA,CAAiB,IAAA,UAAc,QAAA,QAAgB,OAAA,CAAQ,CAAA,IAAK,OAAA,CAAQ,CAAA;EAkBpE,KAAA,CAAA,GAAS,OAAA;EAAA,QAQP,UAAA;EAMF,MAAA,CAAA,GAAU,OAAA;AAAA;;;;cAuCL,sBAAA,YAAkC,qBAAA;EAAA,iBAC5B,aAAA;cAEL,oBAAA;EAON,GAAA,CAAI,EAAA,UAAY,KAAA,EAAO,iBAAA,GAAoB,OAAA,CAAQ,aAAA;EAenD,GAAA,CAAI,EAAA,WAAa,OAAA,CAAQ,aAAA;EAazB,IAAA,CAAK,EAAA,WAAa,OAAA,CAAQ,UAAA;EAQ1B,MAAA,CAAO,EAAA,WAAa,OAAA;AAAA"}
|
|
@@ -1,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 {@link 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);
|
|
@@ -31,19 +48,47 @@ function createExpoSyncoreRuntime(options) {
|
|
|
31
48
|
});
|
|
32
49
|
}
|
|
33
50
|
/**
|
|
34
|
-
* Create a same-process Syncore client from a started Expo runtime.
|
|
51
|
+
* Create a same-process Syncore client directly from a started Expo runtime.
|
|
52
|
+
*
|
|
53
|
+
* Prefer this in scripts or non-component code. For React component trees,
|
|
54
|
+
* use {@link createExpoSyncoreBootstrap} instead to get automatic lifecycle
|
|
55
|
+
* management.
|
|
56
|
+
*
|
|
57
|
+
* ```ts
|
|
58
|
+
* const client = createExpoSyncoreClient(runtime);
|
|
59
|
+
* await client.mutation(api.todos.create, { text: "Buy milk" });
|
|
60
|
+
* ```
|
|
35
61
|
*/
|
|
36
62
|
function createExpoSyncoreClient(runtime) {
|
|
37
63
|
return runtime.createClient();
|
|
38
64
|
}
|
|
39
65
|
/**
|
|
40
|
-
* Create a reusable Expo bootstrap that lazily starts the local runtime
|
|
66
|
+
* Create a reusable Expo bootstrap that lazily starts the local runtime the
|
|
67
|
+
* first time a client is requested.
|
|
68
|
+
*
|
|
69
|
+
* The bootstrap keeps a single runtime instance alive across component
|
|
70
|
+
* remounts and safely handles concurrent `getClient()` calls.
|
|
71
|
+
*
|
|
72
|
+
* ```ts
|
|
73
|
+
* // app/_layout.tsx
|
|
74
|
+
* import { createExpoSyncoreBootstrap } from "syncorejs/expo";
|
|
75
|
+
* import schema from "../syncore/schema";
|
|
76
|
+
* import { functions } from "../syncore/_generated/functions";
|
|
77
|
+
*
|
|
78
|
+
* export const syncoreBootstrap = createExpoSyncoreBootstrap({
|
|
79
|
+
* schema,
|
|
80
|
+
* functions,
|
|
81
|
+
* });
|
|
82
|
+
*
|
|
83
|
+
* // Later in SyncoreProvider:
|
|
84
|
+
* const client = await syncoreBootstrap.getClient();
|
|
85
|
+
* ```
|
|
41
86
|
*/
|
|
42
87
|
function createExpoSyncoreBootstrap(options) {
|
|
43
88
|
let runtime = null;
|
|
44
89
|
let started = null;
|
|
45
|
-
const ensureRuntime = () => {
|
|
46
|
-
runtime ??= createExpoSyncoreRuntime(options);
|
|
90
|
+
const ensureRuntime = async () => {
|
|
91
|
+
runtime ??= isWebEnvironment() ? await createExpoWebSyncoreRuntime(options) : createExpoSyncoreRuntime(options);
|
|
47
92
|
return runtime;
|
|
48
93
|
};
|
|
49
94
|
return {
|
|
@@ -51,10 +96,7 @@ function createExpoSyncoreBootstrap(options) {
|
|
|
51
96
|
throw new Error("createExpoSyncoreBootstrap().getRuntime() is not available synchronously. Use getClient() instead.");
|
|
52
97
|
},
|
|
53
98
|
async getClient() {
|
|
54
|
-
if (!started)
|
|
55
|
-
const activeRuntime = ensureRuntime();
|
|
56
|
-
started = activeRuntime.start().then(() => activeRuntime.createClient());
|
|
57
|
-
}
|
|
99
|
+
if (!started) started = ensureRuntime().then((activeRuntime) => activeRuntime.start().then(() => activeRuntime.createClient()));
|
|
58
100
|
return started;
|
|
59
101
|
},
|
|
60
102
|
async stop() {
|
|
@@ -74,6 +116,7 @@ function createExpoSyncoreBootstrap(options) {
|
|
|
74
116
|
* Syncore SQL driver implementation backed by `expo-sqlite`.
|
|
75
117
|
*/
|
|
76
118
|
var ExpoSqliteDriver = class {
|
|
119
|
+
database;
|
|
77
120
|
transactionDepth = 0;
|
|
78
121
|
closed = false;
|
|
79
122
|
databaseName;
|
|
@@ -151,6 +194,7 @@ var ExpoSqliteDriver = class {
|
|
|
151
194
|
}
|
|
152
195
|
};
|
|
153
196
|
var ExpoWebExternalChangeApplier = class {
|
|
197
|
+
driver;
|
|
154
198
|
constructor(driver) {
|
|
155
199
|
this.driver = driver;
|
|
156
200
|
}
|
|
@@ -223,6 +267,28 @@ function normalizeBinary(data) {
|
|
|
223
267
|
if (data instanceof Uint8Array) return data;
|
|
224
268
|
return new Uint8Array(data);
|
|
225
269
|
}
|
|
270
|
+
async function createExpoWebSyncoreRuntime(options) {
|
|
271
|
+
const wasmUrl = options.wasmUrl ?? (options.locateFile ? void 0 : await resolveDefaultExpoWebSqlJsWasmUrl());
|
|
272
|
+
return createWebSyncoreRuntime({
|
|
273
|
+
schema: options.schema,
|
|
274
|
+
functions: options.functions,
|
|
275
|
+
...options.components ? { components: options.components } : {},
|
|
276
|
+
...options.capabilities ? { capabilities: options.capabilities } : {},
|
|
277
|
+
databaseName: options.databaseName ?? "syncore.db",
|
|
278
|
+
storageNamespace: options.storageDirectoryName ?? "syncore-storage",
|
|
279
|
+
...wasmUrl ? { wasmUrl } : {},
|
|
280
|
+
...options.locateFile ? { locateFile: options.locateFile } : {},
|
|
281
|
+
platform: options.platform ?? "expo-web",
|
|
282
|
+
...options.devtools !== void 0 ? { devtools: options.devtools } : {},
|
|
283
|
+
...options.scheduler ? { scheduler: options.scheduler } : {}
|
|
284
|
+
});
|
|
285
|
+
}
|
|
286
|
+
async function resolveDefaultExpoWebSqlJsWasmUrl() {
|
|
287
|
+
return (await import("./web-sqljs-wasm.js")).resolveDefaultExpoWebSqlJsWasmUrl();
|
|
288
|
+
}
|
|
289
|
+
function isWebEnvironment() {
|
|
290
|
+
return typeof window !== "undefined" && typeof document !== "undefined";
|
|
291
|
+
}
|
|
226
292
|
//#endregion
|
|
227
293
|
export { ExpoFileStorageAdapter, ExpoSqliteDriver, createExpoSyncoreBootstrap, createExpoSyncoreClient, createExpoSyncoreRuntime };
|
|
228
294
|
|
|
@@ -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 {@link SyncoreRuntime}. Call `await runtime.start()`\n * before using the client:\n *\n * ```ts\n * import { createExpoSyncoreRuntime } from \"syncorejs/expo\";\n * import schema from \"./syncore/schema\";\n * import { functions } from \"./syncore/_generated/functions\";\n *\n * const runtime = createExpoSyncoreRuntime({ schema, functions });\n * await runtime.start();\n * const client = runtime.createClient();\n * ```\n *\n * For managed lifecycle in React components, prefer\n * {@link createExpoSyncoreBootstrap} instead.\n */\nexport function createExpoSyncoreRuntime<\n TSchema extends ExpoSyncoreSchema\n>(\n options: CreateExpoRuntimeOptions<TSchema>\n): SyncoreRuntime<TSchema> {\n const databaseDirectory =\n options.databaseDirectory ??\n (typeof defaultDatabaseDirectory === \"string\"\n ? defaultDatabaseDirectory\n : undefined);\n const driver =\n options.driver ??\n new ExpoSqliteDriver(\n openDatabaseSync(\n options.databaseName ?? \"syncore.db\",\n undefined,\n databaseDirectory\n ),\n {\n databaseName: options.databaseName ?? \"syncore.db\",\n ...(databaseDirectory ? { databaseDirectory } : {})\n }\n );\n const storage =\n options.storage ??\n new ExpoFileStorageAdapter(\n options.storageDirectoryName ?? \"syncore-storage\"\n );\n const isWebEnvironment =\n typeof window !== \"undefined\" && typeof document !== \"undefined\";\n const webExternalChangeSignal =\n isWebEnvironment && !options.externalChangeSignal\n ? new BroadcastChannelExternalChangeSignal({\n channelName: createDefaultSyncChannelName(\n options.databaseName ?? \"syncore.db\"\n )\n })\n : undefined;\n const webExternalChangeApplier =\n isWebEnvironment &&\n !options.externalChangeApplier &&\n driver instanceof ExpoSqliteDriver\n ? new ExpoWebExternalChangeApplier(driver)\n : undefined;\n\n return new SyncoreRuntime({\n schema: options.schema,\n functions: options.functions,\n ...(options.components ? { components: options.components } : {}),\n driver,\n storage,\n ...(isWebEnvironment && options.externalChangeSignal\n ? { externalChangeSignal: options.externalChangeSignal }\n : isWebEnvironment && webExternalChangeSignal\n ? { externalChangeSignal: webExternalChangeSignal }\n : {}),\n ...(isWebEnvironment && options.externalChangeApplier\n ? { externalChangeApplier: options.externalChangeApplier }\n : isWebEnvironment && webExternalChangeApplier\n ? { externalChangeApplier: webExternalChangeApplier }\n : {}),\n platform: options.platform ?? \"expo\",\n ...(options.capabilities ? { capabilities: options.capabilities } : {}),\n ...(options.devtools ? { devtools: options.devtools } : {}),\n ...(options.scheduler ? { scheduler: options.scheduler } : {})\n });\n}\n\n/**\n * Create a same-process Syncore client directly from a started Expo runtime.\n *\n * Prefer this in scripts or non-component code. For React component trees,\n * use {@link createExpoSyncoreBootstrap} instead to get automatic lifecycle\n * management.\n *\n * ```ts\n * const client = createExpoSyncoreClient(runtime);\n * await client.mutation(api.todos.create, { text: \"Buy milk\" });\n * ```\n */\nexport function createExpoSyncoreClient<\n TSchema extends ExpoSyncoreSchema\n>(runtime: SyncoreRuntime<TSchema>) {\n return runtime.createClient();\n}\n\n/**\n * Create a reusable Expo bootstrap that lazily starts the local runtime the\n * first time a client is requested.\n *\n * The bootstrap keeps a single runtime instance alive across component\n * remounts and safely handles concurrent `getClient()` calls.\n *\n * ```ts\n * // app/_layout.tsx\n * import { createExpoSyncoreBootstrap } from \"syncorejs/expo\";\n * import schema from \"../syncore/schema\";\n * import { functions } from \"../syncore/_generated/functions\";\n *\n * export const syncoreBootstrap = createExpoSyncoreBootstrap({\n * schema,\n * functions,\n * });\n *\n * // Later in SyncoreProvider:\n * const client = await syncoreBootstrap.getClient();\n * ```\n */\nexport function createExpoSyncoreBootstrap<\n TSchema extends ExpoSyncoreSchema\n>(\n options: CreateExpoRuntimeOptions<TSchema>\n): ExpoSyncoreBootstrap<TSchema> {\n let runtime: SyncoreRuntime<TSchema> | null = null;\n let started: Promise<\n ReturnType<SyncoreRuntime<TSchema>[\"createClient\"]>\n > | null = null;\n\n const ensureRuntime = async () => {\n runtime ??= isWebEnvironment()\n ? await createExpoWebSyncoreRuntime(options)\n : createExpoSyncoreRuntime(options);\n return runtime;\n };\n\n return {\n getRuntime() {\n throw new Error(\n \"createExpoSyncoreBootstrap().getRuntime() is not available synchronously. Use getClient() instead.\"\n );\n },\n async getClient() {\n if (!started) {\n started = ensureRuntime().then((activeRuntime) =>\n activeRuntime.start().then(() => activeRuntime.createClient())\n );\n }\n return started;\n },\n async stop() {\n if (!runtime) {\n return;\n }\n await runtime.stop();\n runtime = null;\n started = null;\n },\n async reset() {\n if (runtime) {\n await runtime.stop();\n }\n runtime = null;\n started = null;\n }\n };\n}\n\n/**\n * Syncore SQL driver implementation backed by `expo-sqlite`.\n */\nexport class ExpoSqliteDriver implements SyncoreSqlDriver {\n private transactionDepth = 0;\n private closed = false;\n private readonly databaseName: string;\n private readonly databaseDirectory: string | undefined;\n\n constructor(\n private database: SQLiteDatabase,\n options?: {\n databaseName?: string;\n databaseDirectory?: string;\n }\n ) {\n this.databaseName = options?.databaseName ?? \"syncore.db\";\n this.databaseDirectory = options?.databaseDirectory;\n }\n\n async exec(sql: string): Promise<void> {\n this.ensureOpen();\n await this.database.execAsync(sql);\n }\n\n async run(\n sql: string,\n params: unknown[] = []\n ): Promise<{ changes: number; lastInsertRowid?: number | string }> {\n this.ensureOpen();\n const result = await this.database.runAsync(sql, normalizeParams(params));\n return {\n changes: result.changes,\n lastInsertRowid: result.lastInsertRowId\n };\n }\n\n async get<T>(sql: string, params: unknown[] = []): Promise<T | undefined> {\n this.ensureOpen();\n const row = await this.database.getFirstAsync<T>(\n sql,\n normalizeParams(params)\n );\n return row ?? undefined;\n }\n\n async all<T>(sql: string, params: unknown[] = []): Promise<T[]> {\n this.ensureOpen();\n return this.database.getAllAsync<T>(sql, normalizeParams(params));\n }\n\n async withTransaction<T>(callback: () => Promise<T>): Promise<T> {\n this.ensureOpen();\n if (this.transactionDepth > 0) {\n return this.withSavepoint(`nested_${this.transactionDepth}`, callback);\n }\n\n this.transactionDepth += 1;\n await this.database.execAsync(\"BEGIN IMMEDIATE\");\n try {\n const result = await callback();\n await this.database.execAsync(\"COMMIT\");\n return result;\n } catch (error) {\n await this.database.execAsync(\"ROLLBACK\");\n throw error;\n } finally {\n this.transactionDepth -= 1;\n }\n }\n\n async withSavepoint<T>(name: string, callback: () => Promise<T>): Promise<T> {\n this.ensureOpen();\n const safeName = name.replaceAll(/[^a-zA-Z0-9_]/g, \"_\");\n this.transactionDepth += 1;\n await this.database.execAsync(`SAVEPOINT ${safeName}`);\n try {\n const result = await callback();\n await this.database.execAsync(`RELEASE SAVEPOINT ${safeName}`);\n return result;\n } catch (error) {\n await this.database.execAsync(`ROLLBACK TO SAVEPOINT ${safeName}`);\n await this.database.execAsync(`RELEASE SAVEPOINT ${safeName}`);\n throw error;\n } finally {\n this.transactionDepth -= 1;\n }\n }\n\n async close(): Promise<void> {\n if (this.closed) {\n return;\n }\n await this.database.closeAsync();\n this.closed = true;\n }\n\n private ensureOpen(): void {\n if (this.closed) {\n throw new Error(\"The Expo SQLite driver is already closed.\");\n }\n }\n\n async reopen(): Promise<void> {\n this.ensureOpen();\n await this.database.closeAsync();\n this.database = openDatabaseSync(\n this.databaseName,\n undefined,\n this.databaseDirectory\n );\n }\n}\n\nclass ExpoWebExternalChangeApplier implements SyncoreExternalChangeApplier {\n constructor(private readonly driver: ExpoSqliteDriver) {}\n\n async applyExternalChange(event: {\n scope: \"database\" | \"storage\" | \"all\";\n changedScopes?: ImpactScope[];\n changedTables?: string[];\n storageIds?: string[];\n }) {\n if (event.scope === \"database\" || event.scope === \"all\") {\n await this.driver.reopen();\n }\n return {\n databaseChanged: event.scope === \"database\" || event.scope === \"all\",\n storageChanged: event.scope === \"storage\" || event.scope === \"all\",\n changedScopes:\n event.changedScopes ??\n ([\n ...(event.changedTables ?? []).map((tableName) => `table:${tableName}`),\n ...(event.storageIds ?? []).map((storageId) => `storage:${storageId}`)\n ] as ImpactScope[])\n };\n }\n}\n\n/**\n * Syncore file/blob storage backed by the Expo file system.\n */\nexport class ExpoFileStorageAdapter implements SyncoreStorageAdapter {\n private readonly rootDirectory: Directory;\n\n constructor(storageDirectoryName: string) {\n this.rootDirectory = new Directory(Paths.document, storageDirectoryName);\n if (!this.rootDirectory.exists) {\n this.rootDirectory.create({ idempotent: true, intermediates: true });\n }\n }\n\n async put(id: string, input: StorageWriteInput): Promise<StorageObject> {\n const file = new File(this.rootDirectory, id);\n if (!file.exists) {\n file.create({ intermediates: true, overwrite: true });\n }\n const bytes = normalizeBinary(input.data);\n file.write(bytes);\n return {\n id,\n path: file.uri,\n size: bytes.byteLength,\n contentType: input.contentType ?? null\n };\n }\n\n async get(id: string): Promise<StorageObject | null> {\n const file = new File(this.rootDirectory, id);\n if (!file.exists) {\n return null;\n }\n return {\n id,\n path: file.uri,\n size: file.size,\n contentType: file.type || null\n };\n }\n\n async read(id: string): Promise<Uint8Array | null> {\n const file = new File(this.rootDirectory, id);\n if (!file.exists) {\n return null;\n }\n return file.bytes();\n }\n\n async delete(id: string): Promise<void> {\n const file = new File(this.rootDirectory, id);\n if (file.exists) {\n file.delete();\n }\n }\n}\n\nfunction normalizeParams(\n values: unknown[]\n): Array<string | number | Uint8Array | null> {\n return values.map((value) => {\n if (typeof value === \"boolean\") {\n return value ? 1 : 0;\n }\n if (\n value === null ||\n typeof value === \"string\" ||\n typeof value === \"number\" ||\n value instanceof Uint8Array\n ) {\n return value;\n }\n if (value instanceof ArrayBuffer) {\n return new Uint8Array(value);\n }\n return JSON.stringify(value);\n });\n}\n\nfunction normalizeBinary(data: StorageWriteInput[\"data\"]): Uint8Array {\n if (typeof data === \"string\") {\n return new TextEncoder().encode(data);\n }\n if (data instanceof Uint8Array) {\n return data;\n }\n return new Uint8Array(data);\n}\n\nasync function createExpoWebSyncoreRuntime<TSchema extends ExpoSyncoreSchema>(\n options: CreateExpoRuntimeOptions<TSchema>\n): Promise<SyncoreRuntime<TSchema>> {\n const wasmUrl =\n options.wasmUrl ??\n (options.locateFile\n ? undefined\n : await resolveDefaultExpoWebSqlJsWasmUrl());\n\n return createWebSyncoreRuntime({\n schema: options.schema,\n functions: options.functions,\n ...(options.components ? { components: options.components } : {}),\n ...(options.capabilities ? { capabilities: options.capabilities } : {}),\n databaseName: options.databaseName ?? \"syncore.db\",\n storageNamespace: options.storageDirectoryName ?? \"syncore-storage\",\n ...(wasmUrl ? { wasmUrl } : {}),\n ...(options.locateFile ? { locateFile: options.locateFile } : {}),\n platform: options.platform ?? \"expo-web\",\n ...(options.devtools !== undefined ? { devtools: options.devtools } : {}),\n ...(options.scheduler ? { scheduler: options.scheduler } : {})\n });\n}\n\nasync function resolveDefaultExpoWebSqlJsWasmUrl(): Promise<\n string | undefined\n> {\n const module = await import(\"./web-sqljs-wasm.js\");\n return module.resolveDefaultExpoWebSqlJsWasmUrl();\n}\n\nfunction isWebEnvironment(): boolean {\n return typeof window !== \"undefined\" && typeof document !== \"undefined\";\n}\n"],"mappings":"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"}
|
|
@@ -1 +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"}
|
|
@@ -1,14 +1,27 @@
|
|
|
1
1
|
import { AttachNodeIpcRuntimeOptions, AttachedNodeIpcRuntime, NodeIpcSyncoreSchema, RendererQueryWatch, SyncoreIpcMessageEndpoint, SyncoreMainProcessBridge, SyncoreRendererBridge, SyncoreRendererClient, SyncoreWindowBridge, attachNodeIpcRuntime, createNodeIpcMessageEndpoint, createRendererSyncoreBridgeClient, createRendererSyncoreClient, createRendererSyncoreWindowClient, installSyncoreWindowBridge } from "./ipc.mjs";
|
|
2
|
-
import { SyncoreActiveQueryInfo, SyncoreDevtoolsEvent, SyncoreRuntimeSummary } from "../devtools-protocol/index.d.ts";
|
|
3
|
-
import
|
|
4
|
-
import { DevtoolsCommandHandler, DevtoolsSink, DevtoolsSubscriptionHost, SchedulerOptions, StorageObject, StorageWriteInput, SyncoreCapabilities, SyncoreDataModel, SyncoreRuntime, SyncoreRuntimeOptions, SyncoreSqlDriver, SyncoreStorageAdapter } from "../core/index.d.mts";
|
|
2
|
+
import { SyncoreActiveQueryInfo, SyncoreDevtoolsCapabilities, SyncoreDevtoolsEvent, SyncoreRuntimeSummary } from "../devtools-protocol/index.d.ts";
|
|
3
|
+
import { DevtoolsCommandHandler, DevtoolsSink, DevtoolsSubscriptionHost, SchedulerOptions, StorageObject, StorageWriteInput, SyncoreCapabilities, SyncoreDataModel, SyncoreExternalChangeSignal, SyncoreRuntime, SyncoreRuntimeOptions, SyncoreSqlDriver, SyncoreStorageAdapter } from "../core/index.d.mts";
|
|
5
4
|
|
|
6
5
|
//#region src/index.d.ts
|
|
7
6
|
type NodeSyncoreSchema<TSchema extends SyncoreDataModel = SyncoreDataModel> = TSchema;
|
|
7
|
+
/**
|
|
8
|
+
* SQLite driver backed by Node.js’s built-in `node:sqlite` module (Node 22+).
|
|
9
|
+
*
|
|
10
|
+
* Opens the database at `databasePath` with `WAL` journal mode and foreign-key
|
|
11
|
+
* enforcement enabled. The file is created if it does not exist.
|
|
12
|
+
*
|
|
13
|
+
* ```ts
|
|
14
|
+
* const driver = new NodeSqliteDriver("./data/app.db");
|
|
15
|
+
* ```
|
|
16
|
+
*
|
|
17
|
+
* In most cases you should use {@link createNodeSyncoreRuntime} which
|
|
18
|
+
* instantiates this driver automatically from your `databasePath` option.
|
|
19
|
+
*/
|
|
8
20
|
declare class NodeSqliteDriver implements SyncoreSqlDriver {
|
|
21
|
+
readonly databasePath: string;
|
|
9
22
|
private readonly database;
|
|
10
23
|
private transactionDepth;
|
|
11
|
-
constructor(
|
|
24
|
+
constructor(databasePath: string);
|
|
12
25
|
exec(sql: string): Promise<void>;
|
|
13
26
|
run(sql: string, params?: unknown[]): Promise<{
|
|
14
27
|
changes: number;
|
|
@@ -20,6 +33,19 @@ declare class NodeSqliteDriver implements SyncoreSqlDriver {
|
|
|
20
33
|
withSavepoint<T>(name: string, callback: () => Promise<T>): Promise<T>;
|
|
21
34
|
close(): Promise<void>;
|
|
22
35
|
}
|
|
36
|
+
/**
|
|
37
|
+
* Blob storage adapter that reads and writes files in a local directory.
|
|
38
|
+
*
|
|
39
|
+
* Each stored object is saved as a flat file named by its ID inside
|
|
40
|
+
* `directory`. The directory is created automatically on first write.
|
|
41
|
+
*
|
|
42
|
+
* ```ts
|
|
43
|
+
* const storage = new NodeFileStorageAdapter("./data/storage");
|
|
44
|
+
* ```
|
|
45
|
+
*
|
|
46
|
+
* In most cases you should use {@link createNodeSyncoreRuntime} which
|
|
47
|
+
* instantiates this adapter automatically from your `storageDirectory` option.
|
|
48
|
+
*/
|
|
23
49
|
declare class NodeFileStorageAdapter implements SyncoreStorageAdapter {
|
|
24
50
|
private readonly directory;
|
|
25
51
|
constructor(directory: string);
|
|
@@ -30,50 +56,153 @@ declare class NodeFileStorageAdapter implements SyncoreStorageAdapter {
|
|
|
30
56
|
delete(id: string): Promise<void>;
|
|
31
57
|
list(): Promise<StorageObject[]>;
|
|
32
58
|
}
|
|
59
|
+
/**
|
|
60
|
+
* Options for {@link createNodeSyncoreRuntime}.
|
|
61
|
+
*
|
|
62
|
+
* At minimum supply `databasePath`, `storageDirectory`, `schema`, and
|
|
63
|
+
* `functions`. Everything else has sensible defaults (auto-devtools connect in
|
|
64
|
+
* development, Node SQLite driver, local file storage).
|
|
65
|
+
*
|
|
66
|
+
* ```ts
|
|
67
|
+
* createNodeSyncoreRuntime({
|
|
68
|
+
* databasePath: path.join(dataDir, "app.db"),
|
|
69
|
+
* storageDirectory: path.join(dataDir, "storage"),
|
|
70
|
+
* schema,
|
|
71
|
+
* functions,
|
|
72
|
+
* });
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
33
75
|
interface CreateNodeRuntimeOptions<TSchema extends NodeSyncoreSchema = NodeSyncoreSchema> {
|
|
76
|
+
/**
|
|
77
|
+
* Absolute or relative path to the SQLite database file.
|
|
78
|
+
*
|
|
79
|
+
* The file is created if it does not exist. Use an absolute path in
|
|
80
|
+
* production to avoid ambiguity about the current working directory.
|
|
81
|
+
*/
|
|
34
82
|
databasePath: string;
|
|
83
|
+
/**
|
|
84
|
+
* Directory where blob storage objects (images, files, etc.) are persisted.
|
|
85
|
+
*
|
|
86
|
+
* The directory is created automatically if it does not exist.
|
|
87
|
+
*/
|
|
35
88
|
storageDirectory: string;
|
|
89
|
+
/** The data model that defines the available tables and indexes. */
|
|
36
90
|
schema: TSchema;
|
|
91
|
+
/**
|
|
92
|
+
* The registered function map. Use the `functions` export from
|
|
93
|
+
* `syncore/_generated/functions.ts`.
|
|
94
|
+
*/
|
|
37
95
|
functions: SyncoreRuntimeOptions<TSchema>["functions"];
|
|
96
|
+
/**
|
|
97
|
+
* Resolved Syncore component instances. Only required when your app
|
|
98
|
+
* installs Syncore component packages.
|
|
99
|
+
*/
|
|
38
100
|
components?: SyncoreRuntimeOptions<TSchema>["components"];
|
|
101
|
+
/**
|
|
102
|
+
* Platform capabilities injected into `ctx.capabilities` inside function
|
|
103
|
+
* handlers.
|
|
104
|
+
*/
|
|
39
105
|
capabilities?: SyncoreCapabilities;
|
|
106
|
+
/** Human-readable app name shown in the devtools dashboard. */
|
|
40
107
|
appName?: string;
|
|
108
|
+
/** Origin label (e.g. process name) shown in devtools. */
|
|
41
109
|
origin?: string;
|
|
110
|
+
/** Devtools session label. Auto-generated when omitted. */
|
|
42
111
|
sessionLabel?: string;
|
|
112
|
+
/**
|
|
113
|
+
* Platform label reported to devtools. Defaults to `"node"`, or
|
|
114
|
+
* `"electron-main"` when the runtime is used inside Electron's main process.
|
|
115
|
+
*/
|
|
43
116
|
platform?: string;
|
|
117
|
+
/**
|
|
118
|
+
* Devtools event sink. Pass `false` to disable devtools entirely (recommended
|
|
119
|
+
* for production). Omit to auto-connect to the local devtools server when
|
|
120
|
+
* running in development.
|
|
121
|
+
*/
|
|
44
122
|
devtools?: DevtoolsSink | false;
|
|
123
|
+
/**
|
|
124
|
+
* Explicit devtools WebSocket server URL. Defaults to
|
|
125
|
+
* `ws://localhost:3099` (the Syncore devtools default port).
|
|
126
|
+
*/
|
|
45
127
|
devtoolsUrl?: string;
|
|
128
|
+
/** Scheduler configuration for background and recurring jobs. */
|
|
46
129
|
scheduler?: SchedulerOptions;
|
|
47
130
|
}
|
|
48
131
|
/**
|
|
49
|
-
*
|
|
132
|
+
* Alias of {@link CreateNodeRuntimeOptions} exposed for the managed-client
|
|
133
|
+
* helper.
|
|
134
|
+
* @see CreateNodeRuntimeOptions
|
|
50
135
|
*/
|
|
51
136
|
type WithNodeSyncoreClientOptions<TSchema extends NodeSyncoreSchema = NodeSyncoreSchema> = CreateNodeRuntimeOptions<TSchema>;
|
|
52
137
|
/**
|
|
53
138
|
* A started local Node runtime paired with its client and a dispose helper.
|
|
139
|
+
*
|
|
140
|
+
* Returned by `withNodeSyncoreClient()`. Call `dispose()` when you are
|
|
141
|
+
* finished (e.g. in tests or short-lived scripts) to stop the runtime and
|
|
142
|
+
* close the database.
|
|
54
143
|
*/
|
|
55
144
|
interface ManagedNodeSyncoreClient<TSchema extends NodeSyncoreSchema = NodeSyncoreSchema> {
|
|
145
|
+
/** The underlying runtime instance. */
|
|
56
146
|
runtime: SyncoreRuntime<TSchema>;
|
|
147
|
+
/** A ready-to-use client for calling Syncore functions. */
|
|
57
148
|
client: ReturnType<SyncoreRuntime<TSchema>["createClient"]>;
|
|
149
|
+
/** Stop the runtime, flush pending jobs, and close the database. */
|
|
58
150
|
dispose(): Promise<void>;
|
|
59
151
|
}
|
|
152
|
+
/**
|
|
153
|
+
* Opaque handle returned by Syncore’s Electron IPC bridge setup.
|
|
154
|
+
*
|
|
155
|
+
* - `ready`: resolves when the bridge is connected and the renderer is ready to
|
|
156
|
+
* receive messages.
|
|
157
|
+
* - `dispose()`: tears down the bridge and removes IPC listeners.
|
|
158
|
+
*/
|
|
60
159
|
interface SyncoreElectronIpcBinding {
|
|
61
160
|
ready: Promise<void>;
|
|
62
161
|
dispose(): Promise<void>;
|
|
63
162
|
}
|
|
163
|
+
/**
|
|
164
|
+
* Minimal interface that Syncore requires from an Electron `BrowserWindow`
|
|
165
|
+
* instance.
|
|
166
|
+
*
|
|
167
|
+
* Scoped to avoid importing Electron at the type level.
|
|
168
|
+
*/
|
|
64
169
|
interface SyncoreElectronBridgeWindow {
|
|
65
170
|
isDestroyed(): boolean;
|
|
66
171
|
webContents: {
|
|
67
172
|
send(channel: string, message: unknown): void;
|
|
68
173
|
};
|
|
69
174
|
}
|
|
175
|
+
/**
|
|
176
|
+
* Options for setting up Syncore’s Electron main-process IPC bridge.
|
|
177
|
+
*
|
|
178
|
+
* The bridge forwards database change events from the main-process runtime to
|
|
179
|
+
* the renderer window over a named IPC channel.
|
|
180
|
+
*
|
|
181
|
+
* ```ts
|
|
182
|
+
* createElectronSyncoreBridge(runtime, {
|
|
183
|
+
* window: mainWindow,
|
|
184
|
+
* onRendererMessage: (listener) => {
|
|
185
|
+
* ipcMain.on("syncore", (_e, msg) => listener(msg));
|
|
186
|
+
* return () => ipcMain.removeAllListeners("syncore");
|
|
187
|
+
* },
|
|
188
|
+
* });
|
|
189
|
+
* ```
|
|
190
|
+
*/
|
|
70
191
|
interface CreateElectronSyncoreBridgeOptions {
|
|
192
|
+
/** The renderer window that will receive push messages. */
|
|
71
193
|
window: SyncoreElectronBridgeWindow;
|
|
194
|
+
/**
|
|
195
|
+
* Register a listener for messages sent from the renderer. Must return an
|
|
196
|
+
* unsubscribe function.
|
|
197
|
+
*/
|
|
72
198
|
onRendererMessage(listener: (message: unknown) => void): () => void;
|
|
199
|
+
/** IPC channel name. Defaults to `"syncore"`. */
|
|
73
200
|
channel?: string;
|
|
74
201
|
}
|
|
75
202
|
/**
|
|
76
|
-
* The subset of Electron
|
|
203
|
+
* The subset of Electron’s `ipcMain` used by Syncore’s main-process helper.
|
|
204
|
+
*
|
|
205
|
+
* Using this narrowed interface avoids a hard runtime dependency on Electron.
|
|
77
206
|
*/
|
|
78
207
|
interface SyncoreElectronIpcMain {
|
|
79
208
|
on(channel: string, listener: (event: {
|
|
@@ -83,17 +212,48 @@ interface SyncoreElectronIpcMain {
|
|
|
83
212
|
sender: unknown;
|
|
84
213
|
}, message: unknown) => void): void;
|
|
85
214
|
}
|
|
215
|
+
/**
|
|
216
|
+
* Options for creating a client inside an Electron renderer process via the
|
|
217
|
+
* preload IPC bridge.
|
|
218
|
+
*/
|
|
86
219
|
interface CreateSyncoreRendererWindowClientOptions {
|
|
220
|
+
/** Name of the bridge registered in the preload script. Defaults to `"syncore"`. */
|
|
87
221
|
bridgeName?: string;
|
|
88
222
|
}
|
|
89
223
|
/**
|
|
90
|
-
* Create a Node or Electron
|
|
224
|
+
* Create a Syncore runtime for Node.js (or Electron’s main process) backed by
|
|
225
|
+
* the built-in `node:sqlite` driver and local file storage.
|
|
226
|
+
*
|
|
227
|
+
* This is the recommended entry point for Node and Electron apps. It wires up
|
|
228
|
+
* the SQL driver, storage adapter, devtools WebSocket connection, and
|
|
229
|
+
* cross-process change signals automatically.
|
|
230
|
+
*
|
|
231
|
+
* ```ts
|
|
232
|
+
* import path from "node:path";
|
|
233
|
+
* import { createNodeSyncoreRuntime } from "syncorejs/node";
|
|
234
|
+
* import schema from "./syncore/schema";
|
|
235
|
+
* import { functions } from "./syncore/_generated/functions";
|
|
236
|
+
*
|
|
237
|
+
* const runtime = createNodeSyncoreRuntime({
|
|
238
|
+
* databasePath: path.join(app.getPath("userData"), "db.sqlite"),
|
|
239
|
+
* storageDirectory: path.join(app.getPath("userData"), "storage"),
|
|
240
|
+
* schema,
|
|
241
|
+
* functions,
|
|
242
|
+
* });
|
|
243
|
+
*
|
|
244
|
+
* await runtime.start();
|
|
245
|
+
* const client = runtime.createClient();
|
|
246
|
+
* ```
|
|
247
|
+
*
|
|
248
|
+
* @param options - Configuration object. See {@link CreateNodeRuntimeOptions}.
|
|
249
|
+
* @returns A configured (but not yet started) {@link SyncoreRuntime}. Call
|
|
250
|
+
* `await runtime.start()` before using the client.
|
|
91
251
|
*/
|
|
92
252
|
declare function createNodeSyncoreRuntime<TSchema extends NodeSyncoreSchema>(options: CreateNodeRuntimeOptions<TSchema>): SyncoreRuntime<TSchema>;
|
|
93
253
|
/**
|
|
94
254
|
* Create a same-process Syncore client from a started Node runtime.
|
|
95
255
|
*/
|
|
96
|
-
declare function createNodeSyncoreClient<TSchema extends NodeSyncoreSchema>(runtime: SyncoreRuntime<TSchema>):
|
|
256
|
+
declare function createNodeSyncoreClient<TSchema extends NodeSyncoreSchema>(runtime: SyncoreRuntime<TSchema>): import("../core/index.d.mts").SyncoreClient;
|
|
97
257
|
/**
|
|
98
258
|
* Start a Node Syncore runtime and return its client together with a dispose helper.
|
|
99
259
|
*/
|
|
@@ -113,7 +273,7 @@ declare function withNodeSyncoreClient<TSchema extends NodeSyncoreSchema, TResul
|
|
|
113
273
|
* Create the default Electron main-process bridge used to connect a BrowserWindow
|
|
114
274
|
* to a Syncore runtime.
|
|
115
275
|
*/
|
|
116
|
-
declare function createElectronSyncoreBridge(options: CreateElectronSyncoreBridgeOptions):
|
|
276
|
+
declare function createElectronSyncoreBridge(options: CreateElectronSyncoreBridgeOptions): import("../core/index.d.mts").SyncoreBridgeMessageEndpoint & {
|
|
117
277
|
dispose(): void;
|
|
118
278
|
};
|
|
119
279
|
/**
|
|
@@ -138,14 +298,18 @@ interface NodeWebSocketDevtoolsSinkOptions {
|
|
|
138
298
|
origin?: string;
|
|
139
299
|
sessionLabel?: string;
|
|
140
300
|
targetKind?: "client" | "project";
|
|
301
|
+
runtimeRole?: "app" | "project-target";
|
|
141
302
|
storageProtocol?: string;
|
|
142
303
|
databaseLabel?: string;
|
|
304
|
+
dataSourceAlias?: string;
|
|
143
305
|
storageIdentity?: string;
|
|
306
|
+
capabilities?: SyncoreDevtoolsCapabilities;
|
|
144
307
|
}
|
|
145
308
|
interface NodeWebSocketDevtoolsSink extends DevtoolsSink {
|
|
146
309
|
attachRuntime(runtime: SyncoreRuntime<NodeSyncoreSchema>): void;
|
|
147
310
|
attachCommandHandler(handler: DevtoolsCommandHandler): void;
|
|
148
311
|
attachSubscriptionHost(host: DevtoolsSubscriptionHost): void;
|
|
312
|
+
externalChangeSignal?: SyncoreExternalChangeSignal;
|
|
149
313
|
dispose(): void;
|
|
150
314
|
}
|
|
151
315
|
declare function createNodeWebSocketDevtoolsSink(options: NodeWebSocketDevtoolsSinkOptions): NodeWebSocketDevtoolsSink;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":"
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../src/index.ts"],"mappings":"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"}
|