@staticbolt/core 1.0.0-beta.3 → 1.0.0-beta.30

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.
@@ -0,0 +1,15 @@
1
+ import { DeferredPass } from "@staticbolt/core";
2
+ //#region src/plugins/write-files/deferred-worker.d.ts
3
+ /** A written file and the pass a plugin handed over instead of running. */
4
+ interface DeferredJob {
5
+ /** Absolute path of the file to run the pass over, in place. */
6
+ path: string;
7
+ pass: DeferredPass;
8
+ }
9
+ /** Sent back once the file is done, whether or not the pass went through. A worker is only ever given one job at a time. */
10
+ interface DeferredJobResult {
11
+ error?: string;
12
+ }
13
+ //#endregion
14
+ export { DeferredJob, DeferredJobResult };
15
+ //# sourceMappingURL=deferred-worker.d.mts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deferred-worker.d.mts","names":[],"sources":["../../../src/plugins/write-files/deferred-worker.ts"],"mappings":";;;UAMiB;;EAEf;EAEA,MAAM;;;UAIS;EACf"}
@@ -0,0 +1,35 @@
1
+ import { readFileSync, writeFileSync } from "node:fs";
2
+ import { parentPort } from "node:worker_threads";
3
+
4
+ //#region src/plugins/write-files/deferred-worker.ts
5
+ /** Passes are looked up once and kept: a worker is handed the same kind of file over and over. */
6
+ const handlers = /* @__PURE__ */ new Map();
7
+ async function resolveHandler({ module, export: exportName }) {
8
+ const key = `${module}#${exportName}`;
9
+ const cached = handlers.get(key);
10
+ if (cached) return cached;
11
+ const handler = (await import(module))[exportName];
12
+ if (typeof handler !== "function") throw new TypeError(`"${module}" does not export "${exportName}"`);
13
+ handlers.set(key, handler);
14
+ return handler;
15
+ }
16
+ /** Reads the file, runs the pass the plugin named over its contents, and writes the result back over it. */
17
+ async function applyPass({ path, pass }) {
18
+ const handler = await resolveHandler(pass);
19
+ const code = readFileSync(path, "utf8");
20
+ writeFileSync(path, await handler(code, pass.payload), "utf8");
21
+ }
22
+ const port = parentPort;
23
+ if (port) port.on("message", async (job) => {
24
+ const result = {};
25
+ try {
26
+ await applyPass(job);
27
+ } catch (error) {
28
+ result.error = error instanceof Error ? error.message : String(error);
29
+ }
30
+ port.postMessage(result);
31
+ });
32
+
33
+ //#endregion
34
+ export { };
35
+ //# sourceMappingURL=deferred-worker.mjs.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"deferred-worker.mjs","names":[],"sources":["../../../src/plugins/write-files/deferred-worker.ts"],"sourcesContent":["import { readFileSync, writeFileSync } from \"node:fs\";\nimport { parentPort } from \"node:worker_threads\";\n\nimport type { DeferredPass, DeferredPassHandler } from \"@staticbolt/core\";\n\n/** A written file and the pass a plugin handed over instead of running. */\nexport interface DeferredJob {\n /** Absolute path of the file to run the pass over, in place. */\n path: string;\n\n pass: DeferredPass;\n}\n\n/** Sent back once the file is done, whether or not the pass went through. A worker is only ever given one job at a time. */\nexport interface DeferredJobResult {\n error?: string;\n}\n\n/** Passes are looked up once and kept: a worker is handed the same kind of file over and over. */\nconst handlers = new Map<string, DeferredPassHandler<unknown>>();\n\nasync function resolveHandler({ module, export: exportName }: DeferredPass): Promise<DeferredPassHandler<unknown>> {\n const key = `${module}#${exportName}`;\n\n const cached = handlers.get(key);\n if (cached) {\n return cached;\n }\n\n const namespace = (await import(module)) as Record<string, unknown>;\n const handler = namespace[exportName];\n\n if (typeof handler !== \"function\") {\n throw new TypeError(`\"${module}\" does not export \"${exportName}\"`);\n }\n\n handlers.set(key, handler as DeferredPassHandler<unknown>);\n\n return handler as DeferredPassHandler<unknown>;\n}\n\n/** Reads the file, runs the pass the plugin named over its contents, and writes the result back over it. */\nasync function applyPass({ path, pass }: DeferredJob): Promise<void> {\n const handler = await resolveHandler(pass);\n const code = readFileSync(path, \"utf8\");\n\n writeFileSync(path, await handler(code, pass.payload), \"utf8\");\n}\n\nconst port = parentPort;\n\nif (port) {\n port.on(\"message\", async (job: DeferredJob) => {\n const result: DeferredJobResult = {};\n\n try {\n await applyPass(job);\n } catch (error) {\n result.error = error instanceof Error ? error.message : String(error);\n }\n\n port.postMessage(result);\n });\n}\n"],"mappings":";;;;;AAmBA,MAAM,2BAAW,IAAI,IAA0C;AAE/D,eAAe,eAAe,EAAE,QAAQ,QAAQ,cAAmE;CACjH,MAAM,MAAM,GAAG,OAAO,GAAG;CAEzB,MAAM,SAAS,SAAS,IAAI,GAAG;CAC/B,IAAI,QACF,OAAO;CAIT,MAAM,WAAU,MADS,OAAO,QACP,CAAC;CAE1B,IAAI,OAAO,YAAY,YACrB,MAAM,IAAI,UAAU,IAAI,OAAO,qBAAqB,WAAW,EAAE;CAGnE,SAAS,IAAI,KAAK,OAAuC;CAEzD,OAAO;AACT;;AAGA,eAAe,UAAU,EAAE,MAAM,QAAoC;CACnE,MAAM,UAAU,MAAM,eAAe,IAAI;CACzC,MAAM,OAAO,aAAa,MAAM,MAAM;CAEtC,cAAc,MAAM,MAAM,QAAQ,MAAM,KAAK,OAAO,GAAG,MAAM;AAC/D;AAEA,MAAM,OAAO;AAEb,IAAI,MACF,KAAK,GAAG,WAAW,OAAO,QAAqB;CAC7C,MAAM,SAA4B,CAAC;CAEnC,IAAI;EACF,MAAM,UAAU,GAAG;CACrB,SAAS,OAAO;EACd,OAAO,QAAQ,iBAAiB,QAAQ,MAAM,UAAU,OAAO,KAAK;CACtE;CAEA,KAAK,YAAY,MAAM;AACzB,CAAC"}
@@ -0,0 +1,20 @@
1
+ import { createRequire } from "node:module";
2
+
3
+ //#region \0rolldown/runtime.js
4
+ var __defProp = Object.defineProperty;
5
+ var __exportAll = (all, no_symbols) => {
6
+ let target = {};
7
+ for (var name in all) {
8
+ __defProp(target, name, {
9
+ get: all[name],
10
+ enumerable: true
11
+ });
12
+ }
13
+ if (!no_symbols) {
14
+ __defProp(target, Symbol.toStringTag, { value: "Module" });
15
+ }
16
+ return target;
17
+ };
18
+
19
+ //#endregion
20
+ export { __exportAll as t };
@@ -1,15 +1,369 @@
1
- import { i as CUSTOM_ATTRIBUTES, t as Log } from "./logger-BuxMGhij.mjs";
1
+ import { _ as replaceExtension, c as isAbsolute, d as join, f as normalize, n as CUSTOM_ATTRIBUTES, o as dirname, r as Log, s as extname } from "./common-DUFKS3lW.mjs";
2
+ import { existsSync, readFileSync, statSync } from "node:fs";
3
+ import { ResolverFactory } from "oxc-resolver";
4
+ import chalk from "chalk";
5
+ import json5 from "json5";
6
+ import { readFile } from "node:fs/promises";
7
+ import _generator from "@babel/generator";
2
8
  import { NodeType } from "@staticbolt/node-html-parser";
