@zthun/crumbtrail-cli 2.4.9 → 2.4.11
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/dist/cli.cjs +1 -1
- package/dist/cli.cjs.map +1 -1
- package/dist/cli.js +1 -1
- package/dist/cli.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.js +1 -1
- package/dist/{watch-E8sN7ITE.cjs → watch-DXvYTgIr.cjs} +2 -8
- package/dist/{watch-E8sN7ITE.cjs.map → watch-DXvYTgIr.cjs.map} +1 -1
- package/dist/{watch-CzQSbX_I.js → watch-peSooqy2.js} +1 -1
- package/dist/{watch-CzQSbX_I.js.map → watch-peSooqy2.js.map} +1 -1
- package/package.json +13 -13
package/dist/cli.cjs
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
const require_watch = require("./watch-
|
|
2
|
+
const require_watch = require("./watch-DXvYTgIr.cjs");
|
|
3
3
|
let _zthun_crumbtrail_fs = require("@zthun/crumbtrail-fs");
|
|
4
4
|
let _zthun_lumberjacky_log = require("@zthun/lumberjacky-log");
|
|
5
5
|
let commander = require("commander");
|
package/dist/cli.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.cjs","names":["ZWatchDelay","ZLoggerConsole","ZLoggerSilent","Command","ZCrumbtrailNudge","ZCrumbtrailWatch","logger","console","application","name","description","command","isDefault","option","process","cwd","val","prev","concat","action","options","result","run","exitCode","v","Number","parseInt","log","silent","parse"],"sources":["../src/cli.mts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { ZWatchDelay } from \"@zthun/crumbtrail-fs\";\nimport { ZLoggerConsole, ZLoggerSilent } from \"@zthun/lumberjacky-log\";\nimport { Command } from \"commander\";\n\nimport type { IZCrumbtrailNudgeOptions } from \"./nudge/nudge.mjs\";\nimport { ZCrumbtrailNudge } from \"./nudge/nudge.mjs\";\nimport type { IZCrumbtrailWatchOptions } from \"./watch/watch.mjs\";\nimport { ZCrumbtrailWatch } from \"./watch/watch.mjs\";\n\nconst logger = new ZLoggerConsole(console);\nconst application = new Command();\n\napplication\n .name(\"crumbtrail-cli\")\n .description(\"Crumbtrail utilities for debugging\");\n\napplication\n .command(\"watch\", { isDefault: true })\n .description(\"Watch a directory and log changes\")\n .option(\"-d, --directory <dir>\", \"The directory to watch\", process.cwd())\n .option(\n \"-g, --glob <pattern>\",\n \"Glob pattern (repeatable)\",\n (val, prev: string[]) => prev.concat(val),\n [],\n )\n .action(async (options: IZCrumbtrailWatchOptions) => {\n const command = new ZCrumbtrailWatch(logger);\n const result = await command.run(options);\n process.exitCode = result;\n });\n\napplication\n .command(\"nudge\")\n .description(\"Touch directory timestamps to prompt a refresh\")\n .option(\"-d, --directory <path>\", \"Directory to refresh\", process.cwd())\n .option(\"--recursive\", \"Nudge all subdirectories as well\", false)\n .option(\"--silent\", \"Do not log any output. Nudge silently\", false)\n .option(\n \"-e, --every <ms>\",\n \"Time between nudges in milliseconds\",\n (v) => Number.parseInt(v, 10),\n ZWatchDelay,\n )\n .action(async (options: IZCrumbtrailNudgeOptions & { silent: boolean }) => {\n const log = options.silent ? new ZLoggerSilent() : logger;\n const command = new ZCrumbtrailNudge(log);\n process.exitCode = await command.run(options);\n });\n\napplication.parse();\n"],"mappings":";;;;;;AAWA,IAAMM,SAAS,IAAIL,uBAAAA,eAAeM,
|
|
1
|
+
{"version":3,"file":"cli.cjs","names":["ZWatchDelay","ZLoggerConsole","ZLoggerSilent","Command","ZCrumbtrailNudge","ZCrumbtrailWatch","logger","console","application","name","description","command","isDefault","option","process","cwd","val","prev","concat","action","options","result","run","exitCode","v","Number","parseInt","log","silent","parse"],"sources":["../src/cli.mts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { ZWatchDelay } from \"@zthun/crumbtrail-fs\";\nimport { ZLoggerConsole, ZLoggerSilent } from \"@zthun/lumberjacky-log\";\nimport { Command } from \"commander\";\n\nimport type { IZCrumbtrailNudgeOptions } from \"./nudge/nudge.mjs\";\nimport { ZCrumbtrailNudge } from \"./nudge/nudge.mjs\";\nimport type { IZCrumbtrailWatchOptions } from \"./watch/watch.mjs\";\nimport { ZCrumbtrailWatch } from \"./watch/watch.mjs\";\n\nconst logger = new ZLoggerConsole(console);\nconst application = new Command();\n\napplication\n .name(\"crumbtrail-cli\")\n .description(\"Crumbtrail utilities for debugging\");\n\napplication\n .command(\"watch\", { isDefault: true })\n .description(\"Watch a directory and log changes\")\n .option(\"-d, --directory <dir>\", \"The directory to watch\", process.cwd())\n .option(\n \"-g, --glob <pattern>\",\n \"Glob pattern (repeatable)\",\n (val, prev: string[]) => prev.concat(val),\n [],\n )\n .action(async (options: IZCrumbtrailWatchOptions) => {\n const command = new ZCrumbtrailWatch(logger);\n const result = await command.run(options);\n process.exitCode = result;\n });\n\napplication\n .command(\"nudge\")\n .description(\"Touch directory timestamps to prompt a refresh\")\n .option(\"-d, --directory <path>\", \"Directory to refresh\", process.cwd())\n .option(\"--recursive\", \"Nudge all subdirectories as well\", false)\n .option(\"--silent\", \"Do not log any output. Nudge silently\", false)\n .option(\n \"-e, --every <ms>\",\n \"Time between nudges in milliseconds\",\n (v) => Number.parseInt(v, 10),\n ZWatchDelay,\n )\n .action(async (options: IZCrumbtrailNudgeOptions & { silent: boolean }) => {\n const log = options.silent ? new ZLoggerSilent() : logger;\n const command = new ZCrumbtrailNudge(log);\n process.exitCode = await command.run(options);\n });\n\napplication.parse();\n"],"mappings":";;;;;;AAWA,IAAMM,SAAS,IAAIL,uBAAAA,eAAeM,OAAAA;AAClC,IAAMC,cAAc,IAAIL,UAAAA,QAAAA;AAExBK,YACGC,KAAK,gBAAA,EACLC,YAAY,oCAAA;AAEfF,YACGG,QAAQ,SAAS,EAAEC,WAAW,KAAK,CAAA,EACnCF,YAAY,mCAAA,EACZG,OAAO,yBAAyB,0BAA0BC,QAAQC,IAAG,CAAA,EACrEF,OACC,wBACA,8BACCG,KAAKC,SAAmBA,KAAKC,OAAOF,GAAAA,GACrC,CAAA,CAAE,EAEHG,OAAO,OAAOC,YAAAA;CAEb,MAAMC,SAAS,MAAMV,IADDN,cAAAA,iBAAiBC,MAChBK,EAAQW,IAAIF,OAAAA;CACjCN,QAAQS,WAAWF;AACrB,CAAA;AAEFb,YACGG,QAAQ,OAAA,EACRD,YAAY,gDAAA,EACZG,OAAO,0BAA0B,wBAAwBC,QAAQC,IAAG,CAAA,EACpEF,OAAO,eAAe,oCAAoC,KAAA,EAC1DA,OAAO,YAAY,0CAA0C,KAAA,EAC7DA,OACC,oBACA,wCACCW,MAAMC,OAAOC,SAASF,GAAG,EAAA,GAC1BxB,qBAAAA,WAAAA,EAEDmB,OAAO,OAAOC,YAAAA;CAEb,MAAMT,UAAU,IAAIP,cAAAA,iBADRgB,QAAQQ,SAAS,IAAI1B,uBAAAA,cAAAA,IAAkBI,MACdqB;CACrCb,QAAQS,WAAW,MAAMZ,QAAQW,IAAIF,OAAAA;AACvC,CAAA;AAEFZ,YAAYqB,MAAK"}
|
package/dist/cli.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import { n as ZCrumbtrailNudge, t as ZCrumbtrailWatch } from "./watch-
|
|
2
|
+
import { n as ZCrumbtrailNudge, t as ZCrumbtrailWatch } from "./watch-peSooqy2.js";
|
|
3
3
|
import { ZWatchDelay } from "@zthun/crumbtrail-fs";
|
|
4
4
|
import { ZLoggerConsole, ZLoggerSilent } from "@zthun/lumberjacky-log";
|
|
5
5
|
import { Command } from "commander";
|
package/dist/cli.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"cli.js","names":["ZWatchDelay","ZLoggerConsole","ZLoggerSilent","Command","ZCrumbtrailNudge","ZCrumbtrailWatch","logger","console","application","name","description","command","isDefault","option","process","cwd","val","prev","concat","action","options","result","run","exitCode","v","Number","parseInt","log","silent","parse"],"sources":["../src/cli.mts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { ZWatchDelay } from \"@zthun/crumbtrail-fs\";\nimport { ZLoggerConsole, ZLoggerSilent } from \"@zthun/lumberjacky-log\";\nimport { Command } from \"commander\";\n\nimport type { IZCrumbtrailNudgeOptions } from \"./nudge/nudge.mjs\";\nimport { ZCrumbtrailNudge } from \"./nudge/nudge.mjs\";\nimport type { IZCrumbtrailWatchOptions } from \"./watch/watch.mjs\";\nimport { ZCrumbtrailWatch } from \"./watch/watch.mjs\";\n\nconst logger = new ZLoggerConsole(console);\nconst application = new Command();\n\napplication\n .name(\"crumbtrail-cli\")\n .description(\"Crumbtrail utilities for debugging\");\n\napplication\n .command(\"watch\", { isDefault: true })\n .description(\"Watch a directory and log changes\")\n .option(\"-d, --directory <dir>\", \"The directory to watch\", process.cwd())\n .option(\n \"-g, --glob <pattern>\",\n \"Glob pattern (repeatable)\",\n (val, prev: string[]) => prev.concat(val),\n [],\n )\n .action(async (options: IZCrumbtrailWatchOptions) => {\n const command = new ZCrumbtrailWatch(logger);\n const result = await command.run(options);\n process.exitCode = result;\n });\n\napplication\n .command(\"nudge\")\n .description(\"Touch directory timestamps to prompt a refresh\")\n .option(\"-d, --directory <path>\", \"Directory to refresh\", process.cwd())\n .option(\"--recursive\", \"Nudge all subdirectories as well\", false)\n .option(\"--silent\", \"Do not log any output. Nudge silently\", false)\n .option(\n \"-e, --every <ms>\",\n \"Time between nudges in milliseconds\",\n (v) => Number.parseInt(v, 10),\n ZWatchDelay,\n )\n .action(async (options: IZCrumbtrailNudgeOptions & { silent: boolean }) => {\n const log = options.silent ? new ZLoggerSilent() : logger;\n const command = new ZCrumbtrailNudge(log);\n process.exitCode = await command.run(options);\n });\n\napplication.parse();\n"],"mappings":";;;;;;AAWA,IAAMM,SAAS,IAAIL,eAAeM,
|
|
1
|
+
{"version":3,"file":"cli.js","names":["ZWatchDelay","ZLoggerConsole","ZLoggerSilent","Command","ZCrumbtrailNudge","ZCrumbtrailWatch","logger","console","application","name","description","command","isDefault","option","process","cwd","val","prev","concat","action","options","result","run","exitCode","v","Number","parseInt","log","silent","parse"],"sources":["../src/cli.mts"],"sourcesContent":["#!/usr/bin/env node\n\nimport { ZWatchDelay } from \"@zthun/crumbtrail-fs\";\nimport { ZLoggerConsole, ZLoggerSilent } from \"@zthun/lumberjacky-log\";\nimport { Command } from \"commander\";\n\nimport type { IZCrumbtrailNudgeOptions } from \"./nudge/nudge.mjs\";\nimport { ZCrumbtrailNudge } from \"./nudge/nudge.mjs\";\nimport type { IZCrumbtrailWatchOptions } from \"./watch/watch.mjs\";\nimport { ZCrumbtrailWatch } from \"./watch/watch.mjs\";\n\nconst logger = new ZLoggerConsole(console);\nconst application = new Command();\n\napplication\n .name(\"crumbtrail-cli\")\n .description(\"Crumbtrail utilities for debugging\");\n\napplication\n .command(\"watch\", { isDefault: true })\n .description(\"Watch a directory and log changes\")\n .option(\"-d, --directory <dir>\", \"The directory to watch\", process.cwd())\n .option(\n \"-g, --glob <pattern>\",\n \"Glob pattern (repeatable)\",\n (val, prev: string[]) => prev.concat(val),\n [],\n )\n .action(async (options: IZCrumbtrailWatchOptions) => {\n const command = new ZCrumbtrailWatch(logger);\n const result = await command.run(options);\n process.exitCode = result;\n });\n\napplication\n .command(\"nudge\")\n .description(\"Touch directory timestamps to prompt a refresh\")\n .option(\"-d, --directory <path>\", \"Directory to refresh\", process.cwd())\n .option(\"--recursive\", \"Nudge all subdirectories as well\", false)\n .option(\"--silent\", \"Do not log any output. Nudge silently\", false)\n .option(\n \"-e, --every <ms>\",\n \"Time between nudges in milliseconds\",\n (v) => Number.parseInt(v, 10),\n ZWatchDelay,\n )\n .action(async (options: IZCrumbtrailNudgeOptions & { silent: boolean }) => {\n const log = options.silent ? new ZLoggerSilent() : logger;\n const command = new ZCrumbtrailNudge(log);\n process.exitCode = await command.run(options);\n });\n\napplication.parse();\n"],"mappings":";;;;;;AAWA,IAAMM,SAAS,IAAIL,eAAeM,OAAAA;AAClC,IAAMC,cAAc,IAAIL,QAAAA;AAExBK,YACGC,KAAK,gBAAA,EACLC,YAAY,oCAAA;AAEfF,YACGG,QAAQ,SAAS,EAAEC,WAAW,KAAK,CAAA,EACnCF,YAAY,mCAAA,EACZG,OAAO,yBAAyB,0BAA0BC,QAAQC,IAAG,CAAA,EACrEF,OACC,wBACA,8BACCG,KAAKC,SAAmBA,KAAKC,OAAOF,GAAAA,GACrC,CAAA,CAAE,EAEHG,OAAO,OAAOC,YAAAA;CAEb,MAAMC,SAAS,MAAMV,IADDN,iBAAiBC,MAChBK,EAAQW,IAAIF,OAAAA;CACjCN,QAAQS,WAAWF;AACrB,CAAA;AAEFb,YACGG,QAAQ,OAAA,EACRD,YAAY,gDAAA,EACZG,OAAO,0BAA0B,wBAAwBC,QAAQC,IAAG,CAAA,EACpEF,OAAO,eAAe,oCAAoC,KAAA,EAC1DA,OAAO,YAAY,0CAA0C,KAAA,EAC7DA,OACC,oBACA,wCACCW,MAAMC,OAAOC,SAASF,GAAG,EAAA,GAC1BxB,WAAAA,EAEDmB,OAAO,OAAOC,YAAAA;CAEb,MAAMT,UAAU,IAAIP,iBADRgB,QAAQQ,SAAS,IAAI1B,cAAAA,IAAkBI,MACdqB;CACrCb,QAAQS,WAAW,MAAMZ,QAAQW,IAAIF,OAAAA;AACvC,CAAA;AAEFZ,YAAYqB,MAAK"}
|
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
Object.defineProperty(exports, Symbol.toStringTag, { value: "Module" });
|
|
2
|
-
const require_watch = require("./watch-
|
|
2
|
+
const require_watch = require("./watch-DXvYTgIr.cjs");
|
|
3
3
|
exports.ZCrumbtrailNudge = require_watch.ZCrumbtrailNudge;
|
|
4
4
|
exports.ZCrumbtrailWatch = require_watch.ZCrumbtrailWatch;
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import { n as ZCrumbtrailNudge, t as ZCrumbtrailWatch } from "./watch-
|
|
1
|
+
import { n as ZCrumbtrailNudge, t as ZCrumbtrailWatch } from "./watch-peSooqy2.js";
|
|
2
2
|
export { ZCrumbtrailNudge, ZCrumbtrailWatch };
|
|
@@ -26,7 +26,7 @@ let _zthun_crumbtrail_fs = require("@zthun/crumbtrail-fs");
|
|
|
26
26
|
let _zthun_helpful_fn = require("@zthun/helpful-fn");
|
|
27
27
|
let _zthun_lumberjacky_log = require("@zthun/lumberjacky-log");
|
|
28
28
|
let fast_glob = require("fast-glob");
|
|
29
|
-
fast_glob = __toESM(fast_glob);
|
|
29
|
+
fast_glob = __toESM(fast_glob, 1);
|
|
30
30
|
let lodash_es = require("lodash-es");
|
|
31
31
|
let node_process = require("node:process");
|
|
32
32
|
let minimatch = require("minimatch");
|
|
@@ -222,11 +222,5 @@ Object.defineProperty(exports, "ZCrumbtrailWatch", {
|
|
|
222
222
|
return ZCrumbtrailWatch;
|
|
223
223
|
}
|
|
224
224
|
});
|
|
225
|
-
Object.defineProperty(exports, "__toESM", {
|
|
226
|
-
enumerable: true,
|
|
227
|
-
get: function() {
|
|
228
|
-
return __toESM;
|
|
229
|
-
}
|
|
230
|
-
});
|
|
231
225
|
|
|
232
|
-
//# sourceMappingURL=watch-
|
|
226
|
+
//# sourceMappingURL=watch-DXvYTgIr.cjs.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch-E8sN7ITE.cjs","names":["readdir","dirname","ZWatchDelay","firstTruthy","sleep","ZLogEntryBuilder","ZLoggerContext","glob","noop","ZCrumbtrailNudge","_controller","_resolve","_promise","_logger","logger","kill","abort","run","options","controller","AbortController","promise","resolve","Promise","withResolvers","directory","process","cwd","recursive","every","ms","log","info","message","build","warning","catch","onlyDirectories","signal","aborted","resolve","cwd","ZFileWatch","firstDefined","ZLogEntryBuilder","ZLoggerContext","uniq","minimatch","ZCrumbtrailWatch","_logger","_globs","_watch","_ready","Promise","_promise","_resolve","msg","info","message","build","add","path","remove","warning","update","watching","globs","slice","ready","logger","kill","stop","_handleFsEvent","entry","directory","some","g","log","_handleAdd","node","_handleRemove","_handleUpdate","run","args","promise","withResolvers","length","filter","join","subscribe","bind","start"],"sources":["../src/nudge/nudge.mts","../src/watch/watch.mts"],"sourcesContent":["import { readdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { ZWatchDelay } from \"@zthun/crumbtrail-fs\";\nimport { firstTruthy, sleep } from \"@zthun/helpful-fn\";\nimport type { IZLogger } from \"@zthun/lumberjacky-log\";\nimport { ZLogEntryBuilder, ZLoggerContext } from \"@zthun/lumberjacky-log\";\nimport glob from \"fast-glob\";\nimport { noop } from \"lodash-es\";\n\n/**\n * Options for the nudge command.\n */\nexport interface IZCrumbtrailNudgeOptions {\n /**\n * The directory to nudge.\n *\n * The default if not specified is the current working directory.\n */\n directory?: string;\n\n /**\n * Whether to nudge recursively.\n *\n * Warning: This can have severe CPU\n * usage for deep directories.\n *\n * Default is false.\n */\n recursive?: boolean;\n\n /**\n * The total number of milliseconds to wait\n * between nudges.\n *\n * Default is {@link ZWatchDelay}\n */\n every?: number;\n}\n\n/**\n * An operation to continuously nudge a directory.\n *\n * This is a special operation that lists the contents of a targeted parent directory.\n * The main reason for this is to work around an issue when you are running inside of\n * a container and your host is not linux.\n *\n * A lot of times, you will not receive events in this situation for add and update\n * until the virtual file bridge is refreshed by listing the outer directory contents.\n * This command helps to force the bridge to send file change events. You should\n * only need this if you are running on a non linux host inside a docker container.\n *\n * Run a separate container in the background and just nudge the directory\n * for however long you need.\n */\nexport class ZCrumbtrailNudge {\n private _controller?: AbortController;\n private _resolve?: (val: number) => void;\n private _promise?: Promise<number>;\n private readonly _logger: IZLogger;\n\n public constructor(logger: IZLogger) {\n this._logger = new ZLoggerContext(\"ZCrumbtrailNudge\", logger);\n }\n\n public async kill(): Promise<void> {\n this._controller?.abort();\n delete this._controller;\n\n await this._promise;\n delete this._promise;\n }\n\n public async run(options: IZCrumbtrailNudgeOptions = {}): Promise<number> {\n await this.kill();\n\n const controller = new AbortController();\n this._controller = controller;\n\n const { promise, resolve } = Promise.withResolvers<number>();\n this._promise = promise;\n this._resolve = resolve;\n\n const {\n directory = process.cwd(),\n recursive,\n every = ZWatchDelay,\n } = options;\n\n const ms = firstTruthy(ZWatchDelay, every);\n\n this._logger.log(\n new ZLogEntryBuilder()\n .info()\n .message(`Starting a nudge loop every ${ms} milliseconds`)\n .build(),\n );\n\n if (recursive) {\n this._logger.log(\n new ZLogEntryBuilder()\n .warning()\n .message(\"Nudging is recursive. Child folders will be nudged too.\")\n .build(),\n );\n }\n\n do {\n this._logger.log(\n new ZLogEntryBuilder()\n .info()\n .message(`Nudging ${directory} to refresh`)\n .build(),\n );\n await readdir(dirname(directory)).catch(noop);\n\n if (recursive) {\n await glob(`${directory}/**`, { onlyDirectories: true }).catch(noop);\n }\n\n await sleep(ms);\n } while (!controller.signal.aborted);\n\n resolve(0);\n delete this._resolve;\n\n return this._promise;\n }\n}\n","import { resolve } from \"node:path\";\nimport { cwd } from \"node:process\";\n\nimport type { IZFileSystemNode } from \"@zthun/crumbtrail-fs\";\nimport { ZFileWatch } from \"@zthun/crumbtrail-fs\";\nimport { firstDefined } from \"@zthun/helpful-fn\";\nimport type { IZLogEntry, IZLogger } from \"@zthun/lumberjacky-log\";\nimport { ZLogEntryBuilder, ZLoggerContext } from \"@zthun/lumberjacky-log\";\nimport { uniq } from \"lodash-es\";\nimport { minimatch } from \"minimatch\";\n\n/**\n * Arguments for the crumbtrail app.\n */\nexport interface IZCrumbtrailWatchOptions {\n /**\n * The directory to watch.\n *\n * If this is falsy, then the cwd is used.\n */\n directory?: string;\n\n /**\n * The list of file globs to watch.\n *\n * If this is falsy or empty, then '**' is used.\n */\n globs?: string[];\n}\n\n/**\n * The root application for the crumbtrail cli.\n */\nexport class ZCrumbtrailWatch {\n private _logger: IZLogger;\n private _globs: string[] | undefined;\n private _watch: ZFileWatch | undefined;\n private _ready: Promise<void> = Promise.resolve();\n private _promise: Promise<number> | undefined;\n private _resolve: ((value: number) => void) | undefined;\n\n /**\n * Gets the entry for a basic information message.\n *\n * @returns\n * The log entry for a basic information message.\n */\n public static msg(msg: string): IZLogEntry {\n return new ZLogEntryBuilder().info().message(msg).build();\n }\n\n /**\n * Gets the message for when a file is added.\n *\n * @returns\n * The message for when a file is added.\n */\n public static add(path: string): IZLogEntry {\n return new ZLogEntryBuilder().info().message(`Node added: ${path}`).build();\n }\n\n /**\n * Gets the message for when a file/folder is removed.\n *\n * @returns\n * The message for when a file/folder is added.\n */\n public static remove(path: string): IZLogEntry {\n return new ZLogEntryBuilder()\n .warning()\n .message(`Node removed: ${path}`)\n .build();\n }\n\n /**\n * Gets the message for when a file is updated.\n *\n * @returns\n * The message for when a file is updated.\n */\n public static update(path: string): IZLogEntry {\n return new ZLogEntryBuilder()\n .info()\n .message(`Node updated: ${path}`)\n .build();\n }\n\n /**\n * Gets the current directory being watched.\n *\n * @returns\n * The directory that is watching for events.\n */\n public watching() {\n return Promise.resolve(this._watch?.path);\n }\n\n /**\n * Gets the list of globs that filter the directory contents.\n *\n * @returns\n * The list of globs that filter the directory contents.\n */\n public globs() {\n return Promise.resolve(this._globs?.slice());\n }\n\n /**\n * Returns a promise that can be awaited on to\n * make sure the watch is initialized.\n */\n public async ready() {\n return this._ready;\n }\n\n /**\n * Initializes a new instance of this object.\n *\n * @param logger -\n * The logger to use to output events.\n */\n public constructor(logger: IZLogger) {\n this._logger = new ZLoggerContext(\"ZCrumbtrailApp\", logger);\n }\n\n /**\n * Kills the application.\n */\n public async kill(): Promise<void> {\n await this._watch?.stop();\n\n delete this._watch;\n delete this._globs;\n this._ready = Promise.resolve();\n\n this._resolve?.(0);\n await this._promise;\n delete this._promise;\n }\n\n private _handleFsEvent(path: string, entry: IZLogEntry) {\n const globs = firstDefined([\"**\"], this._globs);\n const directory = firstDefined(cwd(), this._watch?.path);\n\n if (globs?.some((g) => minimatch(path, resolve(directory, g)))) {\n this._logger.log(entry);\n }\n }\n\n private _handleAdd(node: IZFileSystemNode) {\n this._handleFsEvent(node.path, ZCrumbtrailWatch.add(node.path));\n }\n\n private _handleRemove(node: IZFileSystemNode) {\n this._handleFsEvent(node.path, ZCrumbtrailWatch.remove(node.path));\n }\n\n private _handleUpdate(node: IZFileSystemNode) {\n this._handleFsEvent(node.path, ZCrumbtrailWatch.update(node.path));\n }\n\n /**\n * Runs the application.\n *\n * @param args -\n * The application arguments.\n *\n * @returns\n * The process exit code.\n */\n public async run(args: IZCrumbtrailWatchOptions = {}): Promise<number> {\n if (this._promise) {\n return this._promise;\n }\n\n const { promise, resolve } = Promise.withResolvers<number>();\n this._resolve = resolve;\n this._promise = promise;\n\n const { directory = cwd(), globs = [\"**\"] } = args;\n\n this._globs = uniq(globs.slice());\n this._globs = this._globs.length ? this._globs : [\"**\"];\n this._watch = new ZFileWatch(directory);\n\n const filter = globs.join(\",\");\n this._logger.log(ZCrumbtrailWatch.msg(\"Welcome to Crumbtrail CLI\"));\n this._logger.log(ZCrumbtrailWatch.msg(`You are now watching ${directory}`));\n this._logger.log(ZCrumbtrailWatch.msg(`Logging files matching ${filter}.`));\n this._logger.log(ZCrumbtrailWatch.msg(\"Press Ctrl+C to stop watching\"));\n\n this._watch.add().subscribe(this._handleAdd.bind(this));\n this._watch.remove().subscribe(this._handleRemove.bind(this));\n this._watch.update().subscribe(this._handleUpdate.bind(this));\n\n this._ready = this._watch.start();\n await this._ready;\n\n return this._promise;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"watch-DXvYTgIr.cjs","names":["readdir","dirname","ZWatchDelay","firstTruthy","sleep","ZLogEntryBuilder","ZLoggerContext","glob","noop","ZCrumbtrailNudge","_controller","_resolve","_promise","_logger","logger","kill","abort","run","options","controller","AbortController","promise","resolve","Promise","withResolvers","directory","process","cwd","recursive","every","ms","log","info","message","build","warning","catch","onlyDirectories","signal","aborted","resolve","cwd","ZFileWatch","firstDefined","ZLogEntryBuilder","ZLoggerContext","uniq","minimatch","ZCrumbtrailWatch","_logger","_globs","_watch","_ready","Promise","_promise","_resolve","msg","info","message","build","add","path","remove","warning","update","watching","globs","slice","ready","logger","kill","stop","_handleFsEvent","entry","directory","some","g","log","_handleAdd","node","_handleRemove","_handleUpdate","run","args","promise","withResolvers","length","filter","join","subscribe","bind","start"],"sources":["../src/nudge/nudge.mts","../src/watch/watch.mts"],"sourcesContent":["import { readdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { ZWatchDelay } from \"@zthun/crumbtrail-fs\";\nimport { firstTruthy, sleep } from \"@zthun/helpful-fn\";\nimport type { IZLogger } from \"@zthun/lumberjacky-log\";\nimport { ZLogEntryBuilder, ZLoggerContext } from \"@zthun/lumberjacky-log\";\nimport glob from \"fast-glob\";\nimport { noop } from \"lodash-es\";\n\n/**\n * Options for the nudge command.\n */\nexport interface IZCrumbtrailNudgeOptions {\n /**\n * The directory to nudge.\n *\n * The default if not specified is the current working directory.\n */\n directory?: string;\n\n /**\n * Whether to nudge recursively.\n *\n * Warning: This can have severe CPU\n * usage for deep directories.\n *\n * Default is false.\n */\n recursive?: boolean;\n\n /**\n * The total number of milliseconds to wait\n * between nudges.\n *\n * Default is {@link ZWatchDelay}\n */\n every?: number;\n}\n\n/**\n * An operation to continuously nudge a directory.\n *\n * This is a special operation that lists the contents of a targeted parent directory.\n * The main reason for this is to work around an issue when you are running inside of\n * a container and your host is not linux.\n *\n * A lot of times, you will not receive events in this situation for add and update\n * until the virtual file bridge is refreshed by listing the outer directory contents.\n * This command helps to force the bridge to send file change events. You should\n * only need this if you are running on a non linux host inside a docker container.\n *\n * Run a separate container in the background and just nudge the directory\n * for however long you need.\n */\nexport class ZCrumbtrailNudge {\n private _controller?: AbortController;\n private _resolve?: (val: number) => void;\n private _promise?: Promise<number>;\n private readonly _logger: IZLogger;\n\n public constructor(logger: IZLogger) {\n this._logger = new ZLoggerContext(\"ZCrumbtrailNudge\", logger);\n }\n\n public async kill(): Promise<void> {\n this._controller?.abort();\n delete this._controller;\n\n await this._promise;\n delete this._promise;\n }\n\n public async run(options: IZCrumbtrailNudgeOptions = {}): Promise<number> {\n await this.kill();\n\n const controller = new AbortController();\n this._controller = controller;\n\n const { promise, resolve } = Promise.withResolvers<number>();\n this._promise = promise;\n this._resolve = resolve;\n\n const {\n directory = process.cwd(),\n recursive,\n every = ZWatchDelay,\n } = options;\n\n const ms = firstTruthy(ZWatchDelay, every);\n\n this._logger.log(\n new ZLogEntryBuilder()\n .info()\n .message(`Starting a nudge loop every ${ms} milliseconds`)\n .build(),\n );\n\n if (recursive) {\n this._logger.log(\n new ZLogEntryBuilder()\n .warning()\n .message(\"Nudging is recursive. Child folders will be nudged too.\")\n .build(),\n );\n }\n\n do {\n this._logger.log(\n new ZLogEntryBuilder()\n .info()\n .message(`Nudging ${directory} to refresh`)\n .build(),\n );\n await readdir(dirname(directory)).catch(noop);\n\n if (recursive) {\n await glob(`${directory}/**`, { onlyDirectories: true }).catch(noop);\n }\n\n await sleep(ms);\n } while (!controller.signal.aborted);\n\n resolve(0);\n delete this._resolve;\n\n return this._promise;\n }\n}\n","import { resolve } from \"node:path\";\nimport { cwd } from \"node:process\";\n\nimport type { IZFileSystemNode } from \"@zthun/crumbtrail-fs\";\nimport { ZFileWatch } from \"@zthun/crumbtrail-fs\";\nimport { firstDefined } from \"@zthun/helpful-fn\";\nimport type { IZLogEntry, IZLogger } from \"@zthun/lumberjacky-log\";\nimport { ZLogEntryBuilder, ZLoggerContext } from \"@zthun/lumberjacky-log\";\nimport { uniq } from \"lodash-es\";\nimport { minimatch } from \"minimatch\";\n\n/**\n * Arguments for the crumbtrail app.\n */\nexport interface IZCrumbtrailWatchOptions {\n /**\n * The directory to watch.\n *\n * If this is falsy, then the cwd is used.\n */\n directory?: string;\n\n /**\n * The list of file globs to watch.\n *\n * If this is falsy or empty, then '**' is used.\n */\n globs?: string[];\n}\n\n/**\n * The root application for the crumbtrail cli.\n */\nexport class ZCrumbtrailWatch {\n private _logger: IZLogger;\n private _globs: string[] | undefined;\n private _watch: ZFileWatch | undefined;\n private _ready: Promise<void> = Promise.resolve();\n private _promise: Promise<number> | undefined;\n private _resolve: ((value: number) => void) | undefined;\n\n /**\n * Gets the entry for a basic information message.\n *\n * @returns\n * The log entry for a basic information message.\n */\n public static msg(msg: string): IZLogEntry {\n return new ZLogEntryBuilder().info().message(msg).build();\n }\n\n /**\n * Gets the message for when a file is added.\n *\n * @returns\n * The message for when a file is added.\n */\n public static add(path: string): IZLogEntry {\n return new ZLogEntryBuilder().info().message(`Node added: ${path}`).build();\n }\n\n /**\n * Gets the message for when a file/folder is removed.\n *\n * @returns\n * The message for when a file/folder is added.\n */\n public static remove(path: string): IZLogEntry {\n return new ZLogEntryBuilder()\n .warning()\n .message(`Node removed: ${path}`)\n .build();\n }\n\n /**\n * Gets the message for when a file is updated.\n *\n * @returns\n * The message for when a file is updated.\n */\n public static update(path: string): IZLogEntry {\n return new ZLogEntryBuilder()\n .info()\n .message(`Node updated: ${path}`)\n .build();\n }\n\n /**\n * Gets the current directory being watched.\n *\n * @returns\n * The directory that is watching for events.\n */\n public watching() {\n return Promise.resolve(this._watch?.path);\n }\n\n /**\n * Gets the list of globs that filter the directory contents.\n *\n * @returns\n * The list of globs that filter the directory contents.\n */\n public globs() {\n return Promise.resolve(this._globs?.slice());\n }\n\n /**\n * Returns a promise that can be awaited on to\n * make sure the watch is initialized.\n */\n public async ready() {\n return this._ready;\n }\n\n /**\n * Initializes a new instance of this object.\n *\n * @param logger -\n * The logger to use to output events.\n */\n public constructor(logger: IZLogger) {\n this._logger = new ZLoggerContext(\"ZCrumbtrailApp\", logger);\n }\n\n /**\n * Kills the application.\n */\n public async kill(): Promise<void> {\n await this._watch?.stop();\n\n delete this._watch;\n delete this._globs;\n this._ready = Promise.resolve();\n\n this._resolve?.(0);\n await this._promise;\n delete this._promise;\n }\n\n private _handleFsEvent(path: string, entry: IZLogEntry) {\n const globs = firstDefined([\"**\"], this._globs);\n const directory = firstDefined(cwd(), this._watch?.path);\n\n if (globs?.some((g) => minimatch(path, resolve(directory, g)))) {\n this._logger.log(entry);\n }\n }\n\n private _handleAdd(node: IZFileSystemNode) {\n this._handleFsEvent(node.path, ZCrumbtrailWatch.add(node.path));\n }\n\n private _handleRemove(node: IZFileSystemNode) {\n this._handleFsEvent(node.path, ZCrumbtrailWatch.remove(node.path));\n }\n\n private _handleUpdate(node: IZFileSystemNode) {\n this._handleFsEvent(node.path, ZCrumbtrailWatch.update(node.path));\n }\n\n /**\n * Runs the application.\n *\n * @param args -\n * The application arguments.\n *\n * @returns\n * The process exit code.\n */\n public async run(args: IZCrumbtrailWatchOptions = {}): Promise<number> {\n if (this._promise) {\n return this._promise;\n }\n\n const { promise, resolve } = Promise.withResolvers<number>();\n this._resolve = resolve;\n this._promise = promise;\n\n const { directory = cwd(), globs = [\"**\"] } = args;\n\n this._globs = uniq(globs.slice());\n this._globs = this._globs.length ? this._globs : [\"**\"];\n this._watch = new ZFileWatch(directory);\n\n const filter = globs.join(\",\");\n this._logger.log(ZCrumbtrailWatch.msg(\"Welcome to Crumbtrail CLI\"));\n this._logger.log(ZCrumbtrailWatch.msg(`You are now watching ${directory}`));\n this._logger.log(ZCrumbtrailWatch.msg(`Logging files matching ${filter}.`));\n this._logger.log(ZCrumbtrailWatch.msg(\"Press Ctrl+C to stop watching\"));\n\n this._watch.add().subscribe(this._handleAdd.bind(this));\n this._watch.remove().subscribe(this._handleRemove.bind(this));\n this._watch.update().subscribe(this._handleUpdate.bind(this));\n\n this._ready = this._watch.start();\n await this._ready;\n\n return this._promise;\n }\n}\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"watch-CzQSbX_I.js","names":["readdir","dirname","ZWatchDelay","firstTruthy","sleep","ZLogEntryBuilder","ZLoggerContext","glob","noop","ZCrumbtrailNudge","_controller","_resolve","_promise","_logger","logger","kill","abort","run","options","controller","AbortController","promise","resolve","Promise","withResolvers","directory","process","cwd","recursive","every","ms","log","info","message","build","warning","catch","onlyDirectories","signal","aborted","resolve","cwd","ZFileWatch","firstDefined","ZLogEntryBuilder","ZLoggerContext","uniq","minimatch","ZCrumbtrailWatch","_logger","_globs","_watch","_ready","Promise","_promise","_resolve","msg","info","message","build","add","path","remove","warning","update","watching","globs","slice","ready","logger","kill","stop","_handleFsEvent","entry","directory","some","g","log","_handleAdd","node","_handleRemove","_handleUpdate","run","args","promise","withResolvers","length","filter","join","subscribe","bind","start"],"sources":["../src/nudge/nudge.mts","../src/watch/watch.mts"],"sourcesContent":["import { readdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { ZWatchDelay } from \"@zthun/crumbtrail-fs\";\nimport { firstTruthy, sleep } from \"@zthun/helpful-fn\";\nimport type { IZLogger } from \"@zthun/lumberjacky-log\";\nimport { ZLogEntryBuilder, ZLoggerContext } from \"@zthun/lumberjacky-log\";\nimport glob from \"fast-glob\";\nimport { noop } from \"lodash-es\";\n\n/**\n * Options for the nudge command.\n */\nexport interface IZCrumbtrailNudgeOptions {\n /**\n * The directory to nudge.\n *\n * The default if not specified is the current working directory.\n */\n directory?: string;\n\n /**\n * Whether to nudge recursively.\n *\n * Warning: This can have severe CPU\n * usage for deep directories.\n *\n * Default is false.\n */\n recursive?: boolean;\n\n /**\n * The total number of milliseconds to wait\n * between nudges.\n *\n * Default is {@link ZWatchDelay}\n */\n every?: number;\n}\n\n/**\n * An operation to continuously nudge a directory.\n *\n * This is a special operation that lists the contents of a targeted parent directory.\n * The main reason for this is to work around an issue when you are running inside of\n * a container and your host is not linux.\n *\n * A lot of times, you will not receive events in this situation for add and update\n * until the virtual file bridge is refreshed by listing the outer directory contents.\n * This command helps to force the bridge to send file change events. You should\n * only need this if you are running on a non linux host inside a docker container.\n *\n * Run a separate container in the background and just nudge the directory\n * for however long you need.\n */\nexport class ZCrumbtrailNudge {\n private _controller?: AbortController;\n private _resolve?: (val: number) => void;\n private _promise?: Promise<number>;\n private readonly _logger: IZLogger;\n\n public constructor(logger: IZLogger) {\n this._logger = new ZLoggerContext(\"ZCrumbtrailNudge\", logger);\n }\n\n public async kill(): Promise<void> {\n this._controller?.abort();\n delete this._controller;\n\n await this._promise;\n delete this._promise;\n }\n\n public async run(options: IZCrumbtrailNudgeOptions = {}): Promise<number> {\n await this.kill();\n\n const controller = new AbortController();\n this._controller = controller;\n\n const { promise, resolve } = Promise.withResolvers<number>();\n this._promise = promise;\n this._resolve = resolve;\n\n const {\n directory = process.cwd(),\n recursive,\n every = ZWatchDelay,\n } = options;\n\n const ms = firstTruthy(ZWatchDelay, every);\n\n this._logger.log(\n new ZLogEntryBuilder()\n .info()\n .message(`Starting a nudge loop every ${ms} milliseconds`)\n .build(),\n );\n\n if (recursive) {\n this._logger.log(\n new ZLogEntryBuilder()\n .warning()\n .message(\"Nudging is recursive. Child folders will be nudged too.\")\n .build(),\n );\n }\n\n do {\n this._logger.log(\n new ZLogEntryBuilder()\n .info()\n .message(`Nudging ${directory} to refresh`)\n .build(),\n );\n await readdir(dirname(directory)).catch(noop);\n\n if (recursive) {\n await glob(`${directory}/**`, { onlyDirectories: true }).catch(noop);\n }\n\n await sleep(ms);\n } while (!controller.signal.aborted);\n\n resolve(0);\n delete this._resolve;\n\n return this._promise;\n }\n}\n","import { resolve } from \"node:path\";\nimport { cwd } from \"node:process\";\n\nimport type { IZFileSystemNode } from \"@zthun/crumbtrail-fs\";\nimport { ZFileWatch } from \"@zthun/crumbtrail-fs\";\nimport { firstDefined } from \"@zthun/helpful-fn\";\nimport type { IZLogEntry, IZLogger } from \"@zthun/lumberjacky-log\";\nimport { ZLogEntryBuilder, ZLoggerContext } from \"@zthun/lumberjacky-log\";\nimport { uniq } from \"lodash-es\";\nimport { minimatch } from \"minimatch\";\n\n/**\n * Arguments for the crumbtrail app.\n */\nexport interface IZCrumbtrailWatchOptions {\n /**\n * The directory to watch.\n *\n * If this is falsy, then the cwd is used.\n */\n directory?: string;\n\n /**\n * The list of file globs to watch.\n *\n * If this is falsy or empty, then '**' is used.\n */\n globs?: string[];\n}\n\n/**\n * The root application for the crumbtrail cli.\n */\nexport class ZCrumbtrailWatch {\n private _logger: IZLogger;\n private _globs: string[] | undefined;\n private _watch: ZFileWatch | undefined;\n private _ready: Promise<void> = Promise.resolve();\n private _promise: Promise<number> | undefined;\n private _resolve: ((value: number) => void) | undefined;\n\n /**\n * Gets the entry for a basic information message.\n *\n * @returns\n * The log entry for a basic information message.\n */\n public static msg(msg: string): IZLogEntry {\n return new ZLogEntryBuilder().info().message(msg).build();\n }\n\n /**\n * Gets the message for when a file is added.\n *\n * @returns\n * The message for when a file is added.\n */\n public static add(path: string): IZLogEntry {\n return new ZLogEntryBuilder().info().message(`Node added: ${path}`).build();\n }\n\n /**\n * Gets the message for when a file/folder is removed.\n *\n * @returns\n * The message for when a file/folder is added.\n */\n public static remove(path: string): IZLogEntry {\n return new ZLogEntryBuilder()\n .warning()\n .message(`Node removed: ${path}`)\n .build();\n }\n\n /**\n * Gets the message for when a file is updated.\n *\n * @returns\n * The message for when a file is updated.\n */\n public static update(path: string): IZLogEntry {\n return new ZLogEntryBuilder()\n .info()\n .message(`Node updated: ${path}`)\n .build();\n }\n\n /**\n * Gets the current directory being watched.\n *\n * @returns\n * The directory that is watching for events.\n */\n public watching() {\n return Promise.resolve(this._watch?.path);\n }\n\n /**\n * Gets the list of globs that filter the directory contents.\n *\n * @returns\n * The list of globs that filter the directory contents.\n */\n public globs() {\n return Promise.resolve(this._globs?.slice());\n }\n\n /**\n * Returns a promise that can be awaited on to\n * make sure the watch is initialized.\n */\n public async ready() {\n return this._ready;\n }\n\n /**\n * Initializes a new instance of this object.\n *\n * @param logger -\n * The logger to use to output events.\n */\n public constructor(logger: IZLogger) {\n this._logger = new ZLoggerContext(\"ZCrumbtrailApp\", logger);\n }\n\n /**\n * Kills the application.\n */\n public async kill(): Promise<void> {\n await this._watch?.stop();\n\n delete this._watch;\n delete this._globs;\n this._ready = Promise.resolve();\n\n this._resolve?.(0);\n await this._promise;\n delete this._promise;\n }\n\n private _handleFsEvent(path: string, entry: IZLogEntry) {\n const globs = firstDefined([\"**\"], this._globs);\n const directory = firstDefined(cwd(), this._watch?.path);\n\n if (globs?.some((g) => minimatch(path, resolve(directory, g)))) {\n this._logger.log(entry);\n }\n }\n\n private _handleAdd(node: IZFileSystemNode) {\n this._handleFsEvent(node.path, ZCrumbtrailWatch.add(node.path));\n }\n\n private _handleRemove(node: IZFileSystemNode) {\n this._handleFsEvent(node.path, ZCrumbtrailWatch.remove(node.path));\n }\n\n private _handleUpdate(node: IZFileSystemNode) {\n this._handleFsEvent(node.path, ZCrumbtrailWatch.update(node.path));\n }\n\n /**\n * Runs the application.\n *\n * @param args -\n * The application arguments.\n *\n * @returns\n * The process exit code.\n */\n public async run(args: IZCrumbtrailWatchOptions = {}): Promise<number> {\n if (this._promise) {\n return this._promise;\n }\n\n const { promise, resolve } = Promise.withResolvers<number>();\n this._resolve = resolve;\n this._promise = promise;\n\n const { directory = cwd(), globs = [\"**\"] } = args;\n\n this._globs = uniq(globs.slice());\n this._globs = this._globs.length ? this._globs : [\"**\"];\n this._watch = new ZFileWatch(directory);\n\n const filter = globs.join(\",\");\n this._logger.log(ZCrumbtrailWatch.msg(\"Welcome to Crumbtrail CLI\"));\n this._logger.log(ZCrumbtrailWatch.msg(`You are now watching ${directory}`));\n this._logger.log(ZCrumbtrailWatch.msg(`Logging files matching ${filter}.`));\n this._logger.log(ZCrumbtrailWatch.msg(\"Press Ctrl+C to stop watching\"));\n\n this._watch.add().subscribe(this._handleAdd.bind(this));\n this._watch.remove().subscribe(this._handleRemove.bind(this));\n this._watch.update().subscribe(this._handleUpdate.bind(this));\n\n this._ready = this._watch.start();\n await this._ready;\n\n return this._promise;\n }\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"watch-peSooqy2.js","names":["readdir","dirname","ZWatchDelay","firstTruthy","sleep","ZLogEntryBuilder","ZLoggerContext","glob","noop","ZCrumbtrailNudge","_controller","_resolve","_promise","_logger","logger","kill","abort","run","options","controller","AbortController","promise","resolve","Promise","withResolvers","directory","process","cwd","recursive","every","ms","log","info","message","build","warning","catch","onlyDirectories","signal","aborted","resolve","cwd","ZFileWatch","firstDefined","ZLogEntryBuilder","ZLoggerContext","uniq","minimatch","ZCrumbtrailWatch","_logger","_globs","_watch","_ready","Promise","_promise","_resolve","msg","info","message","build","add","path","remove","warning","update","watching","globs","slice","ready","logger","kill","stop","_handleFsEvent","entry","directory","some","g","log","_handleAdd","node","_handleRemove","_handleUpdate","run","args","promise","withResolvers","length","filter","join","subscribe","bind","start"],"sources":["../src/nudge/nudge.mts","../src/watch/watch.mts"],"sourcesContent":["import { readdir } from \"node:fs/promises\";\nimport { dirname } from \"node:path\";\n\nimport { ZWatchDelay } from \"@zthun/crumbtrail-fs\";\nimport { firstTruthy, sleep } from \"@zthun/helpful-fn\";\nimport type { IZLogger } from \"@zthun/lumberjacky-log\";\nimport { ZLogEntryBuilder, ZLoggerContext } from \"@zthun/lumberjacky-log\";\nimport glob from \"fast-glob\";\nimport { noop } from \"lodash-es\";\n\n/**\n * Options for the nudge command.\n */\nexport interface IZCrumbtrailNudgeOptions {\n /**\n * The directory to nudge.\n *\n * The default if not specified is the current working directory.\n */\n directory?: string;\n\n /**\n * Whether to nudge recursively.\n *\n * Warning: This can have severe CPU\n * usage for deep directories.\n *\n * Default is false.\n */\n recursive?: boolean;\n\n /**\n * The total number of milliseconds to wait\n * between nudges.\n *\n * Default is {@link ZWatchDelay}\n */\n every?: number;\n}\n\n/**\n * An operation to continuously nudge a directory.\n *\n * This is a special operation that lists the contents of a targeted parent directory.\n * The main reason for this is to work around an issue when you are running inside of\n * a container and your host is not linux.\n *\n * A lot of times, you will not receive events in this situation for add and update\n * until the virtual file bridge is refreshed by listing the outer directory contents.\n * This command helps to force the bridge to send file change events. You should\n * only need this if you are running on a non linux host inside a docker container.\n *\n * Run a separate container in the background and just nudge the directory\n * for however long you need.\n */\nexport class ZCrumbtrailNudge {\n private _controller?: AbortController;\n private _resolve?: (val: number) => void;\n private _promise?: Promise<number>;\n private readonly _logger: IZLogger;\n\n public constructor(logger: IZLogger) {\n this._logger = new ZLoggerContext(\"ZCrumbtrailNudge\", logger);\n }\n\n public async kill(): Promise<void> {\n this._controller?.abort();\n delete this._controller;\n\n await this._promise;\n delete this._promise;\n }\n\n public async run(options: IZCrumbtrailNudgeOptions = {}): Promise<number> {\n await this.kill();\n\n const controller = new AbortController();\n this._controller = controller;\n\n const { promise, resolve } = Promise.withResolvers<number>();\n this._promise = promise;\n this._resolve = resolve;\n\n const {\n directory = process.cwd(),\n recursive,\n every = ZWatchDelay,\n } = options;\n\n const ms = firstTruthy(ZWatchDelay, every);\n\n this._logger.log(\n new ZLogEntryBuilder()\n .info()\n .message(`Starting a nudge loop every ${ms} milliseconds`)\n .build(),\n );\n\n if (recursive) {\n this._logger.log(\n new ZLogEntryBuilder()\n .warning()\n .message(\"Nudging is recursive. Child folders will be nudged too.\")\n .build(),\n );\n }\n\n do {\n this._logger.log(\n new ZLogEntryBuilder()\n .info()\n .message(`Nudging ${directory} to refresh`)\n .build(),\n );\n await readdir(dirname(directory)).catch(noop);\n\n if (recursive) {\n await glob(`${directory}/**`, { onlyDirectories: true }).catch(noop);\n }\n\n await sleep(ms);\n } while (!controller.signal.aborted);\n\n resolve(0);\n delete this._resolve;\n\n return this._promise;\n }\n}\n","import { resolve } from \"node:path\";\nimport { cwd } from \"node:process\";\n\nimport type { IZFileSystemNode } from \"@zthun/crumbtrail-fs\";\nimport { ZFileWatch } from \"@zthun/crumbtrail-fs\";\nimport { firstDefined } from \"@zthun/helpful-fn\";\nimport type { IZLogEntry, IZLogger } from \"@zthun/lumberjacky-log\";\nimport { ZLogEntryBuilder, ZLoggerContext } from \"@zthun/lumberjacky-log\";\nimport { uniq } from \"lodash-es\";\nimport { minimatch } from \"minimatch\";\n\n/**\n * Arguments for the crumbtrail app.\n */\nexport interface IZCrumbtrailWatchOptions {\n /**\n * The directory to watch.\n *\n * If this is falsy, then the cwd is used.\n */\n directory?: string;\n\n /**\n * The list of file globs to watch.\n *\n * If this is falsy or empty, then '**' is used.\n */\n globs?: string[];\n}\n\n/**\n * The root application for the crumbtrail cli.\n */\nexport class ZCrumbtrailWatch {\n private _logger: IZLogger;\n private _globs: string[] | undefined;\n private _watch: ZFileWatch | undefined;\n private _ready: Promise<void> = Promise.resolve();\n private _promise: Promise<number> | undefined;\n private _resolve: ((value: number) => void) | undefined;\n\n /**\n * Gets the entry for a basic information message.\n *\n * @returns\n * The log entry for a basic information message.\n */\n public static msg(msg: string): IZLogEntry {\n return new ZLogEntryBuilder().info().message(msg).build();\n }\n\n /**\n * Gets the message for when a file is added.\n *\n * @returns\n * The message for when a file is added.\n */\n public static add(path: string): IZLogEntry {\n return new ZLogEntryBuilder().info().message(`Node added: ${path}`).build();\n }\n\n /**\n * Gets the message for when a file/folder is removed.\n *\n * @returns\n * The message for when a file/folder is added.\n */\n public static remove(path: string): IZLogEntry {\n return new ZLogEntryBuilder()\n .warning()\n .message(`Node removed: ${path}`)\n .build();\n }\n\n /**\n * Gets the message for when a file is updated.\n *\n * @returns\n * The message for when a file is updated.\n */\n public static update(path: string): IZLogEntry {\n return new ZLogEntryBuilder()\n .info()\n .message(`Node updated: ${path}`)\n .build();\n }\n\n /**\n * Gets the current directory being watched.\n *\n * @returns\n * The directory that is watching for events.\n */\n public watching() {\n return Promise.resolve(this._watch?.path);\n }\n\n /**\n * Gets the list of globs that filter the directory contents.\n *\n * @returns\n * The list of globs that filter the directory contents.\n */\n public globs() {\n return Promise.resolve(this._globs?.slice());\n }\n\n /**\n * Returns a promise that can be awaited on to\n * make sure the watch is initialized.\n */\n public async ready() {\n return this._ready;\n }\n\n /**\n * Initializes a new instance of this object.\n *\n * @param logger -\n * The logger to use to output events.\n */\n public constructor(logger: IZLogger) {\n this._logger = new ZLoggerContext(\"ZCrumbtrailApp\", logger);\n }\n\n /**\n * Kills the application.\n */\n public async kill(): Promise<void> {\n await this._watch?.stop();\n\n delete this._watch;\n delete this._globs;\n this._ready = Promise.resolve();\n\n this._resolve?.(0);\n await this._promise;\n delete this._promise;\n }\n\n private _handleFsEvent(path: string, entry: IZLogEntry) {\n const globs = firstDefined([\"**\"], this._globs);\n const directory = firstDefined(cwd(), this._watch?.path);\n\n if (globs?.some((g) => minimatch(path, resolve(directory, g)))) {\n this._logger.log(entry);\n }\n }\n\n private _handleAdd(node: IZFileSystemNode) {\n this._handleFsEvent(node.path, ZCrumbtrailWatch.add(node.path));\n }\n\n private _handleRemove(node: IZFileSystemNode) {\n this._handleFsEvent(node.path, ZCrumbtrailWatch.remove(node.path));\n }\n\n private _handleUpdate(node: IZFileSystemNode) {\n this._handleFsEvent(node.path, ZCrumbtrailWatch.update(node.path));\n }\n\n /**\n * Runs the application.\n *\n * @param args -\n * The application arguments.\n *\n * @returns\n * The process exit code.\n */\n public async run(args: IZCrumbtrailWatchOptions = {}): Promise<number> {\n if (this._promise) {\n return this._promise;\n }\n\n const { promise, resolve } = Promise.withResolvers<number>();\n this._resolve = resolve;\n this._promise = promise;\n\n const { directory = cwd(), globs = [\"**\"] } = args;\n\n this._globs = uniq(globs.slice());\n this._globs = this._globs.length ? this._globs : [\"**\"];\n this._watch = new ZFileWatch(directory);\n\n const filter = globs.join(\",\");\n this._logger.log(ZCrumbtrailWatch.msg(\"Welcome to Crumbtrail CLI\"));\n this._logger.log(ZCrumbtrailWatch.msg(`You are now watching ${directory}`));\n this._logger.log(ZCrumbtrailWatch.msg(`Logging files matching ${filter}.`));\n this._logger.log(ZCrumbtrailWatch.msg(\"Press Ctrl+C to stop watching\"));\n\n this._watch.add().subscribe(this._handleAdd.bind(this));\n this._watch.remove().subscribe(this._handleRemove.bind(this));\n this._watch.update().subscribe(this._handleUpdate.bind(this));\n\n this._ready = this._watch.start();\n await this._ready;\n\n return this._promise;\n }\n}\n"],"mappings":"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"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@zthun/crumbtrail-cli",
|
|
3
|
-
"version": "2.4.
|
|
3
|
+
"version": "2.4.11",
|
|
4
4
|
"description": "An application for crumbtrail that helps with debugging io issues",
|
|
5
5
|
"author": "Anthony Bonta",
|
|
6
6
|
"license": "MIT",
|
|
@@ -31,26 +31,26 @@
|
|
|
31
31
|
"access": "public"
|
|
32
32
|
},
|
|
33
33
|
"dependencies": {
|
|
34
|
-
"@zthun/crumbtrail-fs": "^2.4.
|
|
35
|
-
"@zthun/helpful-fn": "^9.11.
|
|
36
|
-
"@zthun/lumberjacky-log": "^4.0.
|
|
34
|
+
"@zthun/crumbtrail-fs": "^2.4.11",
|
|
35
|
+
"@zthun/helpful-fn": "^9.11.13",
|
|
36
|
+
"@zthun/lumberjacky-log": "^4.0.7",
|
|
37
37
|
"commander": "^14.0.3",
|
|
38
38
|
"fast-glob": "^3.3.3",
|
|
39
|
-
"lodash-es": "^4.
|
|
39
|
+
"lodash-es": "^4.18.1",
|
|
40
40
|
"minimatch": "^10.2.5"
|
|
41
41
|
},
|
|
42
42
|
"devDependencies": {
|
|
43
|
-
"@zthun/janitor-build-config": "^20.0.
|
|
44
|
-
"@zthun/janitor-ts-config": "^20.0.
|
|
45
|
-
"tsx": "^4.
|
|
46
|
-
"typescript": "~
|
|
47
|
-
"vite": "^8.0.
|
|
48
|
-
"vitest": "^4.1.
|
|
49
|
-
"vitest-mock-extended": "^
|
|
43
|
+
"@zthun/janitor-build-config": "^20.0.6",
|
|
44
|
+
"@zthun/janitor-ts-config": "^20.0.4",
|
|
45
|
+
"tsx": "^4.22.3",
|
|
46
|
+
"typescript": "~6.0.3",
|
|
47
|
+
"vite": "^8.0.14",
|
|
48
|
+
"vitest": "^4.1.7",
|
|
49
|
+
"vitest-mock-extended": "^4.0.0"
|
|
50
50
|
},
|
|
51
51
|
"files": [
|
|
52
52
|
"dist"
|
|
53
53
|
],
|
|
54
54
|
"sideEffects": false,
|
|
55
|
-
"gitHead": "
|
|
55
|
+
"gitHead": "b70b686b5976f3837f8fe6fbafe49b344251f20d"
|
|
56
56
|
}
|