@absolutejs/sync-capacitor 0.3.0 → 0.5.0
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/README.md +38 -0
- package/dist/index.d.ts +4 -2
- package/dist/index.js +88 -2
- package/dist/index.js.map +3 -3
- package/package.json +3 -3
package/README.md
CHANGED
|
@@ -3,6 +3,8 @@
|
|
|
3
3
|
Native persistence and lifecycle wiring for `@absolutejs/sync` applications
|
|
4
4
|
running in Capacitor. It stores confirmed rows, cursors, installation identity,
|
|
5
5
|
and the durable mutation outbox in one principal-partitioned SQLite database.
|
|
6
|
+
It also exposes namespace-scoped collection discovery so finite native workers
|
|
7
|
+
can resume safe `id`-keyed pulls without application-authored worker code.
|
|
6
8
|
|
|
7
9
|
AbsoluteJS provisions this automatically when Mobile, Sync, and Auth are enabled.
|
|
8
10
|
Direct Capacitor applications can opt in explicitly:
|
|
@@ -42,6 +44,42 @@ issuer, public client ID, and subject. Signing out locks that partition by
|
|
|
42
44
|
removing it from the active runtime; it does not silently destroy offline data.
|
|
43
45
|
Signing back in as the same verified principal unlocks the same partition.
|
|
44
46
|
|
|
47
|
+
## Installed-data upgrades
|
|
48
|
+
|
|
49
|
+
`storageSchema` accepts the same generated `SyncLocalStoreSchema` used by
|
|
50
|
+
`createIndexedDbSyncLocalStore`. Before any foreground transaction begins, the
|
|
51
|
+
adapter migrates every principal's collections, durable mutations, and logical
|
|
52
|
+
schema marker inside one SQLite transaction. A transform failure or process
|
|
53
|
+
death rolls back the entire upgrade; a runtime older than the stored schema
|
|
54
|
+
fails closed.
|
|
55
|
+
|
|
56
|
+
Migration callbacks are synchronous and deterministic. They may replace or
|
|
57
|
+
delete persisted records, but cannot change a mutation's stable operation ID.
|
|
58
|
+
AbsoluteJS will generate and provision the plan for ordinary applications;
|
|
59
|
+
direct Capacitor integrations can pass it explicitly:
|
|
60
|
+
|
|
61
|
+
```ts
|
|
62
|
+
const store = createCapacitorSyncLocalStore({
|
|
63
|
+
storageSchema: {
|
|
64
|
+
version: 2,
|
|
65
|
+
migrations: [
|
|
66
|
+
{
|
|
67
|
+
toVersion: 2,
|
|
68
|
+
migrateCollection(record) {
|
|
69
|
+
return {
|
|
70
|
+
...record,
|
|
71
|
+
rows: record.rows.map((row) => ({
|
|
72
|
+
...(row as object),
|
|
73
|
+
archived: false
|
|
74
|
+
}))
|
|
75
|
+
};
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
]
|
|
79
|
+
}
|
|
80
|
+
});
|
|
81
|
+
```
|
|
82
|
+
|
|
45
83
|
## Managed native background Sync
|
|
46
84
|
|
|
47
85
|
AbsoluteJS also configures `AbsoluteBackgroundSync` when the application uses
|
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { type SQLiteDBConnection } from '@capacitor-community/sqlite';
|
|
2
|
-
import type { SyncLocalStore } from '@absolutejs/sync/client';
|
|
2
|
+
import type { SyncLocalStore, SyncLocalStoreSchema } from '@absolutejs/sync/client';
|
|
3
3
|
import type { DeviceLifecycleCapability, DeviceNetworkCapability, DeviceSubscription } from '@absolutejs/devices';
|
|
4
4
|
import type { SyncClient } from '@absolutejs/sync/client';
|
|
5
5
|
export type CapacitorBackgroundSyncConfig = {
|
|
@@ -37,13 +37,15 @@ export type CapacitorSyncLocalStoreOptions = {
|
|
|
37
37
|
databaseName?: string;
|
|
38
38
|
/** Injection seam for tests and custom SQLCipher provisioning. */
|
|
39
39
|
connection?: CapacitorSyncSqliteFactory;
|
|
40
|
+
/** Same generated logical migration plan used by web IndexedDB. */
|
|
41
|
+
storageSchema?: SyncLocalStoreSchema;
|
|
40
42
|
};
|
|
41
43
|
/**
|
|
42
44
|
* Native SQLite implementation of Sync's principal-partitioned atomic cache
|
|
43
45
|
* and mutation outbox. All calls are serialized because a Capacitor database
|
|
44
46
|
* connection owns one explicit transaction at a time.
|
|
45
47
|
*/
|
|
46
|
-
export declare const createCapacitorSyncLocalStore: ({ databaseName, connection: createConnection }?: CapacitorSyncLocalStoreOptions) => SyncLocalStore;
|
|
48
|
+
export declare const createCapacitorSyncLocalStore: ({ databaseName, connection: createConnection, storageSchema }?: CapacitorSyncLocalStoreOptions) => SyncLocalStore;
|
|
47
49
|
export type CapacitorSyncLifecycleOptions = {
|
|
48
50
|
client: Pick<SyncClient, 'reconnect'> & Partial<Pick<SyncClient, 'flush'>>;
|
|
49
51
|
lifecycle: DeviceLifecycleCapability;
|
package/dist/index.js
CHANGED
|
@@ -3,10 +3,19 @@ import {
|
|
|
3
3
|
CapacitorSQLite,
|
|
4
4
|
SQLiteConnection
|
|
5
5
|
} from "@capacitor-community/sqlite";
|
|
6
|
+
import {
|
|
7
|
+
migrateSyncLocalCollectionRecord,
|
|
8
|
+
migrateSyncLocalMutationRecord,
|
|
9
|
+
resolveSyncLocalMigrations
|
|
10
|
+
} from "@absolutejs/sync/client";
|
|
6
11
|
import { registerPlugin } from "@capacitor/core";
|
|
7
12
|
var AbsoluteBackgroundSync = registerPlugin("AbsoluteBackgroundSync");
|
|
8
13
|
var configureCapacitorBackgroundSync = (options, plugin = AbsoluteBackgroundSync) => plugin.configure(options);
|
|
9
14
|
var SCHEMA = `
|
|
15
|
+
CREATE TABLE IF NOT EXISTS absolute_sync_schema (
|
|
16
|
+
singleton_id INTEGER PRIMARY KEY NOT NULL CHECK (singleton_id = 1),
|
|
17
|
+
logical_version INTEGER NOT NULL
|
|
18
|
+
);
|
|
10
19
|
CREATE TABLE IF NOT EXISTS absolute_sync_metadata (
|
|
11
20
|
namespace TEXT PRIMARY KEY NOT NULL,
|
|
12
21
|
installation_id TEXT NOT NULL
|
|
@@ -57,14 +66,77 @@ var requireNamespace = (namespace) => {
|
|
|
57
66
|
};
|
|
58
67
|
var createCapacitorSyncLocalStore = ({
|
|
59
68
|
databaseName = "absolutejs-sync-local-v1",
|
|
60
|
-
connection: createConnection = () => defaultConnection(databaseName)
|
|
69
|
+
connection: createConnection = () => defaultConnection(databaseName),
|
|
70
|
+
storageSchema = { version: 1 }
|
|
61
71
|
} = {}) => {
|
|
62
72
|
if (databaseName.length === 0)
|
|
63
73
|
throw new TypeError("Capacitor Sync databaseName cannot be empty.");
|
|
74
|
+
let schemaStatus;
|
|
75
|
+
const prepareSchema = async (database) => {
|
|
76
|
+
await database.beginTransaction();
|
|
77
|
+
try {
|
|
78
|
+
const saved = (await database.query("SELECT logical_version FROM absolute_sync_schema WHERE singleton_id = 1 LIMIT 1")).values?.[0]?.logical_version;
|
|
79
|
+
const storedVersion = typeof saved === "number" ? saved : 1;
|
|
80
|
+
const resolved = resolveSyncLocalMigrations(storedVersion, storageSchema);
|
|
81
|
+
if (resolved.steps.length > 0) {
|
|
82
|
+
const collections = (await database.query("SELECT namespace, collection_key, record_json FROM absolute_sync_collections ORDER BY namespace, collection_key")).values;
|
|
83
|
+
for (const row of collections ?? []) {
|
|
84
|
+
const namespace = row.namespace;
|
|
85
|
+
const key = row.collection_key;
|
|
86
|
+
if (typeof namespace !== "string" || typeof key !== "string")
|
|
87
|
+
throw new Error("Capacitor Sync SQLite returned an invalid collection identity.");
|
|
88
|
+
const record = parseRecord(row.record_json, "collection");
|
|
89
|
+
if (record === undefined)
|
|
90
|
+
throw new Error("Capacitor Sync SQLite returned a missing collection record.");
|
|
91
|
+
const migrated = migrateSyncLocalCollectionRecord(record, { key, namespace }, resolved.steps);
|
|
92
|
+
if (migrated === null)
|
|
93
|
+
await database.run("DELETE FROM absolute_sync_collections WHERE namespace = ? AND collection_key = ?", [namespace, key], false);
|
|
94
|
+
else
|
|
95
|
+
await database.run("UPDATE absolute_sync_collections SET record_json = ? WHERE namespace = ? AND collection_key = ?", [JSON.stringify(migrated), namespace, key], false);
|
|
96
|
+
}
|
|
97
|
+
const mutations = (await database.query("SELECT namespace, operation_id, record_json FROM absolute_sync_mutations ORDER BY namespace, operation_id")).values;
|
|
98
|
+
for (const row of mutations ?? []) {
|
|
99
|
+
const namespace = row.namespace;
|
|
100
|
+
const operationId = row.operation_id;
|
|
101
|
+
if (typeof namespace !== "string" || typeof operationId !== "string")
|
|
102
|
+
throw new Error("Capacitor Sync SQLite returned an invalid mutation identity.");
|
|
103
|
+
const record = parseRecord(row.record_json, "mutation");
|
|
104
|
+
if (record === undefined)
|
|
105
|
+
throw new Error("Capacitor Sync SQLite returned a missing mutation record.");
|
|
106
|
+
const migrated = migrateSyncLocalMutationRecord(record, { key: operationId, namespace }, resolved.steps);
|
|
107
|
+
if (migrated === null)
|
|
108
|
+
await database.run("DELETE FROM absolute_sync_mutations WHERE namespace = ? AND operation_id = ?", [namespace, operationId], false);
|
|
109
|
+
else
|
|
110
|
+
await database.run("UPDATE absolute_sync_mutations SET created_at = ?, record_json = ? WHERE namespace = ? AND operation_id = ?", [
|
|
111
|
+
migrated.createdAt,
|
|
112
|
+
JSON.stringify(migrated),
|
|
113
|
+
namespace,
|
|
114
|
+
operationId
|
|
115
|
+
], false);
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
await database.run("INSERT INTO absolute_sync_schema (singleton_id, logical_version) VALUES (1, ?) ON CONFLICT(singleton_id) DO UPDATE SET logical_version = excluded.logical_version", [resolved.targetVersion], false);
|
|
119
|
+
await database.commitTransaction();
|
|
120
|
+
schemaStatus = {
|
|
121
|
+
minimumCompatibleVersion: resolved.minimumCompatibleVersion,
|
|
122
|
+
state: "ready",
|
|
123
|
+
storedVersion: resolved.targetVersion,
|
|
124
|
+
targetVersion: resolved.targetVersion
|
|
125
|
+
};
|
|
126
|
+
} catch (error) {
|
|
127
|
+
try {
|
|
128
|
+
await database.rollbackTransaction();
|
|
129
|
+
} catch (rollbackError) {
|
|
130
|
+
throw new AggregateError([error, rollbackError], "Capacitor Sync SQLite migration and rollback both failed");
|
|
131
|
+
}
|
|
132
|
+
throw error;
|
|
133
|
+
}
|
|
134
|
+
};
|
|
64
135
|
let connectionPromise;
|
|
65
136
|
const connection = () => {
|
|
66
137
|
connectionPromise ??= Promise.resolve(createConnection()).then(async (database) => {
|
|
67
138
|
await database.execute(SCHEMA);
|
|
139
|
+
await prepareSchema(database);
|
|
68
140
|
return database;
|
|
69
141
|
});
|
|
70
142
|
return connectionPromise;
|
|
@@ -101,6 +173,14 @@ var createCapacitorSyncLocalStore = ({
|
|
|
101
173
|
await database.run("INSERT INTO absolute_sync_metadata (namespace, installation_id) VALUES (?, ?) ON CONFLICT(namespace) DO UPDATE SET installation_id = excluded.installation_id", [namespace, installationId], false);
|
|
102
174
|
},
|
|
103
175
|
getCollection: async (key) => parseRecord((await database.query("SELECT record_json FROM absolute_sync_collections WHERE namespace = ? AND collection_key = ? LIMIT 1", [namespace, key])).values?.[0]?.record_json, "collection"),
|
|
176
|
+
listCollections: async () => {
|
|
177
|
+
const rows = (await database.query("SELECT collection_key, record_json FROM absolute_sync_collections WHERE namespace = ? ORDER BY collection_key ASC", [namespace])).values;
|
|
178
|
+
return (rows ?? []).map((row) => {
|
|
179
|
+
const key = row.collection_key;
|
|
180
|
+
const record = parseRecord(row.record_json, "collection");
|
|
181
|
+
return typeof key === "string" && record ? { key, record } : undefined;
|
|
182
|
+
}).filter((entry) => entry !== undefined);
|
|
183
|
+
},
|
|
104
184
|
putCollection: async (key, record) => {
|
|
105
185
|
writable();
|
|
106
186
|
await database.run("INSERT INTO absolute_sync_collections (namespace, collection_key, record_json) VALUES (?, ?, ?) ON CONFLICT(namespace, collection_key) DO UPDATE SET record_json = excluded.record_json", [namespace, key, JSON.stringify(record)], false);
|
|
@@ -144,6 +224,12 @@ var createCapacitorSyncLocalStore = ({
|
|
|
144
224
|
};
|
|
145
225
|
return {
|
|
146
226
|
transaction,
|
|
227
|
+
getSchemaStatus: async () => {
|
|
228
|
+
await connection();
|
|
229
|
+
if (schemaStatus === undefined)
|
|
230
|
+
throw new Error("Capacitor Sync schema was not prepared.");
|
|
231
|
+
return { ...schemaStatus };
|
|
232
|
+
},
|
|
147
233
|
deleteNamespace: async (namespace) => {
|
|
148
234
|
requireNamespace(namespace);
|
|
149
235
|
await locked(async () => {
|
|
@@ -202,5 +288,5 @@ export {
|
|
|
202
288
|
AbsoluteBackgroundSync
|
|
203
289
|
};
|
|
204
290
|
|
|
205
|
-
//# debugId=
|
|
291
|
+
//# debugId=06552E0CB8413A2564756E2164756E21
|
|
206
292
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -2,9 +2,9 @@
|
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/index.ts"],
|
|
4
4
|
"sourcesContent": [
|
|
5
|
-
"import {\n\tCapacitorSQLite,\n\tSQLiteConnection,\n\ttype SQLiteDBConnection\n} from '@capacitor-community/sqlite';\nimport type {\n\tLocalCollectionRecord,\n\tLocalMutationRecord,\n\tSyncLocalStore,\n\tSyncLocalStoreMode,\n\tSyncLocalTransaction\n} from '@absolutejs/sync/client';\nimport type {\n\tDeviceLifecycleCapability,\n\tDeviceNetworkCapability,\n\tDeviceSubscription\n} from '@absolutejs/devices';\nimport type { SyncClient } from '@absolutejs/sync/client';\nimport { registerPlugin } from '@capacitor/core';\n\nexport type CapacitorBackgroundSyncConfig = {\n\tendpoint: string;\n\tissuer: string;\n\tclientId: string;\n\tnamespace: string;\n\tdatabaseName?: string;\n\tintervalMinutes?: number;\n\tmaxMutations?: number;\n\tmaxPulls?: number;\n\tmaxAttempts?: number;\n};\n\nexport type CapacitorBackgroundSyncStatus = {\n\tconfigured: boolean;\n\trunning: boolean;\n\tlastRunAt?: number;\n\tlastError?: string;\n\tlastAcknowledged?: number;\n\tlastPulled?: number;\n};\n\nexport type AbsoluteBackgroundSyncPlugin = {\n\tconfigure(options: CapacitorBackgroundSyncConfig): Promise<void>;\n\tclear(): Promise<void>;\n\trunNow(): Promise<CapacitorBackgroundSyncStatus>;\n\tstatus(): Promise<CapacitorBackgroundSyncStatus>;\n};\n\nexport const AbsoluteBackgroundSync =\n\tregisterPlugin<AbsoluteBackgroundSyncPlugin>('AbsoluteBackgroundSync');\n\n/** Configure the managed scheduler. Auth credentials remain in the native vault. */\nexport const configureCapacitorBackgroundSync = (\n\toptions: CapacitorBackgroundSyncConfig,\n\tplugin: AbsoluteBackgroundSyncPlugin = AbsoluteBackgroundSync\n) => plugin.configure(options);\n\nexport type CapacitorSyncSqliteConnection = Pick<\n\tSQLiteDBConnection,\n\t| 'beginTransaction'\n\t| 'commitTransaction'\n\t| 'execute'\n\t| 'open'\n\t| 'query'\n\t| 'rollbackTransaction'\n\t| 'run'\n>;\n\nexport type CapacitorSyncSqliteFactory = () =>\n\t| CapacitorSyncSqliteConnection\n\t| Promise<CapacitorSyncSqliteConnection>;\n\nexport type CapacitorSyncLocalStoreOptions = {\n\t/** Defaults to `absolutejs-sync-local-v1`. */\n\tdatabaseName?: string;\n\t/** Injection seam for tests and custom SQLCipher provisioning. */\n\tconnection?: CapacitorSyncSqliteFactory;\n};\n\nconst SCHEMA = `\nCREATE TABLE IF NOT EXISTS absolute_sync_metadata (\n namespace TEXT PRIMARY KEY NOT NULL,\n installation_id TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS absolute_sync_collections (\n namespace TEXT NOT NULL,\n collection_key TEXT NOT NULL,\n record_json TEXT NOT NULL,\n PRIMARY KEY (namespace, collection_key)\n);\nCREATE TABLE IF NOT EXISTS absolute_sync_mutations (\n namespace TEXT NOT NULL,\n operation_id TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n record_json TEXT NOT NULL,\n PRIMARY KEY (namespace, operation_id)\n);\nCREATE INDEX IF NOT EXISTS absolute_sync_mutations_order\n ON absolute_sync_mutations (namespace, created_at, operation_id);\n`;\n\ntype SqliteRow = Record<string, unknown>;\n\nconst firstString = (rows: SqliteRow[] | undefined, field: string) => {\n\tconst value = rows?.[0]?.[field];\n\treturn typeof value === 'string' ? value : undefined;\n};\n\nconst parseRecord = <T>(value: unknown, label: string): T | undefined => {\n\tif (value === undefined) return undefined;\n\tif (typeof value !== 'string')\n\t\tthrow new Error(\n\t\t\t`Capacitor Sync SQLite returned invalid ${label} JSON.`\n\t\t);\n\ttry {\n\t\treturn JSON.parse(value) as T;\n\t} catch (cause) {\n\t\tthrow new Error(\n\t\t\t`Capacitor Sync SQLite could not parse ${label} JSON.`,\n\t\t\t{\n\t\t\t\tcause\n\t\t\t}\n\t\t);\n\t}\n};\n\nconst defaultConnection = async (\n\tdatabaseName: string\n): Promise<CapacitorSyncSqliteConnection> => {\n\tconst sqlite = new SQLiteConnection(CapacitorSQLite);\n\tconst existing = await sqlite.isConnection(databaseName, false);\n\tconst connection = existing.result\n\t\t? await sqlite.retrieveConnection(databaseName, false)\n\t\t: await sqlite.createConnection(\n\t\t\t\tdatabaseName,\n\t\t\t\tfalse,\n\t\t\t\t'no-encryption',\n\t\t\t\t1,\n\t\t\t\tfalse\n\t\t\t);\n\tawait connection.open();\n\treturn connection;\n};\n\nconst requireNamespace = (namespace: string) => {\n\tif (namespace.length === 0)\n\t\tthrow new Error('Sync local-store namespace must not be empty');\n};\n\n/**\n * Native SQLite implementation of Sync's principal-partitioned atomic cache\n * and mutation outbox. All calls are serialized because a Capacitor database\n * connection owns one explicit transaction at a time.\n */\nexport const createCapacitorSyncLocalStore = ({\n\tdatabaseName = 'absolutejs-sync-local-v1',\n\tconnection: createConnection = () => defaultConnection(databaseName)\n}: CapacitorSyncLocalStoreOptions = {}): SyncLocalStore => {\n\tif (databaseName.length === 0)\n\t\tthrow new TypeError('Capacitor Sync databaseName cannot be empty.');\n\tlet connectionPromise: Promise<CapacitorSyncSqliteConnection> | undefined;\n\tconst connection = () => {\n\t\tconnectionPromise ??= Promise.resolve(createConnection()).then(\n\t\t\tasync (database) => {\n\t\t\t\tawait database.execute(SCHEMA);\n\t\t\t\treturn database;\n\t\t\t}\n\t\t);\n\t\treturn connectionPromise;\n\t};\n\tlet tail = Promise.resolve();\n\tconst locked = async <R>(run: () => Promise<R>): Promise<R> => {\n\t\tlet release!: () => void;\n\t\tconst previous = tail;\n\t\ttail = new Promise<void>((resolve) => {\n\t\t\trelease = resolve;\n\t\t});\n\t\tawait previous;\n\t\ttry {\n\t\t\treturn await run();\n\t\t} finally {\n\t\t\trelease();\n\t\t}\n\t};\n\n\tconst transaction = async <R>(\n\t\tnamespace: string,\n\t\tmode: SyncLocalStoreMode,\n\t\trun: (tx: SyncLocalTransaction) => Promise<R>\n\t): Promise<R> => {\n\t\trequireNamespace(namespace);\n\t\treturn locked(async () => {\n\t\t\tconst database = await connection();\n\t\t\tawait database.beginTransaction();\n\t\t\tconst writable = () => {\n\t\t\t\tif (mode !== 'readwrite')\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t'Cannot write in a readonly Sync local transaction'\n\t\t\t\t\t);\n\t\t\t};\n\t\t\tconst tx: SyncLocalTransaction = {\n\t\t\t\tgetInstallationId: async () =>\n\t\t\t\t\tfirstString(\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tawait database.query(\n\t\t\t\t\t\t\t\t'SELECT installation_id FROM absolute_sync_metadata WHERE namespace = ? LIMIT 1',\n\t\t\t\t\t\t\t\t[namespace]\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t).values,\n\t\t\t\t\t\t'installation_id'\n\t\t\t\t\t),\n\t\t\t\tsetInstallationId: async (installationId) => {\n\t\t\t\t\twritable();\n\t\t\t\t\tif (installationId.length === 0)\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t'Sync installation id must not be empty'\n\t\t\t\t\t\t);\n\t\t\t\t\tawait database.run(\n\t\t\t\t\t\t'INSERT INTO absolute_sync_metadata (namespace, installation_id) VALUES (?, ?) ON CONFLICT(namespace) DO UPDATE SET installation_id = excluded.installation_id',\n\t\t\t\t\t\t[namespace, installationId],\n\t\t\t\t\t\tfalse\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tgetCollection: async <T>(key: string) =>\n\t\t\t\t\tparseRecord<LocalCollectionRecord<T>>(\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tawait database.query(\n\t\t\t\t\t\t\t\t'SELECT record_json FROM absolute_sync_collections WHERE namespace = ? AND collection_key = ? LIMIT 1',\n\t\t\t\t\t\t\t\t[namespace, key]\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t).values?.[0]?.record_json,\n\t\t\t\t\t\t'collection'\n\t\t\t\t\t),\n\t\t\t\tputCollection: async (key, record) => {\n\t\t\t\t\twritable();\n\t\t\t\t\tawait database.run(\n\t\t\t\t\t\t'INSERT INTO absolute_sync_collections (namespace, collection_key, record_json) VALUES (?, ?, ?) ON CONFLICT(namespace, collection_key) DO UPDATE SET record_json = excluded.record_json',\n\t\t\t\t\t\t[namespace, key, JSON.stringify(record)],\n\t\t\t\t\t\tfalse\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tdeleteCollection: async (key) => {\n\t\t\t\t\twritable();\n\t\t\t\t\tawait database.run(\n\t\t\t\t\t\t'DELETE FROM absolute_sync_collections WHERE namespace = ? AND collection_key = ?',\n\t\t\t\t\t\t[namespace, key],\n\t\t\t\t\t\tfalse\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tlistMutations: async () => {\n\t\t\t\t\tconst rows = (\n\t\t\t\t\t\tawait database.query(\n\t\t\t\t\t\t\t'SELECT record_json FROM absolute_sync_mutations WHERE namespace = ? ORDER BY created_at ASC, operation_id ASC',\n\t\t\t\t\t\t\t[namespace]\n\t\t\t\t\t\t)\n\t\t\t\t\t).values;\n\t\t\t\t\treturn (rows ?? [])\n\t\t\t\t\t\t.map((row) =>\n\t\t\t\t\t\t\tparseRecord<LocalMutationRecord>(\n\t\t\t\t\t\t\t\trow.record_json,\n\t\t\t\t\t\t\t\t'mutation'\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t(record): record is LocalMutationRecord =>\n\t\t\t\t\t\t\t\trecord !== undefined\n\t\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tgetMutation: async (operationId) =>\n\t\t\t\t\tparseRecord<LocalMutationRecord>(\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tawait database.query(\n\t\t\t\t\t\t\t\t'SELECT record_json FROM absolute_sync_mutations WHERE namespace = ? AND operation_id = ? LIMIT 1',\n\t\t\t\t\t\t\t\t[namespace, operationId]\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t).values?.[0]?.record_json,\n\t\t\t\t\t\t'mutation'\n\t\t\t\t\t),\n\t\t\t\tputMutation: async (record) => {\n\t\t\t\t\twritable();\n\t\t\t\t\tawait database.run(\n\t\t\t\t\t\t'INSERT INTO absolute_sync_mutations (namespace, operation_id, created_at, record_json) VALUES (?, ?, ?, ?) ON CONFLICT(namespace, operation_id) DO UPDATE SET created_at = excluded.created_at, record_json = excluded.record_json',\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tnamespace,\n\t\t\t\t\t\t\trecord.operationId,\n\t\t\t\t\t\t\trecord.createdAt,\n\t\t\t\t\t\t\tJSON.stringify(record)\n\t\t\t\t\t\t],\n\t\t\t\t\t\tfalse\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tdeleteMutation: async (operationId) => {\n\t\t\t\t\twritable();\n\t\t\t\t\tawait database.run(\n\t\t\t\t\t\t'DELETE FROM absolute_sync_mutations WHERE namespace = ? AND operation_id = ?',\n\t\t\t\t\t\t[namespace, operationId],\n\t\t\t\t\t\tfalse\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t};\n\t\t\ttry {\n\t\t\t\tconst result = await run(tx);\n\t\t\t\tawait database.commitTransaction();\n\t\t\t\treturn result;\n\t\t\t} catch (error) {\n\t\t\t\ttry {\n\t\t\t\t\tawait database.rollbackTransaction();\n\t\t\t\t} catch (rollbackError) {\n\t\t\t\t\tthrow new AggregateError(\n\t\t\t\t\t\t[error, rollbackError],\n\t\t\t\t\t\t'Capacitor Sync SQLite transaction and rollback both failed'\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t});\n\t};\n\n\treturn {\n\t\ttransaction,\n\t\tdeleteNamespace: async (namespace) => {\n\t\t\trequireNamespace(namespace);\n\t\t\tawait locked(async () => {\n\t\t\t\tconst database = await connection();\n\t\t\t\tawait database.beginTransaction();\n\t\t\t\ttry {\n\t\t\t\t\tfor (const table of [\n\t\t\t\t\t\t'absolute_sync_metadata',\n\t\t\t\t\t\t'absolute_sync_collections',\n\t\t\t\t\t\t'absolute_sync_mutations'\n\t\t\t\t\t])\n\t\t\t\t\t\tawait database.run(\n\t\t\t\t\t\t\t`DELETE FROM ${table} WHERE namespace = ?`,\n\t\t\t\t\t\t\t[namespace],\n\t\t\t\t\t\t\tfalse\n\t\t\t\t\t\t);\n\t\t\t\t\tawait database.commitTransaction();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tawait database.rollbackTransaction();\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n};\n\nexport type CapacitorSyncLifecycleOptions = {\n\tclient: Pick<SyncClient, 'reconnect'> & Partial<Pick<SyncClient, 'flush'>>;\n\tlifecycle: DeviceLifecycleCapability;\n\tnetwork: DeviceNetworkCapability;\n\t/** Finite outbox budget after a wake-up. Defaults to 10 seconds. */\n\tflushTimeoutMs?: number;\n\t/** Lifecycle flush failures are observable without becoming unhandled. */\n\tonError?: (error: unknown) => void;\n};\n\n/** Refreshes the socket/ticket and runs a bounded outbox flush after wake-up. */\nexport const installCapacitorSyncLifecycle = async ({\n\tclient,\n\tlifecycle,\n\tnetwork,\n\tflushTimeoutMs = 10_000,\n\tonError\n}: CapacitorSyncLifecycleOptions): Promise<DeviceSubscription> => {\n\tif (!Number.isFinite(flushTimeoutMs) || flushTimeoutMs < 0)\n\t\tthrow new TypeError(\n\t\t\t'Capacitor Sync flushTimeoutMs must be a non-negative number.'\n\t\t);\n\tconst wake = () => {\n\t\tclient.reconnect();\n\t\tvoid client\n\t\t\t.flush?.({ timeoutMs: flushTimeoutMs })\n\t\t\t.catch((error) => onError?.(error));\n\t};\n\tconst removers = await Promise.all([\n\t\tlifecycle.onResume?.(wake) ?? (() => undefined),\n\t\tnetwork.onChange((status) => {\n\t\t\tif (status.connected) wake();\n\t\t})\n\t]);\n\tlet active = true;\n\treturn async () => {\n\t\tif (!active) return;\n\t\tactive = false;\n\t\tawait Promise.all(removers.map((remove) => remove()));\n\t};\n};\n"
|
|
5
|
+
"import {\n\tCapacitorSQLite,\n\tSQLiteConnection,\n\ttype SQLiteDBConnection\n} from '@capacitor-community/sqlite';\nimport type {\n\tLocalCollectionRecord,\n\tLocalMutationRecord,\n\tSyncLocalStore,\n\tSyncLocalStoreMode,\n\tSyncLocalStoreSchema,\n\tSyncLocalStoreSchemaStatus,\n\tSyncLocalTransaction\n} from '@absolutejs/sync/client';\nimport {\n\tmigrateSyncLocalCollectionRecord,\n\tmigrateSyncLocalMutationRecord,\n\tresolveSyncLocalMigrations\n} from '@absolutejs/sync/client';\nimport type {\n\tDeviceLifecycleCapability,\n\tDeviceNetworkCapability,\n\tDeviceSubscription\n} from '@absolutejs/devices';\nimport type { SyncClient } from '@absolutejs/sync/client';\nimport { registerPlugin } from '@capacitor/core';\n\nexport type CapacitorBackgroundSyncConfig = {\n\tendpoint: string;\n\tissuer: string;\n\tclientId: string;\n\tnamespace: string;\n\tdatabaseName?: string;\n\tintervalMinutes?: number;\n\tmaxMutations?: number;\n\tmaxPulls?: number;\n\tmaxAttempts?: number;\n};\n\nexport type CapacitorBackgroundSyncStatus = {\n\tconfigured: boolean;\n\trunning: boolean;\n\tlastRunAt?: number;\n\tlastError?: string;\n\tlastAcknowledged?: number;\n\tlastPulled?: number;\n};\n\nexport type AbsoluteBackgroundSyncPlugin = {\n\tconfigure(options: CapacitorBackgroundSyncConfig): Promise<void>;\n\tclear(): Promise<void>;\n\trunNow(): Promise<CapacitorBackgroundSyncStatus>;\n\tstatus(): Promise<CapacitorBackgroundSyncStatus>;\n};\n\nexport const AbsoluteBackgroundSync =\n\tregisterPlugin<AbsoluteBackgroundSyncPlugin>('AbsoluteBackgroundSync');\n\n/** Configure the managed scheduler. Auth credentials remain in the native vault. */\nexport const configureCapacitorBackgroundSync = (\n\toptions: CapacitorBackgroundSyncConfig,\n\tplugin: AbsoluteBackgroundSyncPlugin = AbsoluteBackgroundSync\n) => plugin.configure(options);\n\nexport type CapacitorSyncSqliteConnection = Pick<\n\tSQLiteDBConnection,\n\t| 'beginTransaction'\n\t| 'commitTransaction'\n\t| 'execute'\n\t| 'open'\n\t| 'query'\n\t| 'rollbackTransaction'\n\t| 'run'\n>;\n\nexport type CapacitorSyncSqliteFactory = () =>\n\t| CapacitorSyncSqliteConnection\n\t| Promise<CapacitorSyncSqliteConnection>;\n\nexport type CapacitorSyncLocalStoreOptions = {\n\t/** Defaults to `absolutejs-sync-local-v1`. */\n\tdatabaseName?: string;\n\t/** Injection seam for tests and custom SQLCipher provisioning. */\n\tconnection?: CapacitorSyncSqliteFactory;\n\t/** Same generated logical migration plan used by web IndexedDB. */\n\tstorageSchema?: SyncLocalStoreSchema;\n};\n\nconst SCHEMA = `\nCREATE TABLE IF NOT EXISTS absolute_sync_schema (\n singleton_id INTEGER PRIMARY KEY NOT NULL CHECK (singleton_id = 1),\n logical_version INTEGER NOT NULL\n);\nCREATE TABLE IF NOT EXISTS absolute_sync_metadata (\n namespace TEXT PRIMARY KEY NOT NULL,\n installation_id TEXT NOT NULL\n);\nCREATE TABLE IF NOT EXISTS absolute_sync_collections (\n namespace TEXT NOT NULL,\n collection_key TEXT NOT NULL,\n record_json TEXT NOT NULL,\n PRIMARY KEY (namespace, collection_key)\n);\nCREATE TABLE IF NOT EXISTS absolute_sync_mutations (\n namespace TEXT NOT NULL,\n operation_id TEXT NOT NULL,\n created_at INTEGER NOT NULL,\n record_json TEXT NOT NULL,\n PRIMARY KEY (namespace, operation_id)\n);\nCREATE INDEX IF NOT EXISTS absolute_sync_mutations_order\n ON absolute_sync_mutations (namespace, created_at, operation_id);\n`;\n\ntype SqliteRow = Record<string, unknown>;\n\nconst firstString = (rows: SqliteRow[] | undefined, field: string) => {\n\tconst value = rows?.[0]?.[field];\n\treturn typeof value === 'string' ? value : undefined;\n};\n\nconst parseRecord = <T>(value: unknown, label: string): T | undefined => {\n\tif (value === undefined) return undefined;\n\tif (typeof value !== 'string')\n\t\tthrow new Error(\n\t\t\t`Capacitor Sync SQLite returned invalid ${label} JSON.`\n\t\t);\n\ttry {\n\t\treturn JSON.parse(value) as T;\n\t} catch (cause) {\n\t\tthrow new Error(\n\t\t\t`Capacitor Sync SQLite could not parse ${label} JSON.`,\n\t\t\t{\n\t\t\t\tcause\n\t\t\t}\n\t\t);\n\t}\n};\n\nconst defaultConnection = async (\n\tdatabaseName: string\n): Promise<CapacitorSyncSqliteConnection> => {\n\tconst sqlite = new SQLiteConnection(CapacitorSQLite);\n\tconst existing = await sqlite.isConnection(databaseName, false);\n\tconst connection = existing.result\n\t\t? await sqlite.retrieveConnection(databaseName, false)\n\t\t: await sqlite.createConnection(\n\t\t\t\tdatabaseName,\n\t\t\t\tfalse,\n\t\t\t\t'no-encryption',\n\t\t\t\t1,\n\t\t\t\tfalse\n\t\t\t);\n\tawait connection.open();\n\treturn connection;\n};\n\nconst requireNamespace = (namespace: string) => {\n\tif (namespace.length === 0)\n\t\tthrow new Error('Sync local-store namespace must not be empty');\n};\n\n/**\n * Native SQLite implementation of Sync's principal-partitioned atomic cache\n * and mutation outbox. All calls are serialized because a Capacitor database\n * connection owns one explicit transaction at a time.\n */\nexport const createCapacitorSyncLocalStore = ({\n\tdatabaseName = 'absolutejs-sync-local-v1',\n\tconnection: createConnection = () => defaultConnection(databaseName),\n\tstorageSchema = { version: 1 }\n}: CapacitorSyncLocalStoreOptions = {}): SyncLocalStore => {\n\tif (databaseName.length === 0)\n\t\tthrow new TypeError('Capacitor Sync databaseName cannot be empty.');\n\tlet schemaStatus: SyncLocalStoreSchemaStatus | undefined;\n\tconst prepareSchema = async (\n\t\tdatabase: CapacitorSyncSqliteConnection\n\t): Promise<void> => {\n\t\tawait database.beginTransaction();\n\t\ttry {\n\t\t\tconst saved = (\n\t\t\t\tawait database.query(\n\t\t\t\t\t'SELECT logical_version FROM absolute_sync_schema WHERE singleton_id = 1 LIMIT 1'\n\t\t\t\t)\n\t\t\t).values?.[0]?.logical_version;\n\t\t\tconst storedVersion = typeof saved === 'number' ? saved : 1;\n\t\t\tconst resolved = resolveSyncLocalMigrations(\n\t\t\t\tstoredVersion,\n\t\t\t\tstorageSchema\n\t\t\t);\n\t\t\tif (resolved.steps.length > 0) {\n\t\t\t\tconst collections = (\n\t\t\t\t\tawait database.query(\n\t\t\t\t\t\t'SELECT namespace, collection_key, record_json FROM absolute_sync_collections ORDER BY namespace, collection_key'\n\t\t\t\t\t)\n\t\t\t\t).values;\n\t\t\t\tfor (const row of collections ?? []) {\n\t\t\t\t\tconst namespace = row.namespace;\n\t\t\t\t\tconst key = row.collection_key;\n\t\t\t\t\tif (\n\t\t\t\t\t\ttypeof namespace !== 'string' ||\n\t\t\t\t\t\ttypeof key !== 'string'\n\t\t\t\t\t)\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t'Capacitor Sync SQLite returned an invalid collection identity.'\n\t\t\t\t\t\t);\n\t\t\t\t\tconst record = parseRecord<LocalCollectionRecord>(\n\t\t\t\t\t\trow.record_json,\n\t\t\t\t\t\t'collection'\n\t\t\t\t\t);\n\t\t\t\t\tif (record === undefined)\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t'Capacitor Sync SQLite returned a missing collection record.'\n\t\t\t\t\t\t);\n\t\t\t\t\tconst migrated = migrateSyncLocalCollectionRecord(\n\t\t\t\t\t\trecord,\n\t\t\t\t\t\t{ key, namespace },\n\t\t\t\t\t\tresolved.steps\n\t\t\t\t\t);\n\t\t\t\t\tif (migrated === null)\n\t\t\t\t\t\tawait database.run(\n\t\t\t\t\t\t\t'DELETE FROM absolute_sync_collections WHERE namespace = ? AND collection_key = ?',\n\t\t\t\t\t\t\t[namespace, key],\n\t\t\t\t\t\t\tfalse\n\t\t\t\t\t\t);\n\t\t\t\t\telse\n\t\t\t\t\t\tawait database.run(\n\t\t\t\t\t\t\t'UPDATE absolute_sync_collections SET record_json = ? WHERE namespace = ? AND collection_key = ?',\n\t\t\t\t\t\t\t[JSON.stringify(migrated), namespace, key],\n\t\t\t\t\t\t\tfalse\n\t\t\t\t\t\t);\n\t\t\t\t}\n\n\t\t\t\tconst mutations = (\n\t\t\t\t\tawait database.query(\n\t\t\t\t\t\t'SELECT namespace, operation_id, record_json FROM absolute_sync_mutations ORDER BY namespace, operation_id'\n\t\t\t\t\t)\n\t\t\t\t).values;\n\t\t\t\tfor (const row of mutations ?? []) {\n\t\t\t\t\tconst namespace = row.namespace;\n\t\t\t\t\tconst operationId = row.operation_id;\n\t\t\t\t\tif (\n\t\t\t\t\t\ttypeof namespace !== 'string' ||\n\t\t\t\t\t\ttypeof operationId !== 'string'\n\t\t\t\t\t)\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t'Capacitor Sync SQLite returned an invalid mutation identity.'\n\t\t\t\t\t\t);\n\t\t\t\t\tconst record = parseRecord<LocalMutationRecord>(\n\t\t\t\t\t\trow.record_json,\n\t\t\t\t\t\t'mutation'\n\t\t\t\t\t);\n\t\t\t\t\tif (record === undefined)\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t'Capacitor Sync SQLite returned a missing mutation record.'\n\t\t\t\t\t\t);\n\t\t\t\t\tconst migrated = migrateSyncLocalMutationRecord(\n\t\t\t\t\t\trecord,\n\t\t\t\t\t\t{ key: operationId, namespace },\n\t\t\t\t\t\tresolved.steps\n\t\t\t\t\t);\n\t\t\t\t\tif (migrated === null)\n\t\t\t\t\t\tawait database.run(\n\t\t\t\t\t\t\t'DELETE FROM absolute_sync_mutations WHERE namespace = ? AND operation_id = ?',\n\t\t\t\t\t\t\t[namespace, operationId],\n\t\t\t\t\t\t\tfalse\n\t\t\t\t\t\t);\n\t\t\t\t\telse\n\t\t\t\t\t\tawait database.run(\n\t\t\t\t\t\t\t'UPDATE absolute_sync_mutations SET created_at = ?, record_json = ? WHERE namespace = ? AND operation_id = ?',\n\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\tmigrated.createdAt,\n\t\t\t\t\t\t\t\tJSON.stringify(migrated),\n\t\t\t\t\t\t\t\tnamespace,\n\t\t\t\t\t\t\t\toperationId\n\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\tfalse\n\t\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t}\n\t\t\tawait database.run(\n\t\t\t\t'INSERT INTO absolute_sync_schema (singleton_id, logical_version) VALUES (1, ?) ON CONFLICT(singleton_id) DO UPDATE SET logical_version = excluded.logical_version',\n\t\t\t\t[resolved.targetVersion],\n\t\t\t\tfalse\n\t\t\t);\n\t\t\tawait database.commitTransaction();\n\t\t\tschemaStatus = {\n\t\t\t\tminimumCompatibleVersion: resolved.minimumCompatibleVersion,\n\t\t\t\tstate: 'ready',\n\t\t\t\tstoredVersion: resolved.targetVersion,\n\t\t\t\ttargetVersion: resolved.targetVersion\n\t\t\t};\n\t\t} catch (error) {\n\t\t\ttry {\n\t\t\t\tawait database.rollbackTransaction();\n\t\t\t} catch (rollbackError) {\n\t\t\t\tthrow new AggregateError(\n\t\t\t\t\t[error, rollbackError],\n\t\t\t\t\t'Capacitor Sync SQLite migration and rollback both failed'\n\t\t\t\t);\n\t\t\t}\n\t\t\tthrow error;\n\t\t}\n\t};\n\n\tlet connectionPromise: Promise<CapacitorSyncSqliteConnection> | undefined;\n\tconst connection = () => {\n\t\tconnectionPromise ??= Promise.resolve(createConnection()).then(\n\t\t\tasync (database) => {\n\t\t\t\tawait database.execute(SCHEMA);\n\t\t\t\tawait prepareSchema(database);\n\t\t\t\treturn database;\n\t\t\t}\n\t\t);\n\t\treturn connectionPromise;\n\t};\n\tlet tail = Promise.resolve();\n\tconst locked = async <R>(run: () => Promise<R>): Promise<R> => {\n\t\tlet release!: () => void;\n\t\tconst previous = tail;\n\t\ttail = new Promise<void>((resolve) => {\n\t\t\trelease = resolve;\n\t\t});\n\t\tawait previous;\n\t\ttry {\n\t\t\treturn await run();\n\t\t} finally {\n\t\t\trelease();\n\t\t}\n\t};\n\n\tconst transaction = async <R>(\n\t\tnamespace: string,\n\t\tmode: SyncLocalStoreMode,\n\t\trun: (tx: SyncLocalTransaction) => Promise<R>\n\t): Promise<R> => {\n\t\trequireNamespace(namespace);\n\t\treturn locked(async () => {\n\t\t\tconst database = await connection();\n\t\t\tawait database.beginTransaction();\n\t\t\tconst writable = () => {\n\t\t\t\tif (mode !== 'readwrite')\n\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t'Cannot write in a readonly Sync local transaction'\n\t\t\t\t\t);\n\t\t\t};\n\t\t\tconst tx: SyncLocalTransaction = {\n\t\t\t\tgetInstallationId: async () =>\n\t\t\t\t\tfirstString(\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tawait database.query(\n\t\t\t\t\t\t\t\t'SELECT installation_id FROM absolute_sync_metadata WHERE namespace = ? LIMIT 1',\n\t\t\t\t\t\t\t\t[namespace]\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t).values,\n\t\t\t\t\t\t'installation_id'\n\t\t\t\t\t),\n\t\t\t\tsetInstallationId: async (installationId) => {\n\t\t\t\t\twritable();\n\t\t\t\t\tif (installationId.length === 0)\n\t\t\t\t\t\tthrow new Error(\n\t\t\t\t\t\t\t'Sync installation id must not be empty'\n\t\t\t\t\t\t);\n\t\t\t\t\tawait database.run(\n\t\t\t\t\t\t'INSERT INTO absolute_sync_metadata (namespace, installation_id) VALUES (?, ?) ON CONFLICT(namespace) DO UPDATE SET installation_id = excluded.installation_id',\n\t\t\t\t\t\t[namespace, installationId],\n\t\t\t\t\t\tfalse\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tgetCollection: async <T>(key: string) =>\n\t\t\t\t\tparseRecord<LocalCollectionRecord<T>>(\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tawait database.query(\n\t\t\t\t\t\t\t\t'SELECT record_json FROM absolute_sync_collections WHERE namespace = ? AND collection_key = ? LIMIT 1',\n\t\t\t\t\t\t\t\t[namespace, key]\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t).values?.[0]?.record_json,\n\t\t\t\t\t\t'collection'\n\t\t\t\t\t),\n\t\t\t\tlistCollections: async () => {\n\t\t\t\t\tconst rows = (\n\t\t\t\t\t\tawait database.query(\n\t\t\t\t\t\t\t'SELECT collection_key, record_json FROM absolute_sync_collections WHERE namespace = ? ORDER BY collection_key ASC',\n\t\t\t\t\t\t\t[namespace]\n\t\t\t\t\t\t)\n\t\t\t\t\t).values;\n\t\t\t\t\treturn (rows ?? [])\n\t\t\t\t\t\t.map((row) => {\n\t\t\t\t\t\t\tconst key = row.collection_key;\n\t\t\t\t\t\t\tconst record = parseRecord<LocalCollectionRecord>(\n\t\t\t\t\t\t\t\trow.record_json,\n\t\t\t\t\t\t\t\t'collection'\n\t\t\t\t\t\t\t);\n\t\t\t\t\t\t\treturn typeof key === 'string' && record\n\t\t\t\t\t\t\t\t? { key, record }\n\t\t\t\t\t\t\t\t: undefined;\n\t\t\t\t\t\t})\n\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t(\n\t\t\t\t\t\t\t\tentry\n\t\t\t\t\t\t\t): entry is {\n\t\t\t\t\t\t\t\tkey: string;\n\t\t\t\t\t\t\t\trecord: LocalCollectionRecord;\n\t\t\t\t\t\t\t} => entry !== undefined\n\t\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tputCollection: async (key, record) => {\n\t\t\t\t\twritable();\n\t\t\t\t\tawait database.run(\n\t\t\t\t\t\t'INSERT INTO absolute_sync_collections (namespace, collection_key, record_json) VALUES (?, ?, ?) ON CONFLICT(namespace, collection_key) DO UPDATE SET record_json = excluded.record_json',\n\t\t\t\t\t\t[namespace, key, JSON.stringify(record)],\n\t\t\t\t\t\tfalse\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tdeleteCollection: async (key) => {\n\t\t\t\t\twritable();\n\t\t\t\t\tawait database.run(\n\t\t\t\t\t\t'DELETE FROM absolute_sync_collections WHERE namespace = ? AND collection_key = ?',\n\t\t\t\t\t\t[namespace, key],\n\t\t\t\t\t\tfalse\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tlistMutations: async () => {\n\t\t\t\t\tconst rows = (\n\t\t\t\t\t\tawait database.query(\n\t\t\t\t\t\t\t'SELECT record_json FROM absolute_sync_mutations WHERE namespace = ? ORDER BY created_at ASC, operation_id ASC',\n\t\t\t\t\t\t\t[namespace]\n\t\t\t\t\t\t)\n\t\t\t\t\t).values;\n\t\t\t\t\treturn (rows ?? [])\n\t\t\t\t\t\t.map((row) =>\n\t\t\t\t\t\t\tparseRecord<LocalMutationRecord>(\n\t\t\t\t\t\t\t\trow.record_json,\n\t\t\t\t\t\t\t\t'mutation'\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t(record): record is LocalMutationRecord =>\n\t\t\t\t\t\t\t\trecord !== undefined\n\t\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tgetMutation: async (operationId) =>\n\t\t\t\t\tparseRecord<LocalMutationRecord>(\n\t\t\t\t\t\t(\n\t\t\t\t\t\t\tawait database.query(\n\t\t\t\t\t\t\t\t'SELECT record_json FROM absolute_sync_mutations WHERE namespace = ? AND operation_id = ? LIMIT 1',\n\t\t\t\t\t\t\t\t[namespace, operationId]\n\t\t\t\t\t\t\t)\n\t\t\t\t\t\t).values?.[0]?.record_json,\n\t\t\t\t\t\t'mutation'\n\t\t\t\t\t),\n\t\t\t\tputMutation: async (record) => {\n\t\t\t\t\twritable();\n\t\t\t\t\tawait database.run(\n\t\t\t\t\t\t'INSERT INTO absolute_sync_mutations (namespace, operation_id, created_at, record_json) VALUES (?, ?, ?, ?) ON CONFLICT(namespace, operation_id) DO UPDATE SET created_at = excluded.created_at, record_json = excluded.record_json',\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\tnamespace,\n\t\t\t\t\t\t\trecord.operationId,\n\t\t\t\t\t\t\trecord.createdAt,\n\t\t\t\t\t\t\tJSON.stringify(record)\n\t\t\t\t\t\t],\n\t\t\t\t\t\tfalse\n\t\t\t\t\t);\n\t\t\t\t},\n\t\t\t\tdeleteMutation: async (operationId) => {\n\t\t\t\t\twritable();\n\t\t\t\t\tawait database.run(\n\t\t\t\t\t\t'DELETE FROM absolute_sync_mutations WHERE namespace = ? AND operation_id = ?',\n\t\t\t\t\t\t[namespace, operationId],\n\t\t\t\t\t\tfalse\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t};\n\t\t\ttry {\n\t\t\t\tconst result = await run(tx);\n\t\t\t\tawait database.commitTransaction();\n\t\t\t\treturn result;\n\t\t\t} catch (error) {\n\t\t\t\ttry {\n\t\t\t\t\tawait database.rollbackTransaction();\n\t\t\t\t} catch (rollbackError) {\n\t\t\t\t\tthrow new AggregateError(\n\t\t\t\t\t\t[error, rollbackError],\n\t\t\t\t\t\t'Capacitor Sync SQLite transaction and rollback both failed'\n\t\t\t\t\t);\n\t\t\t\t}\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t});\n\t};\n\n\treturn {\n\t\ttransaction,\n\t\tgetSchemaStatus: async () => {\n\t\t\tawait connection();\n\t\t\tif (schemaStatus === undefined)\n\t\t\t\tthrow new Error('Capacitor Sync schema was not prepared.');\n\t\t\treturn { ...schemaStatus };\n\t\t},\n\t\tdeleteNamespace: async (namespace) => {\n\t\t\trequireNamespace(namespace);\n\t\t\tawait locked(async () => {\n\t\t\t\tconst database = await connection();\n\t\t\t\tawait database.beginTransaction();\n\t\t\t\ttry {\n\t\t\t\t\tfor (const table of [\n\t\t\t\t\t\t'absolute_sync_metadata',\n\t\t\t\t\t\t'absolute_sync_collections',\n\t\t\t\t\t\t'absolute_sync_mutations'\n\t\t\t\t\t])\n\t\t\t\t\t\tawait database.run(\n\t\t\t\t\t\t\t`DELETE FROM ${table} WHERE namespace = ?`,\n\t\t\t\t\t\t\t[namespace],\n\t\t\t\t\t\t\tfalse\n\t\t\t\t\t\t);\n\t\t\t\t\tawait database.commitTransaction();\n\t\t\t\t} catch (error) {\n\t\t\t\t\tawait database.rollbackTransaction();\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t};\n};\n\nexport type CapacitorSyncLifecycleOptions = {\n\tclient: Pick<SyncClient, 'reconnect'> & Partial<Pick<SyncClient, 'flush'>>;\n\tlifecycle: DeviceLifecycleCapability;\n\tnetwork: DeviceNetworkCapability;\n\t/** Finite outbox budget after a wake-up. Defaults to 10 seconds. */\n\tflushTimeoutMs?: number;\n\t/** Lifecycle flush failures are observable without becoming unhandled. */\n\tonError?: (error: unknown) => void;\n};\n\n/** Refreshes the socket/ticket and runs a bounded outbox flush after wake-up. */\nexport const installCapacitorSyncLifecycle = async ({\n\tclient,\n\tlifecycle,\n\tnetwork,\n\tflushTimeoutMs = 10_000,\n\tonError\n}: CapacitorSyncLifecycleOptions): Promise<DeviceSubscription> => {\n\tif (!Number.isFinite(flushTimeoutMs) || flushTimeoutMs < 0)\n\t\tthrow new TypeError(\n\t\t\t'Capacitor Sync flushTimeoutMs must be a non-negative number.'\n\t\t);\n\tconst wake = () => {\n\t\tclient.reconnect();\n\t\tvoid client\n\t\t\t.flush?.({ timeoutMs: flushTimeoutMs })\n\t\t\t.catch((error) => onError?.(error));\n\t};\n\tconst removers = await Promise.all([\n\t\tlifecycle.onResume?.(wake) ?? (() => undefined),\n\t\tnetwork.onChange((status) => {\n\t\t\tif (status.connected) wake();\n\t\t})\n\t]);\n\tlet active = true;\n\treturn async () => {\n\t\tif (!active) return;\n\t\tactive = false;\n\t\tawait Promise.all(removers.map((remove) => remove()));\n\t};\n};\n"
|
|
6
6
|
],
|
|
7
|
-
"mappings": ";AAAA;AAAA;AAAA;AAAA;
|
|
8
|
-
"debugId": "
|
|
7
|
+
"mappings": "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",
|
|
8
|
+
"debugId": "06552E0CB8413A2564756E2164756E21",
|
|
9
9
|
"names": []
|
|
10
10
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@absolutejs/sync-capacitor",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.5.0",
|
|
4
4
|
"description": "Transactional Capacitor SQLite local store and native lifecycle adapter for @absolutejs/sync",
|
|
5
5
|
"repository": {
|
|
6
6
|
"type": "git",
|
|
@@ -38,14 +38,14 @@
|
|
|
38
38
|
"peerDependencies": {
|
|
39
39
|
"@absolutejs/devices": ">=0.0.3 <0.1.0",
|
|
40
40
|
"@absolutejs/devices-capacitor": ">=0.1.3 <0.2.0",
|
|
41
|
-
"@absolutejs/sync": ">=2.
|
|
41
|
+
"@absolutejs/sync": ">=2.25.0 <3",
|
|
42
42
|
"@capacitor/core": ">=8 <9",
|
|
43
43
|
"@capacitor-community/sqlite": ">=8.1.1 <9"
|
|
44
44
|
},
|
|
45
45
|
"devDependencies": {
|
|
46
46
|
"@absolutejs/devices": "0.0.3",
|
|
47
47
|
"@absolutejs/devices-capacitor": "0.1.3",
|
|
48
|
-
"@absolutejs/sync": "2.
|
|
48
|
+
"@absolutejs/sync": "2.25.0",
|
|
49
49
|
"@capacitor/core": "8.5.0",
|
|
50
50
|
"@capacitor-community/sqlite": "8.1.1",
|
|
51
51
|
"@types/bun": "1.3.14",
|