3
- import c from "chalk";
4
9
  import { Node as Node$1 } from "postcss";
5
- import _generator from "@babel/generator";
6
- import _traverse from "@babel/traverse";
7
10
  import boxen from "boxen";
8
11
  import { common, createEmphasize } from "emphasize";
9
- import { readFileSync } from "node:fs";
10
- import { readFile } from "node:fs/promises";
11
12
  import { createHash } from "node:crypto";
12
13
 
14
+ //#region src/helpers/dependency-tracker.ts
15
+ /**
16
+ * Tracks bidirectional dependencies between importers and their sources.\
17
+ * Handles reconciliation when dependencies change, so stale entries are automatically removed when an importer stops referencing
18
+ * a source.
19
+ */
20
+ var DependencyTracker = class {
21
+ /** Source → Set of importers that depend on it */
22
+ #sourcesToImporters = /* @__PURE__ */ new Map();
23
+ /** Importer → Set of sources it depends on */
24
+ #importerToSources = /* @__PURE__ */ new Map();
25
+ /** Updates the full set of sources for a given importer, reconciling any stale entries from previous calls. */
26
+ update(importer, sources) {
27
+ const nextSources = new Set(sources);
28
+ const previousSources = this.#importerToSources.get(importer) ?? /* @__PURE__ */ new Set();
29
+ for (const source of previousSources) if (!nextSources.has(source)) this.#sourcesToImporters.get(source)?.delete(importer);
30
+ for (const source of nextSources) {
31
+ if (!this.#sourcesToImporters.has(source)) this.#sourcesToImporters.set(source, /* @__PURE__ */ new Set());
32
+ this.#sourcesToImporters.get(source).add(importer);
33
+ }
34
+ this.#importerToSources.set(importer, nextSources);
35
+ }
36
+ /** Deletes all dependency data for a given id, whether it's acting as an importer, a source, or both (e.g. on file unlink). */
37
+ delete(id) {
38
+ this.#sourcesToImporters.delete(id);
39
+ const sources = this.#importerToSources.get(id);
40
+ if (sources) {
41
+ for (const source of sources) this.#sourcesToImporters.get(source)?.delete(id);
42
+ this.#importerToSources.delete(id);
43
+ }
44
+ }
45
+ /** Returns all importers that depend on a given source, or an empty set. */
46
+ getImporters(source) {
47
+ return this.#sourcesToImporters.get(source) ?? /* @__PURE__ */ new Set();
48
+ }
49
+ /** Returns all sources that a given importer depends on, or an empty set. */
50
+ getSources(importer) {
51
+ return this.#importerToSources.get(importer) ?? /* @__PURE__ */ new Set();
52
+ }
53
+ };
54
+
55
+ //#endregion
56
+ //#region src/utilities/html-links.ts
57
+ /**
58
+ * Checks if the link is an HTML link (not a file link)
59
+ *
60
+ * @param source - The link
61
+ * @returns
62
+ */
63
+ function isHtmlLink(source) {
64
+ return /^(?:#|https?|mailto:|tel:|url\(|ftp:|data:|javascript:)/i.test(source);
65
+ }
66
+ function isValidRelativePath(source) {
67
+ if (!source) return false;
68
+ if (isAbsolute(source)) return false;
69
+ return !isHtmlLink(source);
70
+ }
71
+ function splitHtmlLink(url) {
72
+ const qIndex = url.indexOf("?");
73
+ const hIndex = url.indexOf("#");
74
+ let delimIndex = -1;
75
+ if (qIndex !== -1 && hIndex !== -1) delimIndex = Math.min(qIndex, hIndex);
76
+ else if (qIndex !== -1) delimIndex = qIndex;
77
+ else if (hIndex !== -1) delimIndex = hIndex;
78
+ if (delimIndex !== -1) {
79
+ const pathEnd = url[delimIndex - 1] === "/" ? delimIndex - 1 : delimIndex;
80
+ return [url.slice(0, pathEnd), url.slice(pathEnd)];
81
+ }
82
+ if (url.endsWith("/")) {
83
+ if (url === "/" || url === "./") return [url, ""];
84
+ return [url.slice(0, -1), "/"];
85
+ }
86
+ return [url, ""];
87
+ }
88
+
89
+ //#endregion
90
+ //#region src/utilities/value-or-error.ts
91
+ function errorsWrapper(function_) {
92
+ return (...arguments_) => {
93
+ try {
94
+ const promiseOrValue = function_(...arguments_);
95
+ if (isPromise(promiseOrValue)) return new Promise((resolve) => {
96
+ promiseOrValue.then((value) => {
97
+ resolve([value, null]);
98
+ }).catch((error) => {
99
+ resolve(handleError(error, function_.name));
100
+ });
101
+ });
102
+ return [promiseOrValue, null];
103
+ } catch (error) {
104
+ return handleError(error, function_.name);
105
+ }
106
+ };
107
+ }
108
+ function isPromise(value) {
109
+ return value && typeof value === "object" && "then" in value && typeof value.then === "function" && "catch" in value && typeof value.catch === "function";
110
+ }
111
+ function handleError(error, functionName = "") {
112
+ if (!error) return [null, /* @__PURE__ */ new Error(`[${functionName}] Unexpected error`)];
113
+ if (typeof error === "string") return [null, new Error(error)];
114
+ if (error instanceof Error) return [null, error];
115
+ if (typeof error === "object" && "message" in error && typeof error.message === "string") return [null, new Error(error.message)];
116
+ return [null, /* @__PURE__ */ new Error(`[${functionName}] Unexpected error`)];
117
+ }
118
+ const valueOrError = errorsWrapper;
119
+
120
+ //#endregion
121
+ //#region src/utilities/read-file.ts
122
+ async function safeReadFile(path, options) {
123
+ try {
124
+ return [await readFile(path, options), null];
125
+ } catch (error) {
126
+ return handleError(error, "readFile");
127
+ }
128
+ }
129
+ function safeReadFileSync(path, options) {
130
+ try {
131
+ return [readFileSync(path, options), null];
132
+ } catch (error) {
133
+ return handleError(error, "readFileSync");
134
+ }
135
+ }
136
+
137
+ //#endregion
138
+ //#region src/utilities/read-json-file.ts
139
+ /** Read a file and parse it as JSON safely. */
140
+ function readJsonFile(path, code) {
141
+ if (!code) {
142
+ const [fileString, readError] = safeReadFileSync(path, "utf8");
143
+ if (readError) return [null, readError];
144
+ code = fileString;
145
+ }
146
+ const [parsed, parseError] = valueOrError(json5.parse)(code);
147
+ if (parseError !== null) return [null, parseError];
148
+ return [parsed, null];
149
+ }
150
+
151
+ //#endregion
152
+ //#region src/resolver/get-aliases.ts
153
+ /** Gets path aliases from `tsconfig.json` */
154
+ function getPathAliases(root) {
155
+ const [tsconfig, tsconfigParseError] = readTsconfig(root);
156
+ if (tsconfigParseError !== null) return [null, tsconfigParseError];
157
+ const paths = tsconfig.paths ?? {};
158
+ const alias = {};
159
+ for (const key in paths) {
160
+ const aliasName = key.replace(/\*$/, "");
161
+ alias[aliasName] = paths[key][0].replace(/\*$/, "");
162
+ }
163
+ return [alias, null];
164
+ }
165
+ function readTsconfig(root) {
166
+ const tsconfigPath = join(root, "tsconfig.json");
167
+ const [tsconfig, tsconfigParseError] = readJsonFile(tsconfigPath);
168
+ if (tsconfigParseError !== null) return [null, tsconfigParseError];
169
+ if (!tsconfig.compilerOptions) return [null, /* @__PURE__ */ new Error("[readTsconfig] No compilerOptions found in tsconfig.json")];
170
+ return [tsconfig.compilerOptions, null];
171
+ }
172
+
173
+ //#endregion
174
+ //#region src/resolver/resolver.ts
175
+ const nodeModulesResolver = new ResolverFactory({
176
+ conditionNames: [
177
+ "browser",
178
+ "import",
179
+ "default"
180
+ ],
181
+ extensions: [
182
+ ".js",
183
+ ".json",
184
+ ".node",
185
+ ".css"
186
+ ],
187
+ symlinks: false
188
+ });
189
+ var Resolver = class Resolver {
190
+ root;
191
+ isProduction;
192
+ aliases = {};
193
+ notFound = /* @__PURE__ */ new Set();
194
+ files = /* @__PURE__ */ new Set();
195
+ directories = /* @__PURE__ */ new Set();
196
+ misses = /* @__PURE__ */ new Set();
197
+ static JS_EXTENSIONS = /* @__PURE__ */ new Set([
198
+ ".js",
199
+ ".mjs",
200
+ ".cjs",
201
+ ".jsx",
202
+ ".ts",
203
+ ".mts",
204
+ ".cts",
205
+ ".tsx"
206
+ ]);
207
+ static HTML_EXTENSIONS = /* @__PURE__ */ new Set([".html", ".md"]);
208
+ constructor(root, isProduction = false, configAliases = {}) {
209
+ this.root = root;
210
+ this.isProduction = isProduction;
211
+ const [aliases] = getPathAliases(root);
212
+ this.aliases = {
213
+ ...aliases,
214
+ ...configAliases
215
+ };
216
+ }
217
+ resolve(sourceOrLink, filePath) {
218
+ if (!isValidRelativePath(sourceOrLink)) return;
219
+ const absFilePath = isAbsolute(filePath) ? filePath : join(this.root, filePath);
220
+ const [source, suffix] = splitHtmlLink(sourceOrLink);
221
+ if (isAbsolute(source)) return;
222
+ const isDirectory = suffix === "/";
223
+ const absSource = join(dirname(absFilePath), source);
224
+ const foundFile = this.findFile(absSource, isDirectory);
225
+ if (foundFile) return {
226
+ path: foundFile,
227
+ exists: true,
228
+ suffix
229
+ };
230
+ const sourceForAlias = suffix === "/" ? source + "/" : source;
231
+ const resolvedPathAlias = Resolver.resolvePathAlias(sourceForAlias, this.aliases);
232
+ if (resolvedPathAlias) {
233
+ const absSource = join(this.root, resolvedPathAlias);
234
+ const foundFile = this.findFile(absSource, isDirectory);
235
+ const isFileAlias = Object.hasOwn(this.aliases, sourceForAlias) && !sourceForAlias.endsWith("/");
236
+ if (!foundFile && !this.notFound.has(absSource.replace(/\/$/, ""))) {
237
+ this.notFound.add(absSource.replace(/\/$/, ""));
238
+ Log.warn(`[resolver] Source "${sourceOrLink}" found in "${filePath}" was resolved to "${resolvedPathAlias}", but the file is missing.`);
239
+ }
240
+ return {
241
+ path: foundFile ?? absSource,
242
+ exists: !!foundFile,
243
+ suffix,
244
+ isFileAlias,
245
+ isDirAlias: !isFileAlias
246
+ };
247
+ }
248
+ if (!source.startsWith(".")) {
249
+ const resolverResult = nodeModulesResolver.sync(this.root, source);
250
+ if (resolverResult.path) return {
251
+ path: resolverResult.path,
252
+ suffix,
253
+ exists: true,
254
+ isPackage: true
255
+ };
256
+ }
257
+ if (source.startsWith("./") || source.startsWith("../")) {
258
+ if (!this.notFound.has(absSource)) {
259
+ this.notFound.add(absSource);
260
+ Log.warn(`[resolver] Source "${sourceOrLink}" found in "${filePath}" points to a non-existent file.`);
261
+ }
262
+ return {
263
+ path: absSource,
264
+ suffix,
265
+ exists: false
266
+ };
267
+ }
268
+ }
269
+ resolveAlias(source) {
270
+ return Resolver.resolvePathAlias(source, this.aliases);
271
+ }
272
+ normalize(filePath) {
273
+ return normalize(filePath);
274
+ }
275
+ static isFile(filePath) {
276
+ try {
277
+ return statSync(filePath).isFile();
278
+ } catch (error) {
279
+ const code = error.code;
280
+ if (code === "ENOENT" || code === "ENOTDIR") return false;
281
+ throw error;
282
+ }
283
+ }
284
+ /** Aliased path to path */
285
+ static resolvePathAlias(filePath, aliases) {
286
+ for (const [key, value] of Object.entries(aliases)) {
287
+ if (key.endsWith("/")) {
288
+ if (!filePath.startsWith(key)) continue;
289
+ return filePath.replace(key, () => value);
290
+ }
291
+ if (filePath === key) return value;
292
+ }
293
+ }
294
+ /** Path to aliased path */
295
+ static resolveAliasPath(filePath, aliases) {
296
+ let shortest;
297
+ for (const [key, value] of Object.entries(aliases)) {
298
+ if (key.endsWith("/")) {
299
+ if (!filePath.startsWith(value)) continue;
300
+ const aliased = filePath.replace(value, () => key);
301
+ if (!shortest || aliased.length < shortest.length) shortest = aliased;
302
+ continue;
303
+ }
304
+ if (filePath === value && (!shortest || key.length < shortest.length)) shortest = key;
305
+ }
306
+ return shortest ?? filePath;
307
+ }
308
+ /** Path to aliased path */
309
+ aliasPath(filePath) {
310
+ return Resolver.resolveAliasPath(filePath, this.aliases);
311
+ }
312
+ findFile(filePath, shouldCheckDirectory = false) {
313
+ const missKey = (shouldCheckDirectory ? "d:" : "f:") + filePath;
314
+ if (this.isProduction && this.misses.has(missKey)) return;
315
+ const found = this.#findFileUncached(filePath, shouldCheckDirectory);
316
+ if (found === void 0 && this.isProduction) this.misses.add(missKey);
317
+ return found;
318
+ }
319
+ #findFileUncached(filePath, shouldCheckDirectory) {
320
+ if (this.files.has(filePath)) return filePath;
321
+ if (Resolver.isFile(filePath)) {
322
+ this.files.add(filePath);
323
+ return filePath;
324
+ }
325
+ const extension = extname(filePath);
326
+ if (!extension) {
327
+ for (const candidateExtension of [...Resolver.JS_EXTENSIONS, ...Resolver.HTML_EXTENSIONS]) {
328
+ const candidate = replaceExtension(filePath, candidateExtension);
329
+ if (this.files.has(candidate)) return candidate;
330
+ if (Resolver.isFile(candidate)) {
331
+ this.files.add(candidate);
332
+ return candidate;
333
+ }
334
+ }
335
+ const withIndex = join(filePath, "index");
336
+ for (const candidateExtension of Resolver.HTML_EXTENSIONS) {
337
+ const candidate = replaceExtension(withIndex, candidateExtension);
338
+ if (this.files.has(candidate)) return candidate;
339
+ if (Resolver.isFile(candidate)) {
340
+ this.files.add(candidate);
341
+ return candidate;
342
+ }
343
+ }
344
+ if (shouldCheckDirectory) {
345
+ if (this.directories.has(filePath)) return filePath;
346
+ if (existsSync(filePath)) {
347
+ this.directories.add(filePath);
348
+ return filePath;
349
+ }
350
+ }
351
+ return;
352
+ }
353
+ if (Resolver.JS_EXTENSIONS.has(extension)) {
354
+ for (const jsExtension of Resolver.JS_EXTENSIONS) {
355
+ const candidate = replaceExtension(filePath, jsExtension);
356
+ if (Resolver.isFile(candidate)) {
357
+ this.files.add(candidate);
358
+ return candidate;
359
+ }
360
+ }
361
+ return;
362
+ }
363
+ }
364
+ };
365
+
366
+ //#endregion
13
367
  //#region src/types/metadata.ts
14
368
  const METADATA_TYPES = Object.freeze({
15
369
  Script: "Script",
@@ -25,7 +379,7 @@ const METADATA_TYPES = Object.freeze({
25
379
 
26
380
  //#endregion
27
381
  //#region src/helpers/is-script-type.ts
28
- const allowedTypes = new Set([
382
+ const allowedTypes = /* @__PURE__ */ new Set([
29
383
  "module",
30
384
  "text/javascript",
31
385
  "application/javascript",
@@ -84,7 +438,8 @@ function filterScriptMetadata(metadata) {
84
438
  for (const scriptTag of scriptTags) {
85
439
  const scriptId = scriptTag.getAttribute(CUSTOM_ATTRIBUTES.MetadataID);
86
440
  if (!scriptId) continue;
87
- if (!isScriptType(scriptTag.getAttribute("type"))) continue;
441
+ const scriptType = scriptTag.getAttribute("type");
442
+ if (!isScriptType(scriptType)) continue;
88
443
  const scriptMetadata = metadata.scriptsMetadataList.get(scriptId);
89
444
  if (!scriptMetadata) continue;
90
445
  result.push({
@@ -125,11 +480,6 @@ function filterStyleMetadata(metadata) {
125
480
  return result;
126
481
  }
127
482
 
128
- //#endregion
129
- //#region src/helpers/babel-fixed-imports.ts
130
- const generator = typeof _generator === "function" ? _generator : _generator.default;
131
- const traverse = typeof _traverse === "function" ? _traverse : _traverse.default;
132
-
133
483
  //#endregion
134
484
  //#region src/utilities/highlight-code.ts
135
485
  /** - Highlight code string for terminal */
@@ -156,7 +506,7 @@ function highlightCode(code, { lang = "ts", maxCodeLength = 170, maxLineLength =
156
506
  withNewLines += currentLine + "\n";
157
507
  }
158
508
  let highlighted = createEmphasize(common).highlight(lang, withNewLines.trim()).value;
159
- if (isTruncated) highlighted += "\n" + c.inverse(" ... ");
509
+ if (isTruncated) highlighted += "\n" + chalk.inverse(" ... ");
160
510
  if (!boxed) return highlighted;
161
511
  return boxen(highlighted, {
162
512
  padding: .5,
@@ -168,6 +518,7 @@ function highlightCode(code, { lang = "ts", maxCodeLength = 170, maxLineLength =
168
518
 
169
519
  //#endregion
170
520
  //#region src/utilities/print-formatted-error.ts
521
+ const generator = typeof _generator === "function" ? _generator : _generator.default;
171
522
  var PrintFormattedError = class PrintFormattedError {
172
523
  options = {};
173
524
  constructor(options = {}) {
@@ -191,9 +542,9 @@ var PrintFormattedError = class PrintFormattedError {
191
542
  Object.assign(options, item);
192
543
  }
193
544
  let message = "";
194
- if (options.filePath) message += c.italic(options.filePath) + "\n";
545
+ if (options.filePath) message += chalk.italic(options.filePath) + "\n";
195
546
  const functionName = options.function?.name ?? options.functionName;
196
- if (functionName) message += c.dim(`[${functionName}] `);
547
+ if (functionName) message += chalk.dim(`[${functionName}] `);
197
548
  message += messagesArray.join(" ");
198
549
  const codeFromNode = options.node && nodeToString(options.node);
199
550
  const code = options.code ?? codeFromNode?.code;
@@ -233,54 +584,6 @@ function nodeToString(node) {
233
584
  };
234
585
  }
235
586
 
236
- //#endregion
237
- //#region src/utilities/value-or-error.ts
238
- function errorsWrapper(function_) {
239
- return (...arguments_) => {
240
- try {
241
- const promiseOrValue = function_(...arguments_);
242
- if (isPromise(promiseOrValue)) return new Promise((resolve) => {
243
- promiseOrValue.then((value) => {
244
- resolve([value, null]);
245
- }).catch((error) => {
246
- resolve(handleError(error, function_.name));
247
- });
248
- });
249
- return [promiseOrValue, null];
250
- } catch (error) {
251
- return handleError(error, function_.name);
252
- }
253
- };
254
- }
255
- function isPromise(value) {
256
- return value && typeof value === "object" && "then" in value && typeof value.then === "function" && "catch" in value && typeof value.catch === "function";
257
- }
258
- function handleError(error, functionName = "") {
259
- if (!error) return [null, /* @__PURE__ */ new Error(`[${functionName}] Unexpected error`)];
260
- if (typeof error === "string") return [null, new Error(error)];
261
- if (error instanceof Error) return [null, error];
262
- if (typeof error === "object" && "message" in error && typeof error.message === "string") return [null, new Error(error.message)];
263
- return [null, /* @__PURE__ */ new Error(`[${functionName}] Unexpected error`)];
264
- }
265
- const valueOrError = errorsWrapper;
266
-
267
- //#endregion
268
- //#region src/utilities/read-file.ts
269
- async function safeReadFile(path, options) {
270
- try {
271
- return [await readFile(path, options), null];
272
- } catch (error) {
273
- return handleError(error, "readFile");
274
- }
275
- }
276
- function safeReadFileSync(path, options) {
277
- try {
278
- return [readFileSync(path, options), null];
279
- } catch (error) {
280
- return handleError(error, "readFileSync");
281
- }
282
- }
283
-
284
587
  //#endregion
285
588
  //#region src/utilities/utilities.ts
286
589
  /** `process.stdout.write` */
@@ -289,10 +592,9 @@ function print(...input) {
289
592
  }
290
593
  /** - Clear the line in the terminal */
291
594
  function clearLn() {
292
- if ("clearLine" in process.stdout && typeof process.stdout.clearLine === "function") {
293
- process.stdout.clearLine(0);
294
- process.stdout.cursorTo(0);
295
- }
595
+ if (!("clearLine" in process.stdout && typeof process.stdout.clearLine === "function")) return;
596
+ process.stdout.clearLine(0);
597
+ process.stdout.cursorTo(0);
296
598
  }
297
599
  /** Used to assign a computed value to a variable */
298
600
  function assign(function_) {
@@ -405,7 +707,7 @@ function hashContent(content) {
405
707
  }
406
708
  const matchHtmlRegExp = /["'&<>]/;
407
709
  function escapeHtml(input) {
408
- const string = "" + input;
710
+ const string = input;
409
711
  const match = matchHtmlRegExp.exec(string);
410
712
  if (!match) return string;
411
713
  let escape;
@@ -439,47 +741,5 @@ function escapeHtml(input) {
439
741
  }
440
742
 
441
743
  //#endregion
442
- //#region src/helpers/dependency-tracker.ts
443
- /**
444
- * Tracks bidirectional dependencies between importers and their sources.\
445
- * Handles reconciliation when dependencies change, so stale entries are automatically removed when an importer stops referencing
446
- * a source.
447
- */
448
- var DependencyTracker = class {
449
- /** Source → Set of importers that depend on it */
450
- #sourcesToImporters = /* @__PURE__ */ new Map();
451
- /** Importer → Set of sources it depends on */
452
- #importerToSources = /* @__PURE__ */ new Map();
453
- /** Updates the full set of sources for a given importer, reconciling any stale entries from previous calls. */
454
- update(importer, sources) {
455
- const nextSources = new Set(sources);
456
- const previousSources = this.#importerToSources.get(importer) ?? /* @__PURE__ */ new Set();
457
- for (const source of previousSources) if (!nextSources.has(source)) this.#sourcesToImporters.get(source)?.delete(importer);
458
- for (const source of nextSources) {
459
- if (!this.#sourcesToImporters.has(source)) this.#sourcesToImporters.set(source, /* @__PURE__ */ new Set());
460
- this.#sourcesToImporters.get(source).add(importer);
461
- }
462
- this.#importerToSources.set(importer, nextSources);
463
- }
464
- /** Deletes all dependency data for a given id, whether it's acting as an importer, a source, or both (e.g. on file unlink). */
465
- delete(id) {
466
- this.#sourcesToImporters.delete(id);
467
- const sources = this.#importerToSources.get(id);
468
- if (sources) {
469
- for (const source of sources) this.#sourcesToImporters.get(source)?.delete(id);
470
- this.#importerToSources.delete(id);
471
- }
472
- }
473
- /** Returns all importers that depend on a given source, or an empty set. */
474
- getImporters(source) {
475
- return this.#sourcesToImporters.get(source) ?? /* @__PURE__ */ new Set();
476
- }
477
- /** Returns all sources that a given importer depends on, or an empty set. */
478
- getSources(importer) {
479
- return this.#importerToSources.get(importer) ?? /* @__PURE__ */ new Set();
480
- }
481
- };
482
-
483
- //#endregion
484
- export { isHtmlMetadata as A, PrintFormattedError as C, filterScriptMetadata as D, traverse as E, isSvgMetadata as F, isTextAssetMetadata as I, isWebManifestMetadata as L, isPackageMetadata as M, isScriptMetadata as N, filterStyleMetadata as O, isStyleMetadata as P, isScriptType as R, valueOrError as S, generator as T, kebabToCamelCase as _, capitalize as a, safeReadFile as b, cloneObject as c, getLineColumn as d, hashContent as f, isURL as g, isObject as h, camelCaseToKebabCase as i, isMarkdownMetadata as j, isBinaryAssetMetadata as k, downloadContent as l, isDefined as m, assign as n, clamp as o, humanReadableBytes as p, bytesToKB as r, clearLn as s, DependencyTracker as t, escapeHtml as u, mergeMaps as v, printFmtError as w, safeReadFileSync as x, print as y, METADATA_TYPES as z };
485
- //# sourceMappingURL=dependency-tracker-BuZfopIj.mjs.map
744
+ export { isTextAssetMetadata as A, isHtmlLink as B, isBinaryAssetMetadata as C, isScriptMetadata as D, isPackageMetadata as E, readJsonFile as F, splitHtmlLink as H, safeReadFile as I, safeReadFileSync as L, isScriptType as M, METADATA_TYPES as N, isStyleMetadata as O, Resolver as P, handleError as R, filterStyleMetadata as S, isMarkdownMetadata as T, DependencyTracker as U, isValidRelativePath as V, mergeMaps as _, clamp as a, printFmtError as b, downloadContent as c, hashContent as d, humanReadableBytes as f, kebabToCamelCase as g, isURL as h, capitalize as i, isWebManifestMetadata as j, isSvgMetadata as k, escapeHtml as l, isObject as m, bytesToKB as n, clearLn as o, isDefined as p, camelCaseToKebabCase as r, cloneObject as s, assign as t, getLineColumn as u, print as v, isHtmlMetadata as w, filterScriptMetadata as x, PrintFormattedError as y, valueOrError as z };
745
+ //# sourceMappingURL=utilities-D0KXIZ-B.mjs.map