@zukhruf/mutex 0.3.16 → 0.3.18
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.
- package/README.md +7 -8
- package/dist/index.d.ts +3 -9
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -7
- package/dist/index.js.map +1 -1
- package/dist/lock-stores/file-system/file-lock-store.d.ts +4 -9
- package/dist/lock-stores/file-system/file-lock-store.d.ts.map +1 -1
- package/dist/lock-stores/file-system/file-lock-store.js +21 -38
- package/dist/lock-stores/file-system/file-lock-store.js.map +1 -1
- package/dist/lock-stores/file-system/lock-file-store.d.ts +1 -1
- package/dist/lock-stores/file-system/lock-file-store.d.ts.map +1 -1
- package/dist/lock-stores/file-system/lock-file-store.js +15 -24
- package/dist/lock-stores/file-system/lock-file-store.js.map +1 -1
- package/dist/lock-stores/file-system/presence.d.ts +10 -17
- package/dist/lock-stores/file-system/presence.d.ts.map +1 -1
- package/dist/lock-stores/file-system/presence.js +30 -69
- package/dist/lock-stores/file-system/presence.js.map +1 -1
- package/dist/lock-stores/file-system/record-file.d.ts +10 -0
- package/dist/lock-stores/file-system/record-file.d.ts.map +1 -0
- package/dist/lock-stores/file-system/record-file.js +21 -0
- package/dist/lock-stores/file-system/record-file.js.map +1 -0
- package/dist/lock-stores/file-system/ticket-queue-file-store.d.ts +1 -1
- package/dist/lock-stores/file-system/ticket-queue-file-store.d.ts.map +1 -1
- package/dist/lock-stores/file-system/ticket-queue-file-store.js +25 -32
- package/dist/lock-stores/file-system/ticket-queue-file-store.js.map +1 -1
- package/dist/lock-stores/ipc/child-process-connection.d.ts +3 -4
- package/dist/lock-stores/ipc/child-process-connection.d.ts.map +1 -1
- package/dist/lock-stores/ipc/child-process-connection.js +11 -27
- package/dist/lock-stores/ipc/child-process-connection.js.map +1 -1
- package/dist/lock-stores/ipc/ipc-lock-coordinator.d.ts +3 -7
- package/dist/lock-stores/ipc/ipc-lock-coordinator.d.ts.map +1 -1
- package/dist/lock-stores/ipc/ipc-lock-coordinator.js +6 -12
- package/dist/lock-stores/ipc/ipc-lock-coordinator.js.map +1 -1
- package/dist/lock-stores/ipc/ipc-store.d.ts +2 -7
- package/dist/lock-stores/ipc/ipc-store.d.ts.map +1 -1
- package/dist/lock-stores/ipc/ipc-store.js +9 -15
- package/dist/lock-stores/ipc/ipc-store.js.map +1 -1
- package/dist/lock-stores/ipc/process-channel-connection.d.ts +4 -4
- package/dist/lock-stores/ipc/process-channel-connection.d.ts.map +1 -1
- package/dist/lock-stores/ipc/process-channel-connection.js +13 -25
- package/dist/lock-stores/ipc/process-channel-connection.js.map +1 -1
- package/dist/lock-stores/memory/memory-store.d.ts +1 -1
- package/dist/lock-stores/memory/memory-store.d.ts.map +1 -1
- package/dist/lock-stores/memory/memory-store.js +1 -1
- package/dist/lock-stores/memory/memory-store.js.map +1 -1
- package/dist/lock-stores/remote/connection-supervisor.d.ts +4 -4
- package/dist/lock-stores/remote/connection-supervisor.d.ts.map +1 -1
- package/dist/lock-stores/remote/connection-supervisor.js.map +1 -1
- package/dist/lock-stores/remote/connection.d.ts +4 -3
- package/dist/lock-stores/remote/connection.d.ts.map +1 -1
- package/dist/lock-stores/remote/connector.d.ts +5 -5
- package/dist/lock-stores/remote/connector.d.ts.map +1 -1
- package/dist/lock-stores/remote/delegating-lock-store.d.ts +14 -0
- package/dist/lock-stores/remote/delegating-lock-store.d.ts.map +1 -0
- package/dist/lock-stores/remote/delegating-lock-store.js +20 -0
- package/dist/lock-stores/remote/delegating-lock-store.js.map +1 -0
- package/dist/lock-stores/remote/lock-coordinator.d.ts +3 -4
- package/dist/lock-stores/remote/lock-coordinator.d.ts.map +1 -1
- package/dist/lock-stores/remote/lock-coordinator.js +23 -12
- package/dist/lock-stores/remote/lock-coordinator.js.map +1 -1
- package/dist/lock-stores/remote/protocol.d.ts +6 -2
- package/dist/lock-stores/remote/protocol.d.ts.map +1 -1
- package/dist/lock-stores/remote/protocol.js +14 -8
- package/dist/lock-stores/remote/protocol.js.map +1 -1
- package/dist/lock-stores/remote/queries.d.ts +2 -2
- package/dist/lock-stores/remote/queries.d.ts.map +1 -1
- package/dist/lock-stores/remote/queries.js.map +1 -1
- package/dist/lock-stores/remote/remote-lock-client.d.ts +2 -2
- package/dist/lock-stores/remote/remote-lock-client.d.ts.map +1 -1
- package/dist/lock-stores/remote/remote-lock-client.js +15 -8
- package/dist/lock-stores/remote/remote-lock-client.js.map +1 -1
- package/dist/lock-stores/remote/shared-channel-connection.d.ts +27 -0
- package/dist/lock-stores/remote/shared-channel-connection.d.ts.map +1 -0
- package/dist/lock-stores/remote/shared-channel-connection.js +41 -0
- package/dist/lock-stores/remote/shared-channel-connection.js.map +1 -0
- package/dist/lock-stores/socket/advertised-ops-connection.d.ts +3 -3
- package/dist/lock-stores/socket/advertised-ops-connection.d.ts.map +1 -1
- package/dist/lock-stores/socket/advertised-ops-connection.js +4 -1
- package/dist/lock-stores/socket/advertised-ops-connection.js.map +1 -1
- package/dist/lock-stores/socket/electing-connector.d.ts +4 -5
- package/dist/lock-stores/socket/electing-connector.d.ts.map +1 -1
- package/dist/lock-stores/socket/electing-connector.js +43 -50
- package/dist/lock-stores/socket/electing-connector.js.map +1 -1
- package/dist/lock-stores/socket/handshake.d.ts.map +1 -1
- package/dist/lock-stores/socket/handshake.js +6 -5
- package/dist/lock-stores/socket/handshake.js.map +1 -1
- package/dist/lock-stores/socket/json-line.d.ts +6 -0
- package/dist/lock-stores/socket/json-line.d.ts.map +1 -0
- package/dist/lock-stores/socket/json-line.js +8 -0
- package/dist/lock-stores/socket/json-line.js.map +1 -0
- package/dist/lock-stores/socket/leave-errors-to-close.d.ts +9 -0
- package/dist/lock-stores/socket/leave-errors-to-close.d.ts.map +1 -0
- package/dist/lock-stores/socket/leave-errors-to-close.js +10 -0
- package/dist/lock-stores/socket/leave-errors-to-close.js.map +1 -0
- package/dist/lock-stores/socket/local-directory-connector.d.ts.map +1 -1
- package/dist/lock-stores/socket/local-directory-connector.js +1 -1
- package/dist/lock-stores/socket/local-directory-connector.js.map +1 -1
- package/dist/lock-stores/socket/lock-server.d.ts +7 -4
- package/dist/lock-stores/socket/lock-server.d.ts.map +1 -1
- package/dist/lock-stores/socket/lock-server.js +29 -26
- package/dist/lock-stores/socket/lock-server.js.map +1 -1
- package/dist/lock-stores/socket/socket-connection.d.ts +5 -5
- package/dist/lock-stores/socket/socket-connection.d.ts.map +1 -1
- package/dist/lock-stores/socket/socket-connection.js +21 -23
- package/dist/lock-stores/socket/socket-connection.js.map +1 -1
- package/dist/lock-stores/socket/socket-election.d.ts +9 -0
- package/dist/lock-stores/socket/socket-election.d.ts.map +1 -0
- package/dist/lock-stores/socket/socket-election.js +16 -0
- package/dist/lock-stores/socket/socket-election.js.map +1 -0
- package/dist/lock-stores/socket/socket-store.d.ts +1 -1
- package/dist/lock-stores/socket/socket-store.d.ts.map +1 -1
- package/dist/lock-stores/socket/socket-store.js +6 -6
- package/dist/lock-stores/socket/socket-store.js.map +1 -1
- package/dist/lock-stores/sqlite/holder-record.d.ts.map +1 -1
- package/dist/lock-stores/sqlite/holder-record.js +9 -23
- package/dist/lock-stores/sqlite/holder-record.js.map +1 -1
- package/dist/lock-stores/sqlite/sqlite-store.d.ts +6 -7
- package/dist/lock-stores/sqlite/sqlite-store.d.ts.map +1 -1
- package/dist/lock-stores/sqlite/sqlite-store.js +31 -101
- package/dist/lock-stores/sqlite/sqlite-store.js.map +1 -1
- package/dist/lock-stores/thread/parent-port-connection.d.ts +3 -4
- package/dist/lock-stores/thread/parent-port-connection.d.ts.map +1 -1
- package/dist/lock-stores/thread/parent-port-connection.js +7 -13
- package/dist/lock-stores/thread/parent-port-connection.js.map +1 -1
- package/dist/lock-stores/thread/thread-lock-coordinator.d.ts +3 -7
- package/dist/lock-stores/thread/thread-lock-coordinator.d.ts.map +1 -1
- package/dist/lock-stores/thread/thread-lock-coordinator.js +6 -12
- package/dist/lock-stores/thread/thread-lock-coordinator.js.map +1 -1
- package/dist/lock-stores/thread/thread-store.d.ts +2 -7
- package/dist/lock-stores/thread/thread-store.d.ts.map +1 -1
- package/dist/lock-stores/thread/thread-store.js +3 -12
- package/dist/lock-stores/thread/thread-store.js.map +1 -1
- package/dist/lock-stores/thread/worker-connection.d.ts +3 -4
- package/dist/lock-stores/thread/worker-connection.d.ts.map +1 -1
- package/dist/lock-stores/thread/worker-connection.js +6 -18
- package/dist/lock-stores/thread/worker-connection.js.map +1 -1
- package/dist/mutex/key.d.ts +3 -3
- package/dist/mutex/key.d.ts.map +1 -1
- package/dist/mutex/key.js.map +1 -1
- package/dist/mutex/lease.d.ts +2 -9
- package/dist/mutex/lease.d.ts.map +1 -1
- package/dist/mutex/lease.js +17 -12
- package/dist/mutex/lease.js.map +1 -1
- package/dist/mutex/mutex.d.ts +3 -3
- package/dist/mutex/mutex.d.ts.map +1 -1
- package/dist/mutex/mutex.js +2 -2
- package/dist/mutex/mutex.js.map +1 -1
- package/package.json +6 -9
- package/dist/fencing/counter-token-source.d.ts +0 -11
- package/dist/fencing/counter-token-source.d.ts.map +0 -1
- package/dist/fencing/counter-token-source.js +0 -13
- package/dist/fencing/counter-token-source.js.map +0 -1
- package/dist/fencing/epoch-token-source.d.ts +0 -13
- package/dist/fencing/epoch-token-source.d.ts.map +0 -1
- package/dist/fencing/epoch-token-source.js +0 -27
- package/dist/fencing/epoch-token-source.js.map +0 -1
- package/dist/fencing/fencing-token.d.ts +0 -12
- package/dist/fencing/fencing-token.d.ts.map +0 -1
- package/dist/fencing/fencing-token.js +0 -18
- package/dist/fencing/fencing-token.js.map +0 -1
- package/dist/fencing/file-token-source.d.ts +0 -13
- package/dist/fencing/file-token-source.d.ts.map +0 -1
- package/dist/fencing/file-token-source.js +0 -36
- package/dist/fencing/file-token-source.js.map +0 -1
- package/dist/fencing/monotonic-clock-token-source.d.ts +0 -12
- package/dist/fencing/monotonic-clock-token-source.d.ts.map +0 -1
- package/dist/fencing/monotonic-clock-token-source.js +0 -15
- package/dist/fencing/monotonic-clock-token-source.js.map +0 -1
- package/dist/fencing/token-source.d.ts +0 -9
- package/dist/fencing/token-source.d.ts.map +0 -1
- package/dist/fencing/token-source.js +0 -2
- package/dist/fencing/token-source.js.map +0 -1
- package/dist/leader-election/index.d.ts +0 -4
- package/dist/leader-election/index.d.ts.map +0 -1
- package/dist/leader-election/index.js +0 -4
- package/dist/leader-election/index.js.map +0 -1
- package/dist/leader-election/leader-election.d.ts +0 -23
- package/dist/leader-election/leader-election.d.ts.map +0 -1
- package/dist/leader-election/leader-election.js +0 -79
- package/dist/leader-election/leader-election.js.map +0 -1
- package/dist/leader-election/leadership.d.ts +0 -14
- package/dist/leader-election/leadership.d.ts.map +0 -1
- package/dist/leader-election/leadership.js +0 -23
- package/dist/leader-election/leadership.js.map +0 -1
- package/dist/local-directory/local-directory.d.ts +0 -7
- package/dist/local-directory/local-directory.d.ts.map +0 -1
- package/dist/local-directory/local-directory.js +0 -75
- package/dist/local-directory/local-directory.js.map +0 -1
- package/dist/local-directory/network-directory-error.d.ts +0 -8
- package/dist/local-directory/network-directory-error.d.ts.map +0 -1
- package/dist/local-directory/network-directory-error.js +0 -13
- package/dist/local-directory/network-directory-error.js.map +0 -1
- package/dist/mutex/lock-lost-error.d.ts +0 -6
- package/dist/mutex/lock-lost-error.d.ts.map +0 -1
- package/dist/mutex/lock-lost-error.js +0 -10
- package/dist/mutex/lock-lost-error.js.map +0 -1
- package/dist/shared/fs/atomic-write.d.ts +0 -3
- package/dist/shared/fs/atomic-write.d.ts.map +0 -1
- package/dist/shared/fs/atomic-write.js +0 -10
- package/dist/shared/fs/atomic-write.js.map +0 -1
- package/dist/shared/fs/create-exclusive.d.ts +0 -6
- package/dist/shared/fs/create-exclusive.d.ts.map +0 -1
- package/dist/shared/fs/create-exclusive.js +0 -29
- package/dist/shared/fs/create-exclusive.js.map +0 -1
- package/dist/shared/fs/durable-write.d.ts +0 -9
- package/dist/shared/fs/durable-write.d.ts.map +0 -1
- package/dist/shared/fs/durable-write.js +0 -49
- package/dist/shared/fs/durable-write.js.map +0 -1
- package/dist/shared/fs/errno.d.ts +0 -2
- package/dist/shared/fs/errno.d.ts.map +0 -1
- package/dist/shared/fs/errno.js +0 -4
- package/dist/shared/fs/errno.js.map +0 -1
- package/dist/shared/fs/patiently.d.ts +0 -3
- package/dist/shared/fs/patiently.d.ts.map +0 -1
- package/dist/shared/fs/patiently.js +0 -30
- package/dist/shared/fs/patiently.js.map +0 -1
- package/dist/shared/fs/replace-file.d.ts +0 -8
- package/dist/shared/fs/replace-file.d.ts.map +0 -1
- package/dist/shared/fs/replace-file.js +0 -12
- package/dist/shared/fs/replace-file.js.map +0 -1
- package/dist/shared/fs/safe-file-name.d.ts +0 -16
- package/dist/shared/fs/safe-file-name.d.ts.map +0 -1
- package/dist/shared/fs/safe-file-name.js +0 -37
- package/dist/shared/fs/safe-file-name.js.map +0 -1
- package/dist/shared/sqlite/is-busy.d.ts +0 -3
- package/dist/shared/sqlite/is-busy.d.ts.map +0 -1
- package/dist/shared/sqlite/is-busy.js +0 -10
- package/dist/shared/sqlite/is-busy.js.map +0 -1
- package/dist/shared/sqlite/is-cant-open.d.ts +0 -3
- package/dist/shared/sqlite/is-cant-open.d.ts.map +0 -1
- package/dist/shared/sqlite/is-cant-open.js +0 -9
- package/dist/shared/sqlite/is-cant-open.js.map +0 -1
- package/dist/shared/sqlite/is-not-a-database.d.ts +0 -3
- package/dist/shared/sqlite/is-not-a-database.d.ts.map +0 -1
- package/dist/shared/sqlite/is-not-a-database.js +0 -9
- package/dist/shared/sqlite/is-not-a-database.js.map +0 -1
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"file-token-source.js","sourceRoot":"","sources":["../../src/fencing/file-token-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,QAAQ,EAAE,MAAM,kBAAkB,CAAC;AACnD,OAAO,EAAE,IAAI,EAAE,MAAM,WAAW,CAAC;AAEjC,OAAO,EAAE,iBAAiB,EAAE,YAAY,EAAE,MAAM,+BAA+B,CAAC;AAChF,OAAO,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AAChD,OAAO,EAAE,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAC9D,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD;;;;GAIG;AACH,MAAM,OAAO,eAAe;IACjB,UAAU,CAAS;IAE5B,YAAY,SAAiB;QAC3B,IAAI,CAAC,UAAU,GAAG,SAAS,CAAC;IAC9B,CAAC;IAED,KAAK,CAAC,IAAI,CAAC,GAAW;QACpB,MAAM,KAAK,CAAC,IAAI,CAAC,UAAU,EAAE,EAAE,SAAS,EAAE,IAAI,EAAE,CAAC,CAAC;QAClD,MAAM,IAAI,GAAG,YAAY,CAAC,GAAG,EAAE,QAAQ,CAAC,MAAM,GAAG,iBAAiB,CAAC,CAAC;QACpE,MAAM,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,UAAU,EAAE,GAAG,IAAI,QAAQ,CAAC,CAAC;QACpD,MAAM,KAAK,GAAG,CAAC,MAAM,WAAW,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,CAAC;QAC7C,MAAM,YAAY,CAAC,IAAI,EAAE,KAAK,CAAC,QAAQ,EAAE,CAAC,CAAC;QAC3C,OAAO,IAAI,YAAY,CAAC,KAAK,CAAC,CAAC;IACjC,CAAC;CACF;AAED,KAAK,UAAU,WAAW,CAAC,IAAY;IACrC,IAAI,CAAC;QACH,OAAO,MAAM,CAAC,MAAM,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAC,CAAC,CAAC;IAC9C,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC;YAAE,OAAO,EAAE,CAAC;QACxC,MAAM,KAAK,CAAC;IACd,CAAC;AACH,CAAC"}
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
import { FencingToken } from './fencing-token.ts';
|
|
2
|
-
import type { TokenSource } from './token-source.ts';
|
|
3
|
-
/**
|
|
4
|
-
* Reads the process-wide monotonic clock, which every worker thread shares, so
|
|
5
|
-
* grants serialized by a lock read strictly later times without shared memory.
|
|
6
|
-
* Tokens restart when the process does.
|
|
7
|
-
*/
|
|
8
|
-
export declare class MonotonicClockTokenSource implements TokenSource {
|
|
9
|
-
#private;
|
|
10
|
-
next(_key: string): Promise<FencingToken>;
|
|
11
|
-
}
|
|
12
|
-
//# sourceMappingURL=monotonic-clock-token-source.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"monotonic-clock-token-source.d.ts","sourceRoot":"","sources":["../../src/fencing/monotonic-clock-token-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAClD,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAErD;;;;GAIG;AACH,qBAAa,yBAA0B,YAAW,WAAW;;IAGrD,IAAI,CAAC,IAAI,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC;CAKhD"}
|
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
import { FencingToken } from "./fencing-token.js";
|
|
2
|
-
/**
|
|
3
|
-
* Reads the process-wide monotonic clock, which every worker thread shares, so
|
|
4
|
-
* grants serialized by a lock read strictly later times without shared memory.
|
|
5
|
-
* Tokens restart when the process does.
|
|
6
|
-
*/
|
|
7
|
-
export class MonotonicClockTokenSource {
|
|
8
|
-
#last = 0n;
|
|
9
|
-
async next(_key) {
|
|
10
|
-
const now = process.hrtime.bigint();
|
|
11
|
-
this.#last = now > this.#last ? now : this.#last + 1n;
|
|
12
|
-
return new FencingToken(this.#last);
|
|
13
|
-
}
|
|
14
|
-
}
|
|
15
|
-
//# sourceMappingURL=monotonic-clock-token-source.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"monotonic-clock-token-source.js","sourceRoot":"","sources":["../../src/fencing/monotonic-clock-token-source.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAGlD;;;;GAIG;AACH,MAAM,OAAO,yBAAyB;IACpC,KAAK,GAAG,EAAE,CAAC;IAEX,KAAK,CAAC,IAAI,CAAC,IAAY;QACrB,MAAM,GAAG,GAAG,OAAO,CAAC,MAAM,CAAC,MAAM,EAAE,CAAC;QACpC,IAAI,CAAC,KAAK,GAAG,GAAG,GAAG,IAAI,CAAC,KAAK,CAAC,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC,IAAI,CAAC,KAAK,GAAG,EAAE,CAAC;QACtD,OAAO,IAAI,YAAY,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;IACtC,CAAC;CACF"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
import type { FencingToken } from './fencing-token.ts';
|
|
2
|
-
/**
|
|
3
|
-
* Mints fencing tokens. Callers hold the key's lock while calling `next`, so
|
|
4
|
-
* minting for one key is never concurrent and each token is newer than the last.
|
|
5
|
-
*/
|
|
6
|
-
export interface TokenSource {
|
|
7
|
-
next(key: string): Promise<FencingToken>;
|
|
8
|
-
}
|
|
9
|
-
//# sourceMappingURL=token-source.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"token-source.d.ts","sourceRoot":"","sources":["../../src/fencing/token-source.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,oBAAoB,CAAC;AAEvD;;;GAGG;AACH,MAAM,WAAW,WAAW;IAC1B,IAAI,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO,CAAC,YAAY,CAAC,CAAC;CAC1C"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"token-source.js","sourceRoot":"","sources":["../../src/fencing/token-source.ts"],"names":[],"mappings":""}
|
|
@@ -1,4 +0,0 @@
|
|
|
1
|
-
export { LeaderElection, type CampaignOptions, type LeaderElectionOptions, } from './leader-election.ts';
|
|
2
|
-
export { Leadership } from './leadership.ts';
|
|
3
|
-
export { NetworkDirectoryError } from '../local-directory/network-directory-error.ts';
|
|
4
|
-
//# sourceMappingURL=index.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/leader-election/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,EACd,KAAK,eAAe,EACpB,KAAK,qBAAqB,GAC3B,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,+CAA+C,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/leader-election/index.ts"],"names":[],"mappings":"AAAA,OAAO,EACL,cAAc,GAGf,MAAM,sBAAsB,CAAC;AAC9B,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAC7C,OAAO,EAAE,qBAAqB,EAAE,MAAM,+CAA+C,CAAC"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
import { Leadership } from './leadership.ts';
|
|
2
|
-
export interface LeaderElectionOptions {
|
|
3
|
-
/** Milliseconds between attempts while another process leads. */
|
|
4
|
-
pollInterval?: number;
|
|
5
|
-
}
|
|
6
|
-
export interface CampaignOptions {
|
|
7
|
-
/** Milliseconds to keep trying before conceding to the current leader. */
|
|
8
|
-
timeout?: number;
|
|
9
|
-
}
|
|
10
|
-
/**
|
|
11
|
-
* Elects one leader among the processes sharing `directory`. The claim is an
|
|
12
|
-
* exclusive SQLite transaction on `leader.lock`, held for the whole term, so the
|
|
13
|
-
* kernel ends the term if the leader dies. Each term gets a higher epoch than
|
|
14
|
-
* every term before it, recorded in `leader.epoch`. Never delete `leader.lock`
|
|
15
|
-
* while campaigners run: a new file would let a second leader win.
|
|
16
|
-
*/
|
|
17
|
-
export declare class LeaderElection {
|
|
18
|
-
#private;
|
|
19
|
-
constructor(directory: string, { pollInterval }?: LeaderElectionOptions);
|
|
20
|
-
/** Resolves with the new term, or `undefined` if another process still leads after `timeout`. */
|
|
21
|
-
campaign({ timeout }?: CampaignOptions): Promise<Leadership | undefined>;
|
|
22
|
-
}
|
|
23
|
-
//# sourceMappingURL=leader-election.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"leader-election.d.ts","sourceRoot":"","sources":["../../src/leader-election/leader-election.ts"],"names":[],"mappings":"AASA,OAAO,EAAE,UAAU,EAAE,MAAM,iBAAiB,CAAC;AAE7C,MAAM,WAAW,qBAAqB;IACpC,iEAAiE;IACjE,YAAY,CAAC,EAAE,MAAM,CAAC;CACvB;AAED,MAAM,WAAW,eAAe;IAC9B,0EAA0E;IAC1E,OAAO,CAAC,EAAE,MAAM,CAAC;CAClB;AAED;;;;;;GAMG;AACH,qBAAa,cAAc;;gBAKvB,SAAS,EAAE,MAAM,EACjB,EAAE,YAAiB,EAAE,GAAE,qBAA0B;IAMnD,iGAAiG;IAC3F,QAAQ,CAAC,EAAE,OAAW,EAAE,GAAE,eAAoB,GAAG,OAAO,CAC5D,UAAU,GAAG,SAAS,CACvB;CAyCF"}
|
|
@@ -1,79 +0,0 @@
|
|
|
1
|
-
import { mkdir, readFile } from 'node:fs/promises';
|
|
2
|
-
import { join } from 'node:path';
|
|
3
|
-
import { DatabaseSync } from 'node:sqlite';
|
|
4
|
-
import { setTimeout as delay } from 'node:timers/promises';
|
|
5
|
-
import { assertLocalDirectory } from "../local-directory/local-directory.js";
|
|
6
|
-
import { durableWrite } from "../shared/fs/durable-write.js";
|
|
7
|
-
import { isErrno } from "../shared/fs/errno.js";
|
|
8
|
-
import { isBusy } from "../shared/sqlite/is-busy.js";
|
|
9
|
-
import { Leadership } from "./leadership.js";
|
|
10
|
-
/**
|
|
11
|
-
* Elects one leader among the processes sharing `directory`. The claim is an
|
|
12
|
-
* exclusive SQLite transaction on `leader.lock`, held for the whole term, so the
|
|
13
|
-
* kernel ends the term if the leader dies. Each term gets a higher epoch than
|
|
14
|
-
* every term before it, recorded in `leader.epoch`. Never delete `leader.lock`
|
|
15
|
-
* while campaigners run: a new file would let a second leader win.
|
|
16
|
-
*/
|
|
17
|
-
export class LeaderElection {
|
|
18
|
-
#directory;
|
|
19
|
-
#pollInterval;
|
|
20
|
-
constructor(directory, { pollInterval = 10 } = {}) {
|
|
21
|
-
this.#directory = directory;
|
|
22
|
-
this.#pollInterval = pollInterval;
|
|
23
|
-
}
|
|
24
|
-
/** Resolves with the new term, or `undefined` if another process still leads after `timeout`. */
|
|
25
|
-
async campaign({ timeout = 0 } = {}) {
|
|
26
|
-
await assertLocalDirectory(this.#directory);
|
|
27
|
-
await mkdir(this.#directory, { recursive: true });
|
|
28
|
-
// A busy timeout above zero would block this process's event loop while it
|
|
29
|
-
// waits, so the claim is retried here instead.
|
|
30
|
-
const claim = new DatabaseSync(join(this.#directory, 'leader.lock'), {
|
|
31
|
-
timeout: 0,
|
|
32
|
-
});
|
|
33
|
-
const deadline = performance.now() + timeout;
|
|
34
|
-
try {
|
|
35
|
-
for (;;) {
|
|
36
|
-
if (this.#tryClaim(claim))
|
|
37
|
-
return new Leadership(await this.#nextEpoch(), claim);
|
|
38
|
-
if (performance.now() >= deadline)
|
|
39
|
-
break;
|
|
40
|
-
await delay(this.#pollInterval);
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
catch (error) {
|
|
44
|
-
claim.close();
|
|
45
|
-
throw error;
|
|
46
|
-
}
|
|
47
|
-
claim.close();
|
|
48
|
-
return undefined;
|
|
49
|
-
}
|
|
50
|
-
#tryClaim(claim) {
|
|
51
|
-
try {
|
|
52
|
-
claim.exec('BEGIN EXCLUSIVE');
|
|
53
|
-
return true;
|
|
54
|
-
}
|
|
55
|
-
catch (error) {
|
|
56
|
-
if (isBusy(error))
|
|
57
|
-
return false;
|
|
58
|
-
throw error;
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
/** Safe without further locking: only the claim holder gets here. */
|
|
62
|
-
async #nextEpoch() {
|
|
63
|
-
const path = join(this.#directory, 'leader.epoch');
|
|
64
|
-
const epoch = (await readEpoch(path)) + 1n;
|
|
65
|
-
await durableWrite(path, epoch.toString());
|
|
66
|
-
return epoch;
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
async function readEpoch(path) {
|
|
70
|
-
try {
|
|
71
|
-
return BigInt(await readFile(path, 'utf8'));
|
|
72
|
-
}
|
|
73
|
-
catch (error) {
|
|
74
|
-
if (isErrno(error, 'ENOENT'))
|
|
75
|
-
return 0n;
|
|
76
|
-
throw error;
|
|
77
|
-
}
|
|
78
|
-
}
|
|
79
|
-
//# sourceMappingURL=leader-election.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"leader-election.js","sourceRoot":"","sources":["../../src/leader-election/leader-election.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
import type { DatabaseSync } from 'node:sqlite';
|
|
2
|
-
/**
|
|
3
|
-
* One term as leader. It lasts until `resign` or until the process dies, when
|
|
4
|
-
* the kernel releases the claim and another campaigner can win.
|
|
5
|
-
*/
|
|
6
|
-
export declare class Leadership implements AsyncDisposable {
|
|
7
|
-
#private;
|
|
8
|
-
/** Grows with every term, so a newer leader can always outrank an older one. */
|
|
9
|
-
readonly epoch: bigint;
|
|
10
|
-
constructor(epoch: bigint, claim: DatabaseSync);
|
|
11
|
-
resign(): Promise<void>;
|
|
12
|
-
[Symbol.asyncDispose](): Promise<void>;
|
|
13
|
-
}
|
|
14
|
-
//# sourceMappingURL=leadership.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"leadership.d.ts","sourceRoot":"","sources":["../../src/leader-election/leadership.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,YAAY,EAAE,MAAM,aAAa,CAAC;AAEhD;;;GAGG;AACH,qBAAa,UAAW,YAAW,eAAe;;IAChD,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAC;gBAGX,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,YAAY;IAKxC,MAAM,IAAI,OAAO,CAAC,IAAI,CAAC;IAM7B,CAAC,MAAM,CAAC,YAAY,CAAC,IAAI,OAAO,CAAC,IAAI,CAAC;CAGvC"}
|
|
@@ -1,23 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* One term as leader. It lasts until `resign` or until the process dies, when
|
|
3
|
-
* the kernel releases the claim and another campaigner can win.
|
|
4
|
-
*/
|
|
5
|
-
export class Leadership {
|
|
6
|
-
/** Grows with every term, so a newer leader can always outrank an older one. */
|
|
7
|
-
epoch;
|
|
8
|
-
#claim;
|
|
9
|
-
constructor(epoch, claim) {
|
|
10
|
-
this.epoch = epoch;
|
|
11
|
-
this.#claim = claim;
|
|
12
|
-
}
|
|
13
|
-
async resign() {
|
|
14
|
-
if (!this.#claim.isOpen)
|
|
15
|
-
return;
|
|
16
|
-
this.#claim.exec('ROLLBACK');
|
|
17
|
-
this.#claim.close();
|
|
18
|
-
}
|
|
19
|
-
[Symbol.asyncDispose]() {
|
|
20
|
-
return this.resign();
|
|
21
|
-
}
|
|
22
|
-
}
|
|
23
|
-
//# sourceMappingURL=leadership.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"leadership.js","sourceRoot":"","sources":["../../src/leader-election/leadership.ts"],"names":[],"mappings":"AAEA;;;GAGG;AACH,MAAM,OAAO,UAAU;IACrB,gFAAgF;IACvE,KAAK,CAAS;IACd,MAAM,CAAe;IAE9B,YAAY,KAAa,EAAE,KAAmB;QAC5C,IAAI,CAAC,KAAK,GAAG,KAAK,CAAC;QACnB,IAAI,CAAC,MAAM,GAAG,KAAK,CAAC;IACtB,CAAC;IAED,KAAK,CAAC,MAAM;QACV,IAAI,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM;YAAE,OAAO;QAChC,IAAI,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,CAAC;QAC7B,IAAI,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC;IACtB,CAAC;IAED,CAAC,MAAM,CAAC,YAAY,CAAC;QACnB,OAAO,IAAI,CAAC,MAAM,EAAE,CAAC;IACvB,CAAC;CACF"}
|
|
@@ -1,7 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Rejects with `NetworkDirectoryError` when `directory` is on a network file
|
|
3
|
-
* system, where the stores' locks are not shared reliably between machines.
|
|
4
|
-
* A directory that does not exist yet is judged by its nearest existing parent.
|
|
5
|
-
*/
|
|
6
|
-
export declare function assertLocalDirectory(directory: string): Promise<void>;
|
|
7
|
-
//# sourceMappingURL=local-directory.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local-directory.d.ts","sourceRoot":"","sources":["../../src/local-directory/local-directory.ts"],"names":[],"mappings":"AA+DA;;;;GAIG;AACH,wBAAsB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAQ3E"}
|
|
@@ -1,75 +0,0 @@
|
|
|
1
|
-
import { statfs } from 'node:fs/promises';
|
|
2
|
-
import { dirname, resolve } from 'node:path';
|
|
3
|
-
import { isErrno } from "../shared/fs/errno.js";
|
|
4
|
-
import { NetworkDirectoryError } from "./network-directory-error.js";
|
|
5
|
-
/**
|
|
6
|
-
* The `f_type` Linux's statfs reports for each network file system: from the
|
|
7
|
-
* kernel's uapi/linux/magic.h, gfs2_ondisk.h (GFS2) and Lustre's lustre_user.h.
|
|
8
|
-
* FUSE is left out on purpose: on one kernel, its mounts hold the stores' locks.
|
|
9
|
-
*/
|
|
10
|
-
const linuxNetworkFileSystems = new Map([
|
|
11
|
-
[0x6969n, 'NFS'],
|
|
12
|
-
[0x517bn, 'SMB'],
|
|
13
|
-
[0xff534d42n, 'CIFS'],
|
|
14
|
-
[0xfe534d42n, 'SMB2'],
|
|
15
|
-
[0x00c36400n, 'Ceph'],
|
|
16
|
-
[0x5346414fn, 'AFS'],
|
|
17
|
-
[0x6b414653n, 'kAFS'],
|
|
18
|
-
[0x73757245n, 'Coda'],
|
|
19
|
-
[0x564cn, 'NCP'],
|
|
20
|
-
[0x7461636fn, 'OCFS2'],
|
|
21
|
-
[0x01161970n, 'GFS2'],
|
|
22
|
-
[0x0bd00bd0n, 'Lustre'],
|
|
23
|
-
[0x01021997n, '9p'],
|
|
24
|
-
]);
|
|
25
|
-
const local = { kind: 'local' };
|
|
26
|
-
const unknown = { kind: 'unknown' };
|
|
27
|
-
/**
|
|
28
|
-
* How each platform judges a directory. Only Linux reports a stable file
|
|
29
|
-
* system type; macOS numbers its file systems as they load, so it has no
|
|
30
|
-
* judge, and every directory counts as local there.
|
|
31
|
-
*/
|
|
32
|
-
const judges = {
|
|
33
|
-
linux: (path) => statfsOfNearest(path).then(({ type }) => {
|
|
34
|
-
// f_type is a signed long, so a magic with its high bit set can arrive sign-extended.
|
|
35
|
-
const fileSystem = linuxNetworkFileSystems.get(BigInt.asUintN(32, type));
|
|
36
|
-
return fileSystem ? { kind: 'network', fileSystem } : local;
|
|
37
|
-
}, () => unknown),
|
|
38
|
-
win32: async (path) => isUncPath(path) ? { kind: 'network', fileSystem: 'UNC share' } : local,
|
|
39
|
-
};
|
|
40
|
-
/** A directory's file system does not change under a running process, so each local one is judged once. */
|
|
41
|
-
const localDirectories = new Set();
|
|
42
|
-
/**
|
|
43
|
-
* Rejects with `NetworkDirectoryError` when `directory` is on a network file
|
|
44
|
-
* system, where the stores' locks are not shared reliably between machines.
|
|
45
|
-
* A directory that does not exist yet is judged by its nearest existing parent.
|
|
46
|
-
*/
|
|
47
|
-
export async function assertLocalDirectory(directory) {
|
|
48
|
-
const path = resolve(directory);
|
|
49
|
-
if (localDirectories.has(path))
|
|
50
|
-
return;
|
|
51
|
-
const judgement = (await judges[process.platform]?.(path)) ?? local;
|
|
52
|
-
if (judgement.kind === 'network') {
|
|
53
|
-
throw new NetworkDirectoryError(directory, judgement.fileSystem);
|
|
54
|
-
}
|
|
55
|
-
if (judgement.kind === 'local')
|
|
56
|
-
localDirectories.add(path);
|
|
57
|
-
}
|
|
58
|
-
async function statfsOfNearest(path) {
|
|
59
|
-
try {
|
|
60
|
-
return await statfs(path, { bigint: true });
|
|
61
|
-
}
|
|
62
|
-
catch (error) {
|
|
63
|
-
const parent = dirname(path);
|
|
64
|
-
if (!isErrno(error, 'ENOENT') || parent === path)
|
|
65
|
-
throw error;
|
|
66
|
-
return statfsOfNearest(parent);
|
|
67
|
-
}
|
|
68
|
-
}
|
|
69
|
-
/** `\\server\share`, `\\?\UNC\server\share` and `\\.\UNC\server\share`; `\\?\C:\` names a local drive. */
|
|
70
|
-
function isUncPath(path) {
|
|
71
|
-
if (/^\\\\[?.]\\/.test(path))
|
|
72
|
-
return /^\\\\[?.]\\UNC\\/i.test(path);
|
|
73
|
-
return path.startsWith('\\\\');
|
|
74
|
-
}
|
|
75
|
-
//# sourceMappingURL=local-directory.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"local-directory.js","sourceRoot":"","sources":["../../src/local-directory/local-directory.ts"],"names":[],"mappings":"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"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/** The lock directory is on a file system that other machines share, where the stores' locks do not hold. */
|
|
2
|
-
export declare class NetworkDirectoryError extends Error {
|
|
3
|
-
readonly directory: string;
|
|
4
|
-
/** The network file system the directory is on, for example `NFS`. */
|
|
5
|
-
readonly fileSystem: string;
|
|
6
|
-
constructor(directory: string, fileSystem: string);
|
|
7
|
-
}
|
|
8
|
-
//# sourceMappingURL=network-directory-error.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"network-directory-error.d.ts","sourceRoot":"","sources":["../../src/local-directory/network-directory-error.ts"],"names":[],"mappings":"AAAA,6GAA6G;AAC7G,qBAAa,qBAAsB,SAAQ,KAAK;IAC9C,QAAQ,CAAC,SAAS,EAAE,MAAM,CAAC;IAC3B,sEAAsE;IACtE,QAAQ,CAAC,UAAU,EAAE,MAAM,CAAC;gBAEhB,SAAS,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM;CAQlD"}
|
|
@@ -1,13 +0,0 @@
|
|
|
1
|
-
/** The lock directory is on a file system that other machines share, where the stores' locks do not hold. */
|
|
2
|
-
export class NetworkDirectoryError extends Error {
|
|
3
|
-
directory;
|
|
4
|
-
/** The network file system the directory is on, for example `NFS`. */
|
|
5
|
-
fileSystem;
|
|
6
|
-
constructor(directory, fileSystem) {
|
|
7
|
-
super(`The lock directory ${JSON.stringify(directory)} is on a network file system (${fileSystem}), where its locks are not shared reliably between machines. Use a local directory.`);
|
|
8
|
-
this.name = 'NetworkDirectoryError';
|
|
9
|
-
this.directory = directory;
|
|
10
|
-
this.fileSystem = fileSystem;
|
|
11
|
-
}
|
|
12
|
-
}
|
|
13
|
-
//# sourceMappingURL=network-directory-error.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"network-directory-error.js","sourceRoot":"","sources":["../../src/local-directory/network-directory-error.ts"],"names":[],"mappings":"AAAA,6GAA6G;AAC7G,MAAM,OAAO,qBAAsB,SAAQ,KAAK;IACrC,SAAS,CAAS;IAC3B,sEAAsE;IAC7D,UAAU,CAAS;IAE5B,YAAY,SAAiB,EAAE,UAAkB;QAC/C,KAAK,CACH,sBAAsB,IAAI,CAAC,SAAS,CAAC,SAAS,CAAC,iCAAiC,UAAU,qFAAqF,CAChL,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,uBAAuB,CAAC;QACpC,IAAI,CAAC,SAAS,GAAG,SAAS,CAAC;QAC3B,IAAI,CAAC,UAAU,GAAG,UAAU,CAAC;IAC/B,CAAC;CACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lock-lost-error.d.ts","sourceRoot":"","sources":["../../src/mutex/lock-lost-error.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,qBAAa,aAAc,SAAQ,KAAK;IACtC,QAAQ,CAAC,GAAG,EAAE,MAAM,CAAC;gBAET,GAAG,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,YAAY;CAQhD"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
/** The key may have been granted to another holder while its lease was still in use. */
|
|
2
|
-
export class LockLostError extends Error {
|
|
3
|
-
key;
|
|
4
|
-
constructor(key, options) {
|
|
5
|
-
super(`Lost the lock on ${JSON.stringify(key)}: another holder may have been granted it.`, options);
|
|
6
|
-
this.name = 'LockLostError';
|
|
7
|
-
this.key = key;
|
|
8
|
-
}
|
|
9
|
-
}
|
|
10
|
-
//# sourceMappingURL=lock-lost-error.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"lock-lost-error.js","sourceRoot":"","sources":["../../src/mutex/lock-lost-error.ts"],"names":[],"mappings":"AAAA,wFAAwF;AACxF,MAAM,OAAO,aAAc,SAAQ,KAAK;IAC7B,GAAG,CAAS;IAErB,YAAY,GAAW,EAAE,OAAsB;QAC7C,KAAK,CACH,oBAAoB,IAAI,CAAC,SAAS,CAAC,GAAG,CAAC,4CAA4C,EACnF,OAAO,CACR,CAAC;QACF,IAAI,CAAC,IAAI,GAAG,eAAe,CAAC;QAC5B,IAAI,CAAC,GAAG,GAAG,GAAG,CAAC;IACjB,CAAC;CACF"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"atomic-write.d.ts","sourceRoot":"","sources":["../../../src/shared/fs/atomic-write.ts"],"names":[],"mappings":"AAKA,qGAAqG;AACrG,wBAAsB,WAAW,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,iBAI9D"}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { writeFile } from 'node:fs/promises';
|
|
3
|
-
import { replaceFile } from "./replace-file.js";
|
|
4
|
-
/** Replaces `path` in one step, so readers see the old or the new content, never a partial write. */
|
|
5
|
-
export async function atomicWrite(path, content) {
|
|
6
|
-
const draft = `${path}.${randomUUID()}.tmp`;
|
|
7
|
-
await writeFile(draft, content);
|
|
8
|
-
await replaceFile(draft, path);
|
|
9
|
-
}
|
|
10
|
-
//# sourceMappingURL=atomic-write.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"atomic-write.js","sourceRoot":"","sources":["../../../src/shared/fs/atomic-write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE7C,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,qGAAqG;AACrG,MAAM,CAAC,KAAK,UAAU,WAAW,CAAC,IAAY,EAAE,OAAe;IAC7D,MAAM,KAAK,GAAG,GAAG,IAAI,IAAI,UAAU,EAAE,MAAM,CAAC;IAC5C,MAAM,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAChC,MAAM,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;AACjC,CAAC"}
|
|
@@ -1,6 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Creates `path` holding `content` unless it already exists. Linking a fully
|
|
3
|
-
* written file makes creation atomic, so the file is never seen empty.
|
|
4
|
-
*/
|
|
5
|
-
export declare function createExclusive(path: string, content: string): Promise<boolean>;
|
|
6
|
-
//# sourceMappingURL=create-exclusive.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"create-exclusive.d.ts","sourceRoot":"","sources":["../../../src/shared/fs/create-exclusive.ts"],"names":[],"mappings":"AAMA;;;GAGG;AACH,wBAAsB,eAAe,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,oBAYlE"}
|
|
@@ -1,29 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { link, unlink, writeFile } from 'node:fs/promises';
|
|
3
|
-
import { isErrno } from "./errno.js";
|
|
4
|
-
import { patiently } from "./patiently.js";
|
|
5
|
-
/**
|
|
6
|
-
* Creates `path` holding `content` unless it already exists. Linking a fully
|
|
7
|
-
* written file makes creation atomic, so the file is never seen empty.
|
|
8
|
-
*/
|
|
9
|
-
export async function createExclusive(path, content) {
|
|
10
|
-
const draft = `${path}.${randomUUID()}.tmp`;
|
|
11
|
-
await writeFile(draft, content);
|
|
12
|
-
try {
|
|
13
|
-
await patiently(() => link(draft, path));
|
|
14
|
-
return true;
|
|
15
|
-
}
|
|
16
|
-
catch (error) {
|
|
17
|
-
if (isErrno(error, 'EEXIST'))
|
|
18
|
-
return false;
|
|
19
|
-
throw error;
|
|
20
|
-
}
|
|
21
|
-
finally {
|
|
22
|
-
await removeDraft(draft);
|
|
23
|
-
}
|
|
24
|
-
}
|
|
25
|
-
/** A draft left behind has a unique name, so it never blocks a key; failing to remove it must not change whether `path` was created. */
|
|
26
|
-
async function removeDraft(draft) {
|
|
27
|
-
await patiently(() => unlink(draft)).catch(() => { });
|
|
28
|
-
}
|
|
29
|
-
//# sourceMappingURL=create-exclusive.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"create-exclusive.js","sourceRoot":"","sources":["../../../src/shared/fs/create-exclusive.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,kBAAkB,CAAC;AAE3D,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,SAAS,EAAE,MAAM,gBAAgB,CAAC;AAE3C;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,IAAY,EAAE,OAAe;IACjE,MAAM,KAAK,GAAG,GAAG,IAAI,IAAI,UAAU,EAAE,MAAM,CAAC;IAC5C,MAAM,SAAS,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;IAChC,IAAI,CAAC;QACH,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,IAAI,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAAC;QACzC,OAAO,IAAI,CAAC;IACd,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC;YAAE,OAAO,KAAK,CAAC;QAC3C,MAAM,KAAK,CAAC;IACd,CAAC;YAAS,CAAC;QACT,MAAM,WAAW,CAAC,KAAK,CAAC,CAAC;IAC3B,CAAC;AACH,CAAC;AAED,wIAAwI;AACxI,KAAK,UAAU,WAAW,CAAC,KAAa;IACtC,MAAM,SAAS,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,GAAG,EAAE,GAAE,CAAC,CAAC,CAAC;AACvD,CAAC"}
|
|
@@ -1,9 +0,0 @@
|
|
|
1
|
-
/** The length of what `durableWrite` adds to a path to name its draft. */
|
|
2
|
-
export declare const draftSuffixLength: number;
|
|
3
|
-
/**
|
|
4
|
-
* Replaces `path` in one step like `atomicWrite`, and returns only once both
|
|
5
|
-
* the new content and the replacement survive a power loss: a counter that
|
|
6
|
-
* goes back after a crash would hand out a token twice.
|
|
7
|
-
*/
|
|
8
|
-
export declare function durableWrite(path: string, content: string): Promise<void>;
|
|
9
|
-
//# sourceMappingURL=durable-write.d.ts.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"durable-write.d.ts","sourceRoot":"","sources":["../../../src/shared/fs/durable-write.ts"],"names":[],"mappings":"AASA,0EAA0E;AAC1E,eAAO,MAAM,iBAAiB,QAAqB,CAAC;AAEpD;;;;GAIG;AACH,wBAAsB,YAAY,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,MAAM,iBAW/D"}
|
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import { randomUUID } from 'node:crypto';
|
|
2
|
-
import { open, rm } from 'node:fs/promises';
|
|
3
|
-
import { dirname } from 'node:path';
|
|
4
|
-
import { isErrno } from "./errno.js";
|
|
5
|
-
import { replaceFile } from "./replace-file.js";
|
|
6
|
-
const draftOf = (path) => `${path}.${randomUUID()}.tmp`;
|
|
7
|
-
/** The length of what `durableWrite` adds to a path to name its draft. */
|
|
8
|
-
export const draftSuffixLength = draftOf('').length;
|
|
9
|
-
/**
|
|
10
|
-
* Replaces `path` in one step like `atomicWrite`, and returns only once both
|
|
11
|
-
* the new content and the replacement survive a power loss: a counter that
|
|
12
|
-
* goes back after a crash would hand out a token twice.
|
|
13
|
-
*/
|
|
14
|
-
export async function durableWrite(path, content) {
|
|
15
|
-
const draft = draftOf(path);
|
|
16
|
-
try {
|
|
17
|
-
await writeSynced(draft, content);
|
|
18
|
-
await replaceFile(draft, path);
|
|
19
|
-
}
|
|
20
|
-
catch (error) {
|
|
21
|
-
// A draft that never replaced `path` would only pile up, one per failed write.
|
|
22
|
-
await rm(draft, { force: true });
|
|
23
|
-
throw error;
|
|
24
|
-
}
|
|
25
|
-
await syncDirectory(dirname(path));
|
|
26
|
-
}
|
|
27
|
-
async function writeSynced(path, content) {
|
|
28
|
-
await using handle = await open(path, 'wx');
|
|
29
|
-
await handle.writeFile(content);
|
|
30
|
-
await handle.sync();
|
|
31
|
-
}
|
|
32
|
-
/**
|
|
33
|
-
* A rename lives in its directory, so the directory must reach the disk too.
|
|
34
|
-
* Windows cannot open a directory to sync it, and some file systems refuse to
|
|
35
|
-
* sync one; there the rename is as durable as that system makes it.
|
|
36
|
-
*/
|
|
37
|
-
async function syncDirectory(directory) {
|
|
38
|
-
if (process.platform === 'win32')
|
|
39
|
-
return;
|
|
40
|
-
await using handle = await open(directory, 'r');
|
|
41
|
-
try {
|
|
42
|
-
await handle.sync();
|
|
43
|
-
}
|
|
44
|
-
catch (error) {
|
|
45
|
-
if (!isErrno(error, 'EINVAL') && !isErrno(error, 'ENOTSUP'))
|
|
46
|
-
throw error;
|
|
47
|
-
}
|
|
48
|
-
}
|
|
49
|
-
//# sourceMappingURL=durable-write.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"durable-write.js","sourceRoot":"","sources":["../../../src/shared/fs/durable-write.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,EAAE,MAAM,aAAa,CAAC;AACzC,OAAO,EAAE,IAAI,EAAE,EAAE,EAAE,MAAM,kBAAkB,CAAC;AAC5C,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAEpC,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AACrC,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAEhD,MAAM,OAAO,GAAG,CAAC,IAAY,EAAE,EAAE,CAAC,GAAG,IAAI,IAAI,UAAU,EAAE,MAAM,CAAC;AAEhE,0EAA0E;AAC1E,MAAM,CAAC,MAAM,iBAAiB,GAAG,OAAO,CAAC,EAAE,CAAC,CAAC,MAAM,CAAC;AAEpD;;;;GAIG;AACH,MAAM,CAAC,KAAK,UAAU,YAAY,CAAC,IAAY,EAAE,OAAe;IAC9D,MAAM,KAAK,GAAG,OAAO,CAAC,IAAI,CAAC,CAAC;IAC5B,IAAI,CAAC;QACH,MAAM,WAAW,CAAC,KAAK,EAAE,OAAO,CAAC,CAAC;QAClC,MAAM,WAAW,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC;IACjC,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,+EAA+E;QAC/E,MAAM,EAAE,CAAC,KAAK,EAAE,EAAE,KAAK,EAAE,IAAI,EAAE,CAAC,CAAC;QACjC,MAAM,KAAK,CAAC;IACd,CAAC;IACD,MAAM,aAAa,CAAC,OAAO,CAAC,IAAI,CAAC,CAAC,CAAC;AACrC,CAAC;AAED,KAAK,UAAU,WAAW,CAAC,IAAY,EAAE,OAAe;IACtD,YAAY,MAAM,GAAG,MAAM,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,CAAC;IAC5C,MAAM,MAAM,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;IAChC,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;AACtB,CAAC;AAED;;;;GAIG;AACH,KAAK,UAAU,aAAa,CAAC,SAAiB;IAC5C,IAAI,OAAO,CAAC,QAAQ,KAAK,OAAO;QAAE,OAAO;IACzC,YAAY,MAAM,GAAG,MAAM,IAAI,CAAC,SAAS,EAAE,GAAG,CAAC,CAAC;IAChD,IAAI,CAAC;QACH,MAAM,MAAM,CAAC,IAAI,EAAE,CAAC;IACtB,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,QAAQ,CAAC,IAAI,CAAC,OAAO,CAAC,KAAK,EAAE,SAAS,CAAC;YAAE,MAAM,KAAK,CAAC;IAC3E,CAAC;AACH,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errno.d.ts","sourceRoot":"","sources":["../../../src/shared/fs/errno.ts"],"names":[],"mappings":"AAAA,wBAAgB,OAAO,CAAC,KAAK,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,GAAG,OAAO,CAE7D"}
|
package/dist/shared/fs/errno.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"errno.js","sourceRoot":"","sources":["../../../src/shared/fs/errno.ts"],"names":[],"mappings":"AAAA,MAAM,UAAU,OAAO,CAAC,KAAc,EAAE,IAAY;IAClD,OAAO,KAAK,YAAY,KAAK,IAAI,MAAM,IAAI,KAAK,IAAI,KAAK,CAAC,IAAI,KAAK,IAAI,CAAC;AAC1E,CAAC"}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"patiently.d.ts","sourceRoot":"","sources":["../../../src/shared/fs/patiently.ts"],"names":[],"mappings":"AAoBA,iIAAiI;AACjI,wBAAsB,SAAS,CAAC,CAAC,EAAE,SAAS,EAAE,MAAM,OAAO,CAAC,CAAC,CAAC,GAAG,OAAO,CAAC,CAAC,CAAC,CAc1E"}
|
|
@@ -1,30 +0,0 @@
|
|
|
1
|
-
import { setTimeout as delay } from 'node:timers/promises';
|
|
2
|
-
import { isErrno } from "./errno.js";
|
|
3
|
-
/** How long to retry a file operation that Windows refuses for a moment. */
|
|
4
|
-
const WINDOWS_PATIENCE = 1000;
|
|
5
|
-
/**
|
|
6
|
-
* Windows refuses a file for a moment while another program holds it open
|
|
7
|
-
* with no sharing, as a virus scanner can, or while a delete of it is in
|
|
8
|
-
* progress. The error code is the same as for a real permission denial, so a
|
|
9
|
-
* refusal is retried only for a limited time.
|
|
10
|
-
*/
|
|
11
|
-
function isRefusedForNow(error) {
|
|
12
|
-
return (process.platform === 'win32' &&
|
|
13
|
-
['EPERM', 'EACCES', 'EBUSY'].some((code) => isErrno(error, code)));
|
|
14
|
-
}
|
|
15
|
-
/** Runs `operation`, and runs it again while Windows refuses the file for a moment; after that, the error reaches the caller. */
|
|
16
|
-
export async function patiently(operation) {
|
|
17
|
-
const started = performance.now();
|
|
18
|
-
for (let attempt = 0;; attempt++) {
|
|
19
|
-
try {
|
|
20
|
-
return await operation();
|
|
21
|
-
}
|
|
22
|
-
catch (error) {
|
|
23
|
-
if (!isRefusedForNow(error) ||
|
|
24
|
-
performance.now() - started > WINDOWS_PATIENCE)
|
|
25
|
-
throw error;
|
|
26
|
-
await delay(Math.min(5 * 2 ** attempt, 100));
|
|
27
|
-
}
|
|
28
|
-
}
|
|
29
|
-
}
|
|
30
|
-
//# sourceMappingURL=patiently.js.map
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"patiently.js","sourceRoot":"","sources":["../../../src/shared/fs/patiently.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,UAAU,IAAI,KAAK,EAAE,MAAM,sBAAsB,CAAC;AAE3D,OAAO,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAErC,4EAA4E;AAC5E,MAAM,gBAAgB,GAAG,IAAI,CAAC;AAE9B;;;;;GAKG;AACH,SAAS,eAAe,CAAC,KAAc;IACrC,OAAO,CACL,OAAO,CAAC,QAAQ,KAAK,OAAO;QAC5B,CAAC,OAAO,EAAE,QAAQ,EAAE,OAAO,CAAC,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,OAAO,CAAC,KAAK,EAAE,IAAI,CAAC,CAAC,CAClE,CAAC;AACJ,CAAC;AAED,iIAAiI;AACjI,MAAM,CAAC,KAAK,UAAU,SAAS,CAAI,SAA2B;IAC5D,MAAM,OAAO,GAAG,WAAW,CAAC,GAAG,EAAE,CAAC;IAClC,KAAK,IAAI,OAAO,GAAG,CAAC,GAAI,OAAO,EAAE,EAAE,CAAC;QAClC,IAAI,CAAC;YACH,OAAO,MAAM,SAAS,EAAE,CAAC;QAC3B,CAAC;QAAC,OAAO,KAAK,EAAE,CAAC;YACf,IACE,CAAC,eAAe,CAAC,KAAK,CAAC;gBACvB,WAAW,CAAC,GAAG,EAAE,GAAG,OAAO,GAAG,gBAAgB;gBAE9C,MAAM,KAAK,CAAC;YACd,MAAM,KAAK,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC,GAAG,CAAC,IAAI,OAAO,EAAE,GAAG,CAAC,CAAC,CAAC;QAC/C,CAAC;IACH,CAAC;AACH,CAAC"}
|
|
@@ -1,8 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Moves `draft` over `path` in one step. On Windows, a rename over a file
|
|
3
|
-
* fails while another process has that file open, for example a waiter that
|
|
4
|
-
* reads it at that moment. The refusal is brief, so the rename is tried again;
|
|
5
|
-
* it stays the single commit point.
|
|
6
|
-
*/
|
|
7
|
-
export declare function replaceFile(draft: string, path: string): Promise<void>;
|
|
8
|
-
//# sourceMappingURL=replace-file.d.ts.map
|