@zukhruf/mutex 0.2.0 → 0.3.1

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 (146) hide show
  1. package/README.md +5 -3
  2. package/dist/fencing/file-token-source.js +2 -2
  3. package/dist/fencing/file-token-source.js.map +1 -1
  4. package/dist/index.d.ts +2 -0
  5. package/dist/index.d.ts.map +1 -1
  6. package/dist/index.js +2 -0
  7. package/dist/index.js.map +1 -1
  8. package/dist/leader-election/index.d.ts +1 -0
  9. package/dist/leader-election/index.d.ts.map +1 -1
  10. package/dist/leader-election/index.js +1 -0
  11. package/dist/leader-election/index.js.map +1 -1
  12. package/dist/leader-election/leader-election.d.ts.map +1 -1
  13. package/dist/leader-election/leader-election.js +4 -2
  14. package/dist/leader-election/leader-election.js.map +1 -1
  15. package/dist/local-directory/local-directory.d.ts +7 -0
  16. package/dist/local-directory/local-directory.d.ts.map +1 -0
  17. package/dist/local-directory/local-directory.js +75 -0
  18. package/dist/local-directory/local-directory.js.map +1 -0
  19. package/dist/local-directory/network-directory-error.d.ts +8 -0
  20. package/dist/local-directory/network-directory-error.d.ts.map +1 -0
  21. package/dist/local-directory/network-directory-error.js +13 -0
  22. package/dist/local-directory/network-directory-error.js.map +1 -0
  23. package/dist/lock-stores/file-system/file-lock-store.d.ts +6 -3
  24. package/dist/lock-stores/file-system/file-lock-store.d.ts.map +1 -1
  25. package/dist/lock-stores/file-system/file-lock-store.js +40 -11
  26. package/dist/lock-stores/file-system/file-lock-store.js.map +1 -1
  27. package/dist/lock-stores/file-system/lock-file-store.d.ts.map +1 -1
  28. package/dist/lock-stores/file-system/lock-file-store.js +9 -4
  29. package/dist/lock-stores/file-system/lock-file-store.js.map +1 -1
  30. package/dist/lock-stores/file-system/ticket-queue-file-store.d.ts.map +1 -1
  31. package/dist/lock-stores/file-system/ticket-queue-file-store.js +3 -2
  32. package/dist/lock-stores/file-system/ticket-queue-file-store.js.map +1 -1
  33. package/dist/lock-stores/ipc/child-process-connection.d.ts +3 -3
  34. package/dist/lock-stores/ipc/child-process-connection.d.ts.map +1 -1
  35. package/dist/lock-stores/ipc/child-process-connection.js +16 -20
  36. package/dist/lock-stores/ipc/child-process-connection.js.map +1 -1
  37. package/dist/lock-stores/ipc/ipc-store.d.ts.map +1 -1
  38. package/dist/lock-stores/ipc/ipc-store.js +7 -5
  39. package/dist/lock-stores/ipc/ipc-store.js.map +1 -1
  40. package/dist/lock-stores/ipc/process-channel-connection.d.ts +4 -3
  41. package/dist/lock-stores/ipc/process-channel-connection.d.ts.map +1 -1
  42. package/dist/lock-stores/ipc/process-channel-connection.js +6 -14
  43. package/dist/lock-stores/ipc/process-channel-connection.js.map +1 -1
  44. package/dist/lock-stores/memory/memory-store.d.ts +1 -1
  45. package/dist/lock-stores/memory/memory-store.d.ts.map +1 -1
  46. package/dist/lock-stores/memory/memory-store.js +13 -14
  47. package/dist/lock-stores/memory/memory-store.js.map +1 -1
  48. package/dist/lock-stores/remote/connection-supervisor.d.ts +39 -0
  49. package/dist/lock-stores/remote/connection-supervisor.d.ts.map +1 -0
  50. package/dist/lock-stores/remote/connection-supervisor.js +195 -0
  51. package/dist/lock-stores/remote/connection-supervisor.js.map +1 -0
  52. package/dist/lock-stores/remote/connection.d.ts +11 -7
  53. package/dist/lock-stores/remote/connection.d.ts.map +1 -1
  54. package/dist/lock-stores/remote/connector.d.ts +5 -2
  55. package/dist/lock-stores/remote/connector.d.ts.map +1 -1
  56. package/dist/lock-stores/remote/lock-coordinator.d.ts +2 -2
  57. package/dist/lock-stores/remote/lock-coordinator.d.ts.map +1 -1
  58. package/dist/lock-stores/remote/lock-coordinator.js +140 -69
  59. package/dist/lock-stores/remote/lock-coordinator.js.map +1 -1
  60. package/dist/lock-stores/remote/remote-lock-client.d.ts +8 -7
  61. package/dist/lock-stores/remote/remote-lock-client.d.ts.map +1 -1
  62. package/dist/lock-stores/remote/remote-lock-client.js +99 -99
  63. package/dist/lock-stores/remote/remote-lock-client.js.map +1 -1
  64. package/dist/lock-stores/socket/electing-connector.d.ts +7 -4
  65. package/dist/lock-stores/socket/electing-connector.d.ts.map +1 -1
  66. package/dist/lock-stores/socket/electing-connector.js +94 -11
  67. package/dist/lock-stores/socket/electing-connector.js.map +1 -1
  68. package/dist/lock-stores/socket/handshake.d.ts +27 -0
  69. package/dist/lock-stores/socket/handshake.d.ts.map +1 -0
  70. package/dist/lock-stores/socket/handshake.js +80 -0
  71. package/dist/lock-stores/socket/handshake.js.map +1 -0
  72. package/dist/lock-stores/socket/local-directory-connector.d.ts +14 -0
  73. package/dist/lock-stores/socket/local-directory-connector.d.ts.map +1 -0
  74. package/dist/lock-stores/socket/local-directory-connector.js +23 -0
  75. package/dist/lock-stores/socket/local-directory-connector.js.map +1 -0
  76. package/dist/lock-stores/socket/lock-server.d.ts.map +1 -1
  77. package/dist/lock-stores/socket/lock-server.js +7 -1
  78. package/dist/lock-stores/socket/lock-server.js.map +1 -1
  79. package/dist/lock-stores/socket/protocol-version-error.d.ts +12 -0
  80. package/dist/lock-stores/socket/protocol-version-error.d.ts.map +1 -0
  81. package/dist/lock-stores/socket/protocol-version-error.js +19 -0
  82. package/dist/lock-stores/socket/protocol-version-error.js.map +1 -0
  83. package/dist/lock-stores/socket/socket-connection.d.ts +3 -3
  84. package/dist/lock-stores/socket/socket-connection.d.ts.map +1 -1
  85. package/dist/lock-stores/socket/socket-connection.js +16 -18
  86. package/dist/lock-stores/socket/socket-connection.js.map +1 -1
  87. package/dist/lock-stores/socket/socket-store.d.ts +1 -2
  88. package/dist/lock-stores/socket/socket-store.d.ts.map +1 -1
  89. package/dist/lock-stores/socket/socket-store.js +16 -23
  90. package/dist/lock-stores/socket/socket-store.js.map +1 -1
  91. package/dist/lock-stores/thread/parent-port-connection.d.ts +4 -3
  92. package/dist/lock-stores/thread/parent-port-connection.d.ts.map +1 -1
  93. package/dist/lock-stores/thread/parent-port-connection.js +6 -13
  94. package/dist/lock-stores/thread/parent-port-connection.js.map +1 -1
  95. package/dist/lock-stores/thread/thread-store.d.ts.map +1 -1
  96. package/dist/lock-stores/thread/thread-store.js +5 -8
  97. package/dist/lock-stores/thread/thread-store.js.map +1 -1
  98. package/dist/lock-stores/thread/worker-connection.d.ts +3 -3
  99. package/dist/lock-stores/thread/worker-connection.d.ts.map +1 -1
  100. package/dist/lock-stores/thread/worker-connection.js +19 -23
  101. package/dist/lock-stores/thread/worker-connection.js.map +1 -1
  102. package/dist/mutex/acquire-mode.d.ts +6 -3
  103. package/dist/mutex/acquire-mode.d.ts.map +1 -1
  104. package/dist/mutex/acquire-modes/skip-if-busy-mode.d.ts +7 -3
  105. package/dist/mutex/acquire-modes/skip-if-busy-mode.d.ts.map +1 -1
  106. package/dist/mutex/acquire-modes/skip-if-busy-mode.js +7 -4
  107. package/dist/mutex/acquire-modes/skip-if-busy-mode.js.map +1 -1
  108. package/dist/mutex/acquire-modes/wait-mode.d.ts +2 -2
  109. package/dist/mutex/acquire-modes/wait-mode.d.ts.map +1 -1
  110. package/dist/mutex/acquire-modes/wait-mode.js +2 -2
  111. package/dist/mutex/acquire-modes/wait-mode.js.map +1 -1
  112. package/dist/mutex/key.d.ts +3 -2
  113. package/dist/mutex/key.d.ts.map +1 -1
  114. package/dist/mutex/key.js +3 -3
  115. package/dist/mutex/key.js.map +1 -1
  116. package/dist/mutex/mutex.d.ts +3 -3
  117. package/dist/mutex/mutex.d.ts.map +1 -1
  118. package/dist/mutex/mutex.js +28 -5
  119. package/dist/mutex/mutex.js.map +1 -1
  120. package/dist/shared/fs/atomic-write.d.ts.map +1 -1
  121. package/dist/shared/fs/atomic-write.js +3 -27
  122. package/dist/shared/fs/atomic-write.js.map +1 -1
  123. package/dist/shared/fs/create-exclusive.d.ts.map +1 -1
  124. package/dist/shared/fs/create-exclusive.js +7 -2
  125. package/dist/shared/fs/create-exclusive.js.map +1 -1
  126. package/dist/shared/fs/durable-write.d.ts +7 -0
  127. package/dist/shared/fs/durable-write.d.ts.map +1 -0
  128. package/dist/shared/fs/durable-write.js +46 -0
  129. package/dist/shared/fs/durable-write.js.map +1 -0
  130. package/dist/shared/fs/patiently.d.ts +3 -0
  131. package/dist/shared/fs/patiently.d.ts.map +1 -0
  132. package/dist/shared/fs/patiently.js +30 -0
  133. package/dist/shared/fs/patiently.js.map +1 -0
  134. package/dist/shared/fs/replace-file.d.ts +8 -0
  135. package/dist/shared/fs/replace-file.d.ts.map +1 -0
  136. package/dist/shared/fs/replace-file.js +12 -0
  137. package/dist/shared/fs/replace-file.js.map +1 -0
  138. package/dist/shared/latch.d.ts +10 -0
  139. package/dist/shared/latch.d.ts.map +1 -0
  140. package/dist/shared/latch.js +14 -0
  141. package/dist/shared/latch.js.map +1 -0
  142. package/dist/shared/sqlite/is-not-a-database.d.ts +3 -0
  143. package/dist/shared/sqlite/is-not-a-database.d.ts.map +1 -0
  144. package/dist/shared/sqlite/is-not-a-database.js +9 -0
  145. package/dist/shared/sqlite/is-not-a-database.js.map +1 -0
  146. package/package.json +1 -1
