firebird-wasm 0.1.0 → 0.2.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.
Files changed (37) hide show
  1. package/CHANGELOG.md +113 -0
  2. package/README.md +77 -7
  3. package/dist/.tsbuildinfo.build +1 -1
  4. package/dist/browser/engine-transport.d.ts +10 -3
  5. package/dist/browser/engine-transport.d.ts.map +1 -1
  6. package/dist/browser/engine-transport.js +3 -2
  7. package/dist/browser/engine-transport.js.map +1 -1
  8. package/dist/browser/firebird-browser.d.ts +56 -4
  9. package/dist/browser/firebird-browser.d.ts.map +1 -1
  10. package/dist/browser/firebird-browser.js +125 -21
  11. package/dist/browser/firebird-browser.js.map +1 -1
  12. package/dist/browser/index.d.ts +5 -0
  13. package/dist/browser/index.d.ts.map +1 -1
  14. package/dist/browser/index.js +8 -1
  15. package/dist/browser/index.js.map +1 -1
  16. package/dist/browser/isolation.d.ts +21 -0
  17. package/dist/browser/isolation.d.ts.map +1 -0
  18. package/dist/browser/isolation.js +37 -0
  19. package/dist/browser/isolation.js.map +1 -0
  20. package/dist/browser/leader-election.d.ts +55 -0
  21. package/dist/browser/leader-election.d.ts.map +1 -0
  22. package/dist/browser/leader-election.js +64 -0
  23. package/dist/browser/leader-election.js.map +1 -0
  24. package/dist/browser/shared-transport.d.ts +128 -0
  25. package/dist/browser/shared-transport.d.ts.map +1 -0
  26. package/dist/browser/shared-transport.js +339 -0
  27. package/dist/browser/shared-transport.js.map +1 -0
  28. package/dist/browser/worker-transport.d.ts +2 -2
  29. package/dist/browser/worker-transport.d.ts.map +1 -1
  30. package/dist/browser/worker-transport.js +3 -2
  31. package/dist/browser/worker-transport.js.map +1 -1
  32. package/dist/wasm/firebird-embedded.js +1 -1
  33. package/dist/wasm/firebird-embedded.wasm +0 -0
  34. package/dist/wasm-loader.d.ts +8 -0
  35. package/dist/wasm-loader.d.ts.map +1 -1
  36. package/dist/wasm-loader.js.map +1 -1
  37. package/package.json +2 -1
