@homeflare/alchemy 0.37.3 → 0.37.5

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.
@@ -1 +1 @@
1
- {"version":3,"file":"directory-lifecycle.d.ts","sourceRoot":"","sources":["../../src/linux/directory-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,KAAK,UAAU,EAAgB,MAAM,sBAAsB,CAAC;AAErE,MAAM,WAAW,kBAAkB;IACjC,6FAA6F;IAC7F,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,eAAO,MAAM,gBAAgB,MAAQ,CAAC;AAEtC,eAAO,MAAM,MAAM,SAAU,MAAM,WAAW,MAAM,KAAG,KACN,CAAC;AAYlD,eAAO,MAAM,iBAAiB,UAAW,kBAAkB,KAAG,MAAM,EAMnE,CAAC;AA2BF,eAAO,MAAM,aAAa,WAChB,UAAU,QACZ,MAAM,KACX,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAI7C,CAAC;AAeF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,WACrB,UAAU,SACX,kBAAkB,WAChB,uBAAuB,sBAE/B,OAAO,CAAC,uBAAuB,CAwDjC,CAAC;AAYF;;;;GAIG;AACH,eAAO,MAAM,aAAa,WAChB,UAAU,QACZ,kBAAkB,UAChB,uBAAuB,KAC9B,OAAO,CAAC,IAAI,CAed,CAAC;AAEF,mGAAmG;AACnG,eAAO,MAAM,eAAe,WAClB,UAAU,UACV,uBAAuB,KAC9B,OAAO,CAAC,IAAI,CAMd,CAAC"}
1
+ {"version":3,"file":"directory-lifecycle.d.ts","sourceRoot":"","sources":["../../src/linux/directory-lifecycle.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;GAYG;AACH,OAAO,KAAK,EAAE,IAAI,EAAE,MAAM,cAAc,CAAC;AAEzC,OAAO,EAAE,KAAK,UAAU,EAAgB,MAAM,sBAAsB,CAAC;AAErE,MAAM,WAAW,kBAAkB;IACjC,6FAA6F;IAC7F,IAAI,EAAE,MAAM,CAAC;IACb,sCAAsC;IACtC,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,uEAAuE;IACvE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;IACxB,sEAAsE;IACtE,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC;CACzB;AAED,MAAM,WAAW,uBAAuB;IACtC,IAAI,EAAE,MAAM,CAAC;IACb,IAAI,EAAE,MAAM,CAAC;IACb,GAAG,EAAE,MAAM,CAAC;IACZ,GAAG,EAAE,MAAM,CAAC;CACb;AAED,eAAO,MAAM,gBAAgB,MAAQ,CAAC;AAEtC,eAAO,MAAM,MAAM,SAAU,MAAM,WAAW,MAAM,KAAG,KACN,CAAC;AAYlD,eAAO,MAAM,iBAAiB,UAAW,kBAAkB,KAAG,MAAM,EAMnE,CAAC;AA2BF,eAAO,MAAM,aAAa,WAChB,UAAU,QACZ,MAAM,KACX,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAI7C,CAAC;AA0BF;;;;GAIG;AACH,eAAO,MAAM,kBAAkB,WACrB,UAAU,SACX,kBAAkB,WAChB,uBAAuB,sBAE/B,OAAO,CAAC,uBAAuB,CAyDjC,CAAC;AAYF;;;;GAIG;AACH,eAAO,MAAM,aAAa,WAChB,UAAU,QACZ,kBAAkB,UAChB,uBAAuB,KAC9B,OAAO,CAAC,IAAI,CAed,CAAC;AAEF,mGAAmG;AACnG,eAAO,MAAM,eAAe,WAClB,UAAU,UACV,uBAAuB,KAC9B,OAAO,CAAC,IAAI,CAMd,CAAC"}
@@ -0,0 +1,14 @@
1
+ /**
2
+ * The directory a read may stat.
3
+ *
4
+ * ⛔ A `creating` ROW CAN HAVE NO PATH. With `path: Output.interpolate`, Apply commits the row
5
+ * while the path is still an Output, so the next plan's recovery read is asked with `path`
6
+ * missing. `runner.stat` of that value throws `path must be a string` and the plan never
7
+ * finishes — the same brick `binary-read.ts` already closes for `Release.Binary`. A recovery
8
+ * (`recovering`) returns undefined and the create is re-driven. A probe with a missing path
9
+ * still fails, as a message, before any host call.
10
+ */
11
+ import type { HostRunner } from '../launchd/runner.ts';
12
+ import { type HostDirectoryAttributes } from './directory-lifecycle.ts';
13
+ export declare const readInterruptedDirectory: (runner: HostRunner, path: unknown, recovering: boolean) => Promise<HostDirectoryAttributes | undefined>;
14
+ //# sourceMappingURL=directory-read.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"directory-read.d.ts","sourceRoot":"","sources":["../../src/linux/directory-read.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AACH,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,sBAAsB,CAAC;AACvD,OAAO,EAAE,KAAK,uBAAuB,EAAiB,MAAM,0BAA0B,CAAC;AAEvF,eAAO,MAAM,wBAAwB,WAC3B,UAAU,QACZ,OAAO,cACD,OAAO,KAClB,OAAO,CAAC,uBAAuB,GAAG,SAAS,CAM7C,CAAC"}
@@ -3,9 +3,11 @@
3
3
  *
4
4
  * ⚠️ NOTHING IS ADOPTED WITHOUT `--adopt`: a directory already at the path reads as `Unowned`, and
5
5
  * where the plan never asked, reconcile honours the same flag (docs/ownership.md).
6
- * ★ IT IS NOT LINUX-ONLY. `mkdir`, `chmod`, `chown` and `rmdir` are the same argv on macOS, so this
7
- * resource works through any HostRunner; it lives in the linux subpath because the gap it closes
8
- * was found there (a first deploy into a new tree, which every file resource refuses to create).
6
+ * ★ IT IS NOT LINUX-ONLY. It lives in the linux subpath because the gap it closes was found
7
+ * there (a first deploy into a new tree, which every file resource refuses to create).
8
+ * ⚠️ mkdir AND rmdir TAKE `--` ON macOS. chmod AND chown DO NOT: measured 2026-09-24,
9
+ * `/bin/chmod` and `/usr/sbin/chown` treat `--` as a filename and exit 1. The lifecycle
10
+ * omits that token for those two on Darwin.
9
11
  */
10
12
  import { Resource } from 'alchemy';
11
13
  import * as Provider from 'alchemy/Provider';
@@ -1 +1 @@
1
- {"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../../src/linux/directory.ts"],"names":[],"mappings":"AAAA;;;;;;;;GAQG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAG7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAGzD,OAAO,KAAK,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAQ5F,YAAY,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE5F,MAAM,WAAW,aAAc,SAAQ,QAAQ,CAC7C,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,CACxB;CAAG;AAEJ,eAAO,MAAM,aAAa,gDAA4C,CAAC;AAEvE,eAAO,MAAM,qBAAqB,gGAkC/B,CAAC"}
1
+ {"version":3,"file":"directory.d.ts","sourceRoot":"","sources":["../../src/linux/directory.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;GAUG;AACH,OAAO,EAAE,QAAQ,EAAE,MAAM,SAAS,CAAC;AAGnC,OAAO,KAAK,QAAQ,MAAM,kBAAkB,CAAC;AAG7C,OAAO,EAAE,iBAAiB,EAAE,MAAM,sBAAsB,CAAC;AAIzD,OAAO,KAAK,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAI5F,YAAY,EAAE,uBAAuB,EAAE,kBAAkB,EAAE,MAAM,0BAA0B,CAAC;AAE5F,MAAM,WAAW,aAAc,SAAQ,QAAQ,CAC7C,gBAAgB,EAChB,kBAAkB,EAClB,uBAAuB,CACxB;CAAG;AAEJ,eAAO,MAAM,aAAa,gDAA4C,CAAC;AAEvE,eAAO,MAAM,qBAAqB,gGA+C/B,CAAC"}
@@ -326,6 +326,7 @@ var readDirectory = async (runner, path) => {
326
326
  return { gid: stat.gid, mode: stat.mode, path, uid: stat.uid };
327
327
  };
328
328
  var octal = (mode) => mode.toString(8).padStart(3, "0");
329
+ var chmodChownEnd = () => process.platform === "darwin" ? [] : ["--"];
329
330
  var must = async (runner, path, argv) => {
330
331
  const result = await runner.exec(argv);
331
332
  if (result.exitCode !== 0) {
@@ -355,11 +356,11 @@ var reconcileDirectory = async (runner, props, output, adopt = false) => {
355
356
  }
356
357
  await must(runner, props.path, ["mkdir", "-m", octal(want.mode), "--", props.path]);
357
358
  } else if (stat.mode !== want.mode) {
358
- await must(runner, props.path, ["chmod", octal(want.mode), "--", props.path]);
359
+ await must(runner, props.path, ["chmod", octal(want.mode), ...chmodChownEnd(), props.path]);
359
360
  }
360
361
  const owner = ownerMatches({ gid: stat?.gid ?? -1, mode: 0, path: props.path, uid: stat?.uid ?? -1 }, want) ? undefined : ownerArg(want);
361
362
  if (owner !== undefined)
362
- await must(runner, props.path, ["chown", owner, "--", props.path]);
363
+ await must(runner, props.path, ["chown", owner, ...chmodChownEnd(), props.path]);
363
364
  const after = await readDirectory(runner, props.path);
364
365
  if (after === undefined || after.mode !== want.mode || !ownerMatches(after, want)) {
365
366
  throw refuse(props.path, "the directory on the host does not match the declaration");
@@ -392,17 +393,33 @@ var deleteDirectory = async (runner, output) => {
392
393
  await must(runner, output.path, ["rmdir", "--", output.path]);
393
394
  };
394
395
 
396
+ // src/linux/directory-read.ts
397
+ var readInterruptedDirectory = (runner, path, recovering) => {
398
+ if (typeof path !== "string") {
399
+ if (recovering)
400
+ return Promise.resolve(undefined);
401
+ return Promise.reject(new Error("Host.Directory path must be a string"));
402
+ }
403
+ return readDirectory(runner, path);
404
+ };
405
+
395
406
  // src/linux/directory.ts
396
407
  var HostDirectory = Resource("Host.Directory");
397
408
  var HostDirectoryProvider = () => Provider.effect(HostDirectory, Effect6.gen(function* () {
398
409
  const runner = yield* HostRunnerService;
399
410
  return HostDirectory.Provider.of({
400
411
  list: () => Effect6.succeed([]),
401
- read: ({ olds, output }) => lift(async () => {
402
- const found = await readDirectory(runner, olds.path);
403
- if (found === undefined)
404
- return;
405
- return output === undefined ? Unowned2(found) : found;
412
+ read: ({ fqn, instanceId, olds, output }) => Effect6.gen(function* () {
413
+ const recovering = typeof olds.path === "string" ? false : (yield* recordedGeneration(fqn, instanceId)) !== undefined;
414
+ if (recovering) {
415
+ yield* Effect6.logWarning(`${fqn}: the interrupted create's row has no directory path; nothing is recovered, ` + "and the create is re-driven with the declaration as it is now");
416
+ }
417
+ return yield* lift(async () => {
418
+ const found = await readInterruptedDirectory(runner, olds.path, recovering);
419
+ if (found === undefined)
420
+ return;
421
+ return output === undefined ? Unowned2(found) : found;
422
+ });
406
423
  }),
407
424
  diff: ({ instanceId, news, output }) => {
408
425
  if (output === undefined)
@@ -3115,5 +3132,5 @@ export {
3115
3132
  sshSudoRunner
3116
3133
  };
3117
3134
 
3118
- //# debugId=6500D35B9B72590F64756E2164756E21
3135
+ //# debugId=F28A7095F5BC6E5964756E2164756E21
3119
3136
  //# sourceMappingURL=index.js.map