@@ -1,14 +1,26 @@
1
+ import { EventEmitter } from 'node:events';
1
2
  import { unwrap, wrap } from "../remote/envelope.js";
2
3
  import { isLockRequest, } from "../remote/protocol.js";
3
4
  /**
4
5
  * The parent's end of the IPC channel to one child. The kernel closes the
5
6
  * channel when the child dies, so `disconnect` reports even a SIGKILL.
6
7
  */
7
- export class ChildProcessConnection {
8
+ export class ChildProcessConnection extends EventEmitter {
8
9
  #child;
9
- #detach = () => { };
10
+ #onMessage = (envelope) => {
11
+ const request = unwrap(envelope);
12
+ if (isLockRequest(request))
13
+ this.emit('message', request);
14
+ };
15
+ #onDisconnect = () => {
16
+ this.close();
17
+ this.emit('close');
18
+ };
10
19
  constructor(child) {
20
+ super();
11
21
  this.#child = child;
22
+ child.on('message', this.#onMessage);
23
+ child.once('disconnect', this.#onDisconnect);
12
24
  }
13
25
  send(response) {
14
26
  return new Promise((resolve, reject) => {
@@ -19,28 +31,12 @@ export class ChildProcessConnection {
19
31
  this.#child.send(wrap(response), (error) => error ? reject(error) : resolve());
20
32
  });
21
33
  }
22
- listen({ message, close }) {
23
- const onMessage = (envelope) => {
24
- const request = unwrap(envelope);
25
- if (isLockRequest(request))
26
- message(request);
27
- };
28
- const onDisconnect = () => {
29
- this.close();
30
- close();
31
- };
32
- this.#child.on('message', onMessage);
33
- this.#child.once('disconnect', onDisconnect);
34
- this.#detach = () => {
35
- this.#child.off('message', onMessage);
36
- this.#child.off('disconnect', onDisconnect);
37
- };
38
- }
39
34
  /** The running child already keeps the parent alive. */
40
35
  ref() { }
41
36
  unref() { }
42
37
  close() {
43
- this.#detach();
38
+ this.#child.off('message', this.#onMessage);
39
+ this.#child.off('disconnect', this.#onDisconnect);
44
40
  }
45
41
  }
46
42
  //# sourceMappingURL=child-process-connection.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"child-process-connection.js","sourceRoot":"","sources":["../../../src/lock-stores/ipc/child-process-connection.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAGL,aAAa,GACd,MAAM,uBAAuB,CAAC;AAE/B;;;GAGG;AACH,MAAM,OAAO,sBAAsB;IAIxB,MAAM,CAAe;IAC9B,OAAO,GAAG,GAAG,EAAE,GAAE,CAAC,CAAC;IAEnB,YAAY,KAAmB;QAC7B,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,IAAI,CAAC,QAAsB;QACzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBAC3B,MAAM,CAAC,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC,CAAC;gBACzD,OAAO;YACT,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CACzC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAClC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,EAAE,OAAO,EAAE,KAAK,EAAmC;QACxD,MAAM,SAAS,GAAG,CAAC,QAAiB,EAAE,EAAE;YACtC,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;YACjC,IAAI,aAAa,CAAC,OAAO,CAAC;gBAAE,OAAO,CAAC,OAAO,CAAC,CAAC;QAC/C,CAAC,CAAC;QACF,MAAM,YAAY,GAAG,GAAG,EAAE;YACxB,IAAI,CAAC,KAAK,EAAE,CAAC;YACb,KAAK,EAAE,CAAC;QACV,CAAC,CAAC;QACF,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;QACrC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QAC7C,IAAI,CAAC,OAAO,GAAG,GAAG,EAAE;YAClB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,SAAS,CAAC,CAAC;YACtC,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,YAAY,CAAC,CAAC;QAC9C,CAAC,CAAC;IACJ,CAAC;IAED,wDAAwD;IACxD,GAAG,KAAI,CAAC;IAER,KAAK,KAAI,CAAC;IAEV,KAAK;QACH,IAAI,CAAC,OAAO,EAAE,CAAC;IACjB,CAAC;CACF"}
1
+ {"version":3,"file":"child-process-connection.js","sourceRoot":"","sources":["../../../src/lock-stores/ipc/child-process-connection.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAGL,aAAa,GACd,MAAM,uBAAuB,CAAC;AAE/B;;;GAGG;AACH,MAAM,OAAO,sBACX,SAAQ,YAA2C;IAG1C,MAAM,CAAe;IAErB,UAAU,GAAG,CAAC,QAAiB,EAAE,EAAE;QAC1C,MAAM,OAAO,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QACjC,IAAI,aAAa,CAAC,OAAO,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,CAAC;IAC5D,CAAC,CAAC;IAEO,aAAa,GAAG,GAAG,EAAE;QAC5B,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC,CAAC;IAEF,YAAY,KAAmB;QAC7B,KAAK,EAAE,CAAC;QACR,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;QACpB,KAAK,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACrC,KAAK,CAAC,IAAI,CAAC,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAC/C,CAAC;IAED,IAAI,CAAC,QAAsB;QACzB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,SAAS,EAAE,CAAC;gBAC3B,MAAM,CAAC,IAAI,KAAK,CAAC,qCAAqC,CAAC,CAAC,CAAC;gBACzD,OAAO;YACT,CAAC;YACD,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,QAAQ,CAAC,EAAE,CAAC,KAAK,EAAE,EAAE,CACzC,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAClC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,wDAAwD;IACxD,GAAG,KAAI,CAAC;IAER,KAAK,KAAI,CAAC;IAEV,KAAK;QACH,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QAC5C,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IACpD,CAAC;CACF"}
@@ -1 +1 @@
1
- {"version":3,"file":"ipc-store.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/ipc/ipc-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAgB3E;;;;;GAKG;AACH,qBAAa,QAAS,YAAW,SAAS;;;IAYxC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC;IAI9D,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;CAGpD"}
1
+ {"version":3,"file":"ipc-store.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/ipc/ipc-store.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAkB3E;;;;;GAKG;AACH,qBAAa,QAAS,YAAW,SAAS;;;IAcxC,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,cAAc,GAAG,OAAO,CAAC,KAAK,CAAC;IAI9D,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;CAGpD"}
@@ -1,13 +1,15 @@
1
+ import { ConnectionSupervisor } from "../remote/connection-supervisor.js";
1
2
  import { RemoteLockClient } from "../remote/remote-lock-client.js";
2
3
  import { ProcessChannelConnection } from "./process-channel-connection.js";
3
4
  /** The channel to the parent cannot be re-established, so it is handed out once. */
4
5
  class ProcessChannelConnector {
5
- #handedOut = false;
6
+ #channel = [
7
+ new ProcessChannelConnection(),
8
+ ].values();
6
9
  async connect() {
7
- if (this.#handedOut || !process.connected)
10
+ if (!process.connected)
8
11
  return undefined;
9
- this.#handedOut = true;
10
- return new ProcessChannelConnection();
12
+ return this.#channel.next().value;
11
13
  }
12
14
  }
13
15
  /**
@@ -22,7 +24,7 @@ export class IpcStore {
22
24
  if (!process.send) {
23
25
  throw new Error('IpcStore needs an IPC channel to its parent; start this process with fork() or an "ipc" stdio entry.');
24
26
  }
25
- this.#client = new RemoteLockClient(new ProcessChannelConnector());
27
+ this.#client = new RemoteLockClient(new ConnectionSupervisor(new ProcessChannelConnector()));
26
28
  }
27
29
  acquire(key, options) {
28
30
  return this.#client.acquire(key, options);
@@ -1 +1 @@
1
- {"version":3,"file":"ipc-store.js","sourceRoot":"","sources":["../../../src/lock-stores/ipc/ipc-store.ts"],"names":[],"mappings":"AAGA,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAE3E,oFAAoF;AACpF,MAAM,uBAAuB;IAC3B,UAAU,GAAG,KAAK,CAAC;IAEnB,KAAK,CAAC,OAAO;QACX,IAAI,IAAI,CAAC,UAAU,IAAI,CAAC,OAAO,CAAC,SAAS;YAAE,OAAO,SAAS,CAAC;QAC5D,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,OAAO,IAAI,wBAAwB,EAAE,CAAC;IACxC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,QAAQ;IACV,OAAO,CAAmB;IAEnC;QACE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,sGAAsG,CACvG,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,gBAAgB,CAAC,IAAI,uBAAuB,EAAE,CAAC,CAAC;IACrE,CAAC;IAED,OAAO,CAAC,GAAW,EAAE,OAAwB;QAC3C,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,UAAU,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;CACF"}
1
+ {"version":3,"file":"ipc-store.js","sourceRoot":"","sources":["../../../src/lock-stores/ipc/ipc-store.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,oBAAoB,EAAE,MAAM,oCAAoC,CAAC;AAE1E,OAAO,EAAE,gBAAgB,EAAE,MAAM,iCAAiC,CAAC;AACnE,OAAO,EAAE,wBAAwB,EAAE,MAAM,iCAAiC,CAAC;AAE3E,oFAAoF;AACpF,MAAM,uBAAuB;IAClB,QAAQ,GAAkD;QACjE,IAAI,wBAAwB,EAAE;KAC/B,CAAC,MAAM,EAAE,CAAC;IAEX,KAAK,CAAC,OAAO;QACX,IAAI,CAAC,OAAO,CAAC,SAAS;YAAE,OAAO,SAAS,CAAC;QACzC,OAAO,IAAI,CAAC,QAAQ,CAAC,IAAI,EAAE,CAAC,KAAK,CAAC;IACpC,CAAC;CACF;AAED;;;;;GAKG;AACH,MAAM,OAAO,QAAQ;IACV,OAAO,CAAmB;IAEnC;QACE,IAAI,CAAC,OAAO,CAAC,IAAI,EAAE,CAAC;YAClB,MAAM,IAAI,KAAK,CACb,sGAAsG,CACvG,CAAC;QACJ,CAAC;QACD,IAAI,CAAC,OAAO,GAAG,IAAI,gBAAgB,CACjC,IAAI,oBAAoB,CAAC,IAAI,uBAAuB,EAAE,CAAC,CACxD,CAAC;IACJ,CAAC;IAED,OAAO,CAAC,GAAW,EAAE,OAAwB;QAC3C,OAAO,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,CAAC;IAC5C,CAAC;IAED,UAAU,CAAC,GAAW;QACpB,OAAO,IAAI,CAAC,OAAO,CAAC,UAAU,CAAC,GAAG,CAAC,CAAC;IACtC,CAAC;CACF"}
@@ -1,4 +1,5 @@
1
- import type { Connection, ConnectionHandlers } from '../remote/connection.ts';
1
+ import { EventEmitter } from 'node:events';
2
+ import type { Connection, ConnectionEvents } from '../remote/connection.ts';
2
3
  import { type LockRequest, type LockResponse } from '../remote/protocol.ts';
3
4
  /**
4
5
  * The child's end of the IPC channel to its parent. Node counts `message` and
@@ -7,10 +8,10 @@ import { type LockRequest, type LockResponse } from '../remote/protocol.ts';
7
8
  * own listeners in charge of the process lifetime. Messages that arrive while
8
9
  * not listening are buffered by Node and delivered on the next `ref`.
9
10
  */
10
- export declare class ProcessChannelConnection implements Connection<LockRequest, LockResponse> {
11
+ export declare class ProcessChannelConnection extends EventEmitter<ConnectionEvents<LockResponse>> implements Connection<LockRequest, LockResponse> {
11
12
  #private;
12
13
  send(request: LockRequest): Promise<void>;
13
- listen(handlers: ConnectionHandlers<LockResponse>): void;
14
+ /** Removes the listeners before it adds them, so a second `ref` does not listen twice. */
14
15
  ref(): void;
15
16
  unref(): void;
16
17
  close(): void;
@@ -1 +1 @@
1
- {"version":3,"file":"process-channel-connection.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/ipc/process-channel-connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE9E,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,YAAY,EAElB,MAAM,uBAAuB,CAAC;AAE/B;;;;;;GAMG;AACH,qBAAa,wBAAyB,YAAW,UAAU,CACzD,WAAW,EACX,YAAY,CACb;;IAcC,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAYzC,MAAM,CAAC,QAAQ,EAAE,kBAAkB,CAAC,YAAY,CAAC;IAIjD,GAAG;IAOH,KAAK;IAOL,KAAK;CAGN"}
1
+ {"version":3,"file":"process-channel-connection.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/ipc/process-channel-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAE3C,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,MAAM,yBAAyB,CAAC;AAE5E,OAAO,EACL,KAAK,WAAW,EAChB,KAAK,YAAY,EAElB,MAAM,uBAAuB,CAAC;AAE/B;;;;;;GAMG;AACH,qBAAa,wBACX,SAAQ,YAAY,CAAC,gBAAgB,CAAC,YAAY,CAAC,CACnD,YAAW,UAAU,CAAC,WAAW,EAAE,YAAY,CAAC;;IAYhD,IAAI,CAAC,OAAO,EAAE,WAAW,GAAG,OAAO,CAAC,IAAI,CAAC;IAYzC,0FAA0F;IAC1F,GAAG;IAMH,KAAK;IAKL,KAAK;CAGN"}
@@ -1,3 +1,4 @@
1
+ import { EventEmitter } from 'node:events';
1
2
  import { unwrap, wrap } from "../remote/envelope.js";
2
3
  import { isLockResponse, } from "../remote/protocol.js";
3
4
  /**
@@ -7,17 +8,15 @@ import { isLockResponse, } from "../remote/protocol.js";
7
8
  * own listeners in charge of the process lifetime. Messages that arrive while
8
9
  * not listening are buffered by Node and delivered on the next `ref`.
9
10
  */
10
- export class ProcessChannelConnection {
11
- #handlers;
12
- #listening = false;
11
+ export class ProcessChannelConnection extends EventEmitter {
13
12
  #onMessage = (envelope) => {
14
13
  const response = unwrap(envelope);
15
14
  if (isLockResponse(response))
16
- this.#handlers?.message(response);
15
+ this.emit('message', response);
17
16
  };
18
17
  #onDisconnect = () => {
19
18
  this.unref();
20
- this.#handlers?.close();
19
+ this.emit('close');
21
20
  };
22
21
  send(request) {
23
22
  return new Promise((resolve, reject) => {
@@ -28,20 +27,13 @@ export class ProcessChannelConnection {
28
27
  process.send(wrap(request), undefined, {}, (error) => error ? reject(error) : resolve());
29
28
  });
30
29
  }
31
- listen(handlers) {
32
- this.#handlers = handlers;
33
- }
30
+ /** Removes the listeners before it adds them, so a second `ref` does not listen twice. */
34
31
  ref() {
35
- if (this.#listening)
36
- return;
37
- this.#listening = true;
32
+ this.unref();
38
33
  process.on('message', this.#onMessage);
39
34
  process.on('disconnect', this.#onDisconnect);
40
35
  }
41
36
  unref() {
42
- if (!this.#listening)
43
- return;
44
- this.#listening = false;
45
37
  process.off('message', this.#onMessage);
46
38
  process.off('disconnect', this.#onDisconnect);
47
39
  }
@@ -1 +1 @@
1
- {"version":3,"file":"process-channel-connection.js","sourceRoot":"","sources":["../../../src/lock-stores/ipc/process-channel-connection.ts"],"names":[],"mappings":"AACA,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAGL,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B;;;;;;GAMG;AACH,MAAM,OAAO,wBAAwB;IAInC,SAAS,CAA+C;IACxD,UAAU,GAAG,KAAK,CAAC;IAEV,UAAU,GAAG,CAAC,QAAiB,EAAE,EAAE;QAC1C,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QAClC,IAAI,cAAc,CAAC,QAAQ,CAAC;YAAE,IAAI,CAAC,SAAS,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;IAClE,CAAC,CAAC;IAEO,aAAa,GAAG,GAAG,EAAE;QAC5B,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,SAAS,EAAE,KAAK,EAAE,CAAC;IAC1B,CAAC,CAAC;IAEF,IAAI,CAAC,OAAoB;QACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;gBACxC,MAAM,CAAC,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC,CAAC;gBAC9D,OAAO;YACT,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CACnD,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAClC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,MAAM,CAAC,QAA0C;QAC/C,IAAI,CAAC,SAAS,GAAG,QAAQ,CAAC;IAC5B,CAAC;IAED,GAAG;QACD,IAAI,IAAI,CAAC,UAAU;YAAE,OAAO;QAC5B,IAAI,CAAC,UAAU,GAAG,IAAI,CAAC;QACvB,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACvC,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK;QACH,IAAI,CAAC,IAAI,CAAC,UAAU;YAAE,OAAO;QAC7B,IAAI,CAAC,UAAU,GAAG,KAAK,CAAC;QACxB,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAChD,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;CACF"}
1
+ {"version":3,"file":"process-channel-connection.js","sourceRoot":"","sources":["../../../src/lock-stores/ipc/process-channel-connection.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAG3C,OAAO,EAAE,MAAM,EAAE,IAAI,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,EAGL,cAAc,GACf,MAAM,uBAAuB,CAAC;AAE/B;;;;;;GAMG;AACH,MAAM,OAAO,wBACX,SAAQ,YAA4C;IAG3C,UAAU,GAAG,CAAC,QAAiB,EAAE,EAAE;QAC1C,MAAM,QAAQ,GAAG,MAAM,CAAC,QAAQ,CAAC,CAAC;QAClC,IAAI,cAAc,CAAC,QAAQ,CAAC;YAAE,IAAI,CAAC,IAAI,CAAC,SAAS,EAAE,QAAQ,CAAC,CAAC;IAC/D,CAAC,CAAC;IAEO,aAAa,GAAG,GAAG,EAAE;QAC5B,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IACrB,CAAC,CAAC;IAEF,IAAI,CAAC,OAAoB;QACvB,OAAO,IAAI,OAAO,CAAC,CAAC,OAAO,EAAE,MAAM,EAAE,EAAE;YACrC,IAAI,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC,OAAO,CAAC,SAAS,EAAE,CAAC;gBACxC,MAAM,CAAC,IAAI,KAAK,CAAC,0CAA0C,CAAC,CAAC,CAAC;gBAC9D,OAAO;YACT,CAAC;YACD,OAAO,CAAC,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,EAAE,SAAS,EAAE,EAAE,EAAE,CAAC,KAAK,EAAE,EAAE,CACnD,KAAK,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,OAAO,EAAE,CAClC,CAAC;QACJ,CAAC,CAAC,CAAC;IACL,CAAC;IAED,0FAA0F;IAC1F,GAAG;QACD,IAAI,CAAC,KAAK,EAAE,CAAC;QACb,OAAO,CAAC,EAAE,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACvC,OAAO,CAAC,EAAE,CAAC,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAC/C,CAAC;IAED,KAAK;QACH,OAAO,CAAC,GAAG,CAAC,SAAS,EAAE,IAAI,CAAC,UAAU,CAAC,CAAC;QACxC,OAAO,CAAC,GAAG,CAAC,YAAY,EAAE,IAAI,CAAC,aAAa,CAAC,CAAC;IAChD,CAAC;IAED,KAAK;QACH,IAAI,CAAC,KAAK,EAAE,CAAC;IACf,CAAC;CACF"}
@@ -4,7 +4,7 @@ import type { AcquireOptions, LockStore } from '../../mutex/lock-store.ts';
4
4
  export interface MemoryStoreOptions {
5
5
  tokens?: TokenSource;
6
6
  }
7
- /** Per-key FIFO promise chain; locks are shared only through this instance. */
7
+ /** Per-key FIFO line of latches; locks are shared only through this instance. */
8
8
  export declare class MemoryStore implements LockStore {
9
9
  #private;
10
10
  constructor({ tokens }?: MemoryStoreOptions);
@@ -1 +1 @@
1
- {"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/memory/memory-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,KAAK,KAAK,EAAY,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAG3E,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,+EAA+E;AAC/E,qBAAa,WAAY,YAAW,SAAS;;gBAI/B,EAAE,MAAiC,EAAE,GAAE,kBAAuB;IAIpE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,GAAE,cAAmB,GAAG,OAAO,CAAC,KAAK,CAAC;IAwBrE,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;CAI1D"}
1
+ {"version":3,"file":"memory-store.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/memory/memory-store.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,EAAE,KAAK,KAAK,EAAY,MAAM,sBAAsB,CAAC;AAC5D,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAI3E,MAAM,WAAW,kBAAkB;IACjC,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB;AAED,iFAAiF;AACjF,qBAAa,WAAY,YAAW,SAAS;;gBAK/B,EAAE,MAAiC,EAAE,GAAE,kBAAuB;IAIpE,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,GAAE,cAAmB,GAAG,OAAO,CAAC,KAAK,CAAC;IAqBrE,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;CAI1D"}
@@ -1,39 +1,38 @@
1
1
  import { CounterTokenSource } from "../../fencing/counter-token-source.js";
2
2
  import { leaseFor } from "../../mutex/lease.js";
3
+ import { Latch } from "../../shared/latch.js";
3
4
  import { untilAborted } from "../../shared/until-aborted.js";
4
- /** Per-key FIFO promise chain; locks are shared only through this instance. */
5
+ /** Per-key FIFO line of latches; locks are shared only through this instance. */
5
6
  export class MemoryStore {
6
- #tails = new Map();
7
+ /** For each key, the latch that the last caller in line opens when it releases. */
8
+ #lines = new Map();
7
9
  #tokens;
8
10
  constructor({ tokens = new CounterTokenSource() } = {}) {
9
11
  this.#tokens = tokens;
10
12
  }
11
13
  async acquire(key, { signal } = {}) {
12
14
  signal?.throwIfAborted();
13
- const previous = this.#tails.get(key);
14
- const released = Promise.withResolvers();
15
- const tail = previous
16
- ? previous.then(() => released.promise)
17
- : released.promise;
18
- this.#tails.set(key, tail);
15
+ const previous = this.#lines.get(key);
16
+ const released = new Latch();
17
+ this.#lines.set(key, released);
19
18
  const release = async () => {
20
- released.resolve();
21
- if (this.#tails.get(key) === tail)
22
- this.#tails.delete(key);
19
+ released.open();
20
+ if (this.#lines.get(key) === released)
21
+ this.#lines.delete(key);
23
22
  };
24
- const turn = Promise.resolve(previous);
23
+ const turn = previous?.wait() ?? Promise.resolve();
25
24
  try {
26
25
  await untilAborted(turn, signal);
27
26
  }
28
27
  catch (error) {
29
- // A waiter cannot leave the middle of the chain, so its place passes the key on when its turn comes.
28
+ // A waiter cannot leave the middle of the line, so its place passes the key on when its turn comes.
30
29
  void turn.then(release);
31
30
  throw error;
32
31
  }
33
32
  return leaseFor(key, { [Symbol.asyncDispose]: release }, this.#tokens);
34
33
  }
35
34
  async tryAcquire(key) {
36
- if (this.#tails.has(key))
35
+ if (this.#lines.has(key))
37
36
  return undefined;
38
37
  return this.acquire(key);
39
38
  }
@@ -1 +1 @@
1
- {"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../../../src/lock-stores/memory/memory-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAE3E,OAAO,EAAc,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE5D,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAM7D,+EAA+E;AAC/E,MAAM,OAAO,WAAW;IACb,MAAM,GAAG,IAAI,GAAG,EAAyB,CAAC;IAC1C,OAAO,CAAc;IAE9B,YAAY,EAAE,MAAM,GAAG,IAAI,kBAAkB,EAAE,KAAyB,EAAE;QACxE,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW,EAAE,EAAE,MAAM,KAAqB,EAAE;QACxD,MAAM,EAAE,cAAc,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,OAAO,CAAC,aAAa,EAAQ,CAAC;QAC/C,MAAM,IAAI,GAAG,QAAQ;YACnB,CAAC,CAAC,QAAQ,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,QAAQ,CAAC,OAAO,CAAC;YACvC,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC;QACrB,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,IAAI,CAAC,CAAC;QAC3B,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;YACzB,QAAQ,CAAC,OAAO,EAAE,CAAC;YACnB,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,IAAI;gBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QAC7D,CAAC,CAAC;QAEF,MAAM,IAAI,GAAG,OAAO,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC;QACvC,IAAI,CAAC;YACH,MAAM,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,qGAAqG;YACrG,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxB,MAAM,KAAK,CAAC;QACd,CAAC;QACD,OAAO,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACzE,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,GAAW;QAC1B,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3C,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;CACF"}
1
+ {"version":3,"file":"memory-store.js","sourceRoot":"","sources":["../../../src/lock-stores/memory/memory-store.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,kBAAkB,EAAE,MAAM,uCAAuC,CAAC;AAE3E,OAAO,EAAc,QAAQ,EAAE,MAAM,sBAAsB,CAAC;AAE5D,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAC9C,OAAO,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAM7D,iFAAiF;AACjF,MAAM,OAAO,WAAW;IACtB,mFAAmF;IAC1E,MAAM,GAAG,IAAI,GAAG,EAAiB,CAAC;IAClC,OAAO,CAAc;IAE9B,YAAY,EAAE,MAAM,GAAG,IAAI,kBAAkB,EAAE,KAAyB,EAAE;QACxE,IAAI,CAAC,OAAO,GAAG,MAAM,CAAC;IACxB,CAAC;IAED,KAAK,CAAC,OAAO,CAAC,GAAW,EAAE,EAAE,MAAM,KAAqB,EAAE;QACxD,MAAM,EAAE,cAAc,EAAE,CAAC;QACzB,MAAM,QAAQ,GAAG,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,CAAC;QACtC,MAAM,QAAQ,GAAG,IAAI,KAAK,EAAE,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,EAAE,QAAQ,CAAC,CAAC;QAC/B,MAAM,OAAO,GAAG,KAAK,IAAI,EAAE;YACzB,QAAQ,CAAC,IAAI,EAAE,CAAC;YAChB,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC,KAAK,QAAQ;gBAAE,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC,GAAG,CAAC,CAAC;QACjE,CAAC,CAAC;QAEF,MAAM,IAAI,GAAG,QAAQ,EAAE,IAAI,EAAE,IAAI,OAAO,CAAC,OAAO,EAAE,CAAC;QACnD,IAAI,CAAC;YACH,MAAM,YAAY,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC;QACnC,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,oGAAoG;YACpG,KAAK,IAAI,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;YACxB,MAAM,KAAK,CAAC;QACd,CAAC;QACD,OAAO,QAAQ,CAAC,GAAG,EAAE,EAAE,CAAC,MAAM,CAAC,YAAY,CAAC,EAAE,OAAO,EAAE,EAAE,IAAI,CAAC,OAAO,CAAC,CAAC;IACzE,CAAC;IAED,KAAK,CAAC,UAAU,CAAC,GAAW;QAC1B,IAAI,IAAI,CAAC,MAAM,CAAC,GAAG,CAAC,GAAG,CAAC;YAAE,OAAO,SAAS,CAAC;QAC3C,OAAO,IAAI,CAAC,OAAO,CAAC,GAAG,CAAC,CAAC;IAC3B,CAAC;CACF"}
@@ -0,0 +1,39 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import type { Connector } from './connector.ts';
3
+ export type SupervisorStatus = 'idle' | 'connecting' | 'connected' | 'unavailable' | 'closed';
4
+ export interface SupervisorEvents<Incoming> {
5
+ /** A connection is open: the first one, or the replacement for a lost one. */
6
+ connected: [];
7
+ message: [message: Incoming];
8
+ /** The open connection is gone and a replacement is on its way. Nothing sent on it will be answered. */
9
+ disconnected: [];
10
+ /** The connector can never connect again. */
11
+ unavailable: [];
12
+ /** One attempt to connect failed; the next `open` tries again. */
13
+ failed: [error: unknown];
14
+ }
15
+ /**
16
+ * Keeps one connection open at a time. It connects on `open`, replaces a
17
+ * connection that is lost, and stops for good when its connector has no peer
18
+ * left. It never reads the messages it carries: what a replacement must be
19
+ * told again is for its listener to decide.
20
+ */
21
+ export declare class ConnectionSupervisor<Outgoing, Incoming> extends EventEmitter<SupervisorEvents<Incoming>> {
22
+ #private;
23
+ constructor(connector: Connector<Outgoing, Incoming>);
24
+ get status(): SupervisorStatus;
25
+ /** Starts connecting, unless a connection is open, on its way, or never coming. */
26
+ open(): void;
27
+ /** Whether `message` was handed to an open connection. A failed delivery is reported as a loss. */
28
+ send(message: Outgoing): boolean;
29
+ /**
30
+ * Keeps the process alive through the open connection. A replacement starts
31
+ * with its adapter's default, so a listener that waits applies this again on
32
+ * `connected`.
33
+ */
34
+ ref(): void;
35
+ unref(): void;
36
+ /** Closes for good, after any connect still on its way has stopped. */
37
+ close(): Promise<void>;
38
+ }
39
+ //# sourceMappingURL=connection-supervisor.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-supervisor.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/remote/connection-supervisor.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAI3C,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAEhD,MAAM,MAAM,gBAAgB,GAC1B,MAAM,GAAG,YAAY,GAAG,WAAW,GAAG,aAAa,GAAG,QAAQ,CAAC;AAEjE,MAAM,WAAW,gBAAgB,CAAC,QAAQ;IACxC,8EAA8E;IAC9E,SAAS,EAAE,EAAE,CAAC;IACd,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7B,wGAAwG;IACxG,YAAY,EAAE,EAAE,CAAC;IACjB,6CAA6C;IAC7C,WAAW,EAAE,EAAE,CAAC;IAChB,kEAAkE;IAClE,MAAM,EAAE,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;CAC1B;AAED;;;;;GAKG;AACH,qBAAa,oBAAoB,CAAC,QAAQ,EAAE,QAAQ,CAAE,SAAQ,YAAY,CACxE,gBAAgB,CAAC,QAAQ,CAAC,CAC3B;;gBAGa,SAAS,EAAE,SAAS,CAAC,QAAQ,EAAE,QAAQ,CAAC;IAKpD,IAAI,MAAM,IAAI,gBAAgB,CAE7B;IAED,mFAAmF;IACnF,IAAI;IAIJ,mGAAmG;IACnG,IAAI,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO;IAIhC;;;;OAIG;IACH,GAAG;IAIH,KAAK;IAIL,uEAAuE;IACvE,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC;CAGvB"}
@@ -0,0 +1,195 @@
1
+ import { EventEmitter } from 'node:events';
2
+ import { Latch } from "../../shared/latch.js";
3
+ /**
4
+ * Keeps one connection open at a time. It connects on `open`, replaces a
5
+ * connection that is lost, and stops for good when its connector has no peer
6
+ * left. It never reads the messages it carries: what a replacement must be
7
+ * told again is for its listener to decide.
8
+ */
9
+ export class ConnectionSupervisor extends EventEmitter {
10
+ #supervision;
11
+ constructor(connector) {
12
+ super();
13
+ this.#supervision = new Supervision(connector, this);
14
+ }
15
+ get status() {
16
+ return this.#supervision.state.status;
17
+ }
18
+ /** Starts connecting, unless a connection is open, on its way, or never coming. */
19
+ open() {
20
+ this.#supervision.state.open();
21
+ }
22
+ /** Whether `message` was handed to an open connection. A failed delivery is reported as a loss. */
23
+ send(message) {
24
+ return this.#supervision.state.send(message);
25
+ }
26
+ /**
27
+ * Keeps the process alive through the open connection. A replacement starts
28
+ * with its adapter's default, so a listener that waits applies this again on
29
+ * `connected`.
30
+ */
31
+ ref() {
32
+ this.#supervision.state.reference(true);
33
+ }
34
+ unref() {
35
+ this.#supervision.state.reference(false);
36
+ }
37
+ /** Closes for good, after any connect still on its way has stopped. */
38
+ close() {
39
+ return this.#supervision.state.close();
40
+ }
41
+ }
42
+ /** What the states share: the current state, and how to move to the next. */
43
+ class Supervision {
44
+ connector;
45
+ events;
46
+ state;
47
+ constructor(connector, events) {
48
+ this.connector = connector;
49
+ this.events = events;
50
+ this.state = new Idle(this);
51
+ }
52
+ /** A state that stopped being current must not act on what it started. */
53
+ isCurrent(state) {
54
+ return this.state === state;
55
+ }
56
+ become(state) {
57
+ this.state = state;
58
+ state.enter();
59
+ }
60
+ }
61
+ class Idle {
62
+ status = 'idle';
63
+ #supervision;
64
+ constructor(supervision) {
65
+ this.#supervision = supervision;
66
+ }
67
+ enter() { }
68
+ open() {
69
+ this.#supervision.become(new Connecting(this.#supervision));
70
+ }
71
+ send() {
72
+ return false;
73
+ }
74
+ reference() { }
75
+ async close() {
76
+ this.#supervision.become(new Closed());
77
+ }
78
+ }
79
+ class Connecting {
80
+ status = 'connecting';
81
+ #supervision;
82
+ #abort = new AbortController();
83
+ /** Opens when the connect ends, so `close` can wait for it. */
84
+ #ended = new Latch();
85
+ constructor(supervision) {
86
+ this.#supervision = supervision;
87
+ }
88
+ enter() {
89
+ void this.#connect().finally(() => this.#ended.open());
90
+ }
91
+ async #connect() {
92
+ const supervision = this.#supervision;
93
+ let connection;
94
+ try {
95
+ connection = await Promise.try(() => supervision.connector.connect(this.#abort.signal));
96
+ }
97
+ catch (error) {
98
+ if (!supervision.isCurrent(this))
99
+ return;
100
+ supervision.become(new Idle(supervision));
101
+ supervision.events.emit('failed', error);
102
+ return;
103
+ }
104
+ if (!supervision.isCurrent(this)) {
105
+ connection?.close();
106
+ return;
107
+ }
108
+ supervision.become(connection
109
+ ? new Connected(supervision, connection)
110
+ : new Unavailable(supervision));
111
+ }
112
+ open() { }
113
+ send() {
114
+ return false;
115
+ }
116
+ reference() { }
117
+ async close() {
118
+ this.#supervision.become(new Closed());
119
+ this.#abort.abort();
120
+ await this.#ended.wait();
121
+ }
122
+ }
123
+ class Connected {
124
+ status = 'connected';
125
+ #supervision;
126
+ #connection;
127
+ constructor(supervision, connection) {
128
+ this.#supervision = supervision;
129
+ this.#connection = connection;
130
+ }
131
+ enter() {
132
+ const supervision = this.#supervision;
133
+ this.#connection.on('message', (message) => {
134
+ if (supervision.isCurrent(this))
135
+ supervision.events.emit('message', message);
136
+ });
137
+ this.#connection.once('close', () => this.#lose());
138
+ supervision.events.emit('connected');
139
+ }
140
+ open() { }
141
+ /** The connection may report its loss while it sends, so the state is checked after the call. */
142
+ send(message) {
143
+ this.#connection.send(message).catch(() => this.#lose());
144
+ return this.#supervision.isCurrent(this);
145
+ }
146
+ reference(referenced) {
147
+ if (referenced)
148
+ this.#connection.ref();
149
+ else
150
+ this.#connection.unref();
151
+ }
152
+ async close() {
153
+ this.#supervision.become(new Closed());
154
+ this.#connection.close();
155
+ }
156
+ /** A close event and a failed send can both report one loss; only the first counts. */
157
+ #lose() {
158
+ const supervision = this.#supervision;
159
+ if (!supervision.isCurrent(this))
160
+ return;
161
+ this.#connection.close();
162
+ // Leave this state before the listener hears of the loss, so its sends wait for the replacement.
163
+ supervision.become(new Connecting(supervision));
164
+ supervision.events.emit('disconnected');
165
+ }
166
+ }
167
+ class Unavailable {
168
+ status = 'unavailable';
169
+ #supervision;
170
+ constructor(supervision) {
171
+ this.#supervision = supervision;
172
+ }
173
+ enter() {
174
+ this.#supervision.events.emit('unavailable');
175
+ }
176
+ open() { }
177
+ send() {
178
+ return false;
179
+ }
180
+ reference() { }
181
+ async close() {
182
+ this.#supervision.become(new Closed());
183
+ }
184
+ }
185
+ class Closed {
186
+ status = 'closed';
187
+ enter() { }
188
+ open() { }
189
+ send() {
190
+ return false;
191
+ }
192
+ reference() { }
193
+ async close() { }
194
+ }
195
+ //# sourceMappingURL=connection-supervisor.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"connection-supervisor.js","sourceRoot":"","sources":["../../../src/lock-stores/remote/connection-supervisor.ts"],"names":[],"mappings":"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"}
@@ -1,13 +1,17 @@
1
- export interface ConnectionHandlers<Incoming> {
2
- message(message: Incoming): void;
3
- /** Called once, when the peer is gone. */
4
- close(): void;
1
+ import type { EventEmitter } from 'node:events';
2
+ export interface ConnectionEvents<Incoming> {
3
+ message: [message: Incoming];
4
+ /** Emitted once, when the peer is gone. */
5
+ close: [];
5
6
  }
6
- /** A message channel to one peer. Adapters wrap IPC channels and sockets. */
7
- export interface Connection<Outgoing, Incoming> {
7
+ /**
8
+ * A message channel to one peer. Adapters wrap IPC channels and sockets.
9
+ * Subscribe in the task that receives the connection: a message that arrives
10
+ * while nobody listens is not kept.
11
+ */
12
+ export interface Connection<Outgoing, Incoming> extends EventEmitter<ConnectionEvents<Incoming>> {
8
13
  /** Rejects when the message cannot be delivered because the peer is gone. */
9
14
  send(message: Outgoing): Promise<void>;
10
- listen(handlers: ConnectionHandlers<Incoming>): void;
11
15
  /** Keeps the process alive while its owner waits for a message. */
12
16
  ref(): void;
13
17
  /** Lets the process exit; messages and closure are still reported while it runs. */
@@ -1 +1 @@
1
- {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/remote/connection.ts"],"names":[],"mappings":"AAAA,MAAM,WAAW,kBAAkB,CAAC,QAAQ;IAC1C,OAAO,CAAC,OAAO,EAAE,QAAQ,GAAG,IAAI,CAAC;IACjC,0CAA0C;IAC1C,KAAK,IAAI,IAAI,CAAC;CACf;AAED,6EAA6E;AAC7E,MAAM,WAAW,UAAU,CAAC,QAAQ,EAAE,QAAQ;IAC5C,6EAA6E;IAC7E,IAAI,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,MAAM,CAAC,QAAQ,EAAE,kBAAkB,CAAC,QAAQ,CAAC,GAAG,IAAI,CAAC;IACrD,mEAAmE;IACnE,GAAG,IAAI,IAAI,CAAC;IACZ,oFAAoF;IACpF,KAAK,IAAI,IAAI,CAAC;IACd,KAAK,IAAI,IAAI,CAAC;CACf"}
1
+ {"version":3,"file":"connection.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/remote/connection.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD,MAAM,WAAW,gBAAgB,CAAC,QAAQ;IACxC,OAAO,EAAE,CAAC,OAAO,EAAE,QAAQ,CAAC,CAAC;IAC7B,2CAA2C;IAC3C,KAAK,EAAE,EAAE,CAAC;CACX;AAED;;;;GAIG;AACH,MAAM,WAAW,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAE,SAAQ,YAAY,CAClE,gBAAgB,CAAC,QAAQ,CAAC,CAC3B;IACC,6EAA6E;IAC7E,IAAI,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IACvC,mEAAmE;IACnE,GAAG,IAAI,IAAI,CAAC;IACZ,oFAAoF;IACpF,KAAK,IAAI,IAAI,CAAC;IACd,KAAK,IAAI,IAAI,CAAC;CACf"}
@@ -2,11 +2,14 @@ import type { Connection } from './connection.ts';
2
2
  import type { LockRequest, LockResponse } from './protocol.ts';
3
3
  export type ClientConnection = Connection<LockRequest, LockResponse>;
4
4
  /** Decides how a client reaches its coordinator, and whether it can again after losing it. */
5
- export interface Connector {
5
+ export interface Connector<Outgoing, Incoming> {
6
6
  /**
7
7
  * Resolves to `undefined` when the coordinator is gone for good and nothing
8
8
  * can replace it, so no other holder can ever be granted a key either.
9
+ * Rejects when this attempt failed and a later one may succeed. Once
10
+ * `signal` aborts, rejects with its reason and leaves nothing started.
9
11
  */
10
- connect(): Promise<ClientConnection | undefined>;
12
+ connect(signal: AbortSignal): Promise<Connection<Outgoing, Incoming> | undefined>;
11
13
  }
14
+ export type ClientConnector = Connector<LockRequest, LockResponse>;
12
15
  //# sourceMappingURL=connector.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/remote/connector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE/D,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;AAErE,8FAA8F;AAC9F,MAAM,WAAW,SAAS;IACxB;;;OAGG;IACH,OAAO,IAAI,OAAO,CAAC,gBAAgB,GAAG,SAAS,CAAC,CAAC;CAClD"}
1
+ {"version":3,"file":"connector.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/remote/connector.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE/D,MAAM,MAAM,gBAAgB,GAAG,UAAU,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC;AAErE,8FAA8F;AAC9F,MAAM,WAAW,SAAS,CAAC,QAAQ,EAAE,QAAQ;IAC3C;;;;;OAKG;IACH,OAAO,CACL,MAAM,EAAE,WAAW,GAClB,OAAO,CAAC,UAAU,CAAC,QAAQ,EAAE,QAAQ,CAAC,GAAG,SAAS,CAAC,CAAC;CACxD;AAED,MAAM,MAAM,eAAe,GAAG,SAAS,CAAC,WAAW,EAAE,YAAY,CAAC,CAAC"}
@@ -20,14 +20,14 @@ export interface LockCoordinatorOptions {
20
20
  export declare class LockCoordinator implements LockStore {
21
21
  #private;
22
22
  constructor({ tokens, graceWindow }: LockCoordinatorOptions);
23
- acquire(key: string, { signal }?: AcquireOptions): Promise<Lease>;
23
+ acquire(key: string, options?: AcquireOptions): Promise<Lease>;
24
24
  /** Nothing is granted during the grace window, so a key counts as busy then. */
25
25
  tryAcquire(key: string): Promise<Lease | undefined>;
26
26
  serve(connection: Connection<LockResponse, LockRequest>): void;
27
27
  /**
28
28
  * Re-registers a holder from before a failover. Accepted only during the
29
29
  * grace window; for two claims on one key the newer token wins and the older
30
- * claim's `lose` is called. Resolves `undefined` when the claim is refused.
30
+ * claim's `lose` is called. Returns `undefined` when the claim is refused.
31
31
  */
32
32
  reassert(key: string, token: FencingToken, lose: () => void): Promise<Lease> | undefined;
33
33
  }
@@ -1 +1 @@
1
- {"version":3,"file":"lock-coordinator.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/remote/lock-coordinator.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAG3E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE/D,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,WAAW,CAAC;IACpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAQD;;;GAGG;AACH,qBAAa,eAAgB,YAAW,SAAS;;gBAMnC,EAAE,MAAM,EAAE,WAAe,EAAE,EAAE,sBAAsB;IAWzD,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,EAAE,MAAM,EAAE,GAAE,cAAmB,GAAG,OAAO,CAAC,KAAK,CAAC;IAK3E,gFAAgF;IAC1E,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;IAKzD,KAAK,CAAC,UAAU,EAAE,UAAU,CAAC,YAAY,EAAE,WAAW,CAAC,GAAG,IAAI;IAI9D;;;;OAIG;IACH,QAAQ,CACN,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,MAAM,IAAI,GACf,OAAO,CAAC,KAAK,CAAC,GAAG,SAAS;CAY9B"}
1
+ {"version":3,"file":"lock-coordinator.d.ts","sourceRoot":"","sources":["../../../src/lock-stores/remote/lock-coordinator.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,+BAA+B,CAAC;AACjE,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAClD,OAAO,KAAK,EAAE,cAAc,EAAE,SAAS,EAAE,MAAM,2BAA2B,CAAC;AAI3E,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,YAAY,EAAE,MAAM,eAAe,CAAC;AAE/D,MAAM,WAAW,sBAAsB;IACrC,MAAM,EAAE,WAAW,CAAC;IACpB;;;;OAIG;IACH,WAAW,CAAC,EAAE,MAAM,CAAC;CACtB;AAiBD;;;GAGG;AACH,qBAAa,eAAgB,YAAW,SAAS;;gBAGnC,EAAE,MAAM,EAAE,WAAe,EAAE,EAAE,sBAAsB;IAgBzD,OAAO,CAAC,GAAG,EAAE,MAAM,EAAE,OAAO,GAAE,cAAmB,GAAG,OAAO,CAAC,KAAK,CAAC;IAIxE,gFAAgF;IAC1E,UAAU,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,KAAK,GAAG,SAAS,CAAC;IAIzD,KAAK,CAAC,UAAU,EAAE,UAAU,CAAC,YAAY,EAAE,WAAW,CAAC,GAAG,IAAI;IAI9D;;;;OAIG;IACH,QAAQ,CACN,GAAG,EAAE,MAAM,EACX,KAAK,EAAE,YAAY,EACnB,IAAI,EAAE,MAAM,IAAI,GACf,OAAO,CAAC,KAAK,CAAC,GAAG,SAAS;CAG9B"}