velocious 1.0.590 → 1.0.591

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 (65) hide show
  1. package/README.md +4 -0
  2. package/build/background-jobs/pooled-runner-broker-identity.js +76 -0
  3. package/build/background-jobs/pooled-runner-child.js +15 -5
  4. package/build/background-jobs/store.js +11 -14
  5. package/build/background-jobs/worker.js +17 -2
  6. package/build/database/pool/base.js +18 -1
  7. package/build/environment-handlers/base.js +8 -0
  8. package/build/environment-handlers/node.js +12 -0
  9. package/build/src/background-jobs/pooled-runner-broker-identity.d.ts +44 -0
  10. package/build/src/background-jobs/pooled-runner-broker-identity.d.ts.map +1 -0
  11. package/build/src/background-jobs/pooled-runner-broker-identity.js +76 -0
  12. package/build/src/background-jobs/pooled-runner-child.js +16 -6
  13. package/build/src/background-jobs/store.d.ts.map +1 -1
  14. package/build/src/background-jobs/store.js +12 -14
  15. package/build/src/background-jobs/worker.d.ts +6 -0
  16. package/build/src/background-jobs/worker.d.ts.map +1 -1
  17. package/build/src/background-jobs/worker.js +17 -3
  18. package/build/src/database/pool/base.d.ts +6 -0
  19. package/build/src/database/pool/base.d.ts.map +1 -1
  20. package/build/src/database/pool/base.js +18 -2
  21. package/build/src/environment-handlers/base.d.ts +12 -0
  22. package/build/src/environment-handlers/base.d.ts.map +1 -1
  23. package/build/src/environment-handlers/base.js +8 -1
  24. package/build/src/environment-handlers/node.d.ts +11 -0
  25. package/build/src/environment-handlers/node.d.ts.map +1 -1
  26. package/build/src/environment-handlers/node.js +13 -1
  27. package/build/src/testing/shared-transaction-broker-client.d.ts +53 -0
  28. package/build/src/testing/shared-transaction-broker-client.d.ts.map +1 -0
  29. package/build/src/testing/shared-transaction-broker-client.js +105 -0
  30. package/build/src/testing/shared-transaction-broker.d.ts +153 -0
  31. package/build/src/testing/shared-transaction-broker.d.ts.map +1 -0
  32. package/build/src/testing/shared-transaction-broker.js +414 -0
  33. package/build/src/testing/shared-transaction-codec.d.ts +21 -0
  34. package/build/src/testing/shared-transaction-codec.d.ts.map +1 -0
  35. package/build/src/testing/shared-transaction-codec.js +114 -0
  36. package/build/src/testing/shared-transaction-connection-coordinator.d.ts +23 -0
  37. package/build/src/testing/shared-transaction-connection-coordinator.d.ts.map +1 -0
  38. package/build/src/testing/shared-transaction-connection-coordinator.js +36 -0
  39. package/build/src/testing/shared-transaction-proxy-driver.d.ts +42 -0
  40. package/build/src/testing/shared-transaction-proxy-driver.d.ts.map +1 -0
  41. package/build/src/testing/shared-transaction-proxy-driver.js +195 -0
  42. package/build/src/testing/test-runner.d.ts +20 -0
  43. package/build/src/testing/test-runner.d.ts.map +1 -1
  44. package/build/src/testing/test-runner.js +64 -3
  45. package/build/testing/shared-transaction-broker-client.js +107 -0
  46. package/build/testing/shared-transaction-broker.js +401 -0
  47. package/build/testing/shared-transaction-codec.js +110 -0
  48. package/build/testing/shared-transaction-connection-coordinator.js +38 -0
  49. package/build/testing/shared-transaction-proxy-driver.js +205 -0
  50. package/build/testing/test-runner.js +65 -2
  51. package/build/tsconfig.tsbuildinfo +1 -1
  52. package/package.json +4 -2
  53. package/src/background-jobs/pooled-runner-broker-identity.js +76 -0
  54. package/src/background-jobs/pooled-runner-child.js +15 -5
  55. package/src/background-jobs/store.js +11 -14
  56. package/src/background-jobs/worker.js +17 -2
  57. package/src/database/pool/base.js +18 -1
  58. package/src/environment-handlers/base.js +8 -0
  59. package/src/environment-handlers/node.js +12 -0
  60. package/src/testing/shared-transaction-broker-client.js +107 -0
  61. package/src/testing/shared-transaction-broker.js +401 -0
  62. package/src/testing/shared-transaction-codec.js +110 -0
  63. package/src/testing/shared-transaction-connection-coordinator.js +38 -0
  64. package/src/testing/shared-transaction-proxy-driver.js +205 -0
  65. package/src/testing/test-runner.js +65 -2
