@aiao/rxdb-adapter-electron 0.0.26 → 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 (59) hide show
  1. package/README.md +122 -21
  2. package/dist/RxDBAdapterElectron.d.ts +27 -1
  3. package/dist/RxDBAdapterElectron.d.ts.map +1 -1
  4. package/dist/electron-sqlite-host.d.ts.map +1 -1
  5. package/dist/host.d.ts +1 -1
  6. package/dist/host.d.ts.map +1 -1
  7. package/dist/host.js +46 -40
  8. package/dist/index.d.ts +1 -1
  9. package/dist/index.d.ts.map +1 -1
  10. package/dist/index.js +20 -6
  11. package/dist/node-sqlite-engine.d.ts +10 -0
  12. package/dist/node-sqlite-engine.d.ts.map +1 -1
  13. package/dist/pglite/RxDBAdapterElectronPGlite.d.ts +53 -1
  14. package/dist/pglite/RxDBAdapterElectronPGlite.d.ts.map +1 -1
  15. package/dist/pglite/desktop-pglite-client.d.ts +27 -1
  16. package/dist/pglite/desktop-pglite-client.d.ts.map +1 -1
  17. package/dist/pglite/desktop-pglite-results.d.ts +14 -0
  18. package/dist/pglite/desktop-pglite-results.d.ts.map +1 -0
  19. package/dist/pglite/electron-pglite-backup-error.d.ts +32 -0
  20. package/dist/pglite/electron-pglite-backup-error.d.ts.map +1 -0
  21. package/dist/pglite/pglite-adapter.interface.d.ts +12 -0
  22. package/dist/pglite/pglite-adapter.interface.d.ts.map +1 -1
  23. package/dist/pglite/restore-electron-pglite-database.d.ts +68 -0
  24. package/dist/pglite/restore-electron-pglite-database.d.ts.map +1 -0
  25. package/dist/pglite-host/electron-pglite-host.d.ts +47 -32
  26. package/dist/pglite-host/electron-pglite-host.d.ts.map +1 -1
  27. package/dist/pglite-host/pglite-host-data-dir.d.ts +75 -0
  28. package/dist/pglite-host/pglite-host-data-dir.d.ts.map +1 -0
  29. package/dist/pglite-host/pglite-host-lock.d.ts +48 -0
  30. package/dist/pglite-host/pglite-host-lock.d.ts.map +1 -0
  31. package/dist/pglite-host/pglite-host-restore.d.ts +38 -0
  32. package/dist/pglite-host/pglite-host-restore.d.ts.map +1 -0
  33. package/dist/pglite-host/pglite-host-runtime.d.ts +90 -0
  34. package/dist/pglite-host/pglite-host-runtime.d.ts.map +1 -0
  35. package/dist/pglite-host.d.ts +2 -2
  36. package/dist/pglite-host.d.ts.map +1 -1
  37. package/dist/pglite-host.js +643 -120
  38. package/dist/pglite.d.ts +2 -0
  39. package/dist/pglite.d.ts.map +1 -1
  40. package/dist/pglite.js +341 -65
  41. package/package.json +13 -10
  42. package/src/RxDBAdapterElectron.ts +40 -1
  43. package/src/electron-sqlite-host.ts +3 -0
  44. package/src/host.ts +1 -0
  45. package/src/index.ts +1 -0
  46. package/src/node-sqlite-engine.ts +20 -1
  47. package/src/pglite/RxDBAdapterElectronPGlite.ts +80 -5
  48. package/src/pglite/desktop-pglite-client.ts +111 -17
  49. package/src/pglite/desktop-pglite-results.ts +24 -0
  50. package/src/pglite/electron-pglite-backup-error.ts +128 -0
  51. package/src/pglite/pglite-adapter.interface.ts +14 -0
  52. package/src/pglite/restore-electron-pglite-database.ts +429 -0
  53. package/src/pglite-host/electron-pglite-host.ts +409 -160
  54. package/src/pglite-host/pglite-host-data-dir.ts +224 -0
  55. package/src/pglite-host/pglite-host-lock.ts +154 -0
  56. package/src/pglite-host/pglite-host-restore.ts +460 -0
  57. package/src/pglite-host/pglite-host-runtime.ts +166 -0
  58. package/src/pglite-host.ts +7 -0
  59. package/src/pglite.ts +9 -0
