firebird-wasm 0.2.0 → 0.4.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 (68) hide show
  1. package/CHANGELOG.md +199 -0
  2. package/README.md +4 -1
  3. package/dist/.tsbuildinfo.build +1 -1
  4. package/dist/browser/engine-transport.d.ts +63 -5
  5. package/dist/browser/engine-transport.d.ts.map +1 -1
  6. package/dist/browser/engine-transport.js +290 -8
  7. package/dist/browser/engine-transport.js.map +1 -1
  8. package/dist/browser/firebird-browser.d.ts +252 -7
  9. package/dist/browser/firebird-browser.d.ts.map +1 -1
  10. package/dist/browser/firebird-browser.js +373 -20
  11. package/dist/browser/firebird-browser.js.map +1 -1
  12. package/dist/browser/index.d.ts +8 -2
  13. package/dist/browser/index.d.ts.map +1 -1
  14. package/dist/browser/index.js +19 -3
  15. package/dist/browser/index.js.map +1 -1
  16. package/dist/browser/opfs-fs.d.ts +72 -0
  17. package/dist/browser/opfs-fs.d.ts.map +1 -0
  18. package/dist/browser/opfs-fs.js +249 -0
  19. package/dist/browser/opfs-fs.js.map +1 -0
  20. package/dist/browser/params.d.ts +30 -3
  21. package/dist/browser/params.d.ts.map +1 -1
  22. package/dist/browser/params.js +97 -22
  23. package/dist/browser/params.js.map +1 -1
  24. package/dist/browser/shared-transport.d.ts +9 -2
  25. package/dist/browser/shared-transport.d.ts.map +1 -1
  26. package/dist/browser/shared-transport.js +33 -2
  27. package/dist/browser/shared-transport.js.map +1 -1
  28. package/dist/browser/statement-types.d.ts +18 -0
  29. package/dist/browser/statement-types.d.ts.map +1 -0
  30. package/dist/browser/statement-types.js +39 -0
  31. package/dist/browser/statement-types.js.map +1 -0
  32. package/dist/browser/value-types.d.ts +173 -0
  33. package/dist/browser/value-types.d.ts.map +1 -0
  34. package/dist/browser/value-types.js +222 -0
  35. package/dist/browser/value-types.js.map +1 -0
  36. package/dist/browser/worker-entry.d.ts.map +1 -1
  37. package/dist/browser/worker-entry.js +38 -1
  38. package/dist/browser/worker-entry.js.map +1 -1
  39. package/dist/browser/worker-protocol.d.ts +1 -1
  40. package/dist/browser/worker-protocol.d.ts.map +1 -1
  41. package/dist/browser/worker-transport.d.ts +9 -2
  42. package/dist/browser/worker-transport.d.ts.map +1 -1
  43. package/dist/browser/worker-transport.js +29 -2
  44. package/dist/browser/worker-transport.js.map +1 -1
  45. package/dist/firebird.d.ts +69 -5
  46. package/dist/firebird.d.ts.map +1 -1
  47. package/dist/firebird.js +187 -49
  48. package/dist/firebird.js.map +1 -1
  49. package/dist/index.d.ts +4 -1
  50. package/dist/index.d.ts.map +1 -1
  51. package/dist/index.js +9 -1
  52. package/dist/index.js.map +1 -1
  53. package/dist/sql-tag.d.ts +184 -0
  54. package/dist/sql-tag.d.ts.map +1 -0
  55. package/dist/sql-tag.js +287 -0
  56. package/dist/sql-tag.js.map +1 -0
  57. package/dist/statement-types.d.ts +23 -0
  58. package/dist/statement-types.d.ts.map +1 -0
  59. package/dist/statement-types.js +44 -0
  60. package/dist/statement-types.js.map +1 -0
  61. package/dist/types.d.ts +62 -0
  62. package/dist/types.d.ts.map +1 -1
  63. package/dist/wasm/firebird-embedded.js +1 -1
  64. package/dist/wasm/firebird-embedded.wasm +0 -0
  65. package/dist/wasm-loader.d.ts +44 -2
  66. package/dist/wasm-loader.d.ts.map +1 -1
  67. package/dist/wasm-loader.js.map +1 -1
  68. package/package.json +3 -2
@@ -25,6 +25,36 @@
25
25
  Object.defineProperty(exports, "__esModule", { value: true });
26
26
  exports.serveEngine = serveEngine;
27
27
  const engine_transport_1 = require("./engine-transport");