@@ -0,0 +1,105 @@
1
+ // @ts-check
2
+ import WebSocket from "ws";
3
+ import { decodeBrokerValue, encodeBrokerValue } from "./shared-transaction-codec.js";
4
+ export default class SharedTransactionBrokerClient {
5
+ /**
6
+ * Creates a broker client.
7
+ * @param {{address: string, capability: string, databaseIdentifier: string}} args - Broker coordinates.
8
+ */
9
+ constructor({ address, capability, databaseIdentifier }) {
10
+ this.capability = capability;
11
+ this.databaseIdentifier = databaseIdentifier;
12
+ this.nextRequestId = 1;
13
+ /** @type {Map<number, {reject: (error: Error) => void, resolve: (value: ReturnType<typeof decodeBrokerValue>) => void}>} */
14
+ this.pending = new Map();
15
+ this.socket = new WebSocket(address);
16
+ this.connectionPromise = new Promise((resolve, reject) => {
17
+ this.socket.once("open", resolve);
18
+ this.socket.once("error", reject);
19
+ });
20
+ this.socket.on("message", (data) => this.handleMessage(`${data}`));
21
+ this.socket.once("close", () => this.rejectPending(new Error("Shared transaction broker connection closed")));
22
+ this.socket.on("error", (error) => this.rejectPending(error));
23
+ }
24
+ /**
25
+ * Waits for the websocket to open.
26
+ * @returns {Promise<void>} - Resolves after the websocket opens.
27
+ */
28
+ async connected() { await this.connectionPromise; }
29
+ /**
30
+ * Calls one physical connection operation.
31
+ * @param {string} method - Broker operation.
32
+ * @param {Array<ReturnType<typeof JSON.parse>>} args - Operation arguments.
33
+ * @returns {Promise<ReturnType<typeof decodeBrokerValue>>} - Remote result.
34
+ */
35
+ async call(method, args) {
36
+ await this.connected();
37
+ if (this.socket.readyState !== WebSocket.OPEN)
38
+ throw new Error("Shared transaction broker connection is closed");
39
+ const requestId = this.nextRequestId++;
40
+ const response = new Promise((resolve, reject) => this.pending.set(requestId, { resolve, reject }));
41
+ this.socket.send(JSON.stringify({
42
+ requestId,
43
+ capability: this.capability,
44
+ databaseIdentifier: this.databaseIdentifier,
45
+ method,
46
+ args: encodeBrokerValue(args)
47
+ }), (error) => {
48
+ if (!error)
49
+ return;
50
+ const pending = this.pending.get(requestId);
51
+ this.pending.delete(requestId);
52
+ pending?.reject(error);
53
+ });
54
+ return await response;
55
+ }
56
+ /**
57
+ * Handles a correlated broker response.
58
+ * @param {string} serialized - Serialized response.
59
+ * @returns {void} - No return value.
60
+ */
61
+ handleMessage(serialized) {
62
+ const response = /** @type {{requestId: number, result?: import("./shared-transaction-codec.js").EncodedBrokerValue, error?: import("./shared-transaction-codec.js").EncodedBrokerValue}} */ (JSON.parse(serialized));
63
+ const pending = this.pending.get(response.requestId);
64
+ if (!pending)
65
+ return;
66
+ this.pending.delete(response.requestId);
67
+ if (response.error) {
68
+ const error = decodeBrokerValue(response.error);
69
+ pending.reject(error instanceof Error ? error : new Error(String(error)));
70
+ }
71
+ else if (response.result) {
72
+ pending.resolve(decodeBrokerValue(response.result));
73
+ }
74
+ else {
75
+ pending.reject(new Error("Invalid shared transaction broker response"));
76
+ }
77
+ }
78
+ /**
79
+ * Rejects every pending call after disconnect.
80
+ * @param {Error} error - Disconnect error.
81
+ * @returns {void} - No return value.
82
+ */
83
+ rejectPending(error) {
84
+ for (const { reject } of this.pending.values())
85
+ reject(error);
86
+ this.pending.clear();
87
+ }
88
+ /**
89
+ * Closes the client without touching the parent connection.
90
+ * @returns {Promise<void>} - Resolves after the websocket closes.
91
+ */
92
+ async close() {
93
+ if (this.socket.readyState === WebSocket.CLOSED)
94
+ return;
95
+ if (this.socket.readyState === WebSocket.CONNECTING) {
96
+ this.socket.terminate();
97
+ return;
98
+ }
99
+ await new Promise((resolve) => {
100
+ this.socket.once("close", resolve);
101
+ this.socket.close();
102
+ });
103
+ }
104
+ }
105
+ //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoic2hhcmVkLXRyYW5zYWN0aW9uLWJyb2tlci1jbGllbnQuanMiLCJzb3VyY2VSb290IjoiIiwic291cmNlcyI6WyIuLi8uLi8uLi9zcmMvdGVzdGluZy9zaGFyZWQtdHJhbnNhY3Rpb24tYnJva2VyLWNsaWVudC5qcyJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiQUFBQSxZQUFZO0FBRVosT0FBTyxTQUFTLE1BQU0sSUFBSSxDQUFBO0FBQzFCLE9BQU8sRUFBRSxpQkFBaUIsRUFBRSxpQkFBaUIsRUFBRSxNQUFNLCtCQUErQixDQUFBO0FBRXBGLE1BQU0sQ0FBQyxPQUFPLE9BQU8sNkJBQTZCO0lBQ2hEOzs7T0FHRztJQUNILFlBQVksRUFBQyxPQUFPLEVBQUUsVUFBVSxFQUFFLGtCQUFrQixFQUFDO1FBQ25ELElBQUksQ0FBQyxVQUFVLEdBQUcsVUFBVSxDQUFBO1FBQzVCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxrQkFBa0IsQ0FBQTtRQUM1QyxJQUFJLENBQUMsYUFBYSxHQUFHLENBQUMsQ0FBQTtRQUN0Qiw0SEFBNEg7UUFDNUgsSUFBSSxDQUFDLE9BQU8sR0FBRyxJQUFJLEdBQUcsRUFBRSxDQUFBO1FBQ3hCLElBQUksQ0FBQyxNQUFNLEdBQUcsSUFBSSxTQUFTLENBQUMsT0FBTyxDQUFDLENBQUE7UUFDcEMsSUFBSSxDQUFDLGlCQUFpQixHQUFHLElBQUksT0FBTyxDQUFDLENBQUMsT0FBTyxFQUFFLE1BQU0sRUFBRSxFQUFFO1lBQ3ZELElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE1BQU0sRUFBRSxPQUFPLENBQUMsQ0FBQTtZQUNqQyxJQUFJLENBQUMsTUFBTSxDQUFDLElBQUksQ0FBQyxPQUFPLEVBQUUsTUFBTSxDQUFDLENBQUE7UUFDbkMsQ0FBQyxDQUFDLENBQUE7UUFDRixJQUFJLENBQUMsTUFBTSxDQUFDLEVBQUUsQ0FBQyxTQUFTLEVBQUUsQ0FBQyxJQUFJLEVBQUUsRUFBRSxDQUFDLElBQUksQ0FBQyxhQUFhLENBQUMsR0FBRyxJQUFJ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O1FBQ3JELENBQUM7YUFBTSxDQUFDO1lBQ04sT0FBTyxDQUFDLE1BQU0sQ0FBQyxJQUFJLEtBQUssQ0FBQyw0Q0FBNEMsQ0FBQyxDQUFDLENBQUE7UUFDekUsQ0FBQztJQUNILENBQUM7SUFFRDs7OztPQUlHO0lBQ0gsYUFBYSxDQUFDLEtBQUs7UUFDakIsS0FBSyxNQUFNLEVBQUMsTUFBTSxFQUFDLElBQUksSUFBSSxDQUFDLE9BQU8sQ0FBQyxNQUFNLEVBQUU7WUFBRSxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUE7UUFDM0QsSUFBSSxDQUFDLE9BQU8sQ0FBQyxLQUFLLEVBQUUsQ0FBQTtJQUN0QixDQUFDO0lBRUQ7OztPQUdHO0lBQ0gsS0FBSyxDQUFDLEtBQUs7UUFDVCxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxLQUFLLFNBQVMsQ0FBQyxNQUFNO1lBQUUsT0FBTTtRQUN2RCxJQUFJLElBQUksQ0FBQyxNQUFNLENBQUMsVUFBVSxLQUFLLFNBQVMsQ0FBQyxVQUFVLEVBQUUsQ0FBQztZQUNwRCxJQUFJLENBQUMsTUFBTSxDQUFDLFNBQVMsRUFBRSxDQUFBO1lBQ3ZCLE9BQU07UUFDUixDQUFDO1FBQ0QsTUFBTSxJQUFJLE9BQU8sQ0FBQyxDQUFDLE9BQU8sRUFBRSxFQUFFO1lBQzVCLElBQUksQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxPQUFPLENBQUMsQ0FBQTtZQUNsQyxJQUFJLENBQUMsTUFBTSxDQUFDLEtBQUssRUFBRSxDQUFBO1FBQ3JCLENBQUMsQ0FBQyxDQUFBO0lBQ0osQ0FBQztDQUNGIiwic291cmNlc0NvbnRlbnQiOlsiLy8gQHRzLWNoZWNrXG5cbmltcG9ydCBXZWJTb2NrZXQgZnJvbSBcIndzXCJcbmltcG9ydCB7IGRlY29kZUJyb2tlclZhbHVlLCBlbmNvZGVCcm9rZXJWYWx1ZSB9IGZyb20gXCIuL3NoYXJlZC10cmFuc2FjdGlvbi1jb2RlYy5qc1wiXG5cbmV4cG9ydCBkZWZhdWx0IGNsYXNzIFNoYXJlZFRyYW5zYWN0aW9uQnJva2VyQ2xpZW50IHtcbiAgLyoqXG4gICAqIENyZWF0ZXMgYSBicm9rZXIgY2xpZW50LlxuICAgKiBAcGFyYW0ge3thZGRyZXNzOiBzdHJpbmcsIGNhcGFiaWxpdHk6IHN0cmluZywgZGF0YWJhc2VJZGVudGlmaWVyOiBzdHJpbmd9fSBhcmdzIC0gQnJva2VyIGNvb3JkaW5hdGVzLlxuICAgKi9cbiAgY29uc3RydWN0b3Ioe2FkZHJlc3MsIGNhcGFiaWxpdHksIGRhdGFiYXNlSWRlbnRpZmllcn0pIHtcbiAgICB0aGlzLmNhcGFiaWxpdHkgPSBjYXBhYmlsaXR5XG4gICAgdGhpcy5kYXRhYmFzZUlkZW50aWZpZXIgPSBkYXRhYmFzZUlkZW50aWZpZXJcbiAgICB0aGlzLm5leHRSZXF1ZXN0SWQgPSAxXG4gICAgLyoqIEB0eXBlIHtNYXA8bnVtYmVyLCB7cmVqZWN0OiAoZXJyb3I6IEVycm9yKSA9PiB2b2lkLCByZXNvbHZlOiAodmFsdWU6IFJldHVyblR5cGU8dHlwZW9mIGRlY29kZUJyb2tlclZhbHVlPikgPT4gdm9pZH0+fSAqL1xuICAgIHRoaXMucGVuZGluZyA9IG5ldyBNYXAoKVxuICAgIHRoaXMuc29ja2V0ID0gbmV3IFdlYlNvY2tldChhZGRyZXNzKVxuICAgIHRoaXMuY29ubmVjdGlvblByb21pc2UgPSBuZXcgUHJvbWlzZSgocmVzb2x2ZSwgcmVqZWN0KSA9PiB7XG4gICAgICB0aGlzLnNvY2tldC5vbmNlKFwib3BlblwiLCByZXNvbHZlKVxuICAgICAgdGhpcy5zb2NrZXQub25jZShcImVycm9yXCIsIHJlamVjdClcbiAgICB9KVxuICAgIHRoaXMuc29ja2V0Lm9uKFwibWVzc2FnZVwiLCAoZGF0YSkgPT4gdGhpcy5oYW5kbGVNZXNzYWdlKGAke2RhdGF9YCkpXG4gICAgdGhpcy5zb2NrZXQub25jZShcImNsb3NlXCIsICgpID0+IHRoaXMucmVqZWN0UGVuZGluZyhuZXcgRXJyb3IoXCJTaGFyZWQgdHJhbnNhY3Rpb24gYnJva2VyIGNvbm5lY3Rpb24gY2xvc2VkXCIpKSlcbiAgICB0aGlzLnNvY2tldC5vbihcImVycm9yXCIsIChlcnJvcikgPT4gdGhpcy5yZWplY3RQZW5kaW5nKGVycm9yKSlcbiAgfVxuXG4gIC8qKlxuICAgKiBXYWl0cyBmb3IgdGhlIHdlYnNvY2tldCB0byBvcGVuLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciB0aGUgd2Vic29ja2V0IG9wZW5zLlxuICAgKi9cbiAgYXN5bmMgY29ubmVjdGVkKCkgeyBhd2FpdCB0aGlzLmNvbm5lY3Rpb25Qcm9taXNlIH1cblxuICAvKipcbiAgICogQ2FsbHMgb25lIHBoeXNpY2FsIGNvbm5lY3Rpb24gb3BlcmF0aW9uLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gbWV0aG9kIC0gQnJva2VyIG9wZXJhdGlvbi5cbiAgICogQHBhcmFtIHtBcnJheTxSZXR1cm5UeXBlPHR5cGVvZiBKU09OLnBhcnNlPj59IGFyZ3MgLSBPcGVyYXRpb24gYXJndW1lbnRzLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTxSZXR1cm5UeXBlPHR5cGVvZiBkZWNvZGVCcm9rZXJWYWx1ZT4+fSAtIFJlbW90ZSByZXN1bHQuXG4gICAqL1xuICBhc3luYyBjYWxsKG1ldGhvZCwgYXJncykge1xuICAgIGF3YWl0IHRoaXMuY29ubmVjdGVkKClcbiAgICBpZiAodGhpcy5zb2NrZXQucmVhZHlTdGF0ZSAhPT0gV2ViU29ja2V0Lk9QRU4pIHRocm93IG5ldyBFcnJvcihcIlNoYXJlZCB0cmFuc2FjdGlvbiBicm9rZXIgY29ubmVjdGlvbiBpcyBjbG9zZWRcIilcbiAgICBjb25zdCByZXF1ZXN0SWQgPSB0aGlzLm5leHRSZXF1ZXN0SWQrK1xuICAgIGNvbnN0IHJlc3BvbnNlID0gbmV3IFByb21pc2UoKHJlc29sdmUsIHJlamVjdCkgPT4gdGhpcy5wZW5kaW5nLnNldChyZXF1ZXN0SWQsIHtyZXNvbHZlLCByZWplY3R9KSlcblxuICAgIHRoaXMuc29ja2V0LnNlbmQoSlNPTi5zdHJpbmdpZnkoe1xuICAgICAgcmVxdWVzdElkLFxuICAgICAgY2FwYWJpbGl0eTogdGhpcy5jYXBhYmlsaXR5LFxuICAgICAgZGF0YWJhc2VJZGVudGlmaWVyOiB0aGlzLmRhdGFiYXNlSWRlbnRpZmllcixcbiAgICAgIG1ldGhvZCxcbiAgICAgIGFyZ3M6IGVuY29kZUJyb2tlclZhbHVlKGFyZ3MpXG4gICAgfSksIChlcnJvcikgPT4ge1xuICAgICAgaWYgKCFlcnJvcikgcmV0dXJuXG4gICAgICBjb25zdCBwZW5kaW5nID0gdGhpcy5wZW5kaW5nLmdldChyZXF1ZXN0SWQpXG4gICAgICB0aGlzLnBlbmRpbmcuZGVsZXRlKHJlcXVlc3RJZClcbiAgICAgIHBlbmRpbmc/LnJlamVjdChlcnJvcilcbiAgICB9KVxuXG4gICAgcmV0dXJuIGF3YWl0IHJlc3BvbnNlXG4gIH1cblxuICAvKipcbiAgICogSGFuZGxlcyBhIGNvcnJlbGF0ZWQgYnJva2VyIHJlc3BvbnNlLlxuICAgKiBAcGFyYW0ge3N0cmluZ30gc2VyaWFsaXplZCAtIFNlcmlhbGl6ZWQgcmVzcG9uc2UuXG4gICAqIEByZXR1cm5zIHt2b2lkfSAtIE5vIHJldHVybiB2YWx1ZS5cbiAgICovXG4gIGhhbmRsZU1lc3NhZ2Uoc2VyaWFsaXplZCkge1xuICAgIGNvbnN0IHJlc3BvbnNlID0gLyoqIEB0eXBlIHt7cmVxdWVzdElkOiBudW1iZXIsIHJlc3VsdD86IGltcG9ydChcIi4vc2hhcmVkLXRyYW5zYWN0aW9uLWNvZGVjLmpzXCIpLkVuY29kZWRCcm9rZXJWYWx1ZSwgZXJyb3I/OiBpbXBvcnQoXCIuL3NoYXJlZC10cmFuc2FjdGlvbi1jb2RlYy5qc1wiKS5FbmNvZGVkQnJva2VyVmFsdWV9fSAqLyAoSlNPTi5wYXJzZShzZXJpYWxpemVkKSlcbiAgICBjb25zdCBwZW5kaW5nID0gdGhpcy5wZW5kaW5nLmdldChyZXNwb25zZS5yZXF1ZXN0SWQpXG4gICAgaWYgKCFwZW5kaW5nKSByZXR1cm5cbiAgICB0aGlzLnBlbmRpbmcuZGVsZXRlKHJlc3BvbnNlLnJlcXVlc3RJZClcblxuICAgIGlmIChyZXNwb25zZS5lcnJvcikge1xuICAgICAgY29uc3QgZXJyb3IgPSBkZWNvZGVCcm9rZXJWYWx1ZShyZXNwb25zZS5lcnJvcilcbiAgICAgIHBlbmRpbmcucmVqZWN0KGVycm9yIGluc3RhbmNlb2YgRXJyb3IgPyBlcnJvciA6IG5ldyBFcnJvcihTdHJpbmcoZXJyb3IpKSlcbiAgICB9IGVsc2UgaWYgKHJlc3BvbnNlLnJlc3VsdCkge1xuICAgICAgcGVuZGluZy5yZXNvbHZlKGRlY29kZUJyb2tlclZhbHVlKHJlc3BvbnNlLnJlc3VsdCkpXG4gICAgfSBlbHNlIHtcbiAgICAgIHBlbmRpbmcucmVqZWN0KG5ldyBFcnJvcihcIkludmFsaWQgc2hhcmVkIHRyYW5zYWN0aW9uIGJyb2tlciByZXNwb25zZVwiKSlcbiAgICB9XG4gIH1cblxuICAvKipcbiAgICogUmVqZWN0cyBldmVyeSBwZW5kaW5nIGNhbGwgYWZ0ZXIgZGlzY29ubmVjdC5cbiAgICogQHBhcmFtIHtFcnJvcn0gZXJyb3IgLSBEaXNjb25uZWN0IGVycm9yLlxuICAgKiBAcmV0dXJucyB7dm9pZH0gLSBObyByZXR1cm4gdmFsdWUuXG4gICAqL1xuICByZWplY3RQZW5kaW5nKGVycm9yKSB7XG4gICAgZm9yIChjb25zdCB7cmVqZWN0fSBvZiB0aGlzLnBlbmRpbmcudmFsdWVzKCkpIHJlamVjdChlcnJvcilcbiAgICB0aGlzLnBlbmRpbmcuY2xlYXIoKVxuICB9XG5cbiAgLyoqXG4gICAqIENsb3NlcyB0aGUgY2xpZW50IHdpdGhvdXQgdG91Y2hpbmcgdGhlIHBhcmVudCBjb25uZWN0aW9uLlxuICAgKiBAcmV0dXJucyB7UHJvbWlzZTx2b2lkPn0gLSBSZXNvbHZlcyBhZnRlciB0aGUgd2Vic29ja2V0IGNsb3Nlcy5cbiAgICovXG4gIGFzeW5jIGNsb3NlKCkge1xuICAgIGlmICh0aGlzLnNvY2tldC5yZWFkeVN0YXRlID09PSBXZWJTb2NrZXQuQ0xPU0VEKSByZXR1cm5cbiAgICBpZiAodGhpcy5zb2NrZXQucmVhZHlTdGF0ZSA9PT0gV2ViU29ja2V0LkNPTk5FQ1RJTkcpIHtcbiAgICAgIHRoaXMuc29ja2V0LnRlcm1pbmF0ZSgpXG4gICAgICByZXR1cm5cbiAgICB9XG4gICAgYXdhaXQgbmV3IFByb21pc2UoKHJlc29sdmUpID0+IHtcbiAgICAgIHRoaXMuc29ja2V0Lm9uY2UoXCJjbG9zZVwiLCByZXNvbHZlKVxuICAgICAgdGhpcy5zb2NrZXQuY2xvc2UoKVxuICAgIH0pXG4gIH1cbn1cbiJdfQ==
@@ -0,0 +1,153 @@
1
+ import { EventEmitter } from "node:events";
2
+ export type ConnectionState = {
3
+ queue: Promise<void>;
4
+ rootSessions: Set<import("ws").WebSocket>;
5
+ lease?: {
6
+ operations: Promise<void>;
7
+ release: () => void;
8
+ savePointName: string;
9
+ socket: import("ws").WebSocket;
10
+ };
11
+ };
12
+ export default class SharedTransactionBroker extends EventEmitter {
13
+ connections: Record<string, object>;
14
+ secret: string;
15
+ accepting: boolean;
16
+ /** @type {Map<object, ConnectionState>} */
17
+ connectionStates: Map<object, ConnectionState>;
18
+ /** @type {Set<import("ws").WebSocket>} */
19
+ sessions: Set<import("ws").WebSocket>;
20
+ /** @type {Map<import("ws").WebSocket, Promise<void>>} */
21
+ sessionCleanup: Map<import("ws").WebSocket, Promise<void>>;
22
+ /** @type {Array<Error>} */
23
+ cleanupErrors: Array<Error>;
24
+ /** @type {Promise<void> | undefined} */
25
+ closePromise: Promise<void> | undefined;
26
+ /** @type {Map<object, (callback: () => Promise<ReturnType<typeof JSON.parse>>) => Promise<ReturnType<typeof JSON.parse>>>} */
27
+ connectionCoordinators: Map<object, (callback: () => Promise<ReturnType<typeof JSON.parse>>) => Promise<ReturnType<typeof JSON.parse>>>;
28
+ httpServer: import("node:http").Server<typeof import("node:http").IncomingMessage, typeof import("node:http").ServerResponse>;
29
+ websocketServer: import("ws").Server<typeof import("ws").WebSocket, typeof import("node:http").IncomingMessage>;
30
+ /**
31
+ * Creates a broker around parent-owned physical connections.
32
+ * @param {{connections: Record<string, object>}} args - Parent-owned physical connections.
33
+ */
34
+ constructor({ connections }: {
35
+ connections: Record<string, object>;
36
+ });
37
+ /**
38
+ * Starts a broker on an ephemeral loopback port.
39
+ * @param {{connections: Record<string, object>}} args - Parent-owned physical connections.
40
+ * @returns {Promise<SharedTransactionBroker>} - Listening broker.
41
+ */
42
+ static start(args: {
43
+ connections: Record<string, object>;
44
+ }): Promise<SharedTransactionBroker>;
45
+ /**
46
+ * Gets the loopback websocket address.
47
+ * @returns {string} - Loopback websocket address.
48
+ */
49
+ address(): string;
50
+ /**
51
+ * Gets the per-attempt unguessable capability.
52
+ * @returns {string} - Per-attempt unguessable capability.
53
+ */
54
+ capability(): string;
55
+ /**
56
+ * Validates and handles one request.
57
+ * @param {import("ws").WebSocket} socket - Calling session.
58
+ * @param {string} serialized - Request JSON.
59
+ * @returns {Promise<void>} - Resolves after responding.
60
+ */
61
+ handleRequest(socket: import("ws").WebSocket, serialized: string): Promise<void>;
62
+ /**
63
+ * Gets mutable serialization state for one physical connection.
64
+ * @param {object} connection - Physical connection.
65
+ * @returns {ConnectionState} - Connection state.
66
+ */
67
+ connectionState(connection: object): ConnectionState;
68
+ /**
69
+ * Runs a validated request with root transaction lease semantics.
70
+ * @template T
71
+ * @param {{connection: object, method: string, savePointName: string | undefined, socket: import("ws").WebSocket}} args - Request identity.
72
+ * @param {() => Promise<T>} callback - Physical operation.
73
+ * @returns {Promise<T>} - Operation result.
74
+ */
75
+ runConnectionRequest<T>({ connection, method, savePointName, socket }: {
76
+ connection: object;
77
+ method: string;
78
+ savePointName: string | undefined;
79
+ socket: import("ws").WebSocket;
80
+ }, callback: () => Promise<T>): Promise<T>;
81
+ /**
82
+ * Acquires the FIFO physical connection lease and holds the queue until end.
83
+ * @template T
84
+ * @param {{callback: () => Promise<T>, savePointName: string, state: ConnectionState, socket: import("ws").WebSocket}} args - Lease request.
85
+ * @returns {Promise<T>} - Root savepoint start result.
86
+ */
87
+ startRootLease<T>({ callback, savePointName, state, socket }: {
88
+ callback: () => Promise<T>;
89
+ savePointName: string;
90
+ state: ConnectionState;
91
+ socket: import("ws").WebSocket;
92
+ }): Promise<T>;
93
+ /**
94
+ * Finishes the calling session's root lease.
95
+ * @template T
96
+ * @param {{callback: () => Promise<T>, savePointName: string | undefined, state: ConnectionState, socket: import("ws").WebSocket}} args - Lease end request.
97
+ * @returns {Promise<T>} - Savepoint end result.
98
+ */
99
+ finishRootLease<T>({ callback, savePointName, state, socket }: {
100
+ callback: () => Promise<T>;
101
+ savePointName: string | undefined;
102
+ state: ConnectionState;
103
+ socket: import("ws").WebSocket;
104
+ }): Promise<T>;
105
+ /**
106
+ * Serializes operations belonging to the active lease holder.
107
+ * @template T
108
+ * @param {{operations: Promise<void>}} lease - Active lease.
109
+ * @param {() => Promise<T>} callback - Operation.
110
+ * @returns {Promise<T>} - Result.
111
+ */
112
+ serializeLease<T>(lease: {
113
+ operations: Promise<void>;
114
+ }, callback: () => Promise<T>): Promise<T>;
115
+ /**
116
+ * Rolls back leases abandoned by a disconnected session.
117
+ * @param {import("ws").WebSocket} socket - Disconnected session.
118
+ * @returns {Promise<void>} - Resolves after all owned leases release.
119
+ */
120
+ releaseDisconnectedLeases(socket: import("ws").WebSocket): Promise<void>;
121
+ /**
122
+ * Tracks detached socket cleanup and records its failure for close().
123
+ * @param {import("ws").WebSocket} socket - Closed session.
124
+ * @returns {Promise<void>} - Settled tracked cleanup.
125
+ */
126
+ scheduleSessionCleanup(socket: import("ws").WebSocket): Promise<void>;
127
+ /**
128
+ * Rolls back and removes a root savepoint so it cannot remain beneath the next lease.
129
+ * @param {object} connection - Parent physical connection.
130
+ * @param {string} savePointName - Root savepoint name.
131
+ * @returns {Promise<void>} - Resolves after rollback and release.
132
+ */
133
+ rollbackRootSavePoint(connection: object, savePointName: string): Promise<void>;
134
+ /**
135
+ * Serializes ordinary non-holder work through the connection FIFO.
136
+ * @template T
137
+ * @param {ConnectionState} state - Connection state.
138
+ * @param {() => Promise<T>} callback - Work.
139
+ * @returns {Promise<T>} - Work result.
140
+ */
141
+ serialize<T>(state: ConnectionState, callback: () => Promise<T>): Promise<T>;
142
+ /**
143
+ * Stops admission, revokes capability, rejects clients, and drains active work.
144
+ * @returns {Promise<void>} - Resolves after transport shutdown.
145
+ */
146
+ close(): Promise<void>;
147
+ /**
148
+ * Performs deterministic transport shutdown and reports cleanup failures last.
149
+ * @returns {Promise<void>} - Resolves after shutdown or rejects with cleanup errors.
150
+ */
151
+ closeTransport(): Promise<void>;
152
+ }
153
+ //# sourceMappingURL=shared-transaction-broker.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"shared-transaction-broker.d.ts","sourceRoot":"","sources":["../../../src/testing/shared-transaction-broker.js"],"names":[],"mappings":"AAIA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAA;AAKtC,YAA8L,eAAe,GAAnM;IAAC,KAAK,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAAC,YAAY,EAAE,GAAG,CAAC,OAAO,IAAI,EAAE,SAAS,CAAC,CAAC;IAAC,KAAK,CAAC,EAAE;QAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;QAAC,OAAO,EAAE,MAAM,IAAI,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,OAAO,IAAI,EAAE,SAAS,CAAA;KAAC,CAAA;CAAC,CAAiB;AA+BjN,MAAM,CAAC,OAAO,OAAO,uBAAwB,SAAQ,YAAY;IAOxD,WAAW;IACX,MAAM;IACN,SAAS;IACd,2CAA2C;IACtC,gBAAgB,EADV,GAAG,CAAC,MAAM,EAAE,eAAe,CAAC;IAEvC,0CAA0C;IACrC,QAAQ,EADF,GAAG,CAAC,OAAO,IAAI,EAAE,SAAS,CAAC;IAEtC,yDAAyD;IACpD,cAAc,EADR,GAAG,CAAC,OAAO,IAAI,EAAE,SAAS,EAAE,OAAO,CAAC,IAAI,CAAC,CAAC;IAErD,2BAA2B;IACtB,aAAa,EADP,KAAK,CAAC,KAAK,CAAC;IAEvB,wCAAwC;IACnC,YAAY,EADN,OAAO,CAAC,IAAI,CAAC,GAAG,SAAS;IAEpC,8HAA8H;IACzH,sBAAsB,EADhB,GAAG,CAAC,MAAM,EAAE,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,OAAO,CAAC,UAAU,CAAC,OAAO,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC;IAYrH,UAAU;IACV,eAAe;IAhCtB;;;OAGG;IACH,YAAY,EAAC,WAAW,EAAC,EAFd;QAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAEtB,EAqCxB;IAED;;;;OAIG;IACH,OAAa,KAAK,CAAC,IAAI,EAHZ;QAAC,WAAW,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,CAAC,CAAA;KAGxB,GAFV,OAAO,CAAC,uBAAuB,CAAC,CAS5C;IAED;;;OAGG;IACH,OAAO,IAFM,MAAM,CAMlB;IAED;;;OAGG;IACH,UAAU,IAFG,MAAM,CAEgB;IAEnC;;;;;OAKG;IACG,aAAa,CAAC,MAAM,EAJf,OAAO,IAAI,EAAE,SAIE,EAAE,UAAU,EAH3B,MAG2B,GAFzB,OAAO,CAAC,IAAI,CAAC,CAsCzB;IAED;;;;OAIG;IACH,eAAe,CAAC,UAAU,EAHf,MAGe,GAFb,eAAe,CAS3B;IAED;;;;;;OAMG;IACG,oBAAoB,CALb,CAAC,EAKa,EAAC,UAAU,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,EAAC,EAJ3D;QAAC,UAAU,EAAE,MAAM,CAAC;QAAC,MAAM,EAAE,MAAM,CAAC;QAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,MAAM,EAAE,OAAO,IAAI,EAAE,SAAS,CAAA;KAI3C,EAAE,QAAQ,EAHrE,MAAM,OAAO,CAAC,CAAC,CAGsD,GAFnE,OAAO,CAAC,CAAC,CAAC,CAatB;IAED;;;;;OAKG;IACG,cAAc,CAJP,CAAC,EAIO,EAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAC,EAHlD;QAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;QAAC,aAAa,EAAE,MAAM,CAAC;QAAC,KAAK,EAAE,eAAe,CAAC;QAAC,MAAM,EAAE,OAAO,IAAI,EAAE,SAAS,CAAA;KAGxD,GAFhD,OAAO,CAAC,CAAC,CAAC,CAqCtB;IAED;;;;;OAKG;IACG,eAAe,CAJR,CAAC,EAIQ,EAAC,QAAQ,EAAE,aAAa,EAAE,KAAK,EAAE,MAAM,EAAC,EAHnD;QAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,CAAC;QAAC,aAAa,EAAE,MAAM,GAAG,SAAS,CAAC;QAAC,KAAK,EAAE,eAAe,CAAC;QAAC,MAAM,EAAE,OAAO,IAAI,EAAE,SAAS,CAAA;KAGnE,GAFjD,OAAO,CAAC,CAAC,CAAC,CAatB;IAED;;;;;;OAMG;IACG,cAAc,CALP,CAAC,EAKO,KAAK,EAJf;QAAC,UAAU,EAAE,OAAO,CAAC,IAAI,CAAC,CAAA;KAIX,EAAE,QAAQ,EAHzB,MAAM,OAAO,CAAC,CAAC,CAGU,GAFvB,OAAO,CAAC,CAAC,CAAC,CAatB;IAED;;;;OAIG;IACG,yBAAyB,CAAC,MAAM,EAH3B,OAAO,IAAI,EAAE,SAGc,GAFzB,OAAO,CAAC,IAAI,CAAC,CAuBzB;IAED;;;;OAIG;IACH,sBAAsB,CAAC,MAAM,EAHlB,OAAO,IAAI,EAAE,SAGK,GAFhB,OAAO,CAAC,IAAI,CAAC,CAYzB;IAED;;;;;OAKG;IACG,qBAAqB,CAAC,UAAU,EAJ3B,MAI2B,EAAE,aAAa,EAH1C,MAG0C,GAFxC,OAAO,CAAC,IAAI,CAAC,CAmBzB;IAED;;;;;;OAMG;IACG,SAAS,CALF,CAAC,EAKE,KAAK,EAJV,eAIU,EAAE,QAAQ,EAHpB,MAAM,OAAO,CAAC,CAAC,CAGK,GAFlB,OAAO,CAAC,CAAC,CAAC,CAkBtB;IAED;;;OAGG;IACG,KAAK,IAFE,OAAO,CAAC,IAAI,CAAC,CAMzB;IAED;;;OAGG;IACG,cAAc,IAFP,OAAO,CAAC,IAAI,CAAC,CAkBzB;CACF"}