@openclaw/fs-safe 0.13.0 → 0.14.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. package/CHANGELOG.md +26 -1
  2. package/dist/copy-file-input.d.ts +1 -1
  3. package/dist/copy-file-input.d.ts.map +1 -1
  4. package/dist/copy-file-input.js +2 -0
  5. package/dist/file-store-sync-directory.d.ts.map +1 -1
  6. package/dist/file-store-sync-directory.js +14 -7
  7. package/dist/guest-dispatch-python.js +1 -1
  8. package/dist/native-binding.d.ts +9 -0
  9. package/dist/native-binding.d.ts.map +1 -1
  10. package/dist/native-binding.js +8 -1
  11. package/dist/native-operations.d.ts.map +1 -1
  12. package/dist/native-operations.js +6 -4
  13. package/dist/native-parent-admission.d.ts +1 -0
  14. package/dist/native-parent-admission.d.ts.map +1 -1
  15. package/dist/native-parent-admission.js +6 -3
  16. package/dist/native-pinned-write-windows.d.ts.map +1 -1
  17. package/dist/native-pinned-write-windows.js +8 -6
  18. package/dist/native-pinned-write.d.ts.map +1 -1
  19. package/dist/native-pinned-write.js +200 -163
  20. package/dist/native-policy-directory-observation.d.ts +12 -0
  21. package/dist/native-policy-directory-observation.d.ts.map +1 -0
  22. package/dist/native-policy-directory-observation.js +61 -0
  23. package/dist/native-staged-file.d.ts +4 -4
  24. package/dist/native-staged-file.d.ts.map +1 -1
  25. package/dist/native-staged-file.js +20 -10
  26. package/dist/native.d.ts +1 -1
  27. package/dist/native.d.ts.map +1 -1
  28. package/dist/native.js +7 -2
  29. package/dist/pinned-mutation-admission.d.ts.map +1 -1
  30. package/dist/pinned-mutation-admission.js +13 -24
  31. package/dist/pinned-mutation-observation.d.ts +7 -1
  32. package/dist/pinned-mutation-observation.d.ts.map +1 -1
  33. package/dist/pinned-mutation-observation.js +87 -5
  34. package/dist/publish-file.d.ts.map +1 -1
  35. package/dist/publish-file.js +5 -3
  36. package/dist/root-directory-creation.d.ts.map +1 -1
  37. package/dist/root-directory-creation.js +5 -4
  38. package/dist/root-impl.d.ts.map +1 -1
  39. package/dist/root-impl.js +2 -1
  40. package/dist/root-path-existing.d.ts.map +1 -1
  41. package/dist/root-path-existing.js +1 -2
  42. package/dist/root-write-compatibility.d.ts +1 -2
  43. package/dist/root-write-compatibility.d.ts.map +1 -1
  44. package/dist/root-write-compatibility.js +17 -68
  45. package/dist/root-write-complete-parent.d.ts.map +1 -1
  46. package/dist/root-write-complete-parent.js +3 -1
  47. package/dist/root-write-lock-binding.d.ts +15 -0
  48. package/dist/root-write-lock-binding.d.ts.map +1 -0
  49. package/dist/root-write-lock-binding.js +162 -0
  50. package/dist/staged-directory.d.ts +5 -2
  51. package/dist/staged-directory.d.ts.map +1 -1
  52. package/dist/staged-directory.js +37 -1
  53. package/dist/temp-workspace-admission.d.ts.map +1 -1
  54. package/dist/temp-workspace-admission.js +28 -4
  55. package/docs/guest.md +1 -1
  56. package/docs/native-helper.md +14 -1
  57. package/docs/native.md +8 -0
  58. package/docs/writing.md +6 -0
  59. package/package.json +8 -8
@@ -57,12 +57,14 @@ import fs from "node:fs";
57
57
  import path from "node:path";
58
58
  import { FsSafeError } from "./errors.js";
59
59
  import { MutationAuthorityError } from "./mutation-authority.js";
60
+ import { captureNativeFdClose } from "./native-binding.js";
60
61
  import { writeNativeInput } from "./native-operations.js";
61
62
  import { assertNativeCopyCompleted, createNativeCopyFile } from "./copy-file-input.js";
62
63
  import { assertStagedDirectoryCurrent, openStagedDirectory } from "./staged-directory.js";
63
64
  import { assertFinalSymlinkRejected } from "./root-symlink-policy.js";
