@openclaw/fs-safe 0.16.0 → 0.17.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +48 -0
- package/README.md +8 -1
- package/dist/absolute-path.d.ts.map +1 -1
- package/dist/absolute-path.js +2 -8
- package/dist/advanced.d.ts +2 -0
- package/dist/advanced.d.ts.map +1 -1
- package/dist/advanced.js +2 -0
- package/dist/archive-deadline.d.ts.map +1 -1
- package/dist/archive-deadline.js +22 -23
- package/dist/archive-merge.d.ts +1 -0
- package/dist/archive-merge.d.ts.map +1 -1
- package/dist/archive-merge.js +4 -4
- package/dist/archive-native.d.ts +1 -0
- package/dist/archive-native.d.ts.map +1 -1
- package/dist/archive-native.js +1 -0
- package/dist/archive-options.d.ts +2 -0
- package/dist/archive-options.d.ts.map +1 -1
- package/dist/archive-parser.wasm +0 -0
- package/dist/archive-zip-count.d.ts.map +1 -1
- package/dist/archive-zip-count.js +21 -1
- package/dist/archive-zip-directory.d.ts.map +1 -1
- package/dist/archive-zip-directory.js +23 -1
- package/dist/archive-zip-loader.d.ts +2 -0
- package/dist/archive-zip-loader.d.ts.map +1 -1
- package/dist/archive-zip-loader.js +7 -0
- package/dist/archive-zip-names.d.ts.map +1 -1
- package/dist/archive-zip-names.js +7 -2
- package/dist/archive.d.ts.map +1 -1
- package/dist/archive.js +9 -3
- package/dist/byte-view.d.ts +3 -0
- package/dist/byte-view.d.ts.map +1 -0
- package/dist/byte-view.js +13 -0
- package/dist/creation-darwin.d.ts +0 -1
- package/dist/creation-darwin.d.ts.map +1 -1
- package/dist/creation-darwin.js +0 -9
- package/dist/directory-durability.d.ts +6 -6
- package/dist/directory-durability.d.ts.map +1 -1
- package/dist/directory-receipt.d.ts +2 -2
- package/dist/directory-receipt.d.ts.map +1 -1
- package/dist/directory-receipt.js +15 -19
- package/dist/file-cleanup.d.ts +1 -0
- package/dist/file-cleanup.d.ts.map +1 -1
- package/dist/file-cleanup.js +7 -4
- package/dist/file-contents.d.ts +6 -0
- package/dist/file-contents.d.ts.map +1 -0
- package/dist/file-contents.js +40 -0
- package/dist/file-hash.d.ts.map +1 -1
- package/dist/file-hash.js +16 -4
- package/dist/file-lock-sync-root-acquire.d.ts.map +1 -1
- package/dist/file-lock-sync-root-acquire.js +3 -0
- package/dist/file-lock-sync-root-held.d.ts +1 -2
- package/dist/file-lock-sync-root-held.d.ts.map +1 -1
- package/dist/file-lock-sync-root-held.js +7 -5
- package/dist/file-lock-sync-stale-admission.d.ts.map +1 -1
- package/dist/file-lock-sync-stale-admission.js +3 -0
- package/dist/file-lock-sync.d.ts.map +1 -1
- package/dist/file-lock-sync.js +8 -11
- package/dist/file-store.js +3 -3
- package/dist/guarded-mkdir.d.ts.map +1 -1
- package/dist/guarded-mkdir.js +6 -27
- package/dist/install-path.d.ts.map +1 -1
- package/dist/install-path.js +2 -5
- package/dist/json-durable-queue-ownership.d.ts.map +1 -1
- package/dist/json-durable-queue-ownership.js +2 -6
- package/dist/json-durable-queue-paths.d.ts.map +1 -1
- package/dist/json-durable-queue-paths.js +2 -24
- package/dist/json-durable-queue.d.ts.map +1 -1
- package/dist/json-durable-queue.js +10 -9
- package/dist/json.d.ts.map +1 -1
- package/dist/json.js +32 -75
- package/dist/local-roots.d.ts.map +1 -1
- package/dist/local-roots.js +19 -21
- package/dist/move-path-cleanup.d.ts +5 -19
- package/dist/move-path-cleanup.d.ts.map +1 -1
- package/dist/move-path-cleanup.js +57 -21
- package/dist/move-path.d.ts.map +1 -1
- package/dist/move-path.js +62 -39
- package/dist/native-staged-file.d.ts +2 -1
- package/dist/native-staged-file.d.ts.map +1 -1
- package/dist/native-staged-file.js +8 -5
- package/dist/native.js +2 -2
- package/dist/opened-realpath.d.ts.map +1 -1
- package/dist/opened-realpath.js +11 -2
- package/dist/path.d.ts.map +1 -1
- package/dist/path.js +2 -1
- package/dist/permissions.d.ts.map +1 -1
- package/dist/permissions.js +3 -17
- package/dist/pinned-write-input.d.ts.map +1 -1
- package/dist/pinned-write-input.js +11 -1
- package/dist/pinned-write-mode.d.ts +3 -3
- package/dist/pinned-write-mode.d.ts.map +1 -1
- package/dist/pinned-write-mode.js +15 -8
- package/dist/pinned-write-staged.d.ts.map +1 -1
- package/dist/pinned-write-staged.js +10 -11
- package/dist/pinned-write.d.ts.map +1 -1
- package/dist/pinned-write.js +17 -13
- package/dist/publish-file.d.ts +2 -2
- package/dist/publish-file.d.ts.map +1 -1
- package/dist/publish-file.js +56 -96
- package/dist/regular-file.d.ts.map +1 -1
- package/dist/regular-file.js +35 -44
- package/dist/replace-file-copy-fallback.d.ts.map +1 -1
- package/dist/replace-file-copy-fallback.js +28 -26
- package/dist/replace-file-copy-source.d.ts.map +1 -1
- package/dist/replace-file-copy-source.js +13 -22
- package/dist/replace-file-descriptor.d.ts.map +1 -1
- package/dist/replace-file-descriptor.js +10 -16
- package/dist/replace-file-temp-owner.js +6 -6
- package/dist/replace-file.d.ts.map +1 -1
- package/dist/replace-file.js +9 -13
- package/dist/root-directory-list.d.ts.map +1 -1
- package/dist/root-directory-list.js +20 -3
- package/dist/root-file-final-admission.d.ts +1 -1
- package/dist/root-file-final-admission.d.ts.map +1 -1
- package/dist/root-file-final-admission.js +5 -2
- package/dist/root-file.d.ts.map +1 -1
- package/dist/root-file.js +3 -2
- package/dist/root-impl.d.ts.map +1 -1
- package/dist/root-impl.js +50 -20
- package/dist/root-move-noreplace.d.ts +2 -0
- package/dist/root-move-noreplace.d.ts.map +1 -1
- package/dist/root-move-noreplace.js +2 -2
- package/dist/root-read-admission.d.ts.map +1 -1
- package/dist/root-read-admission.js +7 -2
- package/dist/root-remove.d.ts.map +1 -1
- package/dist/root-remove.js +15 -1
- package/dist/sidecar-lock-acquire.d.ts.map +1 -1
- package/dist/sidecar-lock-acquire.js +4 -6
- package/dist/sidecar-lock-handle.d.ts +3 -0
- package/dist/sidecar-lock-handle.d.ts.map +1 -1
- package/dist/sidecar-lock-handle.js +6 -0
- package/dist/sidecar-lock-reclaim.d.ts +1 -1
- package/dist/sidecar-lock-reclaim.d.ts.map +1 -1
- package/dist/sidecar-lock-reclaim.js +11 -8
- package/dist/sidecar-lock.d.ts.map +1 -1
- package/dist/sidecar-lock.js +3 -5
- package/dist/staged-directory.d.ts +2 -2
- package/dist/staged-directory.d.ts.map +1 -1
- package/dist/strict-file-identity.d.ts +1 -1
- package/dist/strict-file-identity.d.ts.map +1 -1
- package/dist/strict-file-identity.js +9 -9
- package/dist/symlink-parents.d.ts.map +1 -1
- package/dist/symlink-parents.js +2 -27
- package/dist/temp-workspace-owner.js +4 -4
- package/dist/unicode-path.d.ts.map +1 -1
- package/dist/unicode-path.js +3 -0
- package/dist/walk.d.ts.map +1 -1
- package/dist/walk.js +4 -2
- package/dist/write-file-handle.d.ts +7 -0
- package/dist/write-file-handle.d.ts.map +1 -1
- package/dist/write-file-handle.js +23 -0
- package/dist/write-open-flags.d.ts.map +1 -1
- package/dist/write-open-flags.js +1 -8
- package/dist/write-queue.d.ts.map +1 -1
- package/dist/write-queue.js +1 -4
- package/docs/advanced.md +68 -1
- package/docs/archive.md +41 -2
- package/docs/atomic.md +29 -5
- package/docs/contributing.md +4 -0
- package/docs/creation.md +8 -4
- package/docs/durability.md +35 -0
- package/docs/file-contents.md +68 -0
- package/docs/json.md +5 -4
- package/docs/local-roots.md +2 -0
- package/docs/mutation-policy-proof.md +5 -3
- package/docs/native.md +9 -8
- package/docs/path.md +4 -4
- package/docs/public-api.md +5 -0
- package/docs/quickstart.md +1 -1
- package/docs/reading.md +2 -2
- package/docs/regular-file.md +3 -0
- package/docs/root.md +9 -0
- package/docs/sidecar-lock.md +9 -1
- package/docs/staged-file.md +4 -3
- package/docs/store.md +3 -1
- package/docs/temp.md +4 -1
- package/docs/types.md +18 -2
- package/docs/walk.md +7 -0
- package/docs/writing.md +9 -2
- package/package.json +8 -8
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"byte-view.d.ts","sourceRoot":"","sources":["../src/byte-view.ts"],"names":[],"mappings":"AAMA,2EAA2E;AAC3E,wBAAgB,gBAAgB,CAAC,KAAK,EAAE,UAAU,GAAG,UAAU,CAK9D"}
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
const ByteView = Uint8Array;
|
|
2
|
+
const typedArray = Object.getPrototypeOf(ByteView.prototype);
|
|
3
|
+
const viewLength = Object.getOwnPropertyDescriptor(typedArray, "byteLength").get;
|
|
4
|
+
const viewOffset = Object.getOwnPropertyDescriptor(typedArray, "byteOffset").get;
|
|
5
|
+
const viewBuffer = Object.getOwnPropertyDescriptor(typedArray, "buffer").get;
|
|
6
|
+
/** Snapshot intrinsic view bounds without copying the borrowed payload. */
|
|
7
|
+
export function snapshotByteView(bytes) {
|
|
8
|
+
const length = Reflect.apply(viewLength, bytes, []);
|
|
9
|
+
// Preserve empty, detached, and out-of-bounds views as zero-byte inputs.
|
|
10
|
+
if (length === 0)
|
|
11
|
+
return new ByteView(0);
|
|
12
|
+
return new ByteView(Reflect.apply(viewBuffer, bytes, []), Reflect.apply(viewOffset, bytes, []), length);
|
|
13
|
+
}
|
|
@@ -3,5 +3,4 @@ export declare function assertDarwinPrivateCreationAvailable(): void;
|
|
|
3
3
|
export declare function assertDarwinPrivateDirectoryMode(mode: number): void;
|
|
4
4
|
export declare function assertDarwinCreationAcl(fd: number, inheritanceTarget?: "file" | "directory"): void;
|
|
5
5
|
export declare function assertDarwinCreationDirectoryAcl(pathname: string, expected: BigIntStats, inheritanceTarget?: "file" | "directory"): void;
|
|
6
|
-
export declare function privateFileMutationAssertion(fd: number, assertion?: () => void): (() => void) | undefined;
|
|
7
6
|
//# sourceMappingURL=creation-darwin.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"creation-darwin.d.ts","sourceRoot":"","sources":["../src/creation-darwin.ts"],"names":[],"mappings":"AAAA,OAAW,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"creation-darwin.d.ts","sourceRoot":"","sources":["../src/creation-darwin.ts"],"names":[],"mappings":"AAAA,OAAW,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAe/C,wBAAgB,oCAAoC,IAAI,IAAI,CAE3D;AAED,wBAAgB,gCAAgC,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAInE;AAED,wBAAgB,uBAAuB,CAAC,EAAE,EAAE,MAAM,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,WAAW,GAAG,IAAI,CAYlG;AAED,wBAAgB,gCAAgC,CAC9C,QAAQ,EAAE,MAAM,EAAE,QAAQ,EAAE,WAAW,EAAE,iBAAiB,CAAC,EAAE,MAAM,GAAG,WAAW,GAChF,IAAI,CAqBN"}
|
package/dist/creation-darwin.js
CHANGED
|
@@ -2,7 +2,6 @@ import fs, {} from "node:fs";
|
|
|
2
2
|
import { inspectDirectoryIdentitySync } from "./directory-guard.js";
|
|
3
3
|
import { nodeDarwinDirectoryMetadataFlags, nodeDirectorySearchOnlyFlags } from "./directory-mode-node.js";
|
|
4
4
|
import { FsSafeError } from "./errors.js";
|
|
5
|
-
import { assertSynchronousCallbackResult } from "./mutation-authority.js";
|
|
6
5
|
import { getNativeBinding } from "./native.js";
|
|
7
6
|
import { inspectFileIdentitySync } from "./strict-file-identity.js";
|
|
8
7
|
function inspector() {
|
|
@@ -69,11 +68,3 @@ export function assertDarwinCreationDirectoryAcl(pathname, expected, inheritance
|
|
|
69
68
|
fs.closeSync(fd);
|
|
70
69
|
}
|
|
71
70
|
}
|
|
72
|
-
export function privateFileMutationAssertion(fd, assertion) {
|
|
73
|
-
if (process.platform !== "darwin")
|
|
74
|
-
return assertion;
|
|
75
|
-
return () => {
|
|
76
|
-
assertSynchronousCallbackResult(assertion?.(), "assertBeforeMutation");
|
|
77
|
-
assertDarwinCreationAcl(fd);
|
|
78
|
-
};
|
|
79
|
-
}
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { type Stats } from "node:fs";
|
|
1
|
+
import { type BigIntStats, type Stats } from "node:fs";
|
|
2
2
|
import type { FileIdentityStat } from "./file-identity.js";
|
|
3
3
|
export type DirectorySyncOutcome = {
|
|
4
4
|
status: "synced";
|
|
@@ -6,10 +6,10 @@ export type DirectorySyncOutcome = {
|
|
|
6
6
|
status: "unsupported";
|
|
7
7
|
code?: string;
|
|
8
8
|
};
|
|
9
|
-
export type DirectoryReceipt = {
|
|
9
|
+
export type DirectoryReceipt<T extends Stats | BigIntStats = Stats> = {
|
|
10
10
|
path: string;
|
|
11
11
|
realPath: string;
|
|
12
|
-
identity:
|
|
12
|
+
identity: T;
|
|
13
13
|
};
|
|
14
14
|
export type DurableDirectoryReceipt = DirectoryReceipt & {
|
|
15
15
|
parentSync: DirectorySyncOutcome | {
|
|
@@ -29,13 +29,13 @@ export type EnsureDurableDirectoryOptions = {
|
|
|
29
29
|
expectedExistingIdentity?: FileIdentityStat;
|
|
30
30
|
create?: (directoryPath: string) => Promise<void>;
|
|
31
31
|
};
|
|
32
|
-
export declare function pinDirectory(directory: string | DirectoryReceipt
|
|
32
|
+
export declare function pinDirectory(directory: string | DirectoryReceipt<Stats | BigIntStats>, options?: {
|
|
33
33
|
label?: string;
|
|
34
34
|
}): Promise<PinnedDirectory>;
|
|
35
|
-
export declare function syncDirectory(directory: string | DirectoryReceipt
|
|
35
|
+
export declare function syncDirectory(directory: string | DirectoryReceipt<Stats | BigIntStats>, options?: {
|
|
36
36
|
label?: string;
|
|
37
37
|
}): Promise<DirectorySyncOutcome>;
|
|
38
|
-
export declare function syncDirectorySync(directory: string | DirectoryReceipt
|
|
38
|
+
export declare function syncDirectorySync(directory: string | DirectoryReceipt<Stats | BigIntStats>, options?: {
|
|
39
39
|
label?: string;
|
|
40
40
|
}): DirectorySyncOutcome;
|
|
41
41
|
export declare function syncDirectoryBestEffort(directoryPath: string): Promise<void>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directory-durability.d.ts","sourceRoot":"","sources":["../src/directory-durability.ts"],"names":[],"mappings":"AAAA,OAAe,EAAE,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;
|
|
1
|
+
{"version":3,"file":"directory-durability.d.ts","sourceRoot":"","sources":["../src/directory-durability.ts"],"names":[],"mappings":"AAAA,OAAe,EAAE,KAAK,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AAM/D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAa3D,MAAM,MAAM,oBAAoB,GAC5B;IAAE,MAAM,EAAE,QAAQ,CAAA;CAAE,GACpB;IAAE,MAAM,EAAE,aAAa,CAAC;IAAC,IAAI,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAE7C,MAAM,MAAM,gBAAgB,CAAC,CAAC,SAAS,KAAK,GAAG,WAAW,GAAG,KAAK,IAAI;IACpE,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,CAAC,CAAC;CACb,CAAC;AAEF,MAAM,MAAM,uBAAuB,GAAG,gBAAgB,GAAG;IACvD,UAAU,EAAE,oBAAoB,GAAG;QAAE,MAAM,EAAE,YAAY,CAAA;KAAE,CAAC;CAC7D,CAAC;AAEF,MAAM,MAAM,eAAe,GAAG;IAC5B,QAAQ,CAAC,OAAO,EAAE,gBAAgB,CAAC;IACnC,aAAa,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;IAC/B,IAAI,IAAI,OAAO,CAAC,oBAAoB,CAAC,CAAC;IACtC,KAAK,IAAI,OAAO,CAAC,IAAI,CAAC,CAAC;CACxB,CAAC;AAEF,MAAM,MAAM,6BAA6B,GAAG;IAC1C,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,wBAAwB,CAAC,EAAE,gBAAgB,CAAC;IAC5C,MAAM,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;CACnD,CAAC;AAkHF,wBAAsB,YAAY,CAChC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAAC,KAAK,GAAG,WAAW,CAAC,EACzD,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/B,OAAO,CAAC,eAAe,CAAC,CAe1B;AAED,wBAAsB,aAAa,CACjC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAAC,KAAK,GAAG,WAAW,CAAC,EACzD,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/B,OAAO,CAAC,oBAAoB,CAAC,CAqB/B;AAED,wBAAgB,iBAAiB,CAC/B,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAAC,KAAK,GAAG,WAAW,CAAC,EACzD,OAAO,GAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAO,GAC/B,oBAAoB,CAkCtB;AAED,wBAAsB,uBAAuB,CAAC,aAAa,EAAE,MAAM,GAAG,OAAO,CAAC,IAAI,CAAC,CAElF;AAED,wBAAgB,2BAA2B,CAAC,aAAa,EAAE,MAAM,GAAG,IAAI,CAMvE;AAiCD,wBAAsB,sBAAsB,CAC1C,OAAO,EAAE,6BAA6B,GACrC,OAAO,CAAC,uBAAuB,CAAC,CA6FlC"}
|
|
@@ -14,8 +14,8 @@ type DirectoryAuthority = DirectoryProvenance & Readonly<{
|
|
|
14
14
|
realPath: string;
|
|
15
15
|
}>;
|
|
16
16
|
export declare function directoryReceiptIdentity(identity: FileIdentityStat): ExactIdentity;
|
|
17
|
-
export declare function directoryReceiptAuthority(receipt: DirectoryReceipt): DirectoryAuthority;
|
|
18
|
-
export declare function ownDirectoryReceipt(receipt: DirectoryReceipt): DirectoryReceipt;
|
|
17
|
+
export declare function directoryReceiptAuthority(receipt: DirectoryReceipt<Stats | BigIntStats>): DirectoryAuthority;
|
|
18
|
+
export declare function ownDirectoryReceipt(receipt: DirectoryReceipt<Stats | BigIntStats>): DirectoryReceipt;
|
|
19
19
|
export declare function copyRetainedDirectoryReceipt(receipt: DirectoryReceipt): DirectoryReceipt;
|
|
20
20
|
export declare function createDirectoryReceiptFromIdentity(pathname: string, realPath: string, exactStat: BigIntStats): DirectoryReceipt;
|
|
21
21
|
export declare function createDirectoryReceiptSync(directoryPath: string, label: string, canonicalize?: (pathname: string) => string): DirectoryReceipt;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"directory-receipt.d.ts","sourceRoot":"","sources":["../src/directory-receipt.ts"],"names":[],"mappings":"AAAA,OAAW,EAAE,KAAK,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAGlE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAQ3D,KAAK,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC;AAChE,QAAA,MAAM,aAAa,YAAI,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAC;AAClH,QAAA,MAAM,UAAU,YAAI,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,CAAU,CAAC;AACrE,KAAK,iBAAiB,GAAG,IAAI,CAAC,KAAK,EAAE,OAAO,aAAa,CAAC,MAAM,CAAC,GAAG,GAAG,OAAO,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACtG,KAAK,mBAAmB,GAAG,QAAQ,CAAC;IAClC,QAAQ,EAAE,aAAa,CAAC;IACxB,QAAQ,EAAE,QAAQ,CAAC,iBAAiB,CAAC,CAAC;CACvC,CAAC,CAAC;AACH,KAAK,kBAAkB,GAAG,mBAAmB,GAAG,QAAQ,CAAC;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAOH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,aAAa,CAuBlF;
|
|
1
|
+
{"version":3,"file":"directory-receipt.d.ts","sourceRoot":"","sources":["../src/directory-receipt.ts"],"names":[],"mappings":"AAAA,OAAW,EAAE,KAAK,WAAW,EAAE,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AAC3D,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,2BAA2B,CAAC;AAGlE,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,oBAAoB,CAAC;AAQ3D,KAAK,aAAa,GAAG,QAAQ,CAAC,IAAI,CAAC,WAAW,EAAE,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC;AAChE,QAAA,MAAM,aAAa,YAAI,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,KAAK,EAAE,KAAK,EAAE,MAAM,EAAE,SAAS,EAAE,KAAK,EAAE,MAAM,EAAE,QAAQ,CAAU,CAAC;AAClH,QAAA,MAAM,UAAU,YAAI,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,WAAW,CAAU,CAAC;AACrE,KAAK,iBAAiB,GAAG,IAAI,CAAC,KAAK,EAAE,OAAO,aAAa,CAAC,MAAM,CAAC,GAAG,GAAG,OAAO,UAAU,CAAC,MAAM,CAAC,IAAI,CAAC,CAAC;AACtG,KAAK,mBAAmB,GAAG,QAAQ,CAAC;IAClC,QAAQ,EAAE,aAAa,CAAC;IACxB,QAAQ,EAAE,QAAQ,CAAC,iBAAiB,CAAC,CAAC;CACvC,CAAC,CAAC;AACH,KAAK,kBAAkB,GAAG,mBAAmB,GAAG,QAAQ,CAAC;IACvD,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;CAClB,CAAC,CAAC;AAOH,wBAAgB,wBAAwB,CAAC,QAAQ,EAAE,gBAAgB,GAAG,aAAa,CAuBlF;AAsCD,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,gBAAgB,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,kBAAkB,CAE5G;AAQD,wBAAgB,mBAAmB,CAAC,OAAO,EAAE,gBAAgB,CAAC,KAAK,GAAG,WAAW,CAAC,GAAG,gBAAgB,CAEpG;AAED,wBAAgB,4BAA4B,CAAC,OAAO,EAAE,gBAAgB,GAAG,gBAAgB,CAGxF;AAWD,wBAAgB,kCAAkC,CAChD,QAAQ,EAAE,MAAM,EAChB,QAAQ,EAAE,MAAM,EAChB,SAAS,EAAE,WAAW,GACrB,gBAAgB,CASlB;AAED,wBAAgB,0BAA0B,CACxC,aAAa,EAAE,MAAM,EACrB,KAAK,EAAE,MAAM,EACb,YAAY,GAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAqB,GACxD,gBAAgB,CASlB;AAED,wBAAgB,iCAAiC,CAC/C,OAAO,EAAE,gBAAgB,EACzB,KAAK,EAAE,MAAM,EACb,YAAY,GAAE,CAAC,QAAQ,EAAE,MAAM,KAAK,MAAqB,GACxD,IAAI,CAUN"}
|
|
@@ -53,10 +53,18 @@ function snapshotDirectoryReceipt(receipt) {
|
|
|
53
53
|
function snapshotDirectoryMetadata(stat, identity) {
|
|
54
54
|
const metadata = {};
|
|
55
55
|
for (const field of numericFields) {
|
|
56
|
-
metadata[field] = field === "dev" || field === "ino" ?
|
|
56
|
+
metadata[field] = Number(field === "dev" || field === "ino" ? identity[field] : stat[field]);
|
|
57
|
+
}
|
|
58
|
+
for (const field of timeFields) {
|
|
59
|
+
if ("atimeNs" in stat) {
|
|
60
|
+
const nanoseconds = stat[`${field}Ns`];
|
|
61
|
+
const remainder = ((nanoseconds % 1000000000n) + 1000000000n) % 1000000000n;
|
|
62
|
+
metadata[`${field}Ms`] = Number((nanoseconds - remainder) / 1000000000n) * 1_000 + Number(remainder) / 1_000_000;
|
|
63
|
+
}
|
|
64
|
+
else {
|
|
65
|
+
metadata[`${field}Ms`] = stat[`${field}Ms`];
|
|
66
|
+
}
|
|
57
67
|
}
|
|
58
|
-
for (const field of timeFields)
|
|
59
|
-
metadata[`${field}Ms`] = stat[`${field}Ms`];
|
|
60
68
|
return Object.freeze(metadata);
|
|
61
69
|
}
|
|
62
70
|
export function directoryReceiptAuthority(receipt) {
|
|
@@ -81,27 +89,15 @@ function receiptFromAuthority(authority) {
|
|
|
81
89
|
identity: Object.assign(Object.create(fs.Stats.prototype), authority.metadata),
|
|
82
90
|
}, authority);
|
|
83
91
|
}
|
|
84
|
-
function numericDirectoryMetadata(exact) {
|
|
85
|
-
// Keep metadata and authority from one observation. A second pathname stat
|
|
86
|
-
// can describe a replacement even when a later fence sees the original again.
|
|
87
|
-
const metadata = {};
|
|
88
|
-
for (const field of numericFields) {
|
|
89
|
-
metadata[field] = Number(exact[field]);
|
|
90
|
-
}
|
|
91
|
-
for (const field of timeFields) {
|
|
92
|
-
const nanoseconds = exact[`${field}Ns`];
|
|
93
|
-
const remainder = ((nanoseconds % 1000000000n) + 1000000000n) % 1000000000n;
|
|
94
|
-
metadata[`${field}Ms`] = Number((nanoseconds - remainder) / 1000000000n) * 1_000 + Number(remainder) / 1_000_000;
|
|
95
|
-
}
|
|
96
|
-
return Object.freeze(metadata);
|
|
97
|
-
}
|
|
98
92
|
// The caller already admitted the exact observation and its paths.
|
|
99
93
|
export function createDirectoryReceiptFromIdentity(pathname, realPath, exactStat) {
|
|
94
|
+
const identity = Object.freeze({ dev: exactStat.dev, ino: exactStat.ino });
|
|
100
95
|
return receiptFromAuthority(Object.freeze({
|
|
101
96
|
path: pathname,
|
|
102
97
|
realPath,
|
|
103
|
-
identity
|
|
104
|
-
metadata
|
|
98
|
+
identity,
|
|
99
|
+
// Project metadata from the admitted observation, never a fresh pathname stat.
|
|
100
|
+
metadata: snapshotDirectoryMetadata(exactStat, identity),
|
|
105
101
|
}));
|
|
106
102
|
}
|
|
107
103
|
export function createDirectoryReceiptSync(directoryPath, label, canonicalize = realpathSync) {
|
package/dist/file-cleanup.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type BigIntStats } from "node:fs";
|
|
2
2
|
import fs, { type FileHandle } from "node:fs/promises";
|
|
3
3
|
import { type AnyAsyncDirectoryGuard } from "./directory-guard.js";
|
|
4
|
+
export declare function readErrorCode(error: unknown): unknown;
|
|
4
5
|
export declare function hasErrorCode(error: unknown, expected: string): boolean;
|
|
5
6
|
type OwnedPathCleanupStatus = "removed" | "name-absent" | "preserved";
|
|
6
7
|
export declare function removeOwnedPath(params: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-cleanup.d.ts","sourceRoot":"","sources":["../src/file-cleanup.ts"],"names":[],"mappings":"AAAA,OAAe,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,EAAE,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAA6B,KAAK,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAI9F,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,
|
|
1
|
+
{"version":3,"file":"file-cleanup.d.ts","sourceRoot":"","sources":["../src/file-cleanup.ts"],"names":[],"mappings":"AAAA,OAAe,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AACnD,OAAO,EAAE,EAAE,EAAE,KAAK,UAAU,EAAE,MAAM,kBAAkB,CAAC;AACvD,OAAO,EAA6B,KAAK,sBAAsB,EAAE,MAAM,sBAAsB,CAAC;AAI9F,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CASrD;AAED,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,EAAE,QAAQ,EAAE,MAAM,GAAG,OAAO,CAEtE;AAED,KAAK,sBAAsB,GAAG,SAAS,GAAG,aAAa,GAAG,WAAW,CAAC;AAEtE,wBAAsB,eAAe,CAAC,MAAM,EAAE;IAC5C,QAAQ,EAAE,IAAI,CAAC,OAAO,EAAE,EAAE,OAAO,GAAG,QAAQ,CAAC,CAAC;IAC9C,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,CAAC,EAAE,WAAW,CAAC;CACxB,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAoBlC;AAGD,wBAAsB,qBAAqB,CAAC,MAAM,EAAE;IAClD,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,IAAI,CAAC,UAAU,EAAE,IAAI,CAAC,CAAC;IAC/B,QAAQ,CAAC,EAAE,WAAW,CAAC;IACvB,WAAW,EAAE,sBAAsB,CAAC;IACpC,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B,GAAG,OAAO,CAAC,sBAAsB,CAAC,CAgClC"}
|
package/dist/file-cleanup.js
CHANGED
|
@@ -3,17 +3,20 @@ import fs, {} from "node:fs/promises";
|
|
|
3
3
|
import { assertAsyncDirectoryGuard } from "./directory-guard.js";
|
|
4
4
|
import { FsSafeError } from "./errors.js";
|
|
5
5
|
import { sameFileIdentityForCleanup } from "./file-identity.js";
|
|
6
|
-
export function
|
|
6
|
+
export function readErrorCode(error) {
|
|
7
7
|
if ((typeof error !== "object" || error === null) && typeof error !== "function") {
|
|
8
|
-
return
|
|
8
|
+
return undefined;
|
|
9
9
|
}
|
|
10
10
|
try {
|
|
11
|
-
return Reflect.get(error, "code")
|
|
11
|
+
return Reflect.get(error, "code");
|
|
12
12
|
}
|
|
13
13
|
catch {
|
|
14
|
-
return
|
|
14
|
+
return undefined;
|
|
15
15
|
}
|
|
16
16
|
}
|
|
17
|
+
export function hasErrorCode(error, expected) {
|
|
18
|
+
return readErrorCode(error) === expected;
|
|
19
|
+
}
|
|
17
20
|
export async function removeOwnedPath(params) {
|
|
18
21
|
if (!params.identity)
|
|
19
22
|
return "preserved";
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
export type SameFileContentsOptions = {
|
|
2
|
+
maxBytes?: number;
|
|
3
|
+
};
|
|
4
|
+
/** Compares borrowed regular files from offset zero without moving or closing either descriptor. */
|
|
5
|
+
export declare function sameFileContentsSync(leftFd: number, rightFd: number, options?: SameFileContentsOptions): boolean;
|
|
6
|
+
//# sourceMappingURL=file-contents.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"file-contents.d.ts","sourceRoot":"","sources":["../src/file-contents.ts"],"names":[],"mappings":"AAKA,MAAM,MAAM,uBAAuB,GAAG;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB,CAAC;AAEF,oGAAoG;AACpG,wBAAgB,oBAAoB,CAClC,MAAM,EAAE,MAAM,EACd,OAAO,EAAE,MAAM,EACf,OAAO,GAAE,uBAA4B,GACpC,OAAO,CAgCT"}
|
|
@@ -0,0 +1,40 @@
|
|
|
1
|
+
import fs from "node:fs";
|
|
2
|
+
import { normalizeMaxBytes } from "./byte-budget.js";
|
|
3
|
+
import { FsSafeError } from "./errors.js";
|
|
4
|
+
import { readFileWindowFullySync } from "./positional-read.js";
|
|
5
|
+
/** Compares borrowed regular files from offset zero without moving or closing either descriptor. */
|
|
6
|
+
export function sameFileContentsSync(leftFd, rightFd, options = {}) {
|
|
7
|
+
const maxBytes = normalizeMaxBytes(options.maxBytes) ?? Infinity;
|
|
8
|
+
const limit = Math.min(maxBytes, Number.MAX_SAFE_INTEGER);
|
|
9
|
+
const tooLarge = () => new FsSafeError("too-large", `file comparison exceeds ${limit} bytes`);
|
|
10
|
+
for (const fd of [leftFd, rightFd]) {
|
|
11
|
+
const stat = fs.fstatSync(fd, { bigint: true });
|
|
12
|
+
if (!stat.isFile()) {
|
|
13
|
+
throw new FsSafeError("not-file", "file comparison requires regular-file descriptors");
|
|
14
|
+
}
|
|
15
|
+
if (stat.size > BigInt(limit))
|
|
16
|
+
throw tooLarge();
|
|
17
|
+
}
|
|
18
|
+
const left = Buffer.allocUnsafe(Math.min(1024 * 1024, Math.max(1, limit)));
|
|
19
|
+
const right = Buffer.allocUnsafe(left.length);
|
|
20
|
+
let position = 0;
|
|
21
|
+
while (true) {
|
|
22
|
+
const length = Math.min(left.length, limit - position);
|
|
23
|
+
if (length === 0) {
|
|
24
|
+
// Probe EOF at the limit without forming an unsafe exclusive window end.
|
|
25
|
+
const leftExtra = fs.readSync(leftFd, left, 0, 1, position);
|
|
26
|
+
const rightExtra = fs.readSync(rightFd, right, 0, 1, position);
|
|
27
|
+
if (leftExtra !== 0 || rightExtra !== 0)
|
|
28
|
+
throw tooLarge();
|
|
29
|
+
return true;
|
|
30
|
+
}
|
|
31
|
+
const leftRead = readFileWindowFullySync(leftFd, left.subarray(0, length), position);
|
|
32
|
+
const rightRead = readFileWindowFullySync(rightFd, right.subarray(0, length), position);
|
|
33
|
+
if (leftRead !== rightRead || !left.subarray(0, leftRead).equals(right.subarray(0, rightRead))) {
|
|
34
|
+
return false;
|
|
35
|
+
}
|
|
36
|
+
if (leftRead < length)
|
|
37
|
+
return true;
|
|
38
|
+
position += leftRead;
|
|
39
|
+
}
|
|
40
|
+
}
|
package/dist/file-hash.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-hash.d.ts","sourceRoot":"","sources":["../src/file-hash.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAKnE,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,UAAU,CAAC;AAClD,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,CAAC;AAElD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,EAClB,MAAM,GAAE,aAAa,GAAG,SAA8B,EACtD,EAAE,QAAmB,EAAE,MAAM,EAAE,GAAE,iBAAsB,GACtD,OAAO,CAAC,gBAAgB,CAAC,CAwD3B;
|
|
1
|
+
{"version":3,"file":"file-hash.d.ts","sourceRoot":"","sources":["../src/file-hash.ts"],"names":[],"mappings":"AAEA,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAInD,OAAO,EAAoB,KAAK,aAAa,EAAE,MAAM,aAAa,CAAC;AAKnE,MAAM,MAAM,eAAe,GAAG,MAAM,GAAG,UAAU,CAAC;AAClD,MAAM,MAAM,mBAAmB,GAAG,MAAM,GAAG,MAAM,CAAC;AAElD,MAAM,MAAM,iBAAiB,GAAG;IAC9B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,MAAM,CAAC,EAAE,WAAW,CAAC;CACtB,CAAC;AAEF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,KAAK,EAAE,MAAM,CAAC;IACd,MAAM,EAAE,MAAM,CAAC;CAChB,CAAC;AAEF,wBAAsB,cAAc,CAClC,MAAM,EAAE,UAAU,EAClB,MAAM,GAAE,aAAa,GAAG,SAA8B,EACtD,EAAE,QAAmB,EAAE,MAAM,EAAE,GAAE,iBAAsB,GACtD,OAAO,CAAC,gBAAgB,CAAC,CAwD3B;AA8DD,wBAAsB,UAAU,CAC9B,KAAK,EAAE,eAAe,EACtB,OAAO,GAAE,iBAAsB,GAC9B,OAAO,CAAC,gBAAgB,CAAC,CAM3B;AA2DD,8FAA8F;AAC9F,wBAAgB,cAAc,CAC5B,KAAK,EAAE,mBAAmB,EAC1B,OAAO,GAAE,iBAAsB,GAC9B,gBAAgB,CAMlB"}
|
package/dist/file-hash.js
CHANGED
|
@@ -99,14 +99,20 @@ async function hashPath(filePath, options) {
|
|
|
99
99
|
catch (error) {
|
|
100
100
|
rethrowHashOpenError(error);
|
|
101
101
|
}
|
|
102
|
+
let completed = false;
|
|
102
103
|
try {
|
|
103
104
|
options.signal?.throwIfAborted();
|
|
104
105
|
const opened = await inspectFileIdentity(() => hashDescriptorIdentity(handle.fd), before);
|
|
105
106
|
await inspectFileIdentity(() => hashPathIdentity(filePath, true), opened);
|
|
106
|
-
|
|
107
|
+
const result = await hashFileHandle(handle, getNativeBinding(), options);
|
|
108
|
+
completed = true;
|
|
109
|
+
return result;
|
|
107
110
|
}
|
|
108
111
|
finally {
|
|
109
|
-
|
|
112
|
+
if (completed)
|
|
113
|
+
await handle.close();
|
|
114
|
+
else
|
|
115
|
+
await handle.close().catch(() => undefined);
|
|
110
116
|
}
|
|
111
117
|
}
|
|
112
118
|
export async function sha256File(input, options = {}) {
|
|
@@ -157,17 +163,23 @@ function hashPathSync(filePath, options) {
|
|
|
157
163
|
catch (error) {
|
|
158
164
|
rethrowHashOpenError(error);
|
|
159
165
|
}
|
|
166
|
+
let completed = false;
|
|
160
167
|
try {
|
|
161
168
|
options.signal?.throwIfAborted();
|
|
162
169
|
const opened = inspectFileIdentitySync(() => hashDescriptorIdentity(fd), before);
|
|
163
170
|
inspectFileIdentitySync(() => hashPathIdentity(filePath, true), opened);
|
|
164
|
-
|
|
171
|
+
const result = hashDescriptorSync(fd, options);
|
|
172
|
+
completed = true;
|
|
173
|
+
return result;
|
|
165
174
|
}
|
|
166
175
|
finally {
|
|
167
176
|
try {
|
|
168
177
|
fsSync.closeSync(fd);
|
|
169
178
|
}
|
|
170
|
-
catch {
|
|
179
|
+
catch (error) {
|
|
180
|
+
if (completed)
|
|
181
|
+
throw error;
|
|
182
|
+
}
|
|
171
183
|
}
|
|
172
184
|
}
|
|
173
185
|
/** Hash synchronously from offset zero, retaining ownership and position of a borrowed fd. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-lock-sync-root-acquire.d.ts","sourceRoot":"","sources":["../src/file-lock-sync-root-acquire.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,0BAA0B,EAC1B,kBAAkB,EACnB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;
|
|
1
|
+
{"version":3,"file":"file-lock-sync-root-acquire.d.ts","sourceRoot":"","sources":["../src/file-lock-sync-root-acquire.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,0BAA0B,EAC1B,kBAAkB,EACnB,MAAM,qBAAqB,CAAC;AAG7B,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAiD3C,wBAAgB,2BAA2B,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAClF,UAAU,EAAE,MAAM,EAClB,YAAY,EAAE,0BAA0B,CAAC,QAAQ,CAAC,EAClD,QAAQ,EAAE,IAAI,GACb,kBAAkB,CAgWpB"}
|
|
@@ -7,6 +7,7 @@ import { computeSidecarLockDelayMs, isTransientLockFileDenial, maxTransientLockD
|
|
|
7
7
|
import { serializeSidecarLockPayload, } from "./sidecar-lock-reclaim.js";
|
|
8
8
|
import { createSuppressedError } from "./suppressed-error.js";
|
|
9
9
|
import { sleepSync } from "./timing.js";
|
|
10
|
+
import { assertSynchronousCallbackResult } from "./mutation-authority.js";
|
|
10
11
|
import { assertNoWindowsPathAlias } from "./windows-path-alias.js";
|
|
11
12
|
import { admitFileLockSyncRootPath, assertFileLockSyncRootPathsCurrent, captureFileLockSyncRootAuthority, normalizeFileLockSyncTargetWithRoot, } from "./file-lock-sync-root.js";
|
|
12
13
|
import { cleanupCreatedRootSyncLock, FileLockSyncRootArbitrationCollision, tryReuseCurrentRootSyncHeldLock, } from "./file-lock-sync-root-arbitration.js";
|
|
@@ -299,6 +300,7 @@ export function acquireFileLockSyncWithRoot(targetPath, inputOptions, lockRoot)
|
|
|
299
300
|
nowMs,
|
|
300
301
|
heldByThisProcess: false,
|
|
301
302
|
}]);
|
|
303
|
+
assertSynchronousCallbackResult(reclaim, "shouldReclaim");
|
|
302
304
|
assertAdmission();
|
|
303
305
|
if (!fileLockSyncRootSnapshotStillCurrent(lockRootPath, current)) {
|
|
304
306
|
throw new FsSafeError("path-mismatch", "sidecar changed during reclaim policy callback");
|
|
@@ -324,6 +326,7 @@ export function acquireFileLockSyncWithRoot(targetPath, inputOptions, lockRoot)
|
|
|
324
326
|
raw: snapshot.raw,
|
|
325
327
|
payload: snapshot.payload,
|
|
326
328
|
}]);
|
|
329
|
+
assertSynchronousCallbackResult(approved, "shouldRemoveStaleLock");
|
|
327
330
|
assertAdmission();
|
|
328
331
|
assertOwnedReclaimGuardCurrent();
|
|
329
332
|
if (approved) {
|
|
@@ -28,7 +28,6 @@ export declare function getRootSyncHeldLocks(): Map<string, RootSyncHeldLock>;
|
|
|
28
28
|
export declare function ensureRootSyncExitCleanupRegistered(): void;
|
|
29
29
|
export declare function verifyRootSyncHeldLock(held: RootSyncHeldLock): boolean;
|
|
30
30
|
export declare function createRootSyncHeldLockHandle(held: RootSyncHeldLock): FileLockSyncHandle;
|
|
31
|
-
export declare function
|
|
32
|
-
export declare function withRootSyncHeldLockHandle<T>(lock: FileLockSyncHandle, fn: () => T): T;
|
|
31
|
+
export declare function withSyncHeldLockHandle<T>(lock: FileLockSyncHandle, fn: () => T): T;
|
|
33
32
|
export {};
|
|
34
33
|
//# sourceMappingURL=file-lock-sync-root-held.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-lock-sync-root-held.d.ts","sourceRoot":"","sources":["../src/file-lock-sync-root-held.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,kBAAkB,EACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAIL,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC9B,MAAM,6BAA6B,CAAC;AAQrC,KAAK,4BAA4B,GAAG,QAAQ,GAAG,WAAW,GAAG,eAAe,GAAG,UAAU,CAAC;AAE1F,KAAK,iCAAiC,GAAG;IACvC,IAAI,EAAE,gBAAgB,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAOF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,oBAAoB,CAAC,EAAE,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAC9D,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,4BAA4B,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,yBAAyB,CAAC;IACzC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,WAAW,EAAE,2BAA2B,CAAC;IACzC,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC;CACxB,CAAC;AAQF,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,oBAAoB,EAC9B,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,EACvC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,EACxC,eAAe,CAAC,EAAE,2BAA2B,GAC5C,wBAAwB,GAAG,IAAI,CAmCjC;AAED,wBAAgB,oBAAoB,IAAI,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAQpE;AA+KD,wBAAgB,mCAAmC,IAAI,IAAI,CAE1D;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAWtE;AAsHD,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,gBAAgB,GAAG,kBAAkB,CAqBvF;AAED,wBAAgB,
|
|
1
|
+
{"version":3,"file":"file-lock-sync-root-held.d.ts","sourceRoot":"","sources":["../src/file-lock-sync-root-held.ts"],"names":[],"mappings":"AAGA,OAAO,KAAK,EACV,kBAAkB,EACnB,MAAM,qBAAqB,CAAC;AAC7B,OAAO,EAGL,KAAK,mBAAmB,EACzB,MAAM,2BAA2B,CAAC;AAEnC,OAAO,EACL,KAAK,yBAAyB,EAC9B,KAAK,oBAAoB,EAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,EAIL,KAAK,2BAA2B,EAChC,KAAK,wBAAwB,EAC9B,MAAM,6BAA6B,CAAC;AAQrC,KAAK,4BAA4B,GAAG,QAAQ,GAAG,WAAW,GAAG,eAAe,GAAG,UAAU,CAAC;AAE1F,KAAK,iCAAiC,GAAG;IACvC,IAAI,EAAE,gBAAgB,CAAC;IACvB,QAAQ,EAAE,OAAO,CAAC;CACnB,CAAC;AAOF,MAAM,MAAM,gBAAgB,GAAG;IAC7B,oBAAoB,CAAC,EAAE,GAAG,CAAC,iCAAiC,CAAC,CAAC;IAC9D,EAAE,EAAE,MAAM,GAAG,SAAS,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACxC,QAAQ,EAAE,MAAM,CAAC;IACjB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,YAAY,EAAE,4BAA4B,CAAC;IAC3C,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,yBAAyB,CAAC;IACzC,QAAQ,EAAE,oBAAoB,CAAC;IAC/B,WAAW,EAAE,2BAA2B,CAAC;IACzC,QAAQ,EAAE,mBAAmB,CAAC;IAC9B,KAAK,CAAC,EAAE,MAAM,CAAC,OAAO,CAAC;CACxB,CAAC;AAQF,wBAAgB,2BAA2B,CACzC,QAAQ,EAAE,oBAAoB,EAC9B,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,EACvC,aAAa,CAAC,EAAE,CAAC,KAAK,EAAE,OAAO,KAAK,IAAI,EACxC,eAAe,CAAC,EAAE,2BAA2B,GAC5C,wBAAwB,GAAG,IAAI,CAmCjC;AAED,wBAAgB,oBAAoB,IAAI,GAAG,CAAC,MAAM,EAAE,gBAAgB,CAAC,CAQpE;AA+KD,wBAAgB,mCAAmC,IAAI,IAAI,CAE1D;AAED,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,gBAAgB,GAAG,OAAO,CAWtE;AAsHD,wBAAgB,4BAA4B,CAAC,IAAI,EAAE,gBAAgB,GAAG,kBAAkB,CAqBvF;AAED,wBAAgB,sBAAsB,CAAC,CAAC,EACtC,IAAI,EAAE,kBAAkB,EACxB,EAAE,EAAE,MAAM,CAAC,GACV,CAAC,CAoBH"}
|
|
@@ -223,7 +223,12 @@ export function ensureRootSyncExitCleanupRegistered() {
|
|
|
223
223
|
ensureFileLockSyncRootExitCleanupRegistered(releaseAllRootSyncHeldLocks);
|
|
224
224
|
}
|
|
225
225
|
export function verifyRootSyncHeldLock(held) {
|
|
226
|
-
const
|
|
226
|
+
const rootPath = held.rootPath;
|
|
227
|
+
const parsePayload = held.parsePayload;
|
|
228
|
+
const rootReceipt = held.rootReceipt;
|
|
229
|
+
const current = parsePayload
|
|
230
|
+
? readRootSidecarSnapshotSync(rootPath, parsePayload, undefined, rootReceipt)
|
|
231
|
+
: readFileLockSyncRootSnapshot(rootPath, { expectedReceipt: rootReceipt });
|
|
227
232
|
if (!current)
|
|
228
233
|
return false;
|
|
229
234
|
return current.receipt.identity.dev === held.rootReceipt.identity.dev &&
|
|
@@ -369,10 +374,7 @@ export function createRootSyncHeldLockHandle(held) {
|
|
|
369
374
|
rootSyncHandleDispositions.set(handle, disposition);
|
|
370
375
|
return handle;
|
|
371
376
|
}
|
|
372
|
-
export function
|
|
373
|
-
return rootSyncHandleDispositions.has(handle);
|
|
374
|
-
}
|
|
375
|
-
export function withRootSyncHeldLockHandle(lock, fn) {
|
|
377
|
+
export function withSyncHeldLockHandle(lock, fn) {
|
|
376
378
|
let result;
|
|
377
379
|
try {
|
|
378
380
|
result = fn();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-lock-sync-stale-admission.d.ts","sourceRoot":"","sources":["../src/file-lock-sync-stale-admission.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAQtE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;
|
|
1
|
+
{"version":3,"file":"file-lock-sync-stale-admission.d.ts","sourceRoot":"","sources":["../src/file-lock-sync-stale-admission.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,0BAA0B,EAAE,MAAM,qBAAqB,CAAC;AAQtE,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,yBAAyB,CAAC;AAGxE,MAAM,MAAM,qBAAqB,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IAC5E,qBAAqB,CAAC,EAAE,OAAO,CAAC;IAChC,aAAa,CAAC,EAAE,0BAA0B,CAAC,QAAQ,CAAC,CAAC,eAAe,CAAC,CAAC;IACtE,oBAAoB,CAAC,EAAE,OAAO,CAAC;IAC/B,YAAY,CAAC,EAAE,0BAA0B,CAAC,QAAQ,CAAC,CAAC,uBAAuB,CAAC,CAAC;CAC9E,CAAC;AAEF,qFAAqF;AACrF,wBAAgB,wBAAwB,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAAE,MAAM,EAAE;IACzF,QAAQ,IAAI,OAAO,CAAC;IACpB,WAAW,IAAI,OAAO,CAAC;IACvB,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,CAAC;IAC9C,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACxC,gBAAgB,EAAE,MAAM,CAAC;IACzB,mBAAmB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAAC;IAC7C,OAAO,EAAE,MAAM,CAAC;IAChB,YAAY,EAAE,qBAAqB,CAAC,QAAQ,CAAC,CAAC;IAC9C,aAAa,CAAC,EAAE,wBAAwB,CAAC;IACzC,YAAY,IAAI,IAAI,CAAC;CACtB,GAAG,IAAI,CAmLP"}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import { defaultSyncShouldReclaim, syncLockTimeout } from "./file-lock-sync-admission.js";
|
|
3
3
|
import { parseSidecarLockSnapshot, readSidecarLockRawSnapshotSync, removeSidecarLockIfUnchangedSync, } from "./sidecar-lock-reclaim.js";
|
|
4
|
+
import { assertSynchronousCallbackResult } from "./mutation-authority.js";
|
|
4
5
|
/** Handle one exclusive-create conflict without surrendering canonical admission. */
|
|
5
6
|
export function handleSyncStaleAdmission(params) {
|
|
6
7
|
const holderChanged = {};
|
|
@@ -110,6 +111,7 @@ export function handleSyncStaleAdmission(params) {
|
|
|
110
111
|
heldByThisProcess: false,
|
|
111
112
|
}])
|
|
112
113
|
: defaultSyncShouldReclaim(snapshot, params.staleMs, nowMs);
|
|
114
|
+
assertSynchronousCallbackResult(reclaim, "shouldReclaim");
|
|
113
115
|
}
|
|
114
116
|
finally {
|
|
115
117
|
assertUnheld();
|
|
@@ -137,6 +139,7 @@ export function handleSyncStaleAdmission(params) {
|
|
|
137
139
|
raw: snapshot.raw,
|
|
138
140
|
payload: snapshot.payload,
|
|
139
141
|
}]);
|
|
142
|
+
assertSynchronousCallbackResult(approved, "shouldRemoveStaleLock");
|
|
140
143
|
}
|
|
141
144
|
finally {
|
|
142
145
|
assertUnheld();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"file-lock-sync.d.ts","sourceRoot":"","sources":["../src/file-lock-sync.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,
|
|
1
|
+
{"version":3,"file":"file-lock-sync.d.ts","sourceRoot":"","sources":["../src/file-lock-sync.ts"],"names":[],"mappings":"AAIA,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,gBAAgB,CAAC;AAC3C,OAAO,EAOL,KAAK,wBAAwB,EAC9B,MAAM,2BAA2B,CAAC;AAUnC,OAAO,KAAK,EACV,0BAA0B,EAC1B,uBAAuB,EACvB,wBAAwB,EACzB,MAAM,yBAAyB,CAAC;AAqBjC,MAAM,MAAM,0BAA0B,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,IAAI;IACjF,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,OAAO,CAAC,EAAE,MAAM,CAAC;IACjB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,KAAK,CAAC,EAAE,uBAAuB,CAAC;IAChC,aAAa,CAAC,EAAE,wBAAwB,CAAC;IACzC,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,OAAO,EAAE,MAAM,QAAQ,CAAC;IACxB,aAAa,CAAC,EAAE,CAAC,MAAM,EAAE;QACvB,QAAQ,EAAE,MAAM,CAAC;QACjB,oBAAoB,EAAE,MAAM,CAAC;QAC7B,OAAO,EAAE,OAAO,CAAC;QACjB,OAAO,EAAE,MAAM,CAAC;QAChB,KAAK,EAAE,MAAM,CAAC;QACd,iBAAiB,EAAE,KAAK,CAAC;KAC1B,KAAK,OAAO,CAAC;IACd,qBAAqB,CAAC,EAAE,CAAC,QAAQ,EAAE,wBAAwB,KAAK,OAAO,CAAC;IACxE,YAAY,CAAC,EAAE,CAAC,GAAG,EAAE,MAAM,KAAK,OAAO,CAAC;IACxC,QAAQ,CAAC,EAAE,IAAI,CAAC;IAChB,aAAa,CAAC,EAAE,CAAC,IAAI,EAAE,0BAA0B,KAAK,IAAI,CAAC;IAC3D,yBAAyB,CAAC,EAAE,MAAM,CAAC;CACpC,CAAC;AAEF,MAAM,MAAM,kBAAkB,GAAG;IAC/B,QAAQ,EAAE,MAAM,CAAC;IACjB,oBAAoB,EAAE,MAAM,CAAC;IAC7B,eAAe,IAAI,OAAO,CAAC;IAC3B,OAAO,IAAI,IAAI,CAAC;IAChB,CAAC,MAAM,CAAC,OAAO,CAAC,IAAI,IAAI,CAAC;CAC1B,CAAC;AA6FF,wBAAgB,mBAAmB,CAAC,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1E,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,GAC5C,kBAAkB,CAyRpB;AAED,wBAAgB,gBAAgB,CAAC,CAAC,EAAE,QAAQ,SAAS,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,EAC1E,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,0BAA0B,CAAC,QAAQ,CAAC,EAC7C,EAAE,EAAE,MAAM,CAAC,GACV,CAAC,CAGH"}
|
package/dist/file-lock-sync.js
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import fs from "node:fs";
|
|
2
2
|
import { acquireFileLockSyncWithRoot } from "./file-lock-sync-root-acquire.js";
|
|
3
|
-
import {
|
|
3
|
+
import { withSyncHeldLockHandle } from "./file-lock-sync-root-held.js";
|
|
4
4
|
import path from "node:path";
|
|
5
|
-
import { readSidecarLockSnapshotSync, removeSidecarLockIfUnchangedSync, serializeSidecarLockPayload, sidecarLockSnapshotMatches, } from "./sidecar-lock-reclaim.js";
|
|
5
|
+
import { readSidecarLockRawSnapshotSync, readSidecarLockSnapshotSync, removeSidecarLockIfUnchangedSync, serializeSidecarLockPayload, sidecarLockSnapshotMatches, } from "./sidecar-lock-reclaim.js";
|
|
6
6
|
import { computeSidecarLockDelayMs, isTransientLockFileDenial, maxTransientLockDenials, validateSidecarLockStaleMs, validateSidecarLockCompromiseCheckIntervalMs, validateSidecarLockRetryOptions, validateSidecarLockTimeoutMs, } from "./sidecar-lock-policy.js";
|
|
7
7
|
import { getFsSafeLockConfig } from "./lock-config.js";
|
|
8
8
|
import { sleepSync } from "./timing.js";
|
|
@@ -37,7 +37,11 @@ function releaseAllSyncHeldLocks() {
|
|
|
37
37
|
getSyncLockAdmissions().clear();
|
|
38
38
|
}
|
|
39
39
|
function verifySyncHeldLock(held) {
|
|
40
|
-
const
|
|
40
|
+
const lockPath = held.lockPath;
|
|
41
|
+
const parsePayload = held.parsePayload;
|
|
42
|
+
const current = parsePayload
|
|
43
|
+
? readSidecarLockSnapshotSync(lockPath, parsePayload)
|
|
44
|
+
: readSidecarLockRawSnapshotSync(lockPath);
|
|
41
45
|
return !!current && sidecarLockSnapshotMatches(current, held.snapshot);
|
|
42
46
|
}
|
|
43
47
|
function releaseSyncHeldLock(held) {
|
|
@@ -412,12 +416,5 @@ export function acquireFileLockSync(targetPath, options) {
|
|
|
412
416
|
}
|
|
413
417
|
export function withFileLockSync(targetPath, options, fn) {
|
|
414
418
|
const lock = acquireFileLockSync(targetPath, options);
|
|
415
|
-
|
|
416
|
-
return withRootSyncHeldLockHandle(lock, fn);
|
|
417
|
-
try {
|
|
418
|
-
return fn();
|
|
419
|
-
}
|
|
420
|
-
finally {
|
|
421
|
-
lock.release();
|
|
422
|
-
}
|
|
419
|
+
return withSyncHeldLockHandle(lock, fn);
|
|
423
420
|
}
|
package/dist/file-store.js
CHANGED
|
@@ -321,10 +321,11 @@ export function fileStoreSync(options) {
|
|
|
321
321
|
mode: writeOptions?.mode ?? mode,
|
|
322
322
|
});
|
|
323
323
|
}
|
|
324
|
+
let readTextIfExists;
|
|
324
325
|
return {
|
|
325
326
|
rootDir,
|
|
326
327
|
path: (relativePath) => resolveStorePath(rootDir, relativePath),
|
|
327
|
-
readTextIfExists: (relativePath, readOptions) => {
|
|
328
|
+
readTextIfExists: readTextIfExists = (relativePath, readOptions) => {
|
|
328
329
|
const limit = normalizeMaxBytes(readOptions?.maxBytes, { defaultValue: maxBytes });
|
|
329
330
|
const targetPath = resolveStorePath(rootDir, relativePath);
|
|
330
331
|
const opened = openRootFileSync({
|
|
@@ -352,8 +353,7 @@ export function fileStoreSync(options) {
|
|
|
352
353
|
}
|
|
353
354
|
},
|
|
354
355
|
readJsonIfExists: (relativePath, readOptions) => {
|
|
355
|
-
const raw =
|
|
356
|
-
.readTextIfExists(relativePath, readOptions);
|
|
356
|
+
const raw = readTextIfExists(relativePath, readOptions);
|
|
357
357
|
return raw === null ? null : JSON.parse(raw);
|
|
358
358
|
},
|
|
359
359
|
write,
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"guarded-mkdir.d.ts","sourceRoot":"","sources":["../src/guarded-mkdir.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAuB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAA4B,KAAK,4BAA4B,EAAE,MAAM,kCAAkC,CAAC;AAC/G,OAAO,KAAK,EACV,6BAA6B,EAC7B,8BAA8B,EAC9B,gCAAgC,EACjC,MAAM,mBAAmB,CAAC;AA4G3B;;;;;GAKG;AACH,wBAAsB,6BAA6B,CAAC,MAAM,EAAE;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClE,qBAAqB,CAAC,EAAE,CACtB,aAAa,EAAE,MAAM,EACrB,qBAAqB,EAAE,MAAM,EAC7B,kBAAkB,EAAE,MAAM,GAAG,SAAS,EACtC,MAAM,EAAE,4BAA4B,KACjC,OAAO,CAAC,8BAA8B,GAAG,SAAS,CAAC,GAAG,8BAA8B,GAAG,SAAS,CAAC;IACtG,kBAAkB,CAAC,EAAE,CACnB,aAAa,EAAE,MAAM,EACrB,qBAAqB,EAAE,MAAM,EAC7B,kBAAkB,EAAE,MAAM,GAAG,SAAS,KACnC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,oBAAoB,CAAC,EAAE,CACrB,OAAO,EAAE,6BAA6B,KACnC,gCAAgC,GAAG,SAAS,CAAC;IAClD,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,oCAAoC,CAAC,EAAE,OAAO,CAAC;IAC/C,qCAAqC,CAAC,EAAE,OAAO,CAAC;IAChD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,oBAAoB,CAAC;CACrC,GAAG,OAAO,CAAC,MAAM,CAAC,
|
|
1
|
+
{"version":3,"file":"guarded-mkdir.d.ts","sourceRoot":"","sources":["../src/guarded-mkdir.ts"],"names":[],"mappings":"AAmBA,OAAO,EAAuB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,EAA4B,KAAK,4BAA4B,EAAE,MAAM,kCAAkC,CAAC;AAC/G,OAAO,KAAK,EACV,6BAA6B,EAC7B,8BAA8B,EAC9B,gCAAgC,EACjC,MAAM,mBAAmB,CAAC;AA4G3B;;;;;GAKG;AACH,wBAAsB,6BAA6B,CAAC,MAAM,EAAE;IAC1D,QAAQ,EAAE,MAAM,CAAC;IACjB,UAAU,EAAE,MAAM,CAAC;IACnB,eAAe,CAAC,EAAE,CAAC,aAAa,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAClE,qBAAqB,CAAC,EAAE,CACtB,aAAa,EAAE,MAAM,EACrB,qBAAqB,EAAE,MAAM,EAC7B,kBAAkB,EAAE,MAAM,GAAG,SAAS,EACtC,MAAM,EAAE,4BAA4B,KACjC,OAAO,CAAC,8BAA8B,GAAG,SAAS,CAAC,GAAG,8BAA8B,GAAG,SAAS,CAAC;IACtG,kBAAkB,CAAC,EAAE,CACnB,aAAa,EAAE,MAAM,EACrB,qBAAqB,EAAE,MAAM,EAC7B,kBAAkB,EAAE,MAAM,GAAG,SAAS,KACnC,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1B,oBAAoB,CAAC,EAAE,CACrB,OAAO,EAAE,6BAA6B,KACnC,gCAAgC,GAAG,SAAS,CAAC;IAClD,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAC;IAClC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,oCAAoC,CAAC,EAAE,OAAO,CAAC;IAC/C,qCAAqC,CAAC,EAAE,OAAO,CAAC;IAChD,kBAAkB,CAAC,EAAE,MAAM,CAAC;IAC5B,YAAY,CAAC,EAAE,oBAAoB,CAAC;CACrC,GAAG,OAAO,CAAC,MAAM,CAAC,CA4MlB"}
|
package/dist/guarded-mkdir.js
CHANGED
|
@@ -149,6 +149,7 @@ export async function mkdirPathComponentsWithGuards(params) {
|
|
|
149
149
|
if (params.revalidateParentAfterBeforeComponent) {
|
|
150
150
|
await assertAsyncDirectoryGuard(parentGuard);
|
|
151
151
|
}
|
|
152
|
+
let shouldCreate = true;
|
|
152
153
|
if (params.beforeCreateComponent) {
|
|
153
154
|
let missing = false;
|
|
154
155
|
try {
|
|
@@ -159,6 +160,7 @@ export async function mkdirPathComponentsWithGuards(params) {
|
|
|
159
160
|
throw error;
|
|
160
161
|
missing = true;
|
|
161
162
|
}
|
|
163
|
+
shouldCreate = missing;
|
|
162
164
|
if (missing) {
|
|
163
165
|
let prospectiveParent = retainedParentPath;
|
|
164
166
|
if (!prospectiveParent) {
|
|
@@ -177,36 +179,12 @@ export async function mkdirPathComponentsWithGuards(params) {
|
|
|
177
179
|
if (!params.synchronousAuthorizationIncludesFence)
|
|
178
180
|
inspectGuardCurrent(parentGuard);
|
|
179
181
|
}
|
|
180
|
-
params.assertBeforeMutation?.();
|
|
181
|
-
// Authority callbacks are an explicit freshness boundary. Recheck the
|
|
182
|
-
// exact parent synchronously so no callback-observed authority is
|
|
183
|
-
// carried into a pathname mkdir after the parent was swapped.
|
|
184
|
-
inspectGuardCurrent(parentGuard);
|
|
185
|
-
try {
|
|
186
|
-
if (params.private) {
|
|
187
|
-
await createDirectoryWithAdmission(next, {
|
|
188
|
-
private: true,
|
|
189
|
-
mode: params.mode,
|
|
190
|
-
assertBeforeMutation: params.assertBeforeMutation,
|
|
191
|
-
}, {
|
|
192
|
-
expectedParentIdentity: {
|
|
193
|
-
dev: parentGuard.stat.dev, ino: parentGuard.stat.ino, realPath: parentGuard.realPath,
|
|
194
|
-
},
|
|
195
|
-
});
|
|
196
|
-
}
|
|
197
|
-
else {
|
|
198
|
-
await fs.mkdir(next, { mode: params.mode });
|
|
199
|
-
}
|
|
200
|
-
created = true;
|
|
201
|
-
}
|
|
202
|
-
catch (error) {
|
|
203
|
-
if (!isDirectoryCollision(error))
|
|
204
|
-
throw error;
|
|
205
|
-
}
|
|
206
182
|
}
|
|
207
183
|
}
|
|
208
|
-
|
|
184
|
+
if (shouldCreate) {
|
|
209
185
|
params.assertBeforeMutation?.();
|
|
186
|
+
// Both policy and ordinary mkdir must renew the parent after callbacks.
|
|
187
|
+
inspectGuardCurrent(parentGuard);
|
|
210
188
|
try {
|
|
211
189
|
if (params.private) {
|
|
212
190
|
await createDirectoryWithAdmission(next, {
|
|
@@ -222,6 +200,7 @@ export async function mkdirPathComponentsWithGuards(params) {
|
|
|
222
200
|
else {
|
|
223
201
|
await fs.mkdir(next, { mode: params.mode });
|
|
224
202
|
}
|
|
203
|
+
created = true;
|
|
225
204
|
}
|
|
226
205
|
catch (error) {
|
|
227
206
|
if (!isDirectoryCollision(error))
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"install-path.d.ts","sourceRoot":"","sources":["../src/install-path.ts"],"names":[],"mappings":"AAWA,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED,2FAA2F;AAC3F,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,
|
|
1
|
+
{"version":3,"file":"install-path.d.ts","sourceRoot":"","sources":["../src/install-path.ts"],"names":[],"mappings":"AAWA,wBAAgB,WAAW,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAMjD;AAED,2FAA2F;AAC3F,wBAAgB,qBAAqB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAc3D;AAED;;;GAGG;AACH,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,MAAM,GAAG,MAAM,CAO7D;AAED,wBAAgB,qBAAqB,CAAC,MAAM,EAAE;IAC5C,OAAO,EAAE,MAAM,CAAC;IAChB,EAAE,EAAE,MAAM,CAAC;IACX,kBAAkB,EAAE,MAAM,CAAC;IAC3B,WAAW,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,MAAM,CAAC;CACtC,GAAG;IAAE,EAAE,EAAE,IAAI,CAAC;IAAC,IAAI,EAAE,MAAM,CAAA;CAAE,GAAG;IAAE,EAAE,EAAE,KAAK,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,CA+B5D;AAED,wBAAsB,6BAA6B,CAAC,MAAM,EAAE;IAC1D,OAAO,EAAE,MAAM,CAAC;IAChB,aAAa,EAAE,MAAM,CAAC;IACtB,aAAa,EAAE,MAAM,CAAC;CACvB,GAAG,OAAO,CAAC,IAAI,CAAC,CAuEhB"}
|
package/dist/install-path.js
CHANGED
|
@@ -15,11 +15,8 @@ export function safeDirName(input) {
|
|
|
15
15
|
export function safePathSegmentHashed(input) {
|
|
16
16
|
const trimmed = input.trim();
|
|
17
17
|
const base = trimmed
|
|
18
|
-
.replaceAll(/[
|
|
19
|
-
.replaceAll(
|
|
20
|
-
.replaceAll(/-+/g, "-")
|
|
21
|
-
.replaceAll(/^-+/g, "")
|
|
22
|
-
.replaceAll(/-+$/g, "");
|
|
18
|
+
.replaceAll(/[^a-zA-Z0-9._]+/g, "-")
|
|
19
|
+
.replaceAll(/^-|-$/g, "");
|
|
23
20
|
const normalized = base.length > 0 ? base : "skill";
|
|
24
21
|
const safe = normalized === "." || normalized === ".." ? "skill" : normalized;
|
|
25
22
|
if (safe !== trimmed || safe.length > 60) {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"json-durable-queue-ownership.d.ts","sourceRoot":"","sources":["../src/json-durable-queue-ownership.ts"],"names":[],"mappings":"AAEA,OAAe,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAUnD,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG,QAAQ,CAAC;IACrD,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC,CAAC;AAUH,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,0BAA0B,GAChC,+BAA+B,CAkBjC;AAyFD,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,0BAA0B,EACjC,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GACtC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOxB;AAGD,wBAAsB,wBAAwB,CAAC,CAAC,EAC9C,KAAK,EAAE,0BAA0B,EACjC,QAAQ,EAAE,WAAW,EACrB,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EACnC,GAAG,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GACxE,OAAO,CAAC,CAAC,CAAC,CAmCZ;AAED,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,OAAO,CAAC,
|
|
1
|
+
{"version":3,"file":"json-durable-queue-ownership.d.ts","sourceRoot":"","sources":["../src/json-durable-queue-ownership.ts"],"names":[],"mappings":"AAEA,OAAe,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAUnD,MAAM,MAAM,0BAA0B,GAAG;IACvC,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,CAAC,EAAE,MAAM,CAAC;CACzB,CAAC;AAEF,MAAM,MAAM,+BAA+B,GAAG,QAAQ,CAAC;IACrD,QAAQ,EAAE,MAAM,CAAC;IACjB,aAAa,EAAE,MAAM,CAAC;IACtB,cAAc,EAAE,MAAM,CAAC;CACxB,CAAC,CAAC;AAUH,wBAAgB,8BAA8B,CAC5C,KAAK,EAAE,0BAA0B,GAChC,+BAA+B,CAkBjC;AAyFD,wBAAsB,sBAAsB,CAC1C,KAAK,EAAE,0BAA0B,EACjC,OAAO,GAAE;IAAE,WAAW,CAAC,EAAE,OAAO,CAAA;CAAO,GACtC,OAAO,CAAC,MAAM,GAAG,IAAI,CAAC,CAOxB;AAGD,wBAAsB,wBAAwB,CAAC,CAAC,EAC9C,KAAK,EAAE,0BAA0B,EACjC,QAAQ,EAAE,WAAW,EACrB,cAAc,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,EACnC,GAAG,EAAE,CAAC,QAAQ,EAAE,MAAM,EAAE,aAAa,EAAE,MAAM,OAAO,CAAC,IAAI,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,GACxE,OAAO,CAAC,CAAC,CAAC,CAmCZ;AAED,wBAAsB,2BAA2B,CAC/C,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,OAAO,CAAC,CAUlB;AAED,wBAAsB,4BAA4B,CAChD,KAAK,EAAE,0BAA0B,GAChC,OAAO,CAAC,IAAI,CAAC,CA0Bf;AAED,wBAAsB,6BAA6B,CAAC,MAAM,EAAE;IAC1D,KAAK,EAAE,0BAA0B,CAAC;IAClC,UAAU,EAAE,MAAM,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CAsDhB;AAKD,wBAAgB,YAAY,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAI1D"}
|