28
+ /**
29
+ * Every distinct ArrayBuffer behind a Uint8Array in a query result.
30
+ *
31
+ * Only query results are walked, and only one level into each row: a value is
32
+ * either a blob or it is not, and scanning arbitrary structures on every reply
33
+ * would cost more than the transfer saves.
34
+ *
35
+ * De-duplicated because transferring the same buffer twice throws
36
+ * DataCloneError, and two rows can hold views on one buffer if the same blob
37
+ * appeared twice.
38
+ */
39
+ function collectBlobBuffers(result) {
40
+ if (typeof result !== 'object' || result === null)
41
+ return [];
42
+ const rows = result.rows;
43
+ if (!Array.isArray(rows))
44
+ return [];
45
+ const buffers = new Set();
46
+ for (const row of rows) {
47
+ if (typeof row !== 'object' || row === null)
48
+ continue;
49
+ // Rows are arrays in rowMode 'array' and plain objects otherwise;
50
+ // Object.values covers both.
51
+ for (const value of Object.values(row)) {
52
+ if (value instanceof Uint8Array)
53
+ buffers.add(value.buffer);
54
+ }
55
+ }
56
+ return [...buffers];
57
+ }
28
58
  /**
29
59
  * Wire a transport up to a Worker scope.
30
60
  *
@@ -35,7 +65,14 @@ function serveEngine(scope, transport) {
35
65
  const reply = (response) => {
36
66
  // Transfer the buffer for readFile rather than copying it: a database
37
67
  // image is measured in megabytes and this runs on every persist.
38
- const transfer = response.result instanceof Uint8Array ? [response.result.buffer] : [];
68
+ //
69
+ // The same applies to binary BLOBs coming back from a query, which arrive
70
+ // as Uint8Arrays inside the rows. Structured cloning would copy every one
71
+ // of them across the boundary — the cost a base64 string could never avoid
72
+ // and the reason the side channel is worth having at all.
73
+ const transfer = response.result instanceof Uint8Array
74
+ ? [response.result.buffer]
75
+ : collectBlobBuffers(response.result);
39
76
  scope.postMessage(response, transfer);
40
77
  };
41
78
  scope.addEventListener('message', (event) => {
@@ -1 +1 @@
1
- {"version":3,"file":"worker-entry.js","sourceRoot":"","sources":["../../src/browser/worker-entry.ts"],"names":[],"mappings":";AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;;AAiCH,kCAoCC;AAnED,yDAAqD;AAyBrD;;;;;GAKG;AACH,SAAgB,WAAW,CACzB,KAAwB,EACxB,SAA0B;IAE1B,MAAM,KAAK,GAAG,CAAC,QAAwB,EAAQ,EAAE;QAC/C,sEAAsE;QACtE,iEAAiE;QACjE,MAAM,QAAQ,GACZ,QAAQ,CAAC,MAAM,YAAY,UAAU,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC;QACxE,KAAK,CAAC,WAAW,CAAC,QAAQ,EAAE,QAA0B,CAAC,CAAC;IAC1D,CAAC,CAAC;IAEF,KAAK,CAAC,gBAAgB,CAAC,SAAS,EAAE,CAAC,KAAkC,EAAE,EAAE;QACvE,MAAM,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,GAAG,KAAK,CAAC,IAAI,CAAC;QAEpC,KAAK,CAAC,KAAK,IAAI,EAAE;YACf,IAAI,CAAC;gBACH,sEAAsE;gBACtE,oEAAoE;gBACpE,MAAM,EAAE,GAAI,SAA8E,CAAC,EAAE,CAAC,CAAC;gBAE/F,IAAI,OAAO,EAAE,KAAK,UAAU,EAAE,CAAC;oBAC7B,MAAM,IAAI,KAAK,CAAC,6BAA6B,EAAE,EAAE,CAAC,CAAC;gBACrD,CAAC;gBAED,MAAM,MAAM,GAAG,CAAC,MAAM,EAAE,CAAC,KAAK,CAAC,SAAS,EAAE,IAAI,CAAC,CAAC,IAAI,IAAI,CAAC;gBACzD,KAAK,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,IAAI,EAAE,MAAM,EAAE,MAAkC,EAAE,CAAC,CAAC;YACtE,CAAC;YAAC,OAAO,GAAG,EAAE,CAAC;gBACb,KAAK,CAAC;oBACJ,EAAE;oBACF,EAAE,EAAE,KAAK;oBACT,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;iBACxD,CAAC,CAAC;YACL,CAAC;QACH,CAAC,CAAC,EAAE,CAAC;IACP,CAAC,CAAC,CAAC;AACL,CAAC;AAED,6CAA6C;AAC7C,IAAI,OAAO,IAAI,KAAK,WAAW,IAAI,OAAO,IAAI,CAAC,WAAW,KAAK,UAAU,EAAE,CAAC;IAC1E,IAAI,CAAC;QACH,WAAW,CAAC,IAAI,EAAE,IAAI,kCAAe,CAAC,IAAI,CAAC,uBAAuB,IAAI,EAAE,CAAC,CAAC,CAAC;IAC7E,CAAC;IAAC,OAAO,GAAG,EAAE,CAAC;QACb,yEAAyE;QACzE,6DAA6D;QAC7D,IAAI,CAAC,WAAW,CAAC;YACf,EAAE,EAAE,CAAC,CAAC;YACN,EAAE,EAAE,KAAK;YACT,KAAK,EAAE,GAAG,YAAY,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;SACxD,CAAC,CAAC;IACL,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"worker-entry.js","sourceRoot":"","sources":["../../src/browser/worker-entry.ts"],"names":[],"mappings":"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"}
@@ -8,7 +8,7 @@
8
8
  import type { Row, QueryResult } from '../types';
9
9
  import type { EngineHandle } from './engine-transport';
10
10
  /** Operations the Worker understands. One per EngineTransport method. */