@@ -0,0 +1,64 @@
1
+ "use strict";
2
+ /**
3
+ * leader-election.ts – exactly one tab owns the engine; the rest wait.
4
+ *
5
+ * Built on the same Web Lock that {@link acquireDatabaseLock} already uses for
6
+ * multi-tab *safety*, because election is the same problem viewed from the
7
+ * other side. Refusing the second tab and serving it from the first differ
8
+ * only in what the loser does after losing.
9
+ *
10
+ * Every participant requests the lock and never gives it back voluntarily.
11
+ * Whoever holds it is the leader; everyone else is queued behind it. When the
12
+ * leader's context dies — closed, crashed, killed while backgrounded — the
13
+ * browser releases the lock and the next waiter is granted it and promoted.
14
+ * There is no heartbeat, no lease to expire, and no way to observe two leaders
15
+ * at once, because the browser will not grant an exclusive lock twice.
16
+ */
17
+ Object.defineProperty(exports, "__esModule", { value: true });
18
+ exports.electLeader = electLeader;
19
+ const db_lock_1 = require("./db-lock");
20
+ /**
21
+ * Join the election for `dbName`.
22
+ *
23
+ * Returns as soon as participation has *started*, not when it is won — a
24
+ * follower must be usable immediately, and the first thing it does is proxy
25
+ * to whoever is already leading.
26
+ */
27
+ function electLeader(dbName, options = {}) {
28
+ let leader = false;
29
+ let enforced = true;
30
+ let lock = null;
31
+ let resigned = false;
32
+ const promoted = (async () => {
33
+ // Infinity, deliberately: a follower is not waiting on a timeout, it is
34
+ // waiting for the leader to go away, which may be never.
35
+ const held = await (0, db_lock_1.acquireDatabaseLock)(dbName, { timeoutMs: Infinity });
36
+ if (resigned) {
37
+ // resign() ran while this was queued. Release immediately rather than
38
+ // silently becoming a leader nobody is going to use.
39
+ await held.release();
40
+ return;
41
+ }
42
+ lock = held;
43
+ enforced = held.enforced;
44
+ leader = true;
45
+ await options.onPromoted?.();
46
+ })();
47
+ return {
48
+ get isLeader() {
49
+ return leader;
50
+ },
51
+ get enforced() {
52
+ return enforced;
53
+ },
54
+ promoted,
55
+ resign: async () => {
56
+ resigned = true;
57
+ const held = lock;
58
+ lock = null;
59
+ leader = false;
60
+ await held?.release();
61
+ },
62
+ };
63
+ }
64
+ //# sourceMappingURL=leader-election.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"leader-election.js","sourceRoot":"","sources":["../../src/browser/leader-election.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;GAcG;;AA6CH,kCA4CC;AAvFD,uCAAgD;AAoChD;;;;;;GAMG;AACH,SAAgB,WAAW,CACzB,MAAc,EACd,UAAiC,EAAE;IAEnC,IAAI,MAAM,GAAG,KAAK,CAAC;IACnB,IAAI,QAAQ,GAAG,IAAI,CAAC;IACpB,IAAI,IAAI,GAAwB,IAAI,CAAC;IACrC,IAAI,QAAQ,GAAG,KAAK,CAAC;IAErB,MAAM,QAAQ,GAAG,CAAC,KAAK,IAAI,EAAE;QAC3B,wEAAwE;QACxE,yDAAyD;QACzD,MAAM,IAAI,GAAG,MAAM,IAAA,6BAAmB,EAAC,MAAM,EAAE,EAAE,SAAS,EAAE,QAAQ,EAAE,CAAC,CAAC;QAExE,IAAI,QAAQ,EAAE,CAAC;YACb,uEAAuE;YACvE,qDAAqD;YACrD,MAAM,IAAI,CAAC,OAAO,EAAE,CAAC;YACrB,OAAO;QACT,CAAC;QAED,IAAI,GAAG,IAAI,CAAC;QACZ,QAAQ,GAAG,IAAI,CAAC,QAAQ,CAAC;QACzB,MAAM,GAAG,IAAI,CAAC;QAEd,MAAM,OAAO,CAAC,UAAU,EAAE,EAAE,CAAC;IAC/B,CAAC,CAAC,EAAE,CAAC;IAEL,OAAO;QACL,IAAI,QAAQ;YACV,OAAO,MAAM,CAAC;QAChB,CAAC;QACD,IAAI,QAAQ;YACV,OAAO,QAAQ,CAAC;QAClB,CAAC;QACD,QAAQ;QACR,MAAM,EAAE,KAAK,IAAI,EAAE;YACjB,QAAQ,GAAG,IAAI,CAAC;YAChB,MAAM,IAAI,GAAG,IAAI,CAAC;YAClB,IAAI,GAAG,IAAI,CAAC;YACZ,MAAM,GAAG,KAAK,CAAC;YACf,MAAM,IAAI,EAAE,OAAO,EAAE,CAAC;QACxB,CAAC;KACF,CAAC;AACJ,CAAC"}
@@ -0,0 +1,128 @@
1
+ /**
2
+ * shared-transport.ts – one engine, many tabs.
3
+ *
4
+ * `multiTab: 'exclusive'` keeps a second tab safe by refusing it. This serves
5
+ * it instead: one tab wins the election, runs the engine, and answers for
6
+ * everyone else over a `BroadcastChannel`.
7
+ *
8
+ * ## Why only one tab may run the engine
9
+ *
10
+ * Not because concurrent access needs coordinating — because each tab holds
11
+ * its own complete copy of the database in memory and persists the whole
12
+ * image. Two engines on one database is not a race to be locked around; the
13
+ * later persist discards the other's work entirely. So the engine is
14
+ * singular by construction, and the other tabs are clients of it.
15
+ *
16
+ * ## What happens when the leader disappears
17
+ *
18
+ * The lock releases, a follower is promoted, and it starts its own engine from
19
+ * the last persisted image. Writes made in the departed leader's final
20
+ * debounce window are lost — the same exposure a single tab has always had,
21
+ * and no worse.
22
+ *
23
+ * In-flight calls at that moment are handled by what they are, not uniformly:
24
+ * a read is re-issued to the new leader, because running a query twice is
25
+ * indistinguishable from running it once; a write is **rejected**. The old
26
+ * leader may have committed it and died before the reply, so re-issuing could
27
+ * apply it twice. An error a caller can see beats a duplicate row it cannot.
28
+ */
29
+ import type { Row, QueryResult, QueryParams, TransactionOptions } from '../types';
30
+ import type { EngineHandle, EngineTransport } from './engine-transport';
31
+ /** Options for {@link SharedEngineTransport}. */
32
+ export interface SharedEngineTransportOptions {
33
+ /** Logical database name; scopes both the lock and the channel. */
34
+ dbName: string;
35
+ /**
36
+ * Builds the engine. Called **only** if this tab becomes leader, so a
37
+ * follower never loads the 9 MB artifact it would not use.
38
+ */
39
+ createEngine: () => EngineTransport;
40
+ /**
41
+ * How long a follower waits for the leader to answer, in milliseconds.
42
+ *
43
+ * Generous by default because creating a database is slow and the follower
44
+ * cannot tell a slow leader from a dead one.
45
+ *
46
+ * @default 120000
47
+ */
48
+ timeoutMs?: number;
49
+ /**
50
+ * Called on the leader when it serves an operation that changed data.
51
+ *
52
+ * Persistence lives with whoever owns the engine, and a follower's writes
53
+ * are executed by the leader — so without this the leader would never learn
54
+ * that anything needs saving.
55
+ */
56
+ onServedMutation?: () => void;
57
+ /**
58
+ * Called when the engine behind this transport has been replaced.
59
+ *
60
+ * Handles are issued by whichever engine is running, so a leadership change
61
+ * voids every one of them — in every tab, not just the promoted one. The
62
+ * owner must re-open the database before using it again, and it must happen
63
+ * on the leader before any follower is told there is a leader to talk to.
64
+ */
65
+ onEngineReplaced?: () => Promise<void>;
66
+ }
67
+ /**
68
+ * An {@link EngineTransport} backed by whichever tab currently owns the engine.
69
+ *
70
+ * @example
71
+ * ```ts
72
+ * const db = new FirebirdBrowser('mydb', {
73
+ * multiTab: 'shared',
74
+ * worker: () => new Worker('/firebird-engine-worker.js'),
75
+ * });
76
+ * ```
77
+ */
78
+ export declare class SharedEngineTransport implements EngineTransport {
79
+ private readonly dbName;
80
+ private readonly createEngine;
81
+ private readonly timeoutMs;
82
+ private readonly onServedMutation?;
83
+ private readonly onEngineReplaced?;
84
+ private readonly channel;
85
+ private readonly clientId;
86
+ private readonly election;
87
+ /** The real engine. Non-null exactly when this tab is the leader. */
88
+ private engine;
89
+ private readonly pending;
90
+ private nextCallId;
91
+ private disposed;
92
+ /** Highest leadership generation seen; guards against stale announcements. */
93
+ private epoch;
94
+ /** True while this tab is standing its engine up, so calls stay local. */
95
+ private promoting;
96
+ /** Resolves once a leader is known to exist, so calls do not go nowhere. */
97
+ private leaderKnown;
98
+ private announceLeaderKnown;
99
+ constructor(options: SharedEngineTransportOptions);
100
+ /** Whether this tab currently runs the engine. */
101
+ get isLeader(): boolean;
102
+ private assumeLeadership;
103
+ private recoverPending;
104
+ /** Follower side: the leader changed, so re-open against the new one. */
105
+ private reopenAfterLeaderChange;
106
+ private readonly onMessage;
107
+ /** Leader side: run the operation and reply to the caller. */
108
+ private serve;
109
+ private settle;
110
+ private runLocally;
111
+ /** Run `op` here if this tab leads, otherwise ask whoever does. */
112
+ private call;
113
+ init(): Promise<void>;
114
+ createDatabase(path: string): Promise<EngineHandle>;
115
+ attachDatabase(path: string): Promise<EngineHandle>;
116
+ detachDatabase(dbHandle: EngineHandle): Promise<void>;
117
+ execute(dbHandle: EngineHandle, txHandle: EngineHandle, sql: string, params?: QueryParams): Promise<number>;
118
+ query<T extends Row = Row>(dbHandle: EngineHandle, txHandle: EngineHandle, sql: string, params?: QueryParams): Promise<QueryResult<T>>;
119
+ startTransaction(dbHandle: EngineHandle, options?: TransactionOptions): Promise<EngineHandle>;
120
+ commit(txHandle: EngineHandle): Promise<void>;
121
+ rollback(txHandle: EngineHandle): Promise<void>;
122
+ mkdir(path: string): Promise<void>;
123
+ exists(path: string): Promise<boolean>;
124
+ readFile(path: string): Promise<Uint8Array>;
125
+ writeFile(path: string, data: Uint8Array): Promise<void>;
126
+ dispose(): Promise<void>;
127
+ }
128
+ //# sourceMappingURL=shared-transport.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-transport.d.ts","sourceRoot":"","sources":["../../src/browser/shared-transport.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,339 @@
1
+ "use strict";
2
+ /**
3
+ * shared-transport.ts – one engine, many tabs.
4
+ *
5
+ * `multiTab: 'exclusive'` keeps a second tab safe by refusing it. This serves
6
+ * it instead: one tab wins the election, runs the engine, and answers for
7
+ * everyone else over a `BroadcastChannel`.
8
+ *
9
+ * ## Why only one tab may run the engine
10
+ *
11
+ * Not because concurrent access needs coordinating — because each tab holds
12
+ * its own complete copy of the database in memory and persists the whole
13
+ * image. Two engines on one database is not a race to be locked around; the
14
+ * later persist discards the other's work entirely. So the engine is
15
+ * singular by construction, and the other tabs are clients of it.
16
+ *
17
+ * ## What happens when the leader disappears
18
+ *
19
+ * The lock releases, a follower is promoted, and it starts its own engine from
20
+ * the last persisted image. Writes made in the departed leader's final
21
+ * debounce window are lost — the same exposure a single tab has always had,
22
+ * and no worse.
23
+ *
24
+ * In-flight calls at that moment are handled by what they are, not uniformly:
25
+ * a read is re-issued to the new leader, because running a query twice is
26
+ * indistinguishable from running it once; a write is **rejected**. The old
27
+ * leader may have committed it and died before the reply, so re-issuing could
28
+ * apply it twice. An error a caller can see beats a duplicate row it cannot.
29
+ */
30
+ Object.defineProperty(exports, "__esModule", { value: true });
31
+ exports.SharedEngineTransport = void 0;
32
+ const leader_election_1 = require("./leader-election");
33
+ /**
34
+ * Operations safe to re-issue to a new leader after the old one vanished.
35
+ *
36
+ * Reads and existence checks only. Every mutation is absent deliberately: its
37
+ * outcome is unknown once the leader dies mid-call, and "unknown" must not be
38
+ * quietly resolved as "did not happen".
39
+ */
40
+ const REPLAYABLE = new Set([
41
+ 'init',
42
+ 'query',
43
+ 'exists',
44
+ 'readFile',
45
+ ]);
46
+ /** Ops that change the database, and so make the leader's image dirty. */
47
+ const MUTATING = new Set([
48
+ 'execute',
49
+ 'commit',
50
+ 'createDatabase',
51
+ 'writeFile',
52
+ ]);
53
+ const DEFAULT_TIMEOUT_MS = 120000;
54
+ /**
55
+ * An {@link EngineTransport} backed by whichever tab currently owns the engine.
56
+ *
57
+ * @example
58
+ * ```ts
59
+ * const db = new FirebirdBrowser('mydb', {
60
+ * multiTab: 'shared',
61
+ * worker: () => new Worker('/firebird-engine-worker.js'),
62
+ * });
63
+ * ```
64
+ */
65
+ class SharedEngineTransport {
66
+ constructor(options) {
67
+ /** The real engine. Non-null exactly when this tab is the leader. */
68
+ this.engine = null;
69
+ this.pending = new Map();
70
+ this.nextCallId = 1;
71
+ this.disposed = false;
72
+ /** Highest leadership generation seen; guards against stale announcements. */
73
+ this.epoch = 0;
74
+ /** True while this tab is standing its engine up, so calls stay local. */
75
+ this.promoting = false;
76
+ // ── Channel ────────────────────────────────────────────────────────────
77
+ this.onMessage = (event) => {
78
+ const message = event.data;
79
+ switch (message.kind) {
80
+ case 'who-leads':
81
+ // Only a leader answers, and only if it has an engine standing.
82
+ if (this.engine) {
83
+ this.channel.postMessage({
84
+ kind: 'leader',
85
+ epoch: this.epoch,
86
+ });
87
+ }
88
+ return;
89
+ case 'leader':
90
+ this.announceLeaderKnown();
91
+ // A *new* leader, not the one this tab already knew about: its engine
92
+ // is a different engine, so this tab's handles mean nothing to it.
93
+ if (message.epoch > this.epoch) {
94
+ this.epoch = message.epoch;
95
+ if (!this.engine)
96
+ void this.reopenAfterLeaderChange();
97
+ }
98
+ return;
99
+ case 'call':
100
+ if (this.engine)
101
+ void this.serve(message);
102
+ return;
103
+ case 'reply':
104
+ if (message.to === this.clientId)
105
+ this.settle(message);
106
+ return;
107
+ }
108
+ };
109
+ this.dbName = options.dbName;
110
+ this.createEngine = options.createEngine;
111
+ this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS;
112
+ this.onServedMutation = options.onServedMutation;
113
+ this.onEngineReplaced = options.onEngineReplaced;
114
+ this.clientId = `${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 10)}`;
115
+ this.channel = new BroadcastChannel(`firebird-wasm:shared:${this.dbName}`);
116
+ this.channel.addEventListener('message', this.onMessage);
117
+ this.leaderKnown = new Promise((resolve) => {
118
+ this.announceLeaderKnown = resolve;
119
+ });
120
+ this.election = (0, leader_election_1.electLeader)(this.dbName, {
121
+ onPromoted: () => this.assumeLeadership(),
122
+ });
123
+ // A follower that starts while a leader already exists hears nothing until
124
+ // it asks; the leader's announcement happened before this tab existed.
125
+ this.channel.postMessage({ kind: 'who-leads' });
126
+ }
127
+ /** Whether this tab currently runs the engine. */
128
+ get isLeader() {
129
+ return this.election.isLeader;
130
+ }
131
+ // ── Leadership ─────────────────────────────────────────────────────────
132
+ async assumeLeadership() {
133
+ if (this.disposed)
134
+ return;
135
+ this.engine = this.createEngine();
136
+ await this.engine.init();
137
+ // Re-open before announcing. A follower that heard "leader" and attached
138
+ // straight away would be attaching to an engine with no database in it.
139
+ this.promoting = true;
140
+ try {
141
+ await this.onEngineReplaced?.();
142
+ }
143
+ finally {
144
+ this.promoting = false;
145
+ }
146
+ this.announceLeaderKnown();
147
+ this.channel.postMessage({ kind: 'leader', epoch: ++this.epoch });
148
+ // Anything still outstanding was addressed to a leader that no longer
149
+ // exists. Replay what is safe to replay; fail the rest loudly.
150
+ this.recoverPending();
151
+ }
152
+ recoverPending() {
153
+ const outstanding = [...this.pending.entries()];
154
+ this.pending.clear();
155
+ for (const [, call] of outstanding) {
156
+ clearTimeout(call.timer);
157
+ if (REPLAYABLE.has(call.op)) {
158
+ this.runLocally(call.op, call.args).then((value) => call.resolve(value), (err) => call.reject(err instanceof Error ? err : new Error(String(err))));
159
+ continue;
160
+ }
161
+ call.reject(new Error(`The tab running the database closed while "${call.op}" was in ` +
162
+ `flight, and this tab has taken over. The operation may or may ` +
163
+ `not have been applied, so it was not retried — re-check the ` +
164
+ `data before repeating it.`));
165
+ }
166
+ }
167
+ /** Follower side: the leader changed, so re-open against the new one. */
168
+ async reopenAfterLeaderChange() {
169
+ if (this.disposed || this.engine)
170
+ return;
171
+ try {
172
+ await this.onEngineReplaced?.();
173
+ }
174
+ catch {
175
+ // Reported through the owner's own error handling; a throw here would
176
+ // become an unhandled rejection in a channel event listener.
177
+ }
178
+ }
179
+ /** Leader side: run the operation and reply to the caller. */
180
+ async serve(message) {
181
+ let reply;
182
+ try {
183
+ const result = await this.runLocally(message.op, message.args);
184
+ reply = {
185
+ kind: 'reply',
186
+ to: message.from,
187
+ id: message.id,
188
+ ok: true,
189
+ result: result ?? null,
190
+ };
191
+ if (MUTATING.has(message.op)) {
192
+ // The write happened here, but the caller that wanted it is in
193
+ // another tab and will never mark this engine dirty.
194
+ this.onServedMutation?.();
195
+ }
196
+ }
197
+ catch (err) {
198
+ reply = {
199
+ kind: 'reply',
200
+ to: message.from,
201
+ id: message.id,
202
+ ok: false,
203
+ // A string, not an Error: structured cloning drops the prototype and
204
+ // the stack belongs to a tab the caller cannot see anyway.
205
+ error: err instanceof Error ? err.message : String(err),
206
+ };
207
+ }
208
+ this.channel.postMessage(reply);
209
+ }
210
+ settle(message) {
211
+ const call = this.pending.get(message.id);
212
+ if (!call)
213
+ return; // already timed out, or replayed after a promotion
214
+ this.pending.delete(message.id);
215
+ clearTimeout(call.timer);
216
+ if (message.ok) {
217
+ call.resolve(message.result);
218
+ }
219
+ else {
220
+ call.reject(new Error(message.error ?? 'the database tab reported an error'));
221
+ }
222
+ }
223
+ runLocally(op, args) {
224
+ const engine = this.engine;
225
+ if (!engine) {
226
+ return Promise.reject(new Error('not the leader'));
227
+ }
228
+ const fn = engine[op];
229
+ if (typeof fn !== 'function') {
230
+ return Promise.reject(new Error(`unknown engine operation: ${op}`));
231
+ }
232
+ return fn.apply(engine, args);
233
+ }
234
+ // ── Dispatch ───────────────────────────────────────────────────────────
235
+ /** Run `op` here if this tab leads, otherwise ask whoever does. */
236
+ async call(op, ...args) {
237
+ if (this.disposed) {
238
+ throw new Error('SharedEngineTransport has been disposed');
239
+ }
240
+ if (this.engine) {
241
+ return (await this.runLocally(op, args));
242
+ }
243
+ // Do not shout into an empty channel: on a cold start every tab is a
244
+ // follower for the moment it takes the winner to stand its engine up.
245
+ await this.leaderKnown;
246
+ // Promotion can happen while waiting, in which case this is now local.
247
+ if (this.engine) {
248
+ return (await this.runLocally(op, args));
249
+ }
250
+ const id = this.nextCallId++;
251
+ return new Promise((resolve, reject) => {
252
+ const timer = setTimeout(() => {
253
+ this.pending.delete(id);
254
+ reject(new Error(`the tab running database "${this.dbName}" did not answer ` +
255
+ `"${op}" within ${this.timeoutMs}ms`));
256
+ }, this.timeoutMs);
257
+ this.pending.set(id, {
258
+ op,
259
+ args,
260
+ resolve: resolve,
261
+ reject,
262
+ timer,
263
+ });
264
+ this.channel.postMessage({
265
+ kind: 'call',
266
+ from: this.clientId,
267
+ id,
268
+ op,
269
+ args,
270
+ });
271
+ });
272
+ }
273
+ // ── EngineTransport ────────────────────────────────────────────────────
274
+ async init() {
275
+ // Whoever wins the election calls the engine's own init(); a follower has
276
+ // nothing to initialise and must not wait for an engine it will not build.
277
+ await Promise.race([this.election.promoted, this.leaderKnown]);
278
+ }
279
+ createDatabase(path) {
280
+ return this.call('createDatabase', path);
281
+ }
282
+ attachDatabase(path) {
283
+ return this.call('attachDatabase', path);
284
+ }
285
+ detachDatabase(dbHandle) {
286
+ // Followers share the leader's attachment; detaching it because one tab
287
+ // closed would pull the database out from under every other tab.
288
+ if (!this.engine)
289
+ return Promise.resolve();
290
+ return this.call('detachDatabase', dbHandle);
291
+ }
292
+ execute(dbHandle, txHandle, sql, params = []) {
293
+ return this.call('execute', dbHandle, txHandle, sql, params);
294
+ }
295
+ query(dbHandle, txHandle, sql, params = []) {
296
+ return this.call('query', dbHandle, txHandle, sql, params);
297
+ }
298
+ startTransaction(dbHandle, options = {}) {
299
+ return this.call('startTransaction', dbHandle, options);
300
+ }
301
+ commit(txHandle) {
302
+ return this.call('commit', txHandle);
303
+ }
304
+ rollback(txHandle) {
305
+ return this.call('rollback', txHandle);
306
+ }
307
+ mkdir(path) {
308
+ return this.call('mkdir', path);
309
+ }
310
+ exists(path) {
311
+ return this.call('exists', path);
312
+ }
313
+ readFile(path) {
314
+ return this.call('readFile', path);
315
+ }
316
+ writeFile(path, data) {
317
+ return this.call('writeFile', path, data);
318
+ }
319
+ async dispose() {
320
+ if (this.disposed)
321
+ return;
322
+ this.disposed = true;
323
+ for (const [, call] of this.pending) {
324
+ clearTimeout(call.timer);
325
+ call.reject(new Error('SharedEngineTransport has been disposed'));
326
+ }
327
+ this.pending.clear();
328
+ this.channel.removeEventListener('message', this.onMessage);
329
+ this.channel.close();
330
+ const engine = this.engine;
331
+ this.engine = null;
332
+ // Resign last: releasing the lock promotes another tab, which will build
333
+ // its own engine, and this one should be gone before that happens.
334
+ await engine?.dispose();
335
+ await this.election.resign();
336
+ }
337
+ }
338
+ exports.SharedEngineTransport = SharedEngineTransport;
339
+ //# sourceMappingURL=shared-transport.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-transport.js","sourceRoot":"","sources":["../../src/browser/shared-transport.ts"],"names":[],"mappings":"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"}
@@ -9,7 +9,7 @@
9
9
  * The Worker also owns Emscripten's filesystem, which is why the filesystem