64
65
  export function assertNativeStaging(binding) {
65
66
  if ([
67
+ binding.closeOwnedFd,
66
68
  binding.createStagedFile,
67
69
  binding.stagedFileMatches,
68
70
  binding.removeStagedFile,
@@ -92,7 +94,9 @@ function failure(error, details) {
92
94
  }
93
95
  class NativeStagedFile {
94
96
  #binding;
97
+ #closeFd;
95
98
  #parentFd;
99
+ #closeParentFd;
96
100
  #directory;
97
101
  #portableNames;
98
102
  #publishedMode;
@@ -102,26 +106,29 @@ class NativeStagedFile {
102
106
  #state = { status: "open", publication: NOT_PUBLISHED };
103
107
  #receipt;
104
108
  #rejectFinalSymlink = false;
105
- constructor(binding, parentFd, directory, portableNames, publishedMode, sync, assertBeforeMutation) {
109
+ constructor(binding, parentFd, closeParentFd, directory, portableNames, publishedMode, sync, assertBeforeMutation) {
110
+ this.#closeFd = captureNativeFdClose(binding);
106
111
  this.#binding = binding;
107
112
  this.#parentFd = parentFd;
113
+ this.#closeParentFd = closeParentFd;
108
114
  this.#directory = directory;
109
115
  this.#portableNames = portableNames;
110
116
  this.#publishedMode = publishedMode;
111
117
  this.#sync = sync;
112
118
  this.#assertBeforeMutation = assertBeforeMutation;
113
119
  }
114
- // Takes ownership of parentFd, including all construction and preparation failures.
115
- static async create(binding, parentFd, directory, input, mode, maxBytes,
120
+ // Public staging supplies a Node parent; pinned writes supply a native parent.
121
+ // The supplied closer owns parentFd even on construction or preparation failure.
122
+ static async create(binding, parentFd, closeParentFd, directory, input, mode, maxBytes,
116
123
  // Public staging uses portable names; existing POSIX writes accept literal names.
117
124
  portableNames = true, sync = true, assertBeforeMutation) {
118
125
  let staged;
119
126
  try {
120
- staged = new NativeStagedFile(binding, parentFd, directory, portableNames, mode, sync, assertBeforeMutation);
127
+ staged = new NativeStagedFile(binding, parentFd, closeParentFd, directory, portableNames, mode, sync, assertBeforeMutation);
121
128
  }
122
129
  catch (error) {
123
130
  try {
124
- fs.closeSync(parentFd);
131
+ closeParentFd(parentFd);
125
132
  }
126
133
  catch (closeError) {
127
134
  throw new AggregateError([error, closeError], "staged owner construction and close failed");
@@ -131,12 +138,12 @@ class NativeStagedFile {
131
138
  await staged.#prepare(input, maxBytes);
132
139
  return staged;
133
140
  }
134
- static async write(binding, parentFd, directory, params, parentGuard) {
141
+ static async write(binding, parentFd, closeParentFd, directory, params, parentGuard) {
135
142
  const env_1 = { stack: [], error: void 0, hasError: false };
136
143
  try {
137
144
  // This owner never escapes. Only the internal verifier borrows its fd;
138
145
  // public descriptor methods remain await-free and cannot race disposal.
139
- const staged = __addDisposableResource(env_1, await NativeStagedFile.create(binding, parentFd, directory, params.input, params.mode, params.maxBytes, false, params.sync, params.assertBeforeMutation), true);
146
+ const staged = __addDisposableResource(env_1, await NativeStagedFile.create(binding, parentFd, closeParentFd, directory, params.input, params.mode, params.maxBytes, false, params.sync, params.assertBeforeMutation), true);
140
147
  staged.#rejectFinalSymlink = params.rejectFinalSymlink === true;
141
148
  if (params.input.kind === "file")
142
149
  await params.input.verifySource();
@@ -336,12 +343,15 @@ class NativeStagedFile {
336
343
  }
337
344
  }
338
345
  let resources = "closed";
339
- for (const fd of [state.fileFd, this.#parentFd]) {
346
+ for (const [fd, closeFd] of [
347
+ [state.fileFd, this.#closeFd],
348
+ [this.#parentFd, this.#closeParentFd],
349
+ ]) {
340
350
  if (fd === undefined) {
341
351
  continue;
342
352
  }
343
353
  try {
344
- fs.closeSync(fd);
354
+ closeFd(fd);
345
355
  }
346
356
  catch (error) {
347
357
  resources = "close-failed";
@@ -385,5 +395,5 @@ export async function stageFileInDirectory(options) {
385
395
  const input = { kind: "buffer", data: Buffer.from(options.content) };
386
396
  const mode = options.mode ?? 0o600;
387
397
  const parent = openStagedDirectory(options.directory);
388
- return await createNativeStage(binding, parent.fd, parent.receipt, input, mode);
398
+ return await createNativeStage(binding, parent.fd, fs.closeSync, parent.receipt, input, mode);
389
399
  }
package/dist/native.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import type { NativeBinding } from "./native-binding.js";
1
+ import { type NativeBinding } from "./native-binding.js";
2
2
  export type { NativeBinding } from "./native-binding.js";
3
3
  export declare function __loadBundledNativeForTest(): NativeBinding;
4
4
  export declare function __nativeLoaderDetectorsForTest(): {
@@ -1 +1 @@
1
- {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAQA,OAAO,KAAK,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAGzD,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAsKzD,wBAAgB,0BAA0B,IAAI,aAAa,CAE1D;AAED,wBAAgB,8BAA8B,IAAI;IAChD,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,cAAc,EAAE,OAAO,GAAG,SAAS,CAAC;CACrC,CAMA;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,IAAI,EAAE,MAAM,EACZ,IAAI,UAAQ,GACX,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,gBAAgB,IAAI,aAAa,GAAG,SAAS,CAkB5D;AAED,wBAAgB,oBAAoB,IAAI,aAAa,CAQpD;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,aAAa,GAAG,IAAI,CAK1E;AAED,wBAAgB,0BAA0B,IAAI,IAAI,CAKjD"}
1
+ {"version":3,"file":"native.d.ts","sourceRoot":"","sources":["../src/native.ts"],"names":[],"mappings":"AAQA,OAAO,EAAwB,KAAK,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAG/E,YAAY,EAAE,aAAa,EAAE,MAAM,qBAAqB,CAAC;AAwKzD,wBAAgB,0BAA0B,IAAI,aAAa,CAE1D;AAED,wBAAgB,8BAA8B,IAAI;IAChD,MAAM,EAAE,OAAO,GAAG,SAAS,CAAC;IAC5B,UAAU,EAAE,OAAO,GAAG,SAAS,CAAC;IAChC,cAAc,EAAE,OAAO,GAAG,SAAS,CAAC;CACrC,CAMA;AAED,wBAAgB,qBAAqB,CACnC,QAAQ,EAAE,MAAM,CAAC,QAAQ,EACzB,IAAI,EAAE,MAAM,EACZ,IAAI,UAAQ,GACX,MAAM,GAAG,SAAS,CAEpB;AAED,wBAAgB,gBAAgB,IAAI,aAAa,GAAG,SAAS,CAoB5D;AAED,wBAAgB,oBAAoB,IAAI,aAAa,CAQpD;AAED,wBAAgB,wBAAwB,CAAC,MAAM,EAAE,MAAM,aAAa,GAAG,IAAI,CAK1E;AAED,wBAAgB,0BAA0B,IAAI,IAAI,CAKjD"}
package/dist/native.js CHANGED
@@ -1,6 +1,7 @@
1
1
  import { closeSync, openSync, readSync, readdirSync, } from "node:fs";
2
2
  import { createRequire } from "node:module";
3
3
  import { FsSafeError } from "./errors.js";
4
+ import { captureNativeFdClose } from "./native-binding.js";
4
5
  import { getFsSafeNativeConfig } from "./native-config.js";
5
6
  const require = createRequire(import.meta.url);
6
7
  let binding;
@@ -144,7 +145,9 @@ function loadBundledBinding() {
144
145
  if (!target) {
145
146
  throw new Error(`Unsupported OS or architecture: ${process.platform}-${process.arch}`);
146
147
  }
147
- return require(nativePackageForTarget(target));
148
+ const loaded = require(nativePackageForTarget(target));
149
+ captureNativeFdClose(loaded);
150
+ return loaded;
148
151
  }
149
152
  export function __loadBundledNativeForTest() {
150
153
  return loadBundledBinding();
@@ -166,7 +169,9 @@ export function getNativeBinding() {
166
169
  if (!attempted) {
167
170
  attempted = true;
168
171
  try {
169
- binding = loadBinding();
172
+ const loaded = loadBinding();
173
+ captureNativeFdClose(loaded);
174
+ binding = loaded;
170
175
  }
171
176
  catch (error) {
172
177
  loadError = error;
@@ -1 +1 @@
1
- {"version":3,"file":"pinned-mutation-admission.d.ts","sourceRoot":"","sources":["../src/pinned-mutation-admission.ts"],"names":[],"mappings":"AACA,OAAO,EAA2B,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGvF,OAAO,EAAuB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,KAAK,EAKV,4BAA4B,EAC7B,MAAM,mBAAmB,CAAC;AAQ3B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAgCtE,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;CAC1C,CAAC,CAAC;AAEH,wBAAgB,4BAA4B,CAC1C,aAAa,EAAE,kBAAkB,GAAG,SAAS,EAC7C,gBAAgB,EAAE,qBAAqB,GAAG,SAAS,GAClD,4BAA4B,GAAG,SAAS,CAO1C;AAuJD,wBAAsB,mCAAmC,CAAC,MAAM,EAAE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yBAAyB,EAAE,MAAM,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,4BAA4B,GAAG,SAAS,CAAC;IACjD,cAAc,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD,GAAG,OAAO,CAAC;IACV,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,4BAA4B,CAAC;CAClD,CAAC,CAsQD"}
1
+ {"version":3,"file":"pinned-mutation-admission.d.ts","sourceRoot":"","sources":["../src/pinned-mutation-admission.ts"],"names":[],"mappings":"AACA,OAAO,EAA2B,KAAK,kBAAkB,EAAE,MAAM,qBAAqB,CAAC;AAGvF,OAAO,EAAuB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AACpF,OAAO,KAAK,EAKV,4BAA4B,EAC7B,MAAM,mBAAmB,CAAC;AAQ3B,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,0BAA0B,CAAC;AAgCtE,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,aAAa,CAAC,EAAE,kBAAkB,CAAC;IACnC,gBAAgB,CAAC,EAAE,qBAAqB,CAAC;CAC1C,CAAC,CAAC;AAEH,wBAAgB,4BAA4B,CAC1C,aAAa,EAAE,kBAAkB,GAAG,SAAS,EAC7C,gBAAgB,EAAE,qBAAqB,GAAG,SAAS,GAClD,4BAA4B,GAAG,SAAS,CAO1C;AAuJD,wBAAsB,mCAAmC,CAAC,MAAM,EAAE;IAChE,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,CAAC,EAAE,oBAAoB,CAAC;IACpC,kBAAkB,EAAE,MAAM,CAAC;IAC3B,yBAAyB,EAAE,MAAM,CAAC;IAClC,YAAY,CAAC,EAAE,MAAM,CAAC;IACtB,MAAM,EAAE,4BAA4B,GAAG,SAAS,CAAC;IACjD,cAAc,IAAI,OAAO,CAAC;QAAE,QAAQ,EAAE,MAAM,CAAA;KAAE,CAAC,CAAC;CACjD,GAAG,OAAO,CAAC;IACV,kBAAkB,EAAE,MAAM,CAAC;IAC3B,iBAAiB,CAAC,EAAE,4BAA4B,CAAC;CAClD,CAAC,CA2PD"}
@@ -7,7 +7,7 @@ import { ordinarySharedAbsoluteInsideRoot, simpleSharedRoute, } from "./pinned-m
7
7
  import { resolvePathViaExistingAncestor } from "./root-path-existing.js";
8
8
  import { outsideWorkspaceError } from "./root-errors.js";
9
9
  import { getFsSafeNativeConfig } from "./native-config.js";
10
- import { advanceMutationObservation, mutationObservationCurrent, observeMutationPath, mutationDirectoryObservationCurrent, mutationObservationUsesDirectory, missingMutationSegments, nextMissingMutationPath, } from "./pinned-mutation-observation.js";
10
+ import { advanceMutationObservation, mutationObservationCurrent, observeMutationPath, mutationObservationsCurrent, mutationObservationUsesDirectory, missingMutationSegments, nextMissingMutationPath, } from "./pinned-mutation-observation.js";
11
11
  export function snapshotPinnedMutationPolicy(denyMutations, mutationSymlinks) {
12
12
  if (denyMutations === undefined && mutationSymlinks === undefined)
13
13
  return undefined;
@@ -92,10 +92,12 @@ function captureEpoch(rootReal, target, policy, session) {
92
92
  return undefined;
93
93
  }
94
94
  }
95
- function epochCurrent(epoch) {
95
+ function epochCurrent(epoch, directories) {
96
96
  return !process.versions.bun && epoch.mode === epoch.session.nativeMode &&
97
97
  getFsSafeNativeConfig().mode === epoch.mode &&
98
- epoch.observations.every(mutationObservationCurrent);
98
+ (directories ? mutationObservationsCurrent(epoch.observations, directories) :
99
+ epoch.observations.every(mutationObservationCurrent)) &&
100
+ getFsSafeNativeConfig().mode === epoch.mode;
99
101
  }
100
102
  function assertCachedNotDenied(target, epoch) {
101
103
  if (epoch.paths.some((paths) => paths.some((denied) => isPathInside(denied, target) && isPathInside(target, denied))) ||
@@ -143,10 +145,8 @@ function advanceAuthorizedDirectory(admittedEpoch, admitted, receipt) {
143
145
  target,
144
146
  observations: Object.freeze(complete),
145
147
  });
146
- if (!mutationDirectoryObservationCurrent(receipt.parent) ||
147
- !mutationDirectoryObservationCurrent(receipt.child) ||
148
- !mutationObservationUsesDirectory(target, receipt.child) ||
149
- !epochCurrent(next))
148
+ if (!mutationObservationUsesDirectory(target, receipt.child) ||
149
+ !epochCurrent(next, [receipt.parent, receipt.child]))
150
150
  return undefined;
151
151
  assertCachedNotDenied(target.path, next);
152
152
  assertCachedNotDenied(receipt.child.path, next);
@@ -232,20 +232,14 @@ export async function preparePinnedWriteMutationAdmission(params) {
232
232
  if (!reusable || reusable.session !== session ||
233
233
  !reusableSharedCreateRequest(request, reusable) ||
234
234
  !mutationObservationUsesDirectory(reusable.target, parent) ||
235
- !epochCurrent(reusable)) {
235
+ !nonzeroDirectoryObservation(parent) || !epochCurrent(reusable, [parent])) {
236
236
  disable();
237
237
  return undefined;
238
238
  }
239
239
  assertCachedNotDenied(request.targetPath, reusable);
240
240
  assertCachedNotDenied(request.mutationPath, reusable);
241
- // This is the required end fence. A returned receipt remains usable
242
- // only synchronously, while the exact parent identity and spelling
243
- // still match the observation captured by this walk.
244
- if (!nonzeroDirectoryObservation(parent) ||
245
- !mutationDirectoryObservationCurrent(parent)) {
246
- disable();
247
- return undefined;
248
- }
241
+ // The epoch check ends with the exact parent fence. The receipt is
242
+ // consumed synchronously before any intervening authority callback.
249
243
  sharedPending = Object.freeze({
250
244
  epoch: reusable,
251
245
  childPath: request.mutationPath,
@@ -342,19 +336,14 @@ export async function preparePinnedWriteMutationAdmission(params) {
342
336
  if (!reusable || reusable.session !== pinnedSession ||
343
337
  !reusableRequest(request, reusable) ||
344
338
  !mutationObservationUsesDirectory(reusable.target, parent) ||
345
- !epochCurrent(reusable)) {
339
+ !epochCurrent(reusable, [parent])) {
346
340
  epoch = undefined;
347
341
  return undefined;
348
342
  }
349
343
  assertCachedNotDenied(request.targetPath, reusable);
350
344
  assertCachedNotDenied(request.mutationPath, reusable);
351
- // This is the required end fence. The caller can consume the returned
352
- // token without awaiting only while the exact pathname, canonical
353
- // spelling, descriptor identity, type, mode, and link count still match.
354
- if (!mutationDirectoryObservationCurrent(parent)) {
355
- epoch = undefined;
356
- return undefined;
357
- }
345
+ // The epoch check ends at the exact parent pathname, canonical spelling,
346
+ // identity, type, mode and link-count fence, with no intervening await.
358
347
  if (request.phase === "parent-create") {
359
348
  pending = Object.freeze({
360
349
  epoch: reusable,
@@ -6,6 +6,11 @@ export type MutationIdentity = Readonly<{
6
6
  nlink: bigint;
7
7
  }>;
8
8
  declare const checkedDirectoryObservation: unique symbol;
9
+ export type MutationDirectoryCurrent = Readonly<{
10
+ canonicalPath: string;
11
+ identity: MutationIdentity;
12
+ }>;
13
+ export type MutationDirectoryObserver = () => MutationDirectoryCurrent | undefined;
9
14
  export type MutationDirectoryObservation = Readonly<{
10
15
  path: string;
11
16
  canonicalPath: string;
@@ -24,11 +29,12 @@ export type MutationPathObservation = Readonly<{
24
29
  }>;
25
30
  export declare function missingMutationSegments(observation: MutationPathObservation): number;
26
31
  export declare function nextMissingMutationPath(observation: MutationPathObservation): string | undefined;
27
- export declare function checkedMutationDirectory(pathname: string, canonicalPath: string, stat: BigIntStats): MutationDirectoryObservation;
32
+ export declare function checkedMutationDirectory(pathname: string, canonicalPath: string, stat: Pick<BigIntStats, "dev" | "ino" | "mode" | "nlink">, observeCurrent?: MutationDirectoryObserver): MutationDirectoryObservation;
28
33
  export declare function mutationDirectoryObservationCurrent(observation: MutationDirectoryObservation): boolean;
29
34
  export declare function mutationObservationUsesDirectory(observation: MutationPathObservation, directory: MutationDirectoryObservation): boolean;
30
35
  export declare function observeMutationPath(pathname: string): MutationPathObservation | undefined;
31
36
  export declare function mutationObservationCurrent(observation: MutationPathObservation): boolean;
37
+ export declare function mutationObservationsCurrent(observations: readonly MutationPathObservation[], directories: readonly MutationDirectoryObservation[]): boolean;
32
38
  export declare function advanceMutationObservation(observation: MutationPathObservation, parent: MutationDirectoryObservation, child: MutationDirectoryObservation): MutationPathObservation | undefined;
33
39
  export {};
34
40
  //# sourceMappingURL=pinned-mutation-observation.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"pinned-mutation-observation.d.ts","sourceRoot":"","sources":["../src/pinned-mutation-observation.ts"],"names":[],"mappings":"AAAA,OAAW,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAM/C,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC,CAAC;AAEH,QAAA,MAAM,2BAA2B,eAAmD,CAAC;AAErF,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,CAAC,2BAA2B,CAAC,EAAE,IAAI,CAAC;CACrC,CAAC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,gBAAgB,CAAC;IACxB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC,CAAC;AA8BH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,uBAAuB,GAAG,MAAM,CAEpF;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,uBAAuB,GAAG,MAAM,GAAG,SAAS,CAGhG;AAKD,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,WAAW,GAChB,4BAA4B,CAU9B;AAQD,wBAAgB,mCAAmC,CACjD,WAAW,EAAE,4BAA4B,GACxC,OAAO,CAUT;AAED,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,uBAAuB,EACpC,SAAS,EAAE,4BAA4B,GACtC,OAAO,CAMT;AAGD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,uBAAuB,GAAG,SAAS,CA0BzF;AAED,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,uBAAuB,GAAG,OAAO,CAaxF;AAID,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,uBAAuB,EACpC,MAAM,EAAE,4BAA4B,EACpC,KAAK,EAAE,4BAA4B,GAClC,uBAAuB,GAAG,SAAS,CAiBrC"}
1
+ {"version":3,"file":"pinned-mutation-observation.d.ts","sourceRoot":"","sources":["../src/pinned-mutation-observation.ts"],"names":[],"mappings":"AAAA,OAAW,EAAE,KAAK,WAAW,EAAE,MAAM,SAAS,CAAC;AAM/C,MAAM,MAAM,gBAAgB,GAAG,QAAQ,CAAC;IACtC,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;IACZ,IAAI,EAAE,MAAM,CAAC;IACb,KAAK,EAAE,MAAM,CAAC;CACf,CAAC,CAAC;AAEH,QAAA,MAAM,2BAA2B,eAAmD,CAAC;AAGrF,MAAM,MAAM,wBAAwB,GAAG,QAAQ,CAAC;IAC9C,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,gBAAgB,CAAC;CAC5B,CAAC,CAAC;AACH,MAAM,MAAM,yBAAyB,GAAG,MAAM,wBAAwB,GAAG,SAAS,CAAC;AAEnF,MAAM,MAAM,4BAA4B,GAAG,QAAQ,CAAC;IAClD,IAAI,EAAE,MAAM,CAAC;IACb,aAAa,EAAE,MAAM,CAAC;IACtB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,CAAC,2BAA2B,CAAC,EAAE,IAAI,CAAC;CACrC,CAAC,CAAC;AAEH,MAAM,MAAM,uBAAuB,GAAG,QAAQ,CAAC;IAC7C,IAAI,EAAE,MAAM,CAAC;IACb,QAAQ,EAAE,MAAM,CAAC;IACjB,iBAAiB,EAAE,MAAM,CAAC;IAC1B,aAAa,EAAE,MAAM,CAAC;IACtB,KAAK,EAAE,gBAAgB,CAAC;IACxB,QAAQ,EAAE,gBAAgB,CAAC;IAC3B,eAAe,EAAE,SAAS,MAAM,EAAE,CAAC;IACnC,aAAa,EAAE,MAAM,CAAC;CACvB,CAAC,CAAC;AA6BH,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,uBAAuB,GAAG,MAAM,CAEpF;AAED,wBAAgB,uBAAuB,CAAC,WAAW,EAAE,uBAAuB,GAAG,MAAM,GAAG,SAAS,CAGhG;AAKD,wBAAgB,wBAAwB,CACtC,QAAQ,EAAE,MAAM,EAChB,aAAa,EAAE,MAAM,EACrB,IAAI,EAAE,IAAI,CAAC,WAAW,EAAE,KAAK,GAAG,KAAK,GAAG,MAAM,GAAG,OAAO,CAAC,EACzD,cAAc,CAAC,EAAE,yBAAyB,GACzC,4BAA4B,CAY9B;AAQD,wBAAgB,mCAAmC,CACjD,WAAW,EAAE,4BAA4B,GACxC,OAAO,CAgBT;AAED,wBAAgB,gCAAgC,CAC9C,WAAW,EAAE,uBAAuB,EACpC,SAAS,EAAE,4BAA4B,GACtC,OAAO,CAMT;AAGD,wBAAgB,mBAAmB,CAAC,QAAQ,EAAE,MAAM,GAAG,uBAAuB,GAAG,SAAS,CA0BzF;AAED,wBAAgB,0BAA0B,CAAC,WAAW,EAAE,uBAAuB,GAAG,OAAO,CAaxF;AAKD,wBAAgB,2BAA2B,CACzC,YAAY,EAAE,SAAS,uBAAuB,EAAE,EAChD,WAAW,EAAE,SAAS,4BAA4B,EAAE,GACnD,OAAO,CAiET;AAID,wBAAgB,0BAA0B,CACxC,WAAW,EAAE,uBAAuB,EACpC,MAAM,EAAE,4BAA4B,EACpC,KAAK,EAAE,4BAA4B,GAClC,uBAAuB,GAAG,SAAS,CAiBrC"}
@@ -4,6 +4,7 @@ import { isNotFoundPathError } from "./path.js";
4
4
  import { realpathSync } from "./realpath.js";
5
5
  import { inspectFileIdentitySync } from "./strict-file-identity.js";
6
6
  const checkedDirectoryObservation = Symbol("checked mutation directory observation");
7
+ const directoryObservers = new WeakMap();
7
8
  function identity(stat) {
8
9
  return Object.freeze({ dev: stat.dev, ino: stat.ino, mode: stat.mode, nlink: stat.nlink });
9
10
  }
@@ -17,8 +18,7 @@ function directoryMode(mode) {
17
18
  }
18
19
  function absent(pathname) {
19
20
  try {
20
- fs.lstatSync(pathname);
21
- return false;
21
+ return fs.lstatSync(pathname, { throwIfNoEntry: false }) === undefined;
22
22
  }
23
23
  catch (error) {
24
24
  // ENOTDIR is incomplete evidence, not a missing child of a directory.
@@ -35,16 +35,19 @@ export function nextMissingMutationPath(observation) {
35
35
  // Callers may construct this only from their just-completed exact pathname and
36
36
  // canonical fences. The private brand prevents unverified structural objects
37
37
  // from advancing an admission epoch.
38
- export function checkedMutationDirectory(pathname, canonicalPath, stat) {
39
- if (!stat.isDirectory() || stat.isSymbolicLink()) {
38
+ export function checkedMutationDirectory(pathname, canonicalPath, stat, observeCurrent) {
39
+ if (!directoryMode(stat.mode)) {
40
40
  throw new TypeError("mutation directory evidence must describe a real directory");
41
41
  }
42
- return Object.freeze({
42
+ const observation = Object.freeze({
43
43
  path: pathname,
44
44
  canonicalPath,
45
45
  identity: identity(stat),
46
46
  [checkedDirectoryObservation]: true,
47
47
  });
48
+ if (observeCurrent)
49
+ directoryObservers.set(observation, observeCurrent);
50
+ return observation;
48
51
  }
49
52
  function checkedDirectory(observation) {
50
53
  return observation[checkedDirectoryObservation] === true &&
@@ -55,6 +58,12 @@ export function mutationDirectoryObservationCurrent(observation) {
55
58
  if (!checkedDirectory(observation))
56
59
  return false;
57
60
  try {
61
+ const observed = directoryObservers.get(observation)?.();
62
+ if (observed) {
63
+ return directoryMode(observed.identity.mode) &&
64
+ sameIdentity(observation.identity, observed.identity) &&
65
+ observed.canonicalPath === observation.canonicalPath;
66
+ }
58
67
  const stat = inspectFileIdentitySync(() => fs.lstatSync(observation.path, { bigint: true }));
59
68
  return stat.isDirectory() && !stat.isSymbolicLink() &&
60
69
  sameIdentity(observation.identity, stat) &&
@@ -118,6 +127,79 @@ export function mutationObservationCurrent(observation) {
118
127
  return false;
119
128
  }
120
129
  }
130
+ // Share only ordinary spelling observations collected in this synchronous
131
+ // phase. Aliases retain their independent raw/canonical binding checks, and no
132
+ // fact escapes this call or crosses an authority callback or mutation.
133
+ export function mutationObservationsCurrent(observations, directories) {
134
+ const groups = new Map();
135
+ const groupFor = (pathname) => {
136
+ let group = groups.get(pathname);
137
+ if (!group) {
138
+ group = { observations: [], directories: [] };
139
+ groups.set(pathname, group);
140
+ }
141
+ return group;
142
+ };
143
+ try {
144
+ for (const observation of observations) {
145
+ if (observation.ancestor !== observation.canonicalAncestor) {
146
+ if (!mutationObservationCurrent(observation))
147
+ return false;
148
+ }
149
+ else {
150
+ groupFor(observation.ancestor).observations.push(observation);
151
+ }
152
+ }
153
+ for (const directory of directories) {
154
+ if (!checkedDirectory(directory))
155
+ return false;
156
+ groupFor(directory.path).directories.push(directory);
157
+ }
158
+ const current = (pathname, group) => {
159
+ const missing = new Set(group.observations.flatMap((observation) => {
160
+ const next = nextMissingMutationPath(observation);
161
+ return next === undefined ? [] : [next];
162
+ }));
163
+ // Exact directory roles are the end fence. Observe missing children
164
+ // before refreshing that parent, matching the ordered admission fence.
165
+ if (group.directories.length && ![...missing].every(absent))
166
+ return false;
167
+ const observed = group.directories.length
168
+ ? directoryObservers.get(group.directories[0])?.() : undefined;
169
+ const stat = observed?.identity ??
170
+ inspectFileIdentitySync(() => fs.lstatSync(pathname, { bigint: true }));
171
+ const canonical = observed?.canonicalPath ?? realpathSync.native(pathname);
172
+ const isDirectory = directoryMode(stat.mode);
173
+ if (!group.observations.every((observation) => canonical === observation.canonicalAncestor &&
174
+ sameIdentity(observation.entry, stat, isDirectory) &&
175
+ sameIdentity(observation.identity, stat, isDirectory) &&
176
+ (missingMutationSegments(observation) === 0 || isDirectory)))
177
+ return false;
178
+ if (!group.directories.every((directory) => isDirectory &&
179
+ sameIdentity(directory.identity, stat) && canonical === directory.canonicalPath))
180
+ return false;
181
+ return group.directories.length > 0 || [...missing].every(absent);
182
+ };
183
+ for (const [pathname, group] of groups) {
184
+ if (!group.directories.length && !current(pathname, group))
185
+ return false;
186
+ }
187
+ // Preserve the supplied parent/child order, even when a directory also
188
+ // appeared earlier as the Root or a denied path's nearest ancestor.
189
+ const checked = new Set();
190
+ for (const directory of directories) {
191
+ if (checked.has(directory.path))
192
+ continue;
193
+ if (!current(directory.path, groups.get(directory.path)))
194
+ return false;
195
+ checked.add(directory.path);
196
+ }
197
+ return true;
198
+ }
199
+ catch {
200
+ return false;
201
+ }
202
+ }
121
203
  // This is deliberately a pure tentative update. The immediately following
122
204
  // parent authorization validates the complete epoch once before reusing it.
123
205
  export function advanceMutationObservation(observation, parent, child) {
@@ -1 +1 @@
1
- {"version":3,"file":"publish-file.d.ts","sourceRoot":"","sources":["../src/publish-file.ts"],"names":[],"mappings":"AACA,OAAe,EAAoB,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AAI/D,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EAC1B,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAI5B,OAAO,EAML,KAAK,qCAAqC,EAC3C,MAAM,2BAA2B,CAAC;AAKnC,YAAY,EACV,2BAA2B,EAC3B,wCAAwC,EACxC,kCAAkC,EAClC,gCAAgC,EAChC,qCAAqC,GACtC,MAAM,2BAA2B,CAAC;AAEnC,MAAM,MAAM,4BAA4B,GAAG,cAAc,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAEjG,MAAM,MAAM,0BAA0B,GAAG;IACvC,MAAM,EAAE,UAAU,GAAG,gBAAgB,GAAG,kBAAkB,CAAC;IAC3D,QAAQ,EAAE,KAAK,CAAC;IAChB,aAAa,EAAE,oBAAoB,CAAC;CACrC,CAAC;AAIF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE/D;AAyND,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB,CAAC,EAAE,gBAAgB,CAAC;IAC1C,QAAQ,EAAE,4BAA4B,CAAC;IACvC,aAAa,CAAC,EAAE,qCAAqC,CAAC;IACtD,aAAa,CAAC,EAAE,gBAAgB,CAAC;CAClC,GAAG,OAAO,CAAC,0BAA0B,CAAC,CA6NtC"}
1
+ {"version":3,"file":"publish-file.d.ts","sourceRoot":"","sources":["../src/publish-file.ts"],"names":[],"mappings":"AACA,OAAe,EAAoB,KAAK,KAAK,EAAE,MAAM,SAAS,CAAC;AAG/D,OAAO,EAEL,KAAK,gBAAgB,EACrB,KAAK,oBAAoB,EAC1B,MAAM,2BAA2B,CAAC;AAGnC,OAAO,EAGL,KAAK,gBAAgB,EACtB,MAAM,oBAAoB,CAAC;AAK5B,OAAO,EAML,KAAK,qCAAqC,EAC3C,MAAM,2BAA2B,CAAC;AAKnC,YAAY,EACV,2BAA2B,EAC3B,wCAAwC,EACxC,kCAAkC,EAClC,gCAAgC,EAChC,qCAAqC,GACtC,MAAM,2BAA2B,CAAC;AAEnC,MAAM,MAAM,4BAA4B,GAAG,cAAc,GAAG,eAAe,GAAG,kBAAkB,CAAC;AAEjG,MAAM,MAAM,0BAA0B,GAAG;IACvC,MAAM,EAAE,UAAU,GAAG,gBAAgB,GAAG,kBAAkB,CAAC;IAC3D,QAAQ,EAAE,KAAK,CAAC;IAChB,aAAa,EAAE,oBAAoB,CAAC;CACrC,CAAC;AAIF,wBAAgB,uBAAuB,CAAC,KAAK,EAAE,OAAO,GAAG,OAAO,CAE/D;AA0ND,wBAAsB,oBAAoB,CAAC,MAAM,EAAE;IACjD,UAAU,EAAE,MAAM,CAAC;IACnB,UAAU,EAAE,MAAM,CAAC;IACnB,sBAAsB,CAAC,EAAE,gBAAgB,CAAC;IAC1C,QAAQ,EAAE,4BAA4B,CAAC;IACvC,aAAa,CAAC,EAAE,qCAAqC,CAAC;IACtD,aAAa,CAAC,EAAE,gBAAgB,CAAC;CAClC,GAAG,OAAO,CAAC,0BAA0B,CAAC,CA6NtC"}
@@ -1,6 +1,6 @@
1
1
  import { createHash } from "node:crypto";
2
2
  import fsSync, {} from "node:fs";
3
- import fs from "node:fs/promises";
3
+ import fs, {} from "node:fs/promises";
4
4
  import path from "node:path";
5
5
  import { pinDirectory, } from "./directory-durability.js";
6
6
  import { FsSafeError } from "./errors.js";
@@ -8,6 +8,7 @@ import { hashFileHandle } from "./file-hash.js";
8
8
  import { sameFileIdentity, sameFileIdentityForCleanup, } from "./file-identity.js";
9
9
  import { syncFileBestEffortSync } from "./file-sync.js";
10
10
  import { getNativeBinding, requireNativeBinding } from "./native.js";
11
+ import { captureNativeFdClose } from "./native-binding.js";
11
12
  import { resolveReadOpenFlags } from "./read-open-flags.js";
12
13
  import { directorySyncFailure, publicationFailure, rememberCreatedTarget, } from "./publish-file-failure.js";
13
14
  import { admitStandalonePublicationPath } from "./standalone-publication-path.js";
@@ -54,6 +55,7 @@ async function assertPinnedSourceCurrent(params) {
54
55
  }
55
56
  async function copyPinnedSource(params) {
56
57
  if (params.native && params.targetNativeParent) {
58
+ const closeFd = captureNativeFdClose(params.native);
57
59
  for (const method of ["clone", "copy-file-range"]) {
58
60
  let nativeFd;
59
61
  try {
@@ -95,7 +97,7 @@ async function copyPinnedSource(params) {
95
97
  const hashed = await hashFileHandle(target, params.native);
96
98
  const completedFd = nativeFd;
97
99
  nativeFd = undefined;
98
- fsSync.closeSync(completedFd);
100
+ closeFd(completedFd);
99
101
  return {
100
102
  handle: target,
101
103
  exactIdentity: opened,
@@ -109,7 +111,7 @@ async function copyPinnedSource(params) {
109
111
  }
110
112
  finally {
111
113
  if (nativeFd !== undefined)
112
- fsSync.closeSync(nativeFd);
114
+ closeFd(nativeFd);
113
115
  }
114
116
  }
115
117
  }
@@ -1 +1 @@
1
- {"version":3,"file":"root-directory-creation.d.ts","sourceRoot":"","sources":["../src/root-directory-creation.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAEtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAoDrD;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,WAAW,EACjB,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,4BAA4B,GAC9C,OAAO,CAAC,OAAO,CAAC,CAoGlB;AAED,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,WAAW,EACjB,UAAU,EAAE,MAAM,EAClB,oBAAoB,CAAC,EAAE,MAAM,IAAI,EACjC,iBAAiB,CAAC,EAAE,4BAA4B,GAC/C,OAAO,CAAC,MAAM,CAAC,CA2BjB;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAChD,oBAAoB,CAAC,EAAE,MAAM,IAAI,EACjC,cAAc,UAAQ,EACtB,iBAAiB,CAAC,EAAE,4BAA4B,GAC/C,OAAO,CAAC,IAAI,CAAC,CAuBf"}
1
+ {"version":3,"file":"root-directory-creation.d.ts","sourceRoot":"","sources":["../src/root-directory-creation.ts"],"names":[],"mappings":"AAkBA,OAAO,KAAK,EAAE,4BAA4B,EAAE,MAAM,mBAAmB,CAAC;AAEtE,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC;AAuDrD;;;GAGG;AACH,wBAAsB,qBAAqB,CACzC,IAAI,EAAE,WAAW,EACjB,UAAU,EAAE,MAAM,EAClB,iBAAiB,EAAE,4BAA4B,GAC9C,OAAO,CAAC,OAAO,CAAC,CAoGlB;AAED,wBAAsB,sBAAsB,CAC1C,IAAI,EAAE,WAAW,EACjB,UAAU,EAAE,MAAM,EAClB,oBAAoB,CAAC,EAAE,MAAM,IAAI,EACjC,iBAAiB,CAAC,EAAE,4BAA4B,GAC/C,OAAO,CAAC,MAAM,CAAC,CA6BjB;AAED,wBAAsB,iBAAiB,CACrC,IAAI,EAAE,WAAW,EACjB,QAAQ,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,QAAQ,EAAE,MAAM,CAAA;CAAE,EAChD,oBAAoB,CAAC,EAAE,MAAM,IAAI,EACjC,cAAc,UAAQ,EACtB,iBAAiB,CAAC,EAAE,4BAA4B,GAC/C,OAAO,CAAC,IAAI,CAAC,CAyBf"}
@@ -8,9 +8,10 @@ import { hasNodeErrorCode } from "./path.js";
8
8
  import { checkedMutationDirectory, } from "./pinned-mutation-observation.js";
9
9
  import { admitPathInsideRoot } from "./root-boundary.js";
10
10
  import { assertFinalSymlinkRejected } from "./root-symlink-policy.js";
11
+ import { canReuseParentWithMutationAssertion } from "./root-write-lock-binding.js";
11
12
  import { getFsSafeTestHooks } from "./test-hooks.js";
12
- function mutationWalkOptions(mutationAdmission, operationTarget, assertBeforeMutation) {
13
- const session = assertBeforeMutation === undefined
13
+ function mutationWalkOptions(mutationAdmission, operationTarget, assertBeforeMutation, rootPath, targetPath) {
14
+ const session = canReuseParentWithMutationAssertion(assertBeforeMutation, rootPath, targetPath)
14
15
  ? mutationAdmission.beginSharedParentWalk?.()
15
16
  : undefined;
16
17
  return {
@@ -173,7 +174,7 @@ export async function prepareRootWriteTarget(root, targetPath, assertBeforeMutat
173
174
  assertBeforeMutation,
174
175
  };
175
176
  const mutationWalk = mutationAdmission
176
- ? mutationWalkOptions(mutationAdmission, (prospectiveParent) => path.join(prospectiveParent, basename), assertBeforeMutation)
177
+ ? mutationWalkOptions(mutationAdmission, (prospectiveParent) => path.join(prospectiveParent, basename), assertBeforeMutation, root.rootReal, targetPath)
177
178
  : undefined;
178
179
  let parentPath;
179
180
  try {
@@ -197,7 +198,7 @@ export async function mkdirPathFallback(root, resolved, assertBeforeMutation, re
197
198
  beforeComponent: async (componentPath) => await getFsSafeTestHooks()?.beforeRootFallbackMutation?.("mkdir", componentPath),
198
199
  };
199
200
  const mutationWalk = mutationAdmission
200
- ? mutationWalkOptions(mutationAdmission, (prospectiveDirectory) => prospectiveDirectory, assertBeforeMutation)
201
+ ? mutationWalkOptions(mutationAdmission, (prospectiveDirectory) => prospectiveDirectory, assertBeforeMutation, root.rootReal, resolved.resolved)
201
202
  : undefined;
202
203
  try {
203
204
  await mkdirPathComponentsWithGuards(mutationWalk ? {
@@ -1 +1 @@
1
- {"version":3,"file":"root-impl.d.ts","sourceRoot":"","sources":["../src/root-impl.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"root-impl.d.ts","sourceRoot":"","sources":["../src/root-impl.ts"],"names":[],"mappings":"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"}
package/dist/root-impl.js CHANGED
@@ -94,7 +94,8 @@ import { verifyAtomicWriteResult } from "./root-write-verification.js";
94
94
  import { assertRootWritePathSelectionSync, assertRootWriteSelectionSync, createRootWriteSelectionForFd, prepareGuardedRootWritePathSelection, resolveGuardedWritePathInRoot, resolveGuardedWriteTargetInRoot, resolvePinnedWriteTargetInRoot, refreshRetainedRootWriteAdmission, refreshRootWritePathSelection, retainRootWriteSelection, takeRootWriteSelection, } from "./root-write-admission.js";
95
95
  import { prepareSharedRootWriteTarget } from "./root-write-complete-parent.js";
96
96
  import { finishRootFallbackWrite } from "./root-write-publication.js";
97
- import { assertRootFallbackWritePath, withRootFallbackCompatibilityLock } from "./root-write-compatibility.js";
97
+ import { withRootFallbackCompatibilityLock } from "./root-write-compatibility.js";
98
+ import { assertRootFallbackWritePath } from "./root-write-lock-binding.js";
98
99
  import { inspectFileIdentity, inspectFileIdentitySync } from "./strict-file-identity.js";
99
100
  import { movePathNoReplaceNative } from "./root-move-noreplace.js";
100
101
  import { admitRootReadHandle, inspectOpenedPathIdentitySync } from "./root-read-admission.js";
@@ -1 +1 @@
1
- {"version":3,"file":"root-path-existing.d.ts","sourceRoot":"","sources":["../src/root-path-existing.ts"],"names":[],"mappings":"AAWA,OAAO,EAAuB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAEpF,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAarE;AAED,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,EACzB,OAAO,GAAE;IACP,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,oBAAoB,CAAC;CAChC,GACL,MAAM,GAAG,SAAS,CAqDpB;AAkBD,wBAAsB,8BAA8B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkCxF;AAED,wBAAgB,kCAAkC,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAqC7E"}
1
+ {"version":3,"file":"root-path-existing.d.ts","sourceRoot":"","sources":["../src/root-path-existing.ts"],"names":[],"mappings":"AAWA,OAAO,EAAuB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAEpF,wBAAgB,2BAA2B,CAAC,SAAS,EAAE,MAAM,GAAG,MAAM,CAarE;AAED,wBAAgB,8BAA8B,CAC5C,SAAS,EAAE,MAAM,EACjB,iBAAiB,EAAE,MAAM,EACzB,OAAO,GAAE;IACP,cAAc,CAAC,EAAE,OAAO,CAAC;IACzB,kBAAkB,CAAC,EAAE,OAAO,CAAC;IAC7B,YAAY,CAAC,EAAE,oBAAoB,CAAC;CAChC,GACL,MAAM,GAAG,SAAS,CAqDpB;AAiBD,wBAAsB,8BAA8B,CAAC,UAAU,EAAE,MAAM,GAAG,OAAO,CAAC,MAAM,CAAC,CAkCxF;AAED,wBAAgB,kCAAkC,CAAC,UAAU,EAAE,MAAM,GAAG,MAAM,CAqC7E"}
@@ -86,8 +86,7 @@ function isFilesystemRoot(candidate) {
86
86
  }
87
87
  async function pathExists(targetPath) {
88
88
  try {
89
- fs.lstatSync(pathForWindowsFilesystem(targetPath));
90
- return true;
89
+ return fs.lstatSync(pathForWindowsFilesystem(targetPath), { throwIfNoEntry: false }) !== undefined;
91
90
  }
92
91
  catch (error) {
93
92
  if (isNotFoundPathError(error)) {
@@ -1,5 +1,4 @@
1
- import { type RootBoundaryIdentity } from "./root-boundary.js";
2
- export declare function assertRootFallbackWritePath(expected: string | undefined, actual: string): void;
1
+ import type { RootBoundaryIdentity } from "./root-boundary.js";
3
2
  export declare function withRootFallbackCompatibilityLock<T>(params: {
4
3
  rootPath: string;
5
4
  targetPath: string;
@@ -1 +1 @@
1
- {"version":3,"file":"root-write-compatibility.d.ts","sourceRoot":"","sources":["../src/root-write-compatibility.ts"],"names":[],"mappings":"AAIA,OAAO,EAAuB,KAAK,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AA6CpF,wBAAgB,2BAA2B,CAAC,QAAQ,EAAE,MAAM,GAAG,SAAS,EAAE,MAAM,EAAE,MAAM,GAAG,IAAI,CAI9F;AAED,wBAAsB,iCAAiC,CAAC,CAAC,EACvD,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,oBAAoB,CAAC;IAAC,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,EACxH,GAAG,EAAE,CAAC,OAAO,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,oBAAoB,EAAE,MAAM,IAAI,CAAA;CAAE,KAAK,OAAO,CAAC,CAAC,CAAC,GAC3G,OAAO,CAAC,CAAC,CAAC,CAkBZ"}
1
+ {"version":3,"file":"root-write-compatibility.d.ts","sourceRoot":"","sources":["../src/root-write-compatibility.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,oBAAoB,EAAE,MAAM,oBAAoB,CAAC;AAK/D,wBAAsB,iCAAiC,CAAC,CAAC,EACvD,MAAM,EAAE;IAAE,QAAQ,EAAE,MAAM,CAAC;IAAC,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,CAAC,EAAE,oBAAoB,CAAC;IAAC,oBAAoB,CAAC,EAAE,MAAM,IAAI,CAAA;CAAE,EACxH,GAAG,EAAE,CAAC,OAAO,EAAE;IAAE,UAAU,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,oBAAoB,EAAE,MAAM,IAAI,CAAA;CAAE,KAAK,OAAO,CAAC,CAAC,CAAC,GAC3G,OAAO,CAAC,CAAC,CAAC,CAkBZ"}