@aiao/rxdb-adapter-electron 0.0.0-stage → 0.0.28

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/LICENSE +21 -0
  2. package/README.md +394 -2
  3. package/dist/RxDBAdapterElectron.d.ts +61 -0
  4. package/dist/RxDBAdapterElectron.d.ts.map +1 -0
  5. package/dist/electron-adapter.interface.d.ts +23 -0
  6. package/dist/electron-adapter.interface.d.ts.map +1 -0
  7. package/dist/electron-file-host.d.ts +52 -0
  8. package/dist/electron-file-host.d.ts.map +1 -0
  9. package/dist/electron-sqlite-host.d.ts +65 -0
  10. package/dist/electron-sqlite-host.d.ts.map +1 -0
  11. package/dist/host.d.ts +19 -0
  12. package/dist/host.d.ts.map +1 -0
  13. package/dist/host.js +768 -0
  14. package/dist/index.d.ts +22 -0
  15. package/dist/index.d.ts.map +1 -0
  16. package/dist/index.js +36 -0
  17. package/dist/node-sqlite-engine.d.ts +97 -0
  18. package/dist/node-sqlite-engine.d.ts.map +1 -0
  19. package/dist/pglite/RxDBAdapterElectronPGlite.d.ts +96 -0
  20. package/dist/pglite/RxDBAdapterElectronPGlite.d.ts.map +1 -0
  21. package/dist/pglite/desktop-pglite-client.d.ts +144 -0
  22. package/dist/pglite/desktop-pglite-client.d.ts.map +1 -0
  23. package/dist/pglite/desktop-pglite-results.d.ts +14 -0
  24. package/dist/pglite/desktop-pglite-results.d.ts.map +1 -0
  25. package/dist/pglite/electron-pglite-backup-error.d.ts +32 -0
  26. package/dist/pglite/electron-pglite-backup-error.d.ts.map +1 -0
  27. package/dist/pglite/pglite-adapter.interface.d.ts +68 -0
  28. package/dist/pglite/pglite-adapter.interface.d.ts.map +1 -0
  29. package/dist/pglite/restore-electron-pglite-database.d.ts +68 -0
  30. package/dist/pglite/restore-electron-pglite-database.d.ts.map +1 -0
  31. package/dist/pglite-host/electron-pglite-host.d.ts +129 -0
  32. package/dist/pglite-host/electron-pglite-host.d.ts.map +1 -0
  33. package/dist/pglite-host/pglite-host-data-dir.d.ts +75 -0
  34. package/dist/pglite-host/pglite-host-data-dir.d.ts.map +1 -0
  35. package/dist/pglite-host/pglite-host-lock.d.ts +48 -0
  36. package/dist/pglite-host/pglite-host-lock.d.ts.map +1 -0
  37. package/dist/pglite-host/pglite-host-restore.d.ts +38 -0
  38. package/dist/pglite-host/pglite-host-restore.d.ts.map +1 -0
  39. package/dist/pglite-host/pglite-host-runtime.d.ts +90 -0
  40. package/dist/pglite-host/pglite-host-runtime.d.ts.map +1 -0
  41. package/dist/pglite-host.d.ts +17 -0
  42. package/dist/pglite-host.d.ts.map +1 -0
  43. package/dist/pglite-host.js +738 -0
  44. package/dist/pglite.d.ts +22 -0
  45. package/dist/pglite.d.ts.map +1 -0
  46. package/dist/pglite.js +493 -0
  47. package/dist/sqlite-script.d.ts +26 -0
  48. package/dist/sqlite-script.d.ts.map +1 -0
  49. package/package.json +94 -3
  50. package/src/RxDBAdapterElectron.ts +105 -0
  51. package/src/electron-adapter.interface.ts +25 -0
  52. package/src/electron-file-host.ts +758 -0
  53. package/src/electron-sqlite-host.ts +301 -0
  54. package/src/host.ts +64 -0
  55. package/src/index.ts +71 -0
  56. package/src/node-sqlite-engine.ts +631 -0
  57. package/src/pglite/RxDBAdapterElectronPGlite.ts +152 -0
  58. package/src/pglite/desktop-pglite-client.ts +614 -0
  59. package/src/pglite/desktop-pglite-results.ts +24 -0
  60. package/src/pglite/electron-pglite-backup-error.ts +128 -0
  61. package/src/pglite/pglite-adapter.interface.ts +78 -0
  62. package/src/pglite/restore-electron-pglite-database.ts +429 -0
  63. package/src/pglite-host/electron-pglite-host.ts +829 -0
  64. package/src/pglite-host/pglite-host-data-dir.ts +224 -0
  65. package/src/pglite-host/pglite-host-lock.ts +154 -0
  66. package/src/pglite-host/pglite-host-restore.ts +460 -0
  67. package/src/pglite-host/pglite-host-runtime.ts +166 -0
  68. package/src/pglite-host.ts +50 -0
  69. package/src/pglite.ts +51 -0
  70. package/src/sqlite-script.ts +134 -0
@@ -0,0 +1,22 @@
1
+ /**
2
+ * `@aiao/rxdb-adapter-electron` 的 **PGlite renderer 侧**入口。
3
+ *
4
+ * @remarks
5
+ * 与默认入口分开而不是并进去,理由是依赖:默认入口只要共享层,本入口却要
6
+ * `@aiao/rxdb-adapter-pglite` 这个可选 peer。合并的话,任何一个只用 SQLite 的应用
7
+ * 都会在 import 适配器时撞上「找不到 `@aiao/rxdb-adapter-pglite`」——而它压根没打算用 PGlite。
8
+ *
9
+ * 本入口**不引用 PostgreSQL 运行时**:WASM 实例活在主进程,renderer 这边只有一层协议
10
+ * 代理,从 `@electric-sql/pglite` 拿的只有类型和 `/template` 那个约 2 KB 的模板编译子路径,
11
+ * 因此 bundle 里不会多出几十兆的 PostgreSQL。特权侧请用
12
+ * `@aiao/rxdb-adapter-electron/pglite-host`。
13
+ *
14
+ * @module @aiao/rxdb-adapter-electron/pglite
15
+ */
16
+ export { DEFAULT_DATA_DIRECTORY_SUFFIX as DESKTOP_DEFAULT_DATA_DIRECTORY_SUFFIX, ADAPTER_NAME as ELECTRON_PGLITE_ADAPTER_NAME, type ElectronPGliteOptions } from './pglite/pglite-adapter.interface.js';
17
+ export { RxDBAdapterElectronPGlite } from './pglite/RxDBAdapterElectronPGlite.js';
18
+ export { DesktopPGliteClient, type DesktopPGliteClientOptions } from './pglite/desktop-pglite-client.js';
19
+ export type { PGliteRestoreOptions, PGliteRestoreStage } from '@aiao/rxdb-adapter-pglite';
20
+ export { cleanupIncompleteElectronPGliteRestore, restoreElectronPGliteDatabase, type ElectronPGliteRestoreTarget } from './pglite/restore-electron-pglite-database.js';
21
+ export { DESKTOP_HOST_TRANSPORT_KEY, DESKTOP_PGLITE_DEFAULT_BEGIN_TIMEOUT_MS, DESKTOP_PGLITE_MAX_BEGIN_TIMEOUT_MS, DESKTOP_PGLITE_PROTOCOL_VERSION, RxDBAdapterDesktopError, resolveDesktopHostTransport, type DesktopHostTransport, type DesktopPgliteNotifyMessage, type DesktopPgliteQueryResult, type DesktopPgliteRequest, type DesktopPgliteResponse, type RxDBAdapterDesktopErrorCode } from '@aiao/rxdb-adapter-sqlite-core/desktop-host';
22
+ //# sourceMappingURL=pglite.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pglite.d.ts","sourceRoot":"","sources":["../src/pglite.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;GAcG;AAEH,OAAO,EACL,6BAA6B,IAAI,qCAAqC,EACtE,YAAY,IAAI,4BAA4B,EAC5C,KAAK,qBAAqB,EAC3B,MAAM,sCAAsC,CAAC;AAE9C,OAAO,EAAE,yBAAyB,EAAE,MAAM,uCAAuC,CAAC;AAElF,OAAO,EAAE,mBAAmB,EAAE,KAAK,0BAA0B,EAAE,MAAM,mCAAmC,CAAC;AAIzG,YAAY,EAAE,oBAAoB,EAAE,kBAAkB,EAAE,MAAM,2BAA2B,CAAC;AAC1F,OAAO,EACL,sCAAsC,EACtC,6BAA6B,EAC7B,KAAK,2BAA2B,EACjC,MAAM,8CAA8C,CAAC;AAItD,OAAO,EACL,0BAA0B,EAC1B,uCAAuC,EACvC,mCAAmC,EACnC,+BAA+B,EAC/B,uBAAuB,EACvB,2BAA2B,EAC3B,KAAK,oBAAoB,EACzB,KAAK,0BAA0B,EAC/B,KAAK,wBAAwB,EAC7B,KAAK,oBAAoB,EACzB,KAAK,qBAAqB,EAC1B,KAAK,2BAA2B,EACjC,MAAM,6CAA6C,CAAC"}
package/dist/pglite.js ADDED
@@ -0,0 +1,493 @@
1
+ import { DESKTOP_HOST_TRANSPORT_KEY as e, DESKTOP_PGLITE_DEFAULT_BEGIN_TIMEOUT_MS as t, DESKTOP_PGLITE_DEFAULT_BEGIN_TIMEOUT_MS as n, DESKTOP_PGLITE_MAX_BEGIN_TIMEOUT_MS as r, DESKTOP_PGLITE_PROTOCOL_VERSION as i, DESKTOP_PGLITE_PROTOCOL_VERSION as a, RxDBAdapterDesktopError as o, RxDBAdapterDesktopError as s, assertDesktopPgliteResponse as c, assertValidDesktopDatabaseName as l, parseDesktopPgliteBackupItem as u, parseDesktopPgliteEngineResult as d, parseDesktopPgliteHandshakeResult as f, parseDesktopPgliteNotifyMessage as p, parseDesktopPgliteOpenResult as ee, resolveDesktopHostTransport as m, resolveDesktopHostTransport as h } from "@aiao/rxdb-adapter-sqlite-core/desktop-host";
2
+ import { DEFAULT_NOTIFY_BATCH_TIMEOUT_MS as g, PGLITE_BACKUP_ENGINE as _, PGliteNotificationBatcher as v, RxDBAdapterPGlite as y, toPGliteEngineInfo as b, verifyPGliteRestored as x } from "@aiao/rxdb-adapter-pglite";
3
+ import { EventDispatcher as S } from "@aiao/utils";
4
+ import { query as C } from "@electric-sql/pglite/template";
5
+ import { RXDB_CHANGE_CODEC_VERSION as w, RXDB_SYSTEM_SCHEMA_VERSION as T, RxDBBackupArchiveReader as E, RxDBBackupError as D, assertRxDBBackupCompatible as O, getRxDBBackupAuthDomain as k, getRxDBBackupSchemaFingerprint as A } from "@aiao/rxdb";
6
+ //#region src/pglite/pglite-adapter.interface.ts
7
+ var j = "pglite-electron", M = "-pgdata", N = (e, t) => t.dataDirectoryName ?? `${e}-pgdata`, P = (e) => ({
8
+ rows: e.rows,
9
+ fields: e.fields.map((e) => ({
10
+ name: e.name,
11
+ dataTypeID: e.dataTypeID
12
+ })),
13
+ affectedRows: e.affectedRows
14
+ }), F = /* @__PURE__ */ new Map([
15
+ ["database_busy", "target_busy"],
16
+ ["restore_in_progress", "restore_in_progress"],
17
+ ["restore_incomplete", "restore_incomplete"],
18
+ ["target_not_empty", "target_not_empty"],
19
+ ["cleanup_pending", "cleanup_pending"]
20
+ ]), I = /* @__PURE__ */ new Set([
21
+ "unsupported_runtime_engine",
22
+ "invalid_database_name",
23
+ "unsupported_operation"
24
+ ]), L = (e, t) => {
25
+ switch (e) {
26
+ case "target_busy": return `Desktop PGlite data directory "${t}" is open in another connection or being restored`;
27
+ case "restore_in_progress": return `Desktop PGlite data directory "${t}" is being restored`;
28
+ case "restore_incomplete": return `A previous restore into "${t}" did not finish; call cleanupIncompleteElectronPGliteRestore()`;
29
+ case "target_not_empty": return `Desktop PGlite data directory "${t}" already holds a database`;
30
+ default: return `Failed to clean up the incomplete restore of "${t}"; call cleanupIncompleteElectronPGliteRestore()`;
31
+ }
32
+ }, R = (e, t) => {
33
+ if (I.has(e)) return "unsupported_combination";
34
+ switch (e) {
35
+ case "disk_full": return "storage_full";
36
+ case "transaction_unavailable": return "lock_timeout";
37
+ case "session_closed": return "invalid_state";
38
+ case "database_corrupted": return t === "restore" ? "corrupt_archive" : "io_error";
39
+ default: return "io_error";
40
+ }
41
+ }, z = (e, t, n) => {
42
+ let r = F.get(e.code);
43
+ if (r !== void 0) {
44
+ let n = {
45
+ field: "dataDirectoryName",
46
+ actual: t
47
+ };
48
+ return new D(r, L(r, t), {
49
+ details: n,
50
+ cause: e
51
+ });
52
+ }
53
+ return e.code === "protocol_violation" ? new D("unsupported_combination", "The desktop host does not speak this renderer's protocol", {
54
+ details: {
55
+ field: "protocolVersion",
56
+ expected: a
57
+ },
58
+ cause: e
59
+ }) : new D(R(e.code, n), `Desktop PGlite ${n} failed: ${e.detail}`, { cause: e });
60
+ }, B = (e, t, n) => e instanceof D ? e : e instanceof s ? z(e, t, n) : new D("io_error", `Desktop PGlite ${n} failed`, { cause: e }), V = /* @__PURE__ */ new Set(["restore_in_progress", "restore_incomplete"]), H = (e) => {
61
+ if (e !== void 0) throw new s("protocol_violation", "the desktop PGlite protocol carries no QueryOptions; parsers, serializers, onNotice and blob cannot cross the process boundary");
62
+ }, U = (e) => {
63
+ if (e.store !== void 0 || e.dataDir !== void 0) throw new s("protocol_violation", "the desktop PGlite host owns storage; store and dataDir must not be set on the renderer side");
64
+ }, te = (e) => new s("protocol_violation", `${e}() cannot be proxied to the desktop PGlite host; use query() or exec() instead`), W = (e) => {
65
+ queueMicrotask(() => {
66
+ throw e;
67
+ });
68
+ }, G = class extends S {
69
+ #e;
70
+ #t;
71
+ #n = "";
72
+ #r;
73
+ #i;
74
+ #a;
75
+ #o = !1;
76
+ #s;
77
+ #c = Promise.resolve();
78
+ #l = Promise.resolve();
79
+ get sessionId() {
80
+ if (!this.#r) throw new s("session_closed", "the desktop PGlite client has not been initialised yet");
81
+ return this.#r;
82
+ }
83
+ get resolvedLocation() {
84
+ if (!this.#i) throw new s("session_closed", "the desktop PGlite client has not been initialised yet");
85
+ return this.#i;
86
+ }
87
+ get pendingNotificationCount() {
88
+ return this.#t.pendingCount;
89
+ }
90
+ constructor(e) {
91
+ super(), this.#e = e, this.#t = new v({
92
+ resolveDbName: () => this.#n,
93
+ emit: (e) => this.dispatchEvent(e.type, e),
94
+ batchTimeout: e.batchTimeout ?? g,
95
+ onParseError: (e) => console.error("Failed to parse desktop NOTIFY payload:", e)
96
+ });
97
+ }
98
+ async init(e, t) {
99
+ if (U(t), this.#r) throw new s("protocol_violation", `the desktop PGlite client is already bound to session ${this.#r}`);
100
+ this.#n = e;
101
+ let n = c("pg.handshake", await this.#e.transport.request({ kind: "pg.handshake" }));
102
+ f(n.result);
103
+ let r = this.#u(await this.#e.transport.request({
104
+ kind: "pg.open",
105
+ storage: {
106
+ engine: "pglite",
107
+ dataDirectoryName: this.#e.dataDirectoryName
108
+ }
109
+ })), i = await this.#d(r.result);
110
+ this.#r = i.sessionId, this.#i = i.resolvedLocation, this.#a = this.#e.transport.subscribe((e) => this.#x(e)), await this.#f();
111
+ }
112
+ async query(e, t, n) {
113
+ return this.#b(), H(n), this.#v(async () => this.#h(void 0, e, t));
114
+ }
115
+ async sql(e, ...t) {
116
+ this.#b();
117
+ let n = C(e, ...t);
118
+ return this.#v(async () => this.#h(void 0, n.query, n.params));
119
+ }
120
+ async exec(e, t) {
121
+ return this.#b(), H(t), this.#v(async () => this.#_(void 0, e));
122
+ }
123
+ async transaction(e) {
124
+ return this.#b(), this.#v(() => this.#m(e));
125
+ }
126
+ async version() {
127
+ return this.#b(), this.#v(async () => c("pg.version", await this.#y({
128
+ kind: "pg.version",
129
+ sessionId: this.sessionId
130
+ })).result);
131
+ }
132
+ async snapshotDataDir(e) {
133
+ return this.#b(), this.#v(async () => {
134
+ let t = c("pg.backup.begin", await this.#y({
135
+ kind: "pg.backup.begin",
136
+ sessionId: this.sessionId,
137
+ timeout: this.#e.beginTimeout ?? n
138
+ })).result.backupId, r = async () => {
139
+ c("pg.backup.end", await this.#y({
140
+ kind: "pg.backup.end",
141
+ sessionId: this.sessionId,
142
+ backupId: t
143
+ }));
144
+ }, i;
145
+ try {
146
+ i = await e(this.#g(t));
147
+ } catch (e) {
148
+ throw await r().catch(() => void 0), e;
149
+ }
150
+ return await r(), i;
151
+ });
152
+ }
153
+ async disconnect() {
154
+ this.#s ??= this.#p(!0), await this.#s;
155
+ }
156
+ async forceClose() {
157
+ this.#s ??= this.#p(!1), await this.#s;
158
+ }
159
+ #u(e) {
160
+ try {
161
+ return c("pg.open", e);
162
+ } catch (e) {
163
+ throw e instanceof s && V.has(e.code) ? B(e, this.#e.dataDirectoryName, "restore") : e;
164
+ }
165
+ }
166
+ async #d(e) {
167
+ try {
168
+ return ee(e);
169
+ } catch (t) {
170
+ let n = (typeof e == "object" && e ? e : void 0)?.sessionId;
171
+ throw typeof n == "string" && await this.#e.transport.request({
172
+ kind: "pg.close",
173
+ sessionId: n
174
+ }).catch(() => void 0), t;
175
+ }
176
+ }
177
+ async #f() {
178
+ try {
179
+ await this.#e.transport.subscriptionReady?.();
180
+ } catch (e) {
181
+ let t = this.#r;
182
+ throw this.#o = !0, this.#a?.(), await this.#y({
183
+ kind: "pg.close",
184
+ sessionId: t
185
+ }).catch(() => void 0), new s("host_unavailable", `desktop PGlite session ${String(t)} could not subscribe to host notifications`, { cause: e });
186
+ }
187
+ }
188
+ async #p(e) {
189
+ e && await this.#l.catch(() => void 0), this.#o = !0, e && await this.#c.catch(() => void 0);
190
+ let t = this.#r;
191
+ this.#a?.(), this.#t.clear(), this.removeAllEventListeners(), t && c("pg.close", await this.#e.transport.request({
192
+ kind: "pg.close",
193
+ sessionId: t
194
+ }));
195
+ }
196
+ async #m(e) {
197
+ let t = c("pg.begin", await this.#y({
198
+ kind: "pg.begin",
199
+ sessionId: this.sessionId,
200
+ ...this.#e.beginTimeout === void 0 ? {} : { timeout: this.#e.beginTimeout }
201
+ })).result.transactionId, n = !1, r = async (e) => {
202
+ n = !0, c(e, await this.#y({
203
+ kind: e,
204
+ sessionId: this.sessionId,
205
+ transactionId: t
206
+ }));
207
+ }, i = () => {
208
+ if (n) throw new s("transaction_not_found", `transaction ${t} is already closed`);
209
+ }, a = {
210
+ query: async (e, n, r) => (i(), H(r), this.#h(t, e, n)),
211
+ exec: async (e, n) => (i(), H(n), this.#_(t, e)),
212
+ rollback: async () => {
213
+ i(), await r("pg.rollback");
214
+ },
215
+ sql: async (e, ...n) => {
216
+ i();
217
+ let r = C(e, ...n);
218
+ return this.#h(t, r.query, r.params);
219
+ },
220
+ listen: () => {
221
+ throw te("listen");
222
+ },
223
+ get closed() {
224
+ return n;
225
+ }
226
+ };
227
+ try {
228
+ let t = await e(a);
229
+ return n || await r("pg.commit"), t;
230
+ } catch (e) {
231
+ throw n || await r("pg.rollback").catch(() => void 0), e;
232
+ }
233
+ }
234
+ async #h(e, t, n) {
235
+ let r = {
236
+ kind: "pg.query",
237
+ sessionId: this.sessionId,
238
+ sql: t,
239
+ params: n ?? [],
240
+ ...e === void 0 ? {} : { transactionId: e }
241
+ };
242
+ return P(c("pg.query", await this.#y(r)).result);
243
+ }
244
+ async *#g(e) {
245
+ for (;;) {
246
+ let t = c("pg.backup.next", await this.#y({
247
+ kind: "pg.backup.next",
248
+ sessionId: this.sessionId,
249
+ backupId: e
250
+ })), n = u(t.result);
251
+ if (n.type === "end") return;
252
+ yield n;
253
+ }
254
+ }
255
+ async #_(e, t) {
256
+ let n = {
257
+ kind: "pg.exec",
258
+ sessionId: this.sessionId,
259
+ sql: t,
260
+ ...e === void 0 ? {} : { transactionId: e }
261
+ };
262
+ return c("pg.exec", await this.#y(n)).result.map((e) => P(e));
263
+ }
264
+ #v(e) {
265
+ let t = this.#l.then(e);
266
+ return this.#l = t.then(void 0, () => void 0), t;
267
+ }
268
+ #y(e) {
269
+ let t = this.#c.then(() => this.#e.transport.request(e));
270
+ return this.#c = t.then(void 0, () => void 0), t;
271
+ }
272
+ #b() {
273
+ if (this.#o || !this.#r) throw new s("session_closed", `desktop PGlite session ${String(this.#r)} is not open`);
274
+ }
275
+ #x(e) {
276
+ if (!this.#o && typeof e == "object" && e && e.kind === "pg.notify" && e.sessionId === this.#r) try {
277
+ let t = p(e);
278
+ this.#t.accept(t.channel, t.payload);
279
+ } catch (e) {
280
+ W(e);
281
+ }
282
+ }
283
+ }, K = class extends y {
284
+ #e;
285
+ #t;
286
+ name = j;
287
+ get dataDirectoryName() {
288
+ return this.#e;
289
+ }
290
+ constructor(e, t = {}) {
291
+ super(e, {}), this.#t = t, this.#e = N(e.config.dbName, t), l(this.#e);
292
+ }
293
+ async backup(e, t = {}) {
294
+ try {
295
+ return await super.backup(e, t);
296
+ } catch (e) {
297
+ throw B(e, this.#e, "backup");
298
+ }
299
+ }
300
+ createClient() {
301
+ return new G({
302
+ transport: this.#n(),
303
+ dataDirectoryName: this.#e,
304
+ ...this.#t.beginTimeout === void 0 ? {} : { beginTimeout: this.#t.beginTimeout },
305
+ ...this.#t.batchTimeout === void 0 ? {} : { batchTimeout: this.#t.batchTimeout }
306
+ });
307
+ }
308
+ backupStorage() {
309
+ return "directory";
310
+ }
311
+ async backupExtensions() {
312
+ let e = c("pg.engine", await this.#n().request({ kind: "pg.engine" }));
313
+ return d(e.result).extensions;
314
+ }
315
+ #n() {
316
+ return this.#t.transport ?? h();
317
+ }
318
+ }, q = (e) => new D("aborted", "Desktop PGlite restore was aborted", { cause: e.reason }), J = (e) => {
319
+ if (e?.aborted) throw q(e);
320
+ }, Y = (e) => {
321
+ let t = !1;
322
+ if (e.connected$.subscribe((e) => {
323
+ t = e;
324
+ }).unsubscribe(), t) throw new D("target_busy", `RxDB "${e.config.dbName}" is already connected`, { details: {
325
+ field: "rxdb",
326
+ actual: e.config.dbName
327
+ } });
328
+ }, X = async (e) => {
329
+ let t = c("pg.handshake", await e.request({ kind: "pg.handshake" }));
330
+ f(t.result);
331
+ }, Z = async (e) => {
332
+ let t = c("pg.engine", await e.request({ kind: "pg.engine" }));
333
+ return d(t.result);
334
+ }, Q = (e, t) => (e.init(), {
335
+ adapterName: j,
336
+ engine: _,
337
+ engineCompatibility: b(t.serverVersion).compatibility,
338
+ extensions: t.extensions,
339
+ systemSchemaVersion: T,
340
+ changeCodecVersion: w,
341
+ schemaFingerprint: A(e),
342
+ authDomain: k(e)
343
+ }), ne = async (e, t) => {
344
+ let { restoreId: n } = c("pg.restore.begin", await e.request({
345
+ kind: "pg.restore.begin",
346
+ storage: {
347
+ engine: "pglite",
348
+ dataDirectoryName: t
349
+ }
350
+ })).result;
351
+ return {
352
+ step: async (t) => {
353
+ c(t, await e.request({
354
+ kind: t,
355
+ restoreId: n
356
+ }));
357
+ },
358
+ write: async (t) => {
359
+ c("pg.restore.write", await e.request({
360
+ kind: "pg.restore.write",
361
+ restoreId: n,
362
+ item: t
363
+ }));
364
+ },
365
+ query: async (t, r) => c("pg.restore.query", await e.request({
366
+ kind: "pg.restore.query",
367
+ restoreId: n,
368
+ sql: t,
369
+ params: r
370
+ })).result,
371
+ abort: async () => {
372
+ c("pg.restore.abort", await e.request({
373
+ kind: "pg.restore.abort",
374
+ restoreId: n
375
+ }));
376
+ }
377
+ };
378
+ }, re = (e) => {
379
+ let t = {
380
+ type: "entry",
381
+ header: {
382
+ path: e.path,
383
+ kind: e.kind,
384
+ size: e.size
385
+ }
386
+ };
387
+ try {
388
+ u(t);
389
+ } catch (t) {
390
+ throw new D("corrupt_archive", `Archive entry ${JSON.stringify(e.path)} cannot be restored into a desktop data directory`, {
391
+ details: {
392
+ field: "path",
393
+ actual: e.path
394
+ },
395
+ cause: t
396
+ });
397
+ }
398
+ return t;
399
+ }, ie = (e) => e.buffer instanceof ArrayBuffer && e.byteOffset === 0 && e.byteLength === e.buffer.byteLength ? e : e.slice(), ae = async (e, t) => {
400
+ let n = await e.next();
401
+ for (; n.type !== "end";) await t.write(n.type === "entry" ? re(n.header) : {
402
+ type: "data",
403
+ bytes: ie(n.bytes)
404
+ }), n = await e.next();
405
+ return n.trailer;
406
+ }, oe = async (e, t) => {
407
+ let n = { query: async (t, n = []) => P(await e.query(t, n)) };
408
+ try {
409
+ await x(n, t);
410
+ } catch (e) {
411
+ throw e instanceof s && e.code === "statement_failed" ? new D("corrupt_archive", "Restored database cannot answer the verification queries", { cause: e }) : e;
412
+ }
413
+ }, $ = async (e) => {
414
+ let { host: t, archive: n, options: r } = e;
415
+ await t.step("pg.restore.prepare"), await r.onStage?.("marker-written"), J(r.signal);
416
+ let i = await ae(n, t);
417
+ return await t.step("pg.restore.open"), await r.onStage?.("files-written"), J(r.signal), await oe(t, e.manifest), await r.onStage?.("verified"), J(r.signal), await t.step("pg.restore.persist"), await r.onStage?.("persisted"), await t.step("pg.restore.commit"), i;
418
+ }, se = async (e, t, n, r) => {
419
+ try {
420
+ await e.abort();
421
+ } catch (e) {
422
+ let i = AggregateError([r, e], "Restore and cleanup both failed");
423
+ if (!t) {
424
+ let e = B(r, n, "restore");
425
+ throw new D(e.code, e.message, {
426
+ details: e.details,
427
+ cause: i
428
+ });
429
+ }
430
+ throw new D("cleanup_pending", "Desktop PGlite restore failed and its partial data could not be removed; call cleanupIncompleteElectronPGliteRestore()", {
431
+ details: {
432
+ field: "dataDirectoryName",
433
+ actual: n
434
+ },
435
+ cause: i
436
+ });
437
+ }
438
+ throw r;
439
+ }, ce = async (e, t, n, r) => {
440
+ let i = t.options.transport ?? h();
441
+ await X(i);
442
+ let a = Q(t.rxdb, await Z(i));
443
+ J(r.signal);
444
+ let o = await ne(i, n), s = !1;
445
+ try {
446
+ let t = new E(e, r.signal), n = await t.readManifest();
447
+ return O(n, a), s = !0, {
448
+ ...await $({
449
+ host: o,
450
+ archive: t,
451
+ manifest: n,
452
+ options: r
453
+ }),
454
+ manifest: n,
455
+ scope: n.scope
456
+ };
457
+ } catch (e) {
458
+ return se(o, s, n, e);
459
+ }
460
+ }, le = async (e, t, n = {}) => {
461
+ let r = e.getReader(), i = N(t.rxdb.config.dbName, t.options);
462
+ try {
463
+ J(n.signal), l(i), Y(t.rxdb);
464
+ let e = await ce(r, t, i, n);
465
+ return r.releaseLock(), e;
466
+ } catch (e) {
467
+ throw await r.cancel(e).catch(() => void 0), B(e, i, "restore");
468
+ }
469
+ }, ue = async (e) => {
470
+ let t = N(e.rxdb.config.dbName, e.options);
471
+ try {
472
+ l(t);
473
+ let n = e.options.transport ?? h();
474
+ return await X(n), c("pg.restore.cleanup", await n.request({
475
+ kind: "pg.restore.cleanup",
476
+ storage: {
477
+ engine: "pglite",
478
+ dataDirectoryName: t
479
+ }
480
+ })).result.cleaned;
481
+ } catch (e) {
482
+ let n = B(e, t, "restore");
483
+ throw n.code === "io_error" ? new D("cleanup_pending", `Failed to clean up the incomplete restore of "${t}"`, {
484
+ details: {
485
+ field: "dataDirectoryName",
486
+ actual: t
487
+ },
488
+ cause: e
489
+ }) : n;
490
+ }
491
+ };
492
+ //#endregion
493
+ export { M as DESKTOP_DEFAULT_DATA_DIRECTORY_SUFFIX, e as DESKTOP_HOST_TRANSPORT_KEY, t as DESKTOP_PGLITE_DEFAULT_BEGIN_TIMEOUT_MS, r as DESKTOP_PGLITE_MAX_BEGIN_TIMEOUT_MS, i as DESKTOP_PGLITE_PROTOCOL_VERSION, G as DesktopPGliteClient, j as ELECTRON_PGLITE_ADAPTER_NAME, o as RxDBAdapterDesktopError, K as RxDBAdapterElectronPGlite, ue as cleanupIncompleteElectronPGliteRestore, m as resolveDesktopHostTransport, le as restoreElectronPGliteDatabase };
@@ -0,0 +1,26 @@
1
+ /**
2
+ * SQL 脚本切分。
3
+ *
4
+ * @remarks
5
+ * wasm 后端能拿到 `sqlite3_prepare_v3` 的 `pzTail`,由 SQLite 自己逐条吐出语句;`node:sqlite`
6
+ * 没有对应出口——`prepare()` 只编译第一条语句并**静默丢掉**后面所有语句,`exec()` 跑完整个脚本
7
+ * 却不返回任何结果集。多语句脚本里带 `RETURNING` 的那条因此会人间蒸发(分支切换正是这个形状)。
8
+ *
9
+ * 所以切分只能自己做。状态机逐字搬自 SQLite 的 `complete.c`(即 `sqlite3_complete()` 的实现),
10
+ * 与 SQLite 对「一条语句到哪里结束」的判断同源;自己发明规则迟早会在触发器体或字符串字面量上分叉。
11
+ *
12
+ * @module sqlite-script
13
+ */
14
+ /**
15
+ * 把一段可能含多条语句的 SQL 脚本切成单条语句。
16
+ *
17
+ * @remarks
18
+ * 切片保留原文(含语句间的空白与注释),因此把结果按顺序拼回去与原串等价,
19
+ * 报错信息里的 SQL 也仍是调用方写的那一份。只含空白或注释的片段不会成为语句——
20
+ * 它们 prepare 出来是空语句,`node:sqlite` 会直接抛错。
21
+ *
22
+ * @param sql - 一条或多条 SQL 组成的脚本
23
+ * @returns 按出现顺序排列的语句原文;脚本里没有实质语句时为空数组
24
+ */
25
+ export declare function splitSqliteScript(sql: string): string[];
26
+ //# sourceMappingURL=sqlite-script.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"sqlite-script.d.ts","sourceRoot":"","sources":["../src/sqlite-script.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AA0FH;;;;;;;;;;GAUG;AACH,wBAAgB,iBAAiB,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,EAAE,CAoBvD"}
package/package.json CHANGED
@@ -1,6 +1,97 @@
1
1
  {
2
2
  "name": "@aiao/rxdb-adapter-electron",
3
- "version": "0.0.0-stage",
4
- "stub": true,
5
- "description": "Temporary package placeholder for staged publishing"
3
+ "version": "0.0.28",
4
+ "description": "Desktop host adapter for local SQLite files in Electron and Tauri applications.",
5
+ "homepage": "https://rxdb.aiao.io/docs/adapters",
6
+ "bugs": {
7
+ "url": "https://github.com/aiao-io/rxdb/issues"
8
+ },
9
+ "keywords": [
10
+ "aiao",
11
+ "rxdb",
12
+ "sqlite",
13
+ "electron",
14
+ "tauri",
15
+ "desktop"
16
+ ],
17
+ "license": "MIT",
18
+ "repository": {
19
+ "type": "git",
20
+ "url": "git+https://github.com/aiao-io/rxdb.git",
21
+ "directory": "packages/rxdb-adapter-electron"
22
+ },
23
+ "type": "module",
24
+ "main": "./dist/index.js",
25
+ "module": "./dist/index.js",
26
+ "types": "./dist/index.d.ts",
27
+ "sideEffects": false,
28
+ "exports": {
29
+ "./package.json": "./package.json",
30
+ ".": {
31
+ "types": "./dist/index.d.ts",
32
+ "import": "./dist/index.js",
33
+ "default": "./dist/index.js"
34
+ },
35
+ "./host": {
36
+ "@aiao/source": "./src/host.ts",
37
+ "types": "./dist/host.d.ts",
38
+ "import": "./dist/host.js",
39
+ "default": "./dist/host.js"
40
+ },
41
+ "./pglite": {
42
+ "@aiao/source": "./src/pglite.ts",
43
+ "types": "./dist/pglite.d.ts",
44
+ "import": "./dist/pglite.js",
45
+ "default": "./dist/pglite.js"
46
+ },
47
+ "./pglite-host": {
48
+ "@aiao/source": "./src/pglite-host.ts",
49
+ "types": "./dist/pglite-host.d.ts",
50
+ "import": "./dist/pglite-host.js",
51
+ "default": "./dist/pglite-host.js"
52
+ }
53
+ },
54
+ "files": [
55
+ "dist",
56
+ "src",
57
+ "!src/**/*.spec.*",
58
+ "!src/**/*.test.*",
59
+ "!src/**/__tests__/**",
60
+ "!**/*.tsbuildinfo"
61
+ ],
62
+ "publishConfig": {
63
+ "access": "public"
64
+ },
65
+ "nx": {
66
+ "name": "rxdb-adapter-electron",
67
+ "tags": [
68
+ "js-lib"
69
+ ]
70
+ },
71
+ "dependencies": {
72
+ "@aiao/rxdb-adapter-sqlite-core": "^0.0.28",
73
+ "@aiao/utils": "^0.0.28"
74
+ },
75
+ "peerDependencies": {
76
+ "@electric-sql/pglite": "^0.5.8",
77
+ "@aiao/rxdb": "^0.0.28",
78
+ "@aiao/rxdb-adapter-pglite": "^0.0.28"
79
+ },
80
+ "peerDependenciesMeta": {
81
+ "@aiao/rxdb-adapter-pglite": {
82
+ "optional": true
83
+ },
84
+ "@electric-sql/pglite": {
85
+ "optional": true
86
+ }
87
+ },
88
+ "devDependencies": {
89
+ "@electric-sql/pglite": "^0.5.10",
90
+ "@aiao/rxdb-plugin-querycache": "0.0.28",
91
+ "@aiao/rxdb-plugin-sync": "0.0.28",
92
+ "@aiao/rxdb-test": "0.0.28",
93
+ "@aiao/rxdb-plugin-working-tree": "0.0.28",
94
+ "@aiao/rxdb-plugin-history": "0.0.28",
95
+ "@aiao/rxdb-adapter-pglite": "0.0.28"
96
+ }
6
97
  }