Commit a994e01

Anton Golub <antongolub@antongolub.com>
2025-07-23 14:50:12
refactor: rearrange core internals (#1282)
1 parent e3f043a
build/core.cjs
@@ -38,14 +38,14 @@ __export(core_exports, {
   within: () => within
 });
 module.exports = __toCommonJS(core_exports);
-var import_node_child_process = require("child_process");
 var import_node_async_hooks = require("async_hooks");
+var import_node_buffer = require("buffer");
+var import_node_child_process = __toESM(require("child_process"), 1);
+var import_node_events = require("events");
 var import_node_fs = __toESM(require("fs"), 1);
-var import_node_util2 = require("util");
 var import_node_os = require("os");
-var import_node_events = require("events");
-var import_node_buffer = require("buffer");
 var import_node_process2 = __toESM(require("process"), 1);
+var import_node_util2 = require("util");
 
 // src/error.ts
 var EXIT_CODES = {
@@ -242,10 +242,6 @@ var formatErrorDetails = (lines = [], lim = 20) => {
   return errors.slice(0, lim).join("\n") + (errors.length > lim ? "\n..." : "");
 };
 
-// src/core.ts
-var import_vendor_core2 = require("./vendor-core.cjs");
-var import_util = require("./util.cjs");
-
 // src/log.ts
 var import_vendor_core = require("./vendor-core.cjs");
 var import_node_util = require("util");
@@ -381,7 +377,8 @@ function formatCmd(cmd) {
 }
 
 // src/core.ts
-var child_process = __toESM(require("child_process"), 1);
+var import_vendor_core2 = require("./vendor-core.cjs");
+var import_util = require("./util.cjs");
 var import_node_path = __toESM(require("path"), 1);
 var os = __toESM(require("os"), 1);
 var import_vendor_core3 = require("./vendor-core.cjs");
@@ -407,13 +404,6 @@ var ENV_OPTS = /* @__PURE__ */ new Set([
   "postfix",
   "shell"
 ]);
-var storage = new import_node_async_hooks.AsyncLocalStorage();
-function getStore() {
-  return storage.getStore() || defaults;
-}
-function within(callback) {
-  return storage.run(__spreadValues({}, getStore()), callback);
-}
 var defaults = resolveDefaults({
   [CWD]: import_node_process2.default.cwd(),
   [SYNC]: false,
@@ -426,21 +416,26 @@ var defaults = resolveDefaults({
   quiet: false,
   detached: false,
   preferLocal: false,
-  spawn: import_node_child_process.spawn,
-  spawnSync: import_node_child_process.spawnSync,
+  spawn: import_node_child_process.default.spawn,
+  spawnSync: import_node_child_process.default.spawnSync,
   log,
   kill,
   killSignal: SIGTERM,
   timeoutSignal: SIGTERM
 });
+var storage = new import_node_async_hooks.AsyncLocalStorage();
 var snapshots = [];
 var delimiters = [];
+var getStore = () => storage.getStore() || defaults;
 var getSnapshot = (snapshot, from, cmd) => __spreadProps(__spreadValues({}, snapshot), {
   ac: snapshot.ac || new AbortController(),
   ee: new import_node_events.EventEmitter(),
   from,
   cmd
 });
+function within(callback) {
+  return storage.run(__spreadValues({}, getStore()), callback);
+}
 var $ = new Proxy(
   function(pieces, ...args) {
     const snapshot = getStore();
@@ -467,15 +462,16 @@ var $ = new Proxy(
     return pp.sync ? pp.output : pp;
   },
   {
-    set(_, key, value) {
-      const target = key in Function.prototype ? _ : getStore();
-      Reflect.set(target, key === "sync" ? SYNC : key, value);
+    set(t, key, value) {
+      Reflect.set(
+        key in Function.prototype ? t : getStore(),
+        key === "sync" ? SYNC : key,
+        value
+      );
       return true;
     },
-    get(_, key) {
-      if (key === "sync") return $({ sync: true });
-      const target = key in Function.prototype ? _ : getStore();
-      return Reflect.get(target, key);
+    get(t, key) {
+      return key === "sync" ? $({ sync: true }) : Reflect.get(key in Function.prototype ? t : getStore(), key);
     }
   }
 );
@@ -516,13 +512,14 @@ var _ProcessPromise = class _ProcessPromise extends Promise {
     const self = this;
     const $2 = self._snapshot;
     const id = self.id;
+    const cwd = (_b = $2.cwd) != null ? _b : $2[CWD];
     if ($2.preferLocal) {
       const dirs = $2.preferLocal === true ? [$2.cwd, $2[CWD]] : [$2.preferLocal].flat();
       $2.env = (0, import_util.preferLocalBin)($2.env, ...dirs);
     }
     this._zurk = (0, import_vendor_core2.exec)({
       cmd: self.fullCmd,
-      cwd: (_b = $2.cwd) != null ? _b : $2[CWD],
+      cwd,
       input: (_d = (_c = $2.input) == null ? void 0 : _c.stdout) != null ? _d : $2.input,
       stdin: self._stdin,
       sync: self.sync,
@@ -618,7 +615,7 @@ var _ProcessPromise = class _ProcessPromise extends Promise {
       if (dest.isHalted() && this.isHalted()) {
         ee.once("start", () => from.pipe(dest.run()._stdin));
       } else {
-        this.catch((e) => dest.isNothrow() ? import_util.noop : dest._reject(e));
+        this.catch((e) => !dest.isNothrow() && dest._reject(e));
         from.pipe(dest.run()._stdin);
       }
       fillEnd();
@@ -1007,7 +1004,7 @@ function cd(dir) {
 function kill(_0) {
   return __async(this, arguments, function* (pid, signal = $.killSignal) {
     if (import_node_process2.default.platform === "win32" && (yield new Promise((resolve) => {
-      child_process.exec(`taskkill /pid ${pid} /t /f`, (err) => resolve(!err));
+      import_node_child_process.default.exec(`taskkill /pid ${pid} /t /f`, (err) => resolve(!err));
     })))
       return;
     for (const p of yield import_vendor_core2.ps.tree({ pid, recursive: true })) {
build/core.d.ts
@@ -1,14 +1,14 @@
 /// <reference types="node" />
 /// <reference types="fs-extra" />
 
-import { type ChildProcess, type IOType, type StdioOptions, spawn, spawnSync } from 'node:child_process';
+import { Buffer } from 'node:buffer';
+import cp, { type ChildProcess, type IOType, type StdioOptions } from 'node:child_process';
 import { type Encoding } from 'node:crypto';
 import { type Readable, type Writable } from 'node:stream';
 import { inspect } from 'node:util';
-import { Buffer } from 'node:buffer';
+import { log } from './log.js';
 import { type TSpawnStore } from './vendor-core.js';
 import { type Duration, quote } from './util.js';
-import { log } from './log.js';
 export { default as path } from 'node:path';
 export * as os from 'node:os';
 export { log, type LogEntry } from './log.js';
@@ -16,7 +16,6 @@ export { chalk, which, ps } from './vendor-core.js';
 export { type Duration, quote, quotePowerShell } from './util.js';
 declare const CWD: unique symbol;
 declare const SYNC: unique symbol;
-export declare function within<R>(callback: () => R): R;
 export interface Options {
     [CWD]: string;
     [SYNC]: boolean;
@@ -38,8 +37,8 @@ export interface Options {
     quiet: boolean;
     detached: boolean;
     preferLocal: boolean | string | string[];
-    spawn: typeof spawn;
-    spawnSync: typeof spawnSync;
+    spawn: typeof cp.spawn;
+    spawnSync: typeof cp.spawnSync;
     store?: TSpawnStore;
     log: typeof log;
     kill: typeof kill;
@@ -58,6 +57,7 @@ export interface Shell<S = false, R = S extends true ? ProcessOutput : ProcessPr
         (opts: Partial<Omit<Options, 'sync'>>): Shell<true>;
     };
 }
+export declare function within<R>(callback: () => R): R;
 export declare const $: Shell & Options;
 type ProcessStage = 'initial' | 'halted' | 'running' | 'fulfilled' | 'rejected';
 type Resolve = (out: ProcessOutput) => void;
src/core.ts
@@ -12,22 +12,21 @@
 // See the License for the specific language governing permissions and
 // limitations under the License.
 
-import {
+import { type AsyncHook, AsyncLocalStorage, createHook } from 'node:async_hooks'
+import { Buffer } from 'node:buffer'
+import cp, {
   type ChildProcess,
   type IOType,
   type StdioOptions,
-  spawn,
-  spawnSync,
 } from 'node:child_process'
 import { type Encoding } from 'node:crypto'
-import { type AsyncHook, AsyncLocalStorage, createHook } from 'node:async_hooks'
-import { type Readable, type Writable } from 'node:stream'
+import { EventEmitter } from 'node:events'
 import fs from 'node:fs'
-import { inspect } from 'node:util'
 import { EOL as _EOL } from 'node:os'
-import { EventEmitter } from 'node:events'
-import { Buffer } from 'node:buffer'
 import process from 'node:process'
+import { type Readable, type Writable } from 'node:stream'
+import { inspect } from 'node:util'
+
 import {
   formatErrorDetails,
   formatErrorMessage,
@@ -35,6 +34,7 @@ import {
   getCallerLocation,
   getExitCodeInfo,
 } from './error.ts'
+import { log } from './log.ts'
 import {
   exec,
   buildCmd,
@@ -63,8 +63,6 @@ import {
   randomId,
   bufArrJoin,
 } from './util.ts'
-import { log } from './log.ts'
-import * as child_process from 'node:child_process'
 
 export { default as path } from 'node:path'
 export * as os from 'node:os'
@@ -93,15 +91,7 @@ const ENV_OPTS: Set<string> = new Set([
   'postfix',
   'shell',
 ])
-const storage = new AsyncLocalStorage<Options>()
-
-function getStore() {
-  return storage.getStore() || defaults
-}
 
-export function within<R>(callback: () => R): R {
-  return storage.run({ ...getStore() }, callback)
-}
 // prettier-ignore
 export interface Options {
   [CWD]:          string
@@ -124,8 +114,8 @@ export interface Options {
   quiet:          boolean
   detached:       boolean
   preferLocal:    boolean | string | string[]
-  spawn:          typeof spawn
-  spawnSync:      typeof spawnSync
+  spawn:          typeof cp.spawn
+  spawnSync:      typeof cp.spawnSync
   store?:         TSpawnStore
   log:            typeof log
   kill:           typeof kill
@@ -147,14 +137,21 @@ export const defaults: Options = resolveDefaults({
   quiet:          false,
   detached:       false,
   preferLocal:    false,
-  spawn,
-  spawnSync,
+  spawn:          cp.spawn,
+  spawnSync:      cp.spawnSync,
   log,
   kill,
   killSignal:     SIGTERM,
   timeoutSignal:  SIGTERM,
 })
 
+type Snapshot = Options & {
+  from: string
+  cmd: string
+  ee: EventEmitter
+  ac: AbortController
+}
+
 // prettier-ignore
 export interface Shell<
   S = false,
@@ -167,15 +164,13 @@ export interface Shell<
     (opts: Partial<Omit<Options, 'sync'>>): Shell<true>
   }
 }
+
+// Internal storages
+const storage = new AsyncLocalStorage<Options>()
 const snapshots: Snapshot[] = []
 const delimiters: Options['delimiter'][] = []
 
-type Snapshot = Options & {
-  from: string
-  cmd: string
-  ee: EventEmitter
-  ac: AbortController
-}
+const getStore = () => storage.getStore() || defaults
 
 const getSnapshot = (
   snapshot: Options,
@@ -189,6 +184,11 @@ const getSnapshot = (
   cmd,
 })
 
+export function within<R>(callback: () => R): R {
+  return storage.run({ ...getStore() }, callback)
+}
+
+// The zx
 export const $: Shell & Options = new Proxy<Shell & Options>(
   function (pieces: TemplateStringsArray | Partial<Options>, ...args: any[]) {
     const snapshot = getStore()
@@ -219,17 +219,18 @@ export const $: Shell & Options = new Proxy<Shell & Options>(
     return pp.sync ? pp.output : pp
   } as Shell & Options,
   {
-    set(_, key, value) {
-      const target = key in Function.prototype ? _ : getStore()
-      Reflect.set(target, key === 'sync' ? SYNC : key, value)
-
+    set(t, key, value) {
+      Reflect.set(
+        key in Function.prototype ? t : getStore(),
+        key === 'sync' ? SYNC : key,
+        value
+      )
       return true
     },
-    get(_, key) {
-      if (key === 'sync') return $({ sync: true })
-
-      const target = key in Function.prototype ? _ : getStore()
-      return Reflect.get(target, key)
+    get(t, key) {
+      return key === 'sync'
+        ? $({ sync: true })
+        : Reflect.get(key in Function.prototype ? t : getStore(), key)
     },
   }
 )
@@ -288,6 +289,7 @@ export class ProcessPromise extends Promise<ProcessOutput> {
     const self = this
     const $ = self._snapshot
     const id = self.id
+    const cwd = $.cwd ?? $[CWD]
 
     if ($.preferLocal) {
       const dirs =
@@ -298,7 +300,7 @@ export class ProcessPromise extends Promise<ProcessOutput> {
     // prettier-ignore
     this._zurk = exec({
       cmd:      self.fullCmd,
-      cwd:      $.cwd ?? $[CWD],
+      cwd,
       input:    ($.input as ProcessPromise | ProcessOutput)?.stdout ?? $.input,
       stdin:    self._stdin,
       sync:     self.sync,
@@ -424,7 +426,7 @@ export class ProcessPromise extends Promise<ProcessOutput> {
       if (dest.isHalted() && this.isHalted()) {
         ee.once('start', () => from.pipe(dest.run()._stdin))
       } else {
-        this.catch((e) => (dest.isNothrow() ? noop : dest._reject(e)))
+        this.catch((e) => !dest.isNothrow() && dest._reject(e))
         from.pipe(dest.run()._stdin)
       }
       fillEnd()
@@ -934,7 +936,7 @@ export async function kill(pid: number, signal = $.killSignal) {
   if (
     process.platform === 'win32' &&
     (await new Promise((resolve) => {
-      child_process.exec(`taskkill /pid ${pid} /t /f`, (err) => resolve(!err))
+      cp.exec(`taskkill /pid ${pid} /t /f`, (err) => resolve(!err))
     }))
   )
     return
.size-limit.json
@@ -15,7 +15,7 @@
       "README.md",
       "LICENSE"
     ],
-    "limit": "121.20 kB",
+    "limit": "121.15 kB",
     "brotli": false,
     "gzip": false
   },
@@ -29,7 +29,7 @@
       "build/globals.js",
       "build/deno.js"
     ],
-    "limit": "812.20 kB",
+    "limit": "812.10 kB",
     "brotli": false,
     "gzip": false
   },
@@ -62,7 +62,7 @@
       "README.md",
       "LICENSE"
     ],
-    "limit": "868.002 kB",
+    "limit": "867.95 kB",
     "brotli": false,
     "gzip": false
   }