10
10
  * operations are part of the transport rather than being done by the caller.
11
11
  */
12
- import type { Row, QueryResult, QueryParams } from '../types';
12
+ import type { Row, QueryResult, QueryParams, TransactionOptions } from '../types';
13
13
  import type { EngineHandle, EngineTransport } from './engine-transport';
14
14
  /** Options accepted by {@link WorkerTransport}. */
15
15
  export interface WorkerTransportOptions {
@@ -51,7 +51,7 @@ export declare class WorkerTransport implements EngineTransport {
51
51
  detachDatabase(dbHandle: EngineHandle): Promise<void>;
52
52
  execute(dbHandle: EngineHandle, txHandle: EngineHandle, sql: string, params?: QueryParams): Promise<number>;
53
53
  query<T extends Row = Row>(dbHandle: EngineHandle, txHandle: EngineHandle, sql: string, params?: QueryParams): Promise<QueryResult<T>>;
54
- startTransaction(dbHandle: EngineHandle): Promise<EngineHandle>;
54
+ startTransaction(dbHandle: EngineHandle, options?: TransactionOptions): Promise<EngineHandle>;
55
55
  commit(txHandle: EngineHandle): Promise<void>;
56
56
  rollback(txHandle: EngineHandle): Promise<void>;
57
57
  mkdir(path: string): Promise<void>;
@@ -1 +1 @@
1
- {"version":3,"file":"worker-transport.d.ts","sourceRoot":"","sources":["../../src/browser/worker-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AAC9D,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGxE,mDAAmD;AACnD,MAAM,WAAW,sBAAsB;IACrC;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD;;;;;;;;GAQG;AACH,qBAAa,eAAgB,YAAW,eAAe;IACrD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IACtD,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAsB;gBAEzB,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B;IAQhE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAqBxB;IAEF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAEtB;IAEF,8DAA8D;IAC9D,OAAO,CAAC,IAAI;IASZ,OAAO,CAAC,IAAI;IAwBZ,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAInD,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAInD,cAAc,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD,OAAO,CACL,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,YAAY,EACtB,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,WAAgB,GACvB,OAAO,CAAC,MAAM,CAAC;IAIlB,KAAK,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG,EACvB,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,YAAY,EACtB,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,WAAgB,GACvB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAI1B,gBAAgB,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,YAAY,CAAC;IAI/D,MAAM,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C,QAAQ,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAItC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAI3C,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAM/B"}
1
+ {"version":3,"file":"worker-transport.d.ts","sourceRoot":"","sources":["../../src/browser/worker-transport.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,UAAU,CAAC;AAClF,OAAO,KAAK,EAAE,YAAY,EAAE,eAAe,EAAE,MAAM,oBAAoB,CAAC;AAGxE,mDAAmD;AACnD,MAAM,WAAW,sBAAsB;IACrC;;;;;;;;OAQG;IACH,SAAS,CAAC,EAAE,MAAM,CAAC;CACpB;AAUD;;;;;;;;GAQG;AACH,qBAAa,eAAgB,YAAW,eAAe;IACrD,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,OAAO,CAA8B;IACtD,OAAO,CAAC,MAAM,CAAK;IACnB,OAAO,CAAC,OAAO,CAAsB;gBAEzB,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,sBAA2B;IAQhE,OAAO,CAAC,QAAQ,CAAC,SAAS,CAqBxB;IAEF,OAAO,CAAC,QAAQ,CAAC,OAAO,CAEtB;IAEF,8DAA8D;IAC9D,OAAO,CAAC,IAAI;IASZ,OAAO,CAAC,IAAI;IAwBZ,IAAI,IAAI,OAAO,CAAC,IAAI,CAAC;IAIrB,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAInD,cAAc,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;IAInD,cAAc,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAIrD,OAAO,CACL,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,YAAY,EACtB,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,WAAgB,GACvB,OAAO,CAAC,MAAM,CAAC;IAIlB,KAAK,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG,EACvB,QAAQ,EAAE,YAAY,EACtB,QAAQ,EAAE,YAAY,EACtB,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,WAAgB,GACvB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAI1B,gBAAgB,CACd,QAAQ,EAAE,YAAY,EACtB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,YAAY,CAAC;IAKxB,MAAM,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAI7C,QAAQ,CAAC,QAAQ,EAAE,YAAY,GAAG,OAAO,CAAC,IAAI,CAAC;IAI/C,KAAK,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlC,MAAM,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,OAAO,CAAC;IAItC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,UAAU,CAAC;IAI3C,SAAS,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,UAAU,GAAG,OAAO,CAAC,IAAI,CAAC;IAIlD,OAAO,IAAI,OAAO,CAAC,IAAI,CAAC;CAM/B"}
@@ -101,8 +101,9 @@ class WorkerTransport {
101
101
  query(dbHandle, txHandle, sql, params = []) {
102
102
  return this.call('query', dbHandle, txHandle, sql, params);
103
103
  }
104
- startTransaction(dbHandle) {
105
- return this.call('startTransaction', dbHandle);
104
+ startTransaction(dbHandle, options = {}) {
105
+ // Plain data, so it survives structured cloning to the Worker as-is.
106
+ return this.call('startTransaction', dbHandle, options);
106
107
  }
107
108
  commit(txHandle) {
108
109
  return this.call('commit', txHandle);
@@ -1 +1 @@
1
- {"version":3,"file":"worker-transport.js","sourceRoot":"","sources":["../../src/browser/worker-transport.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"worker-transport.js","sourceRoot":"","sources":["../../src/browser/worker-transport.ts"],"names":[],"mappings":"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"}