11
- export type EngineOp = 'init' | 'createDatabase' | 'attachDatabase' | 'detachDatabase' | 'execute' | 'query' | 'startTransaction' | 'commit' | 'rollback' | 'mkdir' | 'exists' | 'readFile' | 'writeFile';
11
+ export type EngineOp = 'init' | 'createDatabase' | 'attachDatabase' | 'detachDatabase' | 'execute' | 'executeBatch' | 'query' | 'describe' | 'startTransaction' | 'commit' | 'rollback' | 'mkdir' | 'exists' | 'readFile' | 'writeFile' | 'unlink' | 'mountOpfs' | 'eventsSubscribe' | 'eventsPoll' | 'eventsCancel';
12
12
  /** A call from the main thread to the Worker. */
13
13
  export interface EngineRequest {
14
14
  id: number;
@@ -1 +1 @@
1
- {"version":3,"file":"worker-protocol.d.ts","sourceRoot":"","sources":["../../src/browser/worker-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,0EAA0E;AAC1E,MAAM,MAAM,QAAQ,GAChB,MAAM,GACN,gBAAgB,GAChB,gBAAgB,GAChB,gBAAgB,GAChB,SAAS,GACT,OAAO,GACP,kBAAkB,GAClB,QAAQ,GACR,UAAU,GACV,OAAO,GACP,QAAQ,GACR,UAAU,GACV,WAAW,CAAC;AAEhB,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,QAAQ,CAAC;IACb,IAAI,EAAE,OAAO,EAAE,CAAC;CACjB;AAED,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,OAAO,CAAC;IACZ,yBAAyB;IACzB,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAChF;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,mFAAmF;AACnF,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,CAAC,CAAC,CAAC;IACP,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACf"}
1
+ {"version":3,"file":"worker-protocol.d.ts","sourceRoot":"","sources":["../../src/browser/worker-protocol.ts"],"names":[],"mappings":"AAAA;;;;;;GAMG;AAEH,OAAO,KAAK,EAAE,GAAG,EAAE,WAAW,EAAE,MAAM,UAAU,CAAC;AACjD,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD,0EAA0E;AAC1E,MAAM,MAAM,QAAQ,GAChB,MAAM,GACN,gBAAgB,GAChB,gBAAgB,GAChB,gBAAgB,GAChB,SAAS,GACT,cAAc,GACd,OAAO,GACP,UAAU,GACV,kBAAkB,GAClB,QAAQ,GACR,UAAU,GACV,OAAO,GACP,QAAQ,GACR,UAAU,GACV,WAAW,GACX,QAAQ,GACR,WAAW,GACX,iBAAiB,GACjB,YAAY,GACZ,cAAc,CAAC;AAEnB,iDAAiD;AACjD,MAAM,WAAW,aAAa;IAC5B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,QAAQ,CAAC;IACb,IAAI,EAAE,OAAO,EAAE,CAAC;CACjB;AAED,4EAA4E;AAC5E,MAAM,WAAW,cAAc;IAC7B,EAAE,EAAE,MAAM,CAAC;IACX,EAAE,EAAE,OAAO,CAAC;IACZ,yBAAyB;IACzB,MAAM,CAAC,EAAE,YAAY,GAAG,MAAM,GAAG,OAAO,GAAG,UAAU,GAAG,WAAW,CAAC,GAAG,CAAC,GAAG,IAAI,CAAC;IAChF;;;;OAIG;IACH,KAAK,CAAC,EAAE,MAAM,CAAC;CAChB;AAED,mFAAmF;AACnF,MAAM,WAAW,WAAW;IAC1B,EAAE,EAAE,CAAC,CAAC,CAAC;IACP,EAAE,EAAE,KAAK,CAAC;IACV,KAAK,EAAE,MAAM,CAAC;CACf"}
@@ -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, TransactionOptions } from '../types';
12
+ import type { Row, QueryResult, QueryDescription, QueryParams, RowMode, TransactionOptions } from '../types';
13
13
  import type { EngineHandle, EngineTransport } from './engine-transport';
14
14
  /** Options accepted by {@link WorkerTransport}. */
15
15
  export interface WorkerTransportOptions {
@@ -50,7 +50,9 @@ export declare class WorkerTransport implements EngineTransport {
50
50
  attachDatabase(path: string): Promise<EngineHandle>;
51
51
  detachDatabase(dbHandle: EngineHandle): Promise<void>;
52
52
  execute(dbHandle: EngineHandle, txHandle: EngineHandle, sql: string, params?: QueryParams): Promise<number>;
53
- query<T extends Row = Row>(dbHandle: EngineHandle, txHandle: EngineHandle, sql: string, params?: QueryParams): Promise<QueryResult<T>>;
53
+ executeBatch(dbHandle: EngineHandle, txHandle: EngineHandle, sql: string, rows: QueryParams[]): Promise<number>;
54
+ query<T = Row>(dbHandle: EngineHandle, txHandle: EngineHandle, sql: string, params?: QueryParams, rowMode?: RowMode, binaryBlobs?: boolean): Promise<QueryResult<T>>;
55
+ describe(dbHandle: EngineHandle, txHandle: EngineHandle, sql: string): Promise<QueryDescription>;
54
56
  startTransaction(dbHandle: EngineHandle, options?: TransactionOptions): Promise<EngineHandle>;
55
57
  commit(txHandle: EngineHandle): Promise<void>;
56
58
  rollback(txHandle: EngineHandle): Promise<void>;
@@ -58,6 +60,11 @@ export declare class WorkerTransport implements EngineTransport {
58
60
  exists(path: string): Promise<boolean>;
59
61
  readFile(path: string): Promise<Uint8Array>;
60
62
  writeFile(path: string, data: Uint8Array): Promise<void>;
63
+ unlink(path: string): Promise<void>;
64
+ eventsSubscribe(dbHandle: EngineHandle, names: string[]): Promise<number>;
65
+ eventsPoll(subscription: number): Promise<Record<string, number>>;
66
+ eventsCancel(subscription: number): Promise<void>;
67
+ mountOpfs(dbName: string): Promise<string>;
61
68
  dispose(): Promise<void>;
62
69
  }
63
70
  //# sourceMappingURL=worker-transport.d.ts.map
@@ -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,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"}
1
+ {"version":3,"file":"worker-transport.d.ts","sourceRoot":"","sources":["../../src/browser/worker-transport.ts"],"names":[],"mappings":"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"}
@@ -98,8 +98,19 @@ class WorkerTransport {
98
98
  execute(dbHandle, txHandle, sql, params = []) {
99
99
  return this.call('execute', dbHandle, txHandle, sql, params);
100
100
  }
101
- query(dbHandle, txHandle, sql, params = []) {
102
- return this.call('query', dbHandle, txHandle, sql, params);
101
+ executeBatch(dbHandle, txHandle, sql, rows) {
102
+ return this.call('executeBatch', dbHandle, txHandle, sql, rows);
103
+ }
104
+ query(dbHandle, txHandle, sql, params = [], rowMode = 'object', binaryBlobs = false) {
105
+ // Decoding happens on the far side, so both of these have to travel with
106
+ // the call rather than being applied to what comes back. They are a string
107
+ // and a boolean, so they survive structured cloning like the rest of the
108
+ // arguments — and the Uint8Arrays that come back from a side-channelled
109
+ // BLOB survive it too, which is what made this placement possible.
110
+ return this.call('query', dbHandle, txHandle, sql, params, rowMode, binaryBlobs);
111
+ }
112
+ describe(dbHandle, txHandle, sql) {
113
+ return this.call('describe', dbHandle, txHandle, sql);
103
114
  }
104
115
  startTransaction(dbHandle, options = {}) {
105
116
  // Plain data, so it survives structured cloning to the Worker as-is.
@@ -123,6 +134,22 @@ class WorkerTransport {
123
134
  writeFile(path, data) {
124
135
  return this.call('writeFile', path, data);
125
136
  }
137
+ unlink(path) {
138
+ return this.call('unlink', path);
139
+ }
140
+ eventsSubscribe(dbHandle, names) {
141
+ return this.call('eventsSubscribe', dbHandle, names);
142
+ }
143
+ eventsPoll(subscription) {
144
+ return this.call('eventsPoll', subscription);
145
+ }
146
+ eventsCancel(subscription) {
147
+ return this.call('eventsCancel', subscription);
148
+ }
149
+ mountOpfs(dbName) {
150
+ // The mount happens on the far side; only the resulting path comes back.
151
+ return this.call('mountOpfs', dbName);
152
+ }
126
153
  async dispose() {
127
154
  this.worker.removeEventListener('message', this.onMessage);
128
155
  this.worker.removeEventListener('error', this.onError);
@@ -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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"}
@@ -1,5 +1,10 @@
1
1
  import type { Attachment, Transaction } from 'node-firebird-driver';
2
- import type { FirebirdLiteOptions, QueryResult, Row, QueryParams, TransactionOptions } from './types';
2
+ import type { ArrayRow, FirebirdLiteOptions, QueryDescription, QueryResult, QueryOptions, Row, QueryParams, RowMode, TransactionOptions } from './types';
3
+ import type { SqlFragment } from './sql-tag';
4
+ /** `QueryOptions` with the array mode pinned, for the overloads below. */
5
+ type ArrayModeOptions = QueryOptions & {
6
+ rowMode: 'array';
7
+ };
3
8
  /**
4
9
  * FirebirdLite – a PGlite-style wrapper around Firebird Embedded.
5
10
  *
@@ -32,15 +37,53 @@ export declare class FirebirdLite {
32
37
  * Execute a DDL or DML statement that does not return rows.
33
38
  *
34
39
  * The statement is executed in its own auto-committed transaction.
40
+ *
41
+ * Accepts a `` sql`…` `` fragment in place of a string, in which case its
42
+ * values are bound rather than interpolated.
43
+ */
44
+ exec(sql: string | SqlFragment, params?: QueryParams): Promise<void>;
45
+ /**
46
+ * Execute one statement once per row of parameters: a batch, prepared once
47
+ * and executed per row in one transaction, all or nothing. The same call
48
+ * as the browser backend's.
35
49
  */
36
- exec(sql: string): Promise<void>;
50
+ execBatch(sql: string, rows: QueryParams[]): Promise<void>;
37
51
  /**
38
52
  * Execute a (parameterised) SQL statement and return the result rows.
39
53
  *
40
54
  * For SELECT queries the rows are returned as plain objects keyed by the
41
55
  * (upper-cased) column name, mirroring the PGlite convention.
56
+ *
57
+ * ```ts
58
+ * await db.query('SELECT * FROM items WHERE id = ?', [id]);
59
+ * await db.query(sql`SELECT * FROM items WHERE id = ${id}`);
60
+ * ```
61
+ */
62
+ query(sql: SqlFragment, options: ArrayModeOptions): Promise<QueryResult<ArrayRow>>;
63
+ query(sql: string | SqlFragment, params: QueryParams | undefined, options: ArrayModeOptions): Promise<QueryResult<ArrayRow>>;
64
+ query<T extends Row = Row>(sql: SqlFragment, options?: QueryOptions): Promise<QueryResult<T>>;
65
+ query<T extends Row = Row>(sql: string, params?: QueryParams, options?: QueryOptions): Promise<QueryResult<T>>;
66
+ query<T extends Row = Row>(sql: string | SqlFragment, params?: QueryParams, options?: QueryOptions): Promise<QueryResult<T>>;
67
+ /**
68
+ * Describe a statement's shape without running it.
69
+ *
70
+ * ```ts
71
+ * const shape = await db.describeQuery('SELECT id, name FROM items WHERE id = ?');
72
+ * // shape.fields → [{ name: 'ID' }, { name: 'NAME' }]
73
+ * // shape.statementType → 'SELECT'
74
+ * ```
75
+ *
76
+ * The statement is prepared and disposed, so nothing runs: describing an
77
+ * `INSERT` inserts nothing.
78
+ *
79
+ * **`params` is `undefined` here.** The native driver exposes no input
80
+ * metadata — `Statement` offers `columnLabels`, `hasResultSet` and `type`
81
+ * and nothing about `?` placeholders — and an empty array would claim the
82
+ * statement takes none. `fields` carries names only, for the same reason
83
+ * `FieldInfo` does everywhere on this backend. The WASM backend reports both
84
+ * in full.
42
85
  */
43
- query<T extends Row = Row>(sql: string, params?: QueryParams, options?: TransactionOptions): Promise<QueryResult<T>>;
86
+ describeQuery(sql: string | SqlFragment): Promise<QueryDescription>;
44
87
  /**
45
88
  * Run a function inside an explicit transaction.
46
89
  *
@@ -60,14 +103,35 @@ export declare class FirebirdLite {
60
103
  export declare class FirebirdTransaction {
61
104
  private readonly attachment;
62
105
  private readonly transaction;
106
+ private finished;
63
107
  constructor(attachment: Attachment, transaction: Transaction);
108
+ /** Whether this transaction has already been rolled back. */
109
+ get isFinished(): boolean;
110
+ /**
111
+ * Roll this transaction back and stop.
112
+ *
113
+ * The enclosing `transaction()` will not commit afterwards. Use this to
114
+ * abandon a transaction deliberately, rather than throwing an error you do
115
+ * not mean — throwing also rolls back, but it propagates to the caller.
116
+ */
117
+ rollback(): Promise<void>;
118
+ private assertUsable;
64
119
  /**
65
120
  * Execute a DDL or DML statement inside this transaction.
66
121
  */
67
- exec(sql: string, params?: QueryParams): Promise<void>;
122
+ exec(sql: string | SqlFragment, params?: QueryParams): Promise<void>;
123
+ /**
124
+ * Execute one statement once per row of parameters inside this
125
+ * transaction: prepared once, executed per row.
126
+ */
127
+ execBatch(sql: string, rows: QueryParams[]): Promise<void>;
68
128
  /**
69
129
  * Execute a SELECT statement inside this transaction and return rows.
70
130
  */
71
- query<T extends Row = Row>(sql: string, params?: QueryParams): Promise<QueryResult<T>>;
131
+ query(sql: string | SqlFragment, params: QueryParams | undefined, options: ArrayModeOptions): Promise<QueryResult<ArrayRow>>;
132
+ query<T extends Row = Row>(sql: string | SqlFragment, params?: QueryParams, options?: {
133
+ rowMode?: RowMode;
134
+ }): Promise<QueryResult<T>>;
72
135
  }
136
+ export {};
73
137
  //# sourceMappingURL=firebird.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"firebird.d.ts","sourceRoot":"","sources":["../src/firebird.ts"],"names":[],"mappings":"AAOA,OAAO,KAAK,EAEV,UAAU,EACV,WAAW,EAEZ,MAAM,sBAAsB,CAAC;AAC9B,OAAO,KAAK,EACV,mBAAmB,EACnB,WAAW,EACX,GAAG,EACH,WAAW,EACX,kBAAkB,EAEnB,MAAM,SAAS,CAAC;AAEjB;;;;;;;;;;;;;;;GAeG;AACH,qBAAa,YAAY;IACvB,OAAO,CAAC,QAAQ,CAAC,MAAM,CAAS;IAChC,OAAO,CAAC,QAAQ,CAAC,WAAW,CAAS;IACrC,OAAO,CAAC,QAAQ,CAAC,cAAc,CAAoE;IACnG,OAAO,CAAC,MAAM,CAAuB;IACrC,OAAO,CAAC,UAAU,CAA2B;IAC7C,OAAO,CAAC,MAAM,CAAS;gBAEX,MAAM,EAAE,MAAM,EAAE,OAAO,GAAE,mBAAwB;IAU7D;;OAEG;YACW,WAAW;IAgBzB;;;;OAIG;IACG,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC;IAatC;;;;;OAKG;IACG,KAAK,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG,EAC7B,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,WAAgB,EACxB,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;IAqC1B;;;;;OAKG;IACG,WAAW,CAAC,CAAC,EACjB,EAAE,EAAE,CAAC,EAAE,EAAE,mBAAmB,KAAK,OAAO,CAAC,CAAC,CAAC,EAC3C,OAAO,GAAE,kBAAuB,GAC/B,OAAO,CAAC,CAAC,CAAC;IAkBb;;OAEG;IACG,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAa7B;AAED;;;GAGG;AACH,qBAAa,mBAAmB;IAE5B,OAAO,CAAC,QAAQ,CAAC,UAAU;IAC3B,OAAO,CAAC,QAAQ,CAAC,WAAW;gBADX,UAAU,EAAE,UAAU,EACtB,WAAW,EAAE,WAAW;IAG3C;;OAEG;IACG,IAAI,CAAC,GAAG,EAAE,MAAM,EAAE,MAAM,GAAE,WAAgB,GAAG,OAAO,CAAC,IAAI,CAAC;IAahE;;OAEG;IACG,KAAK,CAAC,CAAC,SAAS,GAAG,GAAG,GAAG,EAC7B,GAAG,EAAE,MAAM,EACX,MAAM,GAAE,WAAgB,GACvB,OAAO,CAAC,WAAW,CAAC,CAAC,CAAC,CAAC;CAkB3B"}
1
+ {"version":3,"file":"firebird.d.ts","sourceRoot":"","sources":["../src/firebird.ts"],"names":[],"mappings":"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"}
package/dist/firebird.js CHANGED
@@ -3,6 +3,8 @@ Object.defineProperty(exports, "__esModule", { value: true });
3
3
  exports.FirebirdTransaction = exports.FirebirdLite = void 0;
4
4
  const node_firebird_driver_native_1 = require("node-firebird-driver-native");
5
5
  const node_firebird_driver_1 = require("node-firebird-driver");
6
+ const statement_types_1 = require("./statement-types");
7
+ const sql_tag_1 = require("./sql-tag");
6
8
  /**
7
9
  * FirebirdLite – a PGlite-style wrapper around Firebird Embedded.
8
10
  *
@@ -54,14 +56,72 @@ class FirebirdLite {
54
56
  * Execute a DDL or DML statement that does not return rows.
55
57
  *
56
58
  * The statement is executed in its own auto-committed transaction.
59
+ *
60
+ * Accepts a `` sql`…` `` fragment in place of a string, in which case its
61
+ * values are bound rather than interpolated.
62
+ */
63
+ async exec(sql, params = []) {
64
+ // Delegated rather than reimplemented: "parameters present → prepare,
65
+ // execute, dispose; otherwise execute directly" is a rule that belongs in
66
+ // one place, and `transaction()` already wraps it in the commit-or-roll-
67
+ // back this needs. Two copies would drift the first time either grows a
68
+ // case.
69
+ await this.transaction((tx) => tx.exec(sql, params));
70
+ }
71
+ /**
72
+ * Execute one statement once per row of parameters: a batch, prepared once
73
+ * and executed per row in one transaction, all or nothing. The same call
74
+ * as the browser backend's.
57
75
  */
58
- async exec(sql) {
76
+ async execBatch(sql, rows) {
77
+ await this.transaction((tx) => tx.execBatch(sql, rows));
78
+ }
79
+ async query(sql, paramsOrOptions = [], maybeOptions = {}) {
59
80
  await this.ensureReady();
81
+ const { statement, options } = (0, sql_tag_1.resolveQueryCall)(sql, paramsOrOptions, maybeOptions);
82
+ const rowMode = options.rowMode ?? 'object';
60
83
  const attachment = this.attachment;
61
- const transaction = await attachment.startTransaction();
84
+ const txOptions = buildTransactionOptions(options);
85
+ const transaction = await attachment.startTransaction(txOptions);
62
86
  try {
63
- await attachment.execute(transaction, sql);
87
+ const stmt = await attachment.prepare(transaction, statement.sql);
88
+ let rows;
89
+ let fields;
90
+ // Disposed in `finally`, not after the fetch: a statement that throws on
91
+ // execute — a lock conflict, an overflow, a wrong parameter count — would
92
+ // otherwise leak its handle, and the retry loop such failures are usually
93
+ // wrapped in leaks one per attempt until the attachment refuses more.
94
+ try {
95
+ const columnLabels = await stmt.columnLabels;
96
+ fields = columnLabels.map((label) => ({ name: label.toUpperCase() }));
97
+ if (stmt.hasResultSet) {
98
+ const resultSet = await stmt.executeQuery(transaction, statement.params);
99
+ // Same reasoning one level down: a failing fetch must still close.
100
+ try {
101
+ const rawRows = await resultSet.fetch();
102
+ // The driver already hands back positional rows, so array mode is
103
+ // the shape that costs nothing — object mode is the one that
104
+ // builds.
105
+ rows = (rowMode === 'array'
106
+ ? rawRows
107
+ : rawRows.map((cols) => Object.fromEntries(fields.map((f, i) => [f.name, cols[i]]))));
108
+ }
109
+ finally {
110
+ await resultSet.close().catch(() => undefined);
111
+ }
112
+ }
113
+ else {
114
+ await stmt.execute(transaction, statement.params);
115
+ rows = [];
116
+ }
117
+ }
118
+ finally {
119
+ await stmt.dispose().catch(() => undefined);
120
+ }
121
+ // After the statement is disposed, as before — the commit is the last
122
+ // thing that happens on the success path.
64
123
  await transaction.commit();
124
+ return { rows, fields };
65
125
  }
66
126
  catch (err) {
67
127
  await transaction.rollback().catch(() => undefined);
@@ -69,40 +129,49 @@ class FirebirdLite {
69
129
  }
70
130
  }
71
131
  /**
72
- * Execute a (parameterised) SQL statement and return the result rows.
132
+ * Describe a statement's shape without running it.
133
+ *
134
+ * ```ts
135
+ * const shape = await db.describeQuery('SELECT id, name FROM items WHERE id = ?');
136
+ * // shape.fields → [{ name: 'ID' }, { name: 'NAME' }]
137
+ * // shape.statementType → 'SELECT'
138
+ * ```
139
+ *
140
+ * The statement is prepared and disposed, so nothing runs: describing an
141
+ * `INSERT` inserts nothing.
73
142
  *
74
- * For SELECT queries the rows are returned as plain objects keyed by the
75
- * (upper-cased) column name, mirroring the PGlite convention.
143
+ * **`params` is `undefined` here.** The native driver exposes no input
144
+ * metadata — `Statement` offers `columnLabels`, `hasResultSet` and `type`
145
+ * and nothing about `?` placeholders — and an empty array would claim the
146
+ * statement takes none. `fields` carries names only, for the same reason
147
+ * `FieldInfo` does everywhere on this backend. The WASM backend reports both
148
+ * in full.
76
149
  */
77
- async query(sql, params = [], options = {}) {
150
+ async describeQuery(sql) {
78
151
  await this.ensureReady();
79
152
  const attachment = this.attachment;
80
- const txOptions = buildTransactionOptions(options);
81
- const transaction = await attachment.startTransaction(txOptions);
153
+ const text = (0, sql_tag_1.toStatement)(sql).sql;
154
+ const transaction = await attachment.startTransaction();
82
155
  try {
83
- const stmt = await attachment.prepare(transaction, sql);
84
- const columnLabels = await stmt.columnLabels;
85
- const fields = columnLabels.map((label) => ({
86
- name: label.toUpperCase(),
87
- }));
88
- let rows;
89
- if (stmt.hasResultSet) {
90
- const resultSet = await stmt.executeQuery(transaction, params);
91
- const rawRows = await resultSet.fetch();
92
- await resultSet.close();
93
- rows = rawRows.map((cols) => Object.fromEntries(fields.map((f, i) => [f.name, cols[i]])));
156
+ const stmt = await attachment.prepare(transaction, text);
157
+ try {
158
+ const columnLabels = await stmt.columnLabels;
159
+ const type = await stmt.type;
160
+ return {
161
+ params: undefined,
162
+ fields: columnLabels.map((label) => ({ name: label.toUpperCase() })),
163
+ statementType: (0, statement_types_1.statementKind)(type),
164
+ hasResultSet: stmt.hasResultSet,
165
+ };
94
166
  }
95
- else {
96
- await stmt.execute(transaction, params);
97
- rows = [];
167
+ finally {
168
+ await stmt.dispose().catch(() => undefined);
98
169
  }
99
- await stmt.dispose();
100
- await transaction.commit();
101
- return { rows, fields };
102
170
  }
103
- catch (err) {
104
- await transaction.rollback().catch(() => undefined);
105
- throw err;
171
+ finally {
172
+ // Nothing ran, so there is nothing to commit — but the transaction still
173
+ // has to be finished.
174
+ await transaction.commit().catch(() => undefined);
106
175
  }
107
176
  }
108
177
  /**
@@ -117,15 +186,24 @@ class FirebirdLite {
117
186
  const txOptions = buildTransactionOptions(options);
118
187
  const transaction = await attachment.startTransaction(txOptions);
119
188
  const tx = new FirebirdTransaction(attachment, transaction);
189
+ let result;
120
190
  try {
121
- const result = await fn(tx);
122
- await transaction.commit();
123
- return result;
191
+ result = await fn(tx);
124
192
  }
125
193
  catch (err) {
126
- await transaction.rollback().catch(() => undefined);
194
+ // The callback may have rolled back before throwing; rolling back twice
195
+ // targets a transaction the driver has already finished with.
196
+ if (!tx.isFinished) {
197
+ await transaction.rollback().catch(() => undefined);
198
+ }
127
199
  throw err;
128
200
  }
201
+ // A callback that rolled back deliberately must not then be committed.
202
+ if (tx.isFinished) {
203
+ return result;
204
+ }
205
+ await transaction.commit();
206
+ return result;
129
207
  }
130
208
  /**
131
209
  * Close the database connection and release all resources.
@@ -153,39 +231,99 @@ class FirebirdTransaction {
153
231
  constructor(attachment, transaction) {
154
232
  this.attachment = attachment;
155
233
  this.transaction = transaction;
234
+ this.finished = false;
235
+ }
236
+ /** Whether this transaction has already been rolled back. */
237
+ get isFinished() {
238
+ return this.finished;
239
+ }
240
+ /**
241
+ * Roll this transaction back and stop.
242
+ *
243
+ * The enclosing `transaction()` will not commit afterwards. Use this to
244
+ * abandon a transaction deliberately, rather than throwing an error you do
245
+ * not mean — throwing also rolls back, but it propagates to the caller.
246
+ */
247
+ async rollback() {
248
+ if (this.finished)
249
+ return;
250
+ this.finished = true;
251
+ await this.transaction.rollback();
252
+ }
253
+ assertUsable() {
254
+ if (this.finished) {
255
+ throw new Error('Transaction has already been rolled back');
256
+ }
156
257
  }
157
258
  /**
158
259
  * Execute a DDL or DML statement inside this transaction.
159
260
  */
160
261
  async exec(sql, params = []) {
161
- if (params.length > 0) {
162
- const stmt = await this.attachment.prepare(this.transaction, sql);
262
+ this.assertUsable();
263
+ const statement = (0, sql_tag_1.toStatement)(sql, params);
264
+ if (statement.params.length > 0) {
265
+ const stmt = await this.attachment.prepare(this.transaction, statement.sql);
163
266
  try {
164
- await stmt.execute(this.transaction, params);
267
+ await stmt.execute(this.transaction, statement.params);
165
268
  }
166
269
  finally {
167
270
  await stmt.dispose().catch(() => undefined);
168
271
  }
169
272
  }
170
273
  else {
171
- await this.attachment.execute(this.transaction, sql);
274
+ await this.attachment.execute(this.transaction, statement.sql);
172
275
  }
173
276
  }
174
277
  /**
175
- * Execute a SELECT statement inside this transaction and return rows.
278
+ * Execute one statement once per row of parameters inside this
279
+ * transaction: prepared once, executed per row.
176
280
  */
177
- async query(sql, params = []) {
281
+ async execBatch(sql, rows) {
282
+ this.assertUsable();
283
+ if (!Array.isArray(rows)) {
284
+ throw new TypeError('execBatch takes an array of parameter rows');
285
+ }
286
+ if (rows.length === 0)
287
+ return;
178
288
  const stmt = await this.attachment.prepare(this.transaction, sql);
179
- const columnLabels = await stmt.columnLabels;
180
- const fields = columnLabels.map((label) => ({
181
- name: label.toUpperCase(),
182
- }));
183
- const resultSet = await stmt.executeQuery(this.transaction, params);
184
- const rawRows = await resultSet.fetch();
185
- await resultSet.close();
186
- await stmt.dispose();
187
- const rows = rawRows.map((cols) => Object.fromEntries(fields.map((f, i) => [f.name, cols[i]])));
188
- return { rows, fields };
289
+ try {
290
+ for (const row of rows) {
291
+ await stmt.execute(this.transaction, row);
292
+ }
293
+ }
294
+ finally {
295
+ await stmt.dispose().catch(() => undefined);
296
+ }
297
+ }
298
+ async query(sql, params = [], options = {}) {
299
+ this.assertUsable();
300
+ const statement = (0, sql_tag_1.toStatement)(sql, params);
301
+ const rowMode = options.rowMode ?? 'object';
302
+ const stmt = await this.attachment.prepare(this.transaction, statement.sql);
303
+ // Same leak as FirebirdLite.query had: a statement or result set that
304
+ // throws must still be released. More so here, because a transaction
305
+ // callback that catches its own errors goes on using the same attachment.
306
+ try {
307
+ const columnLabels = await stmt.columnLabels;
308
+ const fields = columnLabels.map((label) => ({
309
+ name: label.toUpperCase(),
310
+ }));
311
+ const resultSet = await stmt.executeQuery(this.transaction, statement.params);
312
+ let rawRows;
313
+ try {
314
+ rawRows = await resultSet.fetch();
315
+ }
316
+ finally {
317
+ await resultSet.close().catch(() => undefined);
318
+ }
319
+ const rows = (rowMode === 'array'
320
+ ? rawRows
321
+ : rawRows.map((cols) => Object.fromEntries(fields.map((f, i) => [f.name, cols[i]]))));
322
+ return { rows, fields };
323
+ }
324
+ finally {
325
+ await stmt.dispose().catch(() => undefined);
326
+ }
189
327
  }
190
328
  }
191
329
  exports.FirebirdTransaction = FirebirdTransaction;