package/dist/pglite.d.ts CHANGED
@@ -16,5 +16,7 @@
16
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
17
  export { RxDBAdapterElectronPGlite } from './pglite/RxDBAdapterElectronPGlite.js';
18
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';
19
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';
20
22
  //# sourceMappingURL=pglite.d.ts.map
@@ -1 +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,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"}
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 CHANGED
@@ -1,24 +1,71 @@
1
- import { DESKTOP_HOST_TRANSPORT_KEY as e, DESKTOP_PGLITE_DEFAULT_BEGIN_TIMEOUT_MS as t, DESKTOP_PGLITE_MAX_BEGIN_TIMEOUT_MS as n, DESKTOP_PGLITE_PROTOCOL_VERSION as r, RxDBAdapterDesktopError as i, RxDBAdapterDesktopError as a, assertDesktopPgliteResponse as o, assertValidDesktopDatabaseName as s, parseDesktopPgliteHandshakeResult as c, parseDesktopPgliteNotifyMessage as l, parseDesktopPgliteOpenResult as u, resolveDesktopHostTransport as d, resolveDesktopHostTransport as f } from "@aiao/rxdb-adapter-sqlite-core/desktop-host";
2
- import { DEFAULT_NOTIFY_BATCH_TIMEOUT_MS as p, PGliteNotificationBatcher as m, RxDBAdapterPGlite as h } from "@aiao/rxdb-adapter-pglite";
3
- import { EventDispatcher as g } from "@aiao/utils";
4
- import { query as _ } from "@electric-sql/pglite/template";
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";
5
6
  //#region src/pglite/pglite-adapter.interface.ts
6
- var v = "pglite-electron", y = "-pgdata", b = (e) => ({
7
+ var j = "pglite-electron", M = "-pgdata", N = (e, t) => t.dataDirectoryName ?? `${e}-pgdata`, P = (e) => ({
7
8
  rows: e.rows,
8
9
  fields: e.fields.map((e) => ({
9
10
  name: e.name,
10
11
  dataTypeID: e.dataTypeID
11
12
  })),
12
13
  affectedRows: e.affectedRows
13
- }), x = (e) => {
14
- if (e !== void 0) throw new a("protocol_violation", "the desktop PGlite protocol carries no QueryOptions; parsers, serializers, onNotice and blob cannot cross the process boundary");
15
- }, S = (e) => {
16
- if (e.store !== void 0 || e.dataDir !== void 0) throw new a("protocol_violation", "the desktop PGlite host owns storage; store and dataDir must not be set on the renderer side");
17
- }, C = (e) => new a("protocol_violation", `${e}() cannot be proxied to the desktop PGlite host; use query() or exec() instead`), w = (e) => {
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) => {
18
65
  queueMicrotask(() => {
19
66
  throw e;
20
67
  });
21
- }, T = class extends g {
68
+ }, G = class extends S {
22
69
  #e;
23
70
  #t;
24
71
  #n = "";
@@ -30,67 +77,95 @@ var v = "pglite-electron", y = "-pgdata", b = (e) => ({
30
77
  #c = Promise.resolve();
31
78
  #l = Promise.resolve();
32
79
  get sessionId() {
33
- if (!this.#r) throw new a("session_closed", "the desktop PGlite client has not been initialised yet");
80
+ if (!this.#r) throw new s("session_closed", "the desktop PGlite client has not been initialised yet");
34
81
  return this.#r;
35
82
  }
36
83
  get resolvedLocation() {
37
- if (!this.#i) throw new a("session_closed", "the desktop PGlite client has not been initialised yet");
84
+ if (!this.#i) throw new s("session_closed", "the desktop PGlite client has not been initialised yet");
38
85
  return this.#i;
39
86
  }
40
87
  get pendingNotificationCount() {
41
88
  return this.#t.pendingCount;
42
89
  }
43
90
  constructor(e) {
44
- super(), this.#e = e, this.#t = new m({
91
+ super(), this.#e = e, this.#t = new v({
45
92
  resolveDbName: () => this.#n,
46
93
  emit: (e) => this.dispatchEvent(e.type, e),
47
- batchTimeout: e.batchTimeout ?? p,
94
+ batchTimeout: e.batchTimeout ?? g,
48
95
  onParseError: (e) => console.error("Failed to parse desktop NOTIFY payload:", e)
49
96
  });
50
97
  }
51
98
  async init(e, t) {
52
- if (S(t), this.#r) throw new a("protocol_violation", `the desktop PGlite client is already bound to session ${this.#r}`);
99
+ if (U(t), this.#r) throw new s("protocol_violation", `the desktop PGlite client is already bound to session ${this.#r}`);
53
100
  this.#n = e;
54
- let n = o("pg.handshake", await this.#e.transport.request({ kind: "pg.handshake" }));
55
- c(n.result);
56
- let r = o("pg.open", await this.#e.transport.request({
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({
57
104
  kind: "pg.open",
58
105
  storage: {
59
106
  engine: "pglite",
60
107
  dataDirectoryName: this.#e.dataDirectoryName
61
108
  }
62
- })), i = await this.#u(r.result);
63
- this.#r = i.sessionId, this.#i = i.resolvedLocation, this.#a = this.#e.transport.subscribe((e) => this.#y(e)), await this.#d();
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();
64
111
  }
65
112
  async query(e, t, n) {
66
- return this.#v(), x(n), this.#g(async () => this.#m(void 0, e, t));
113
+ return this.#b(), H(n), this.#v(async () => this.#h(void 0, e, t));
67
114
  }
68
115
  async sql(e, ...t) {
69
- this.#v();
70
- let n = _(e, ...t);
71
- return this.#g(async () => this.#m(void 0, n.query, n.params));
116
+ this.#b();
117
+ let n = C(e, ...t);
118
+ return this.#v(async () => this.#h(void 0, n.query, n.params));
72
119
  }
73
120
  async exec(e, t) {
74
- return this.#v(), x(t), this.#g(async () => this.#h(void 0, e));
121
+ return this.#b(), H(t), this.#v(async () => this.#_(void 0, e));
75
122
  }
76
123
  async transaction(e) {
77
- return this.#v(), this.#g(() => this.#p(e));
124
+ return this.#b(), this.#v(() => this.#m(e));
78
125
  }
79
126
  async version() {
80
- return this.#v(), this.#g(async () => o("pg.version", await this.#_({
127
+ return this.#b(), this.#v(async () => c("pg.version", await this.#y({
81
128
  kind: "pg.version",
82
129
  sessionId: this.sessionId
83
130
  })).result);
84
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
+ }
85
153
  async disconnect() {
86
- this.#s ??= this.#f(!0), await this.#s;
154
+ this.#s ??= this.#p(!0), await this.#s;
87
155
  }
88
156
  async forceClose() {
89
- this.#s ??= this.#f(!1), await this.#s;
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
+ }
90
165
  }
91
- async #u(e) {
166
+ async #d(e) {
92
167
  try {
93
- return u(e);
168
+ return ee(e);
94
169
  } catch (t) {
95
170
  let n = (typeof e == "object" && e ? e : void 0)?.sessionId;
96
171
  throw typeof n == "string" && await this.#e.transport.request({
@@ -99,64 +174,64 @@ var v = "pglite-electron", y = "-pgdata", b = (e) => ({
99
174
  }).catch(() => void 0), t;
100
175
  }
101
176
  }
102
- async #d() {
177
+ async #f() {
103
178
  try {
104
179
  await this.#e.transport.subscriptionReady?.();
105
180
  } catch (e) {
106
181
  let t = this.#r;
107
- throw this.#o = !0, this.#a?.(), await this.#_({
182
+ throw this.#o = !0, this.#a?.(), await this.#y({
108
183
  kind: "pg.close",
109
184
  sessionId: t
110
- }).catch(() => void 0), new a("host_unavailable", `desktop PGlite session ${String(t)} could not subscribe to host notifications`, { cause: e });
185
+ }).catch(() => void 0), new s("host_unavailable", `desktop PGlite session ${String(t)} could not subscribe to host notifications`, { cause: e });
111
186
  }
112
187
  }
113
- async #f(e) {
188
+ async #p(e) {
114
189
  e && await this.#l.catch(() => void 0), this.#o = !0, e && await this.#c.catch(() => void 0);
115
190
  let t = this.#r;
116
- this.#a?.(), this.#t.clear(), this.removeAllEventListeners(), t && o("pg.close", await this.#e.transport.request({
191
+ this.#a?.(), this.#t.clear(), this.removeAllEventListeners(), t && c("pg.close", await this.#e.transport.request({
117
192
  kind: "pg.close",
118
193
  sessionId: t
119
194
  }));
120
195
  }
121
- async #p(e) {
122
- let t = o("pg.begin", await this.#_({
196
+ async #m(e) {
197
+ let t = c("pg.begin", await this.#y({
123
198
  kind: "pg.begin",
124
199
  sessionId: this.sessionId,
125
200
  ...this.#e.beginTimeout === void 0 ? {} : { timeout: this.#e.beginTimeout }
126
201
  })).result.transactionId, n = !1, r = async (e) => {
127
- n = !0, o(e, await this.#_({
202
+ n = !0, c(e, await this.#y({
128
203
  kind: e,
129
204
  sessionId: this.sessionId,
130
205
  transactionId: t
131
206
  }));
132
207
  }, i = () => {
133
- if (n) throw new a("transaction_not_found", `transaction ${t} is already closed`);
134
- }, s = {
135
- query: async (e, n, r) => (i(), x(r), this.#m(t, e, n)),
136
- exec: async (e, n) => (i(), x(n), this.#h(t, e)),
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)),
137
212
  rollback: async () => {
138
213
  i(), await r("pg.rollback");
139
214
  },
140
215
  sql: async (e, ...n) => {
141
216
  i();
142
- let r = _(e, ...n);
143
- return this.#m(t, r.query, r.params);
217
+ let r = C(e, ...n);
218
+ return this.#h(t, r.query, r.params);
144
219
  },
145
220
  listen: () => {
146
- throw C("listen");
221
+ throw te("listen");
147
222
  },
148
223
  get closed() {
149
224
  return n;
150
225
  }
151
226
  };
152
227
  try {
153
- let t = await e(s);
228
+ let t = await e(a);
154
229
  return n || await r("pg.commit"), t;
155
230
  } catch (e) {
156
231
  throw n || await r("pg.rollback").catch(() => void 0), e;
157
232
  }
158
233
  }
159
- async #m(e, t, n) {
234
+ async #h(e, t, n) {
160
235
  let r = {
161
236
  kind: "pg.query",
162
237
  sessionId: this.sessionId,
@@ -164,54 +239,255 @@ var v = "pglite-electron", y = "-pgdata", b = (e) => ({
164
239
  params: n ?? [],
165
240
  ...e === void 0 ? {} : { transactionId: e }
166
241
  };
167
- return b(o("pg.query", await this.#_(r)).result);
242
+ return P(c("pg.query", await this.#y(r)).result);
168
243
  }
169
- async #h(e, t) {
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) {
170
256
  let n = {
171
257
  kind: "pg.exec",
172
258
  sessionId: this.sessionId,
173
259
  sql: t,
174
260
  ...e === void 0 ? {} : { transactionId: e }
175
261
  };
176
- return o("pg.exec", await this.#_(n)).result.map((e) => b(e));
262
+ return c("pg.exec", await this.#y(n)).result.map((e) => P(e));
177
263
  }
178
- #g(e) {
264
+ #v(e) {
179
265
  let t = this.#l.then(e);
180
266
  return this.#l = t.then(void 0, () => void 0), t;
181
267
  }
182
- #_(e) {
268
+ #y(e) {
183
269
  let t = this.#c.then(() => this.#e.transport.request(e));
184
270
  return this.#c = t.then(void 0, () => void 0), t;
185
271
  }
186
- #v() {
187
- if (this.#o || !this.#r) throw new a("session_closed", `desktop PGlite session ${String(this.#r)} is not open`);
272
+ #b() {
273
+ if (this.#o || !this.#r) throw new s("session_closed", `desktop PGlite session ${String(this.#r)} is not open`);
188
274
  }
189
- #y(e) {
275
+ #x(e) {
190
276
  if (!this.#o && typeof e == "object" && e && e.kind === "pg.notify" && e.sessionId === this.#r) try {
191
- let t = l(e);
277
+ let t = p(e);
192
278
  this.#t.accept(t.channel, t.payload);
193
279
  } catch (e) {
194
- w(e);
280
+ W(e);
195
281
  }
196
282
  }
197
- }, E = class extends h {
283
+ }, K = class extends y {
198
284
  #e;
199
285
  #t;
200
- name = v;
286
+ name = j;
201
287
  get dataDirectoryName() {
202
288
  return this.#e;
203
289
  }
204
290
  constructor(e, t = {}) {
205
- super(e, {}), this.#t = t, this.#e = t.dataDirectoryName ?? `${e.config.dbName}-pgdata`, s(this.#e);
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
+ }
206
299
  }
207
300
  createClient() {
208
- return new T({
209
- transport: this.#t.transport ?? f(),
301
+ return new G({
302
+ transport: this.#n(),
210
303
  dataDirectoryName: this.#e,
211
304
  ...this.#t.beginTimeout === void 0 ? {} : { beginTimeout: this.#t.beginTimeout },
212
305
  ...this.#t.batchTimeout === void 0 ? {} : { batchTimeout: this.#t.batchTimeout }
213
306
  });
214
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
+ }
215
491
  };
216
492
  //#endregion
217
- export { y as DESKTOP_DEFAULT_DATA_DIRECTORY_SUFFIX, e as DESKTOP_HOST_TRANSPORT_KEY, t as DESKTOP_PGLITE_DEFAULT_BEGIN_TIMEOUT_MS, n as DESKTOP_PGLITE_MAX_BEGIN_TIMEOUT_MS, r as DESKTOP_PGLITE_PROTOCOL_VERSION, T as DesktopPGliteClient, v as ELECTRON_PGLITE_ADAPTER_NAME, i as RxDBAdapterDesktopError, E as RxDBAdapterElectronPGlite, d as resolveDesktopHostTransport };
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 };
package/package.json CHANGED
@@ -1,8 +1,8 @@
1
1
  {
2
2
  "name": "@aiao/rxdb-adapter-electron",
3
- "version": "0.0.26",
3
+ "version": "0.0.28",
4
4
  "description": "Desktop host adapter for local SQLite files in Electron and Tauri applications.",
5
- "homepage": "https://rxdb.netlify.app/docs/adapters",
5
+ "homepage": "https://rxdb.aiao.io/docs/adapters",
6
6
  "bugs": {
7
7
  "url": "https://github.com/aiao-io/rxdb/issues"
8
8
  },
@@ -69,13 +69,13 @@
69
69
  ]
70
70
  },
71
71
  "dependencies": {
72
- "@aiao/utils": "0.0.26",
73
- "@aiao/rxdb-adapter-sqlite-core": "0.0.26",
74
- "@aiao/rxdb": "0.0.26"
72
+ "@aiao/rxdb-adapter-sqlite-core": "^0.0.28",
73
+ "@aiao/utils": "^0.0.28"
75
74
  },
76
75
  "peerDependencies": {
77
76
  "@electric-sql/pglite": "^0.5.8",
78
- "@aiao/rxdb-adapter-pglite": "0.0.26"
77
+ "@aiao/rxdb": "^0.0.28",
78
+ "@aiao/rxdb-adapter-pglite": "^0.0.28"
79
79
  },
80
80
  "peerDependenciesMeta": {
81
81
  "@aiao/rxdb-adapter-pglite": {
@@ -86,9 +86,12 @@
86
86
  }
87
87
  },
88
88
  "devDependencies": {
89
- "@electric-sql/pglite": "^0.5.8",
90
- "@aiao/rxdb-adapter-pglite": "0.0.26",
91
- "@aiao/rxdb-plugin-history": "0.0.26",
92
- "@aiao/rxdb-test": "0.0.26"
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"
93
96
  }
94
97
  }