@goodbyenjn/utils 26.4.0 → 26.4.2

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/README.md CHANGED
@@ -11,9 +11,9 @@ A modern TypeScript/JavaScript utility library providing a comprehensive collect
11
11
  - 🔒 **Type-safe**: Full TypeScript support with comprehensive type definitions and type inference
12
12
  - 📦 **Modular**: Import only what you need with tree-shakable exports and multiple entry points
13
13
  - 🛡️ **Result Pattern**: Functional error handling without exceptions, based on Rust-style Result types
14
- - 📁 **Safe File System**: Type-safe file system operations with Result-based error handling
15
- - 🐚 **Shell Execution**: Powerful and flexible shell command execution with piping support
16
- - 🧰 **Common Utilities**: String manipulation, math operations, promise utilities, and error handling
14
+ - 📁 **VFile & FS**: Type-safe file system operations and a powerful virtual file object
15
+ - 🐚 **Exec**: Powerful and flexible command execution with safe and unsafe variants
16
+ - 🧰 **Common Utilities**: String manipulation, math operations, promise utilities, and JSON handling
17
17
  - 📊 **Remeda Extensions**: Extended utilities built on top of [Remeda](https://remedajs.com/)
18
18
 
19
19
  ## Installation
@@ -33,9 +33,10 @@ yarn add @goodbyenjn/utils
33
33
  ```typescript
34
34
  // Import what you need from the main module
35
35
  import { sleep, template } from "@goodbyenjn/utils";
36
- import { $ } from "@goodbyenjn/utils/shell";
37
- import { safeReadFile } from "@goodbyenjn/utils/fs";
36
+ import { exec, safeExec } from "@goodbyenjn/utils/exec";
37
+ import { BaseVFile } from "@goodbyenjn/utils/fs";
38
38
  import { ok, Result } from "@goodbyenjn/utils/result";
39
+ import { parse, safeParse } from "@goodbyenjn/utils/json";
39
40
  ```
40
41
 
41
42
  ### Common Utilities
@@ -154,34 +155,39 @@ setTimeout(() => resolve("done!"), 1000);
154
155
  const result = await promise;
155
156
  ```
156
157
 
157
- #### Shell Command Execution
158
+ ### Command Execution
158
159
 
159
160
  ```typescript
160
- import { $ } from "@goodbyenjn/utils/shell";
161
+ import { exec, safeExec } from "@goodbyenjn/utils/exec";
161
162
 
162
- // Execute shell commands with template literals
163
- const result = await $`npm install`;
164
- console.log(result.stdout);
165
- console.log(result.stderr);
163
+ // 1. Unsafe Execution (throws on failure)
164
+ const output = await exec`npm install`;
165
+ console.log(output.stdout);
166
166
 
167
167
  // String command with args
168
- const output = await $("ls", ["-la"]);
169
- console.log(output.stdout);
168
+ const lsOutput = await exec("ls", ["-la"]);
169
+ console.log(lsOutput.stdout);
170
170
 
171
- // Pipe commands
172
- const piped = await $`echo "hello"`.pipe`cat`;
171
+ // 2. Safe Execution (returns Result)
172
+ const safeOutput = await safeExec`npm install`;
173
+ if (safeOutput.isOk()) {
174
+ console.log("Success:", safeOutput.unwrap().stdout);
175
+ } else {
176
+ // Result contains error information (e.g., NonZeroExitError)
177
+ console.error("Failed:", safeOutput.unwrapErr().message);
178
+ }
179
+
180
+ // 3. Pipe Output
181
+ const piped = await exec`echo "hello"`.pipe`cat`;
173
182
  console.log(piped.stdout);
174
183
 
175
- // Iterate output line by line
176
- for await (const line of $`cat large-file.txt`) {
184
+ // 4. Iterate Output
185
+ for await (const line of exec`cat large-file.txt`) {
177
186
  console.log(line);
178
187
  }
179
188
 
180
- // Using options
181
- const result2 = await $("npm", ["install"], { cwd: "/path/to/project" });
182
-
183
- // Factory function with options
184
- const withCwd = $({ cwd: "/path/to/project" });
189
+ // 5. Configuration Factory
190
+ const withCwd = exec({ cwd: "/path/to/project" });
185
191
  const result3 = await withCwd`npm install`;
186
192
  ```
187
193
 
@@ -236,6 +242,25 @@ const throttledScroll = throttle(() => {
236
242
  window.addEventListener("scroll", throttledScroll);
237
243
  ```
238
244
 
245
+ #### JSON Handling
246
+
247
+ ```typescript
248
+ import { parse, stringify, safeParse, safeStringify } from "@goodbyenjn/utils/json";
249
+
250
+ // Standard JSON parsing (returns value or nil)
251
+ const data = parse('{"a": 1}'); // { a: 1 }
252
+ const invalid = parse("bad"); // nil
253
+
254
+ // Safe JSON parsing (returns Result)
255
+ const result = safeParse('{"a": 1}');
256
+ if (result.isOk()) {
257
+ console.log(result.unwrap().a);
258
+ }
259
+
260
+ // Safe stringify
261
+ const json = safeStringify({ a: 1 }); // Result<string, Error>
262
+ ```
263
+
239
264
  ### File System Operations
240
265
 
241
266
  ```typescript
@@ -248,33 +273,50 @@ import {
248
273
  safeMkdir,
249
274
  safeRm,
250
275
  safeReadFileByLine,
276
+ BaseVFile,
251
277
  } from "@goodbyenjn/utils/fs";
252
278
 
253
- // Read text file safely
254
- const textResult = await safeReadFile("config.txt", "utf8");
279
+ // ... (safe operations)
280
+
281
+ // BaseVFile - Unified file handling
282
+ const vfile = new BaseVFile("example.json");
283
+
284
+ // Fluid path manipulation
285
+ vfile.filename("data").extname("ts");
286
+ console.log(vfile.basename()); // "data.ts"
287
+
288
+ // Cross-platform path handling
289
+ const relative = vfile.pathname.relative(); // "data.ts" (relative to cwd)
290
+ const absolute = vfile.pathname(); // "/full/path/to/data.ts"
291
+
292
+ // Built-in operations (available in extended VFile implementations)
293
+ // await vfile.read(); // Get content
294
+ // await vfile.write(); // Write content
295
+ ```
296
+
255
297
  if (textResult.isOk()) {
256
- console.log("File content:", textResult.unwrap());
298
+ console.log("File content:", textResult.unwrap());
257
299
  } else {
258
- console.error("Failed to read file:", textResult.unwrapErr().message);
300
+ console.error("Failed to read file:", textResult.unwrapErr().message);
259
301
  }
260
302
 
261
303
  // Read and parse JSON safely
262
304
  const jsonResult = await safeReadJson("package.json");
263
305
  if (jsonResult.isOk()) {
264
- const pkg = jsonResult.unwrap();
265
- console.log("Package name:", pkg.name);
306
+ const pkg = jsonResult.unwrap();
307
+ console.log("Package name:", pkg.name);
266
308
  }
267
309
 
268
310
  // Write JSON file
269
311
  const writeResult = await safeWriteJson("data.json", { users: [] }, { pretty: true });
270
312
  if (writeResult.isErr()) {
271
- console.error("Write failed:", writeResult.unwrapErr());
313
+ console.error("Write failed:", writeResult.unwrapErr());
272
314
  }
273
315
 
274
316
  // Check if file exists
275
317
  const existsResult = await safeExists("path/to/file.txt");
276
318
  if (existsResult.isOk() && existsResult.unwrap()) {
277
- console.log("File exists!");
319
+ console.log("File exists!");
278
320
  }
279
321
 
280
322
  // Create directories (recursive)
@@ -286,11 +328,12 @@ const rmResult = await safeRm("build", { recursive: true, force: true });
286
328
  // Read file line by line
287
329
  const lineResult = await safeReadFileByLine("large-file.log");
288
330
  if (lineResult.isOk()) {
289
- for await (const line of lineResult.unwrap()) {
290
- console.log(line);
291
- }
331
+ for await (const line of lineResult.unwrap()) {
332
+ console.log(line);
292
333
  }
293
- ```
334
+ }
335
+
336
+ ````
294
337
 
295
338
  ### Glob Patterns
296
339
 
@@ -306,7 +349,7 @@ const syncFiles = globSync("**/*.test.ts", { cwd: "tests" });
306
349
 
307
350
  // Convert file path to glob pattern
308
351
  const pattern = convertPathToPattern("/home/user/project");
309
- ```
352
+ ````
310
353
 
311
354
  ### Result Pattern - Functional Error Handling
312
355
 
@@ -1,8 +1,7 @@
1
- import { i as __toESM, t as __commonJSMin } from "./chunk-7ffde8d4.js";
2
- import { Dt as isBoolean, Et as isBigInt, Gr as isFunction, Gt as isString, It as isNonNullish, Kt as isSymbol, Nt as isError, Tt as isArray, Vt as isPlainObject, Wr as isPromiseLike, p as clamp, zt as isNumber } from "./chunk-b61db0a7.js";
3
-
4
- //#region node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/index.js
5
- var require_safe_stable_stringify = __commonJSMin(((exports, module) => {
1
+ import { a as __toESM, t as __commonJSMin } from "./chunk-3ce2ea14.js";
2
+ import { add, addProp, allPass, anyPass, capitalize, ceil, chunk, clamp, clone, concat, conditional, constant, countBy, debounce as debounce$1, defaultTo, difference, differenceWith, divide, doNothing, drop, dropFirstBy, dropLast, dropLastWhile, dropWhile, endsWith, entries, evolve, filter, find, findIndex, findLast, findLastIndex, first, firstBy, flat, flatMap, floor, forEach, forEachObj, fromEntries, fromKeys, funnel, groupBy, groupByProp, hasAtLeast, hasSubObject, identity, indexBy, intersection, intersectionWith, invert, isArray, isBigInt, isBoolean, isDate, isDeepEqual, isDefined, isEmpty, isEmptyish, isError, isFunction, isIncludedIn, isNonNull, isNonNullish, isNot, isNullish, isNumber, isObjectType, isObjectType as isObjectType$1, isPlainObject, isPromise, isShallowEqual, isStrictEqual, isString as isString$1, isSymbol, isTruthy, join as join$1, keys, last, length, map, mapKeys, mapToObj, mapValues, mapWithFeedback, mean, meanBy, median, merge, mergeAll, mergeDeep, multiply, nthBy, objOf, omit, omitBy, once, only, partialBind, partialLastBind, partition, pathOr, pick, pickBy, pipe, piped, product, prop, pullObject, purry, purry as purry$1, randomBigInt, randomInteger, randomString, range, rankBy, reduce, reverse, round, sample, set, setPath, shuffle, sliceString, sort, sortBy, sortedIndex, sortedIndexBy, sortedIndexWith, sortedLastIndex, sortedLastIndexBy, splice, split as split$1, splitAt, splitWhen, startsWith, stringToPath, subtract, sum, sumBy, swapIndices, swapProps, take, takeFirstBy, takeLast, takeLastWhile, takeWhile, tap, times, toCamelCase, toKebabCase, toLowerCase, toSnakeCase, toTitleCase, toUpperCase, truncate, uncapitalize, unique, uniqueBy, uniqueWith, values, when, zip, zipWith } from "remeda";
3
+ import { accumulateAsync as accumulateP, accumulateSync as accumulate, awaitAll, buffer, chunkAsync as chunkP, compose, concatAsync as concatP, concurrency, differenceAsync as differenceP, differenceByAsync as differenceByP, differenceBySync as differenceBy, differenceWithAsync as differenceWithP, dropAsync as dropP, everyAsync as everyP, everySync as every, executeAsync as executeP, executeSync as execute, filterAsync as filterP, findAsync as findP, flatMapAsync as flatMapP, flattenAsync as flattenP, flattenSync as flatten, forEachAsync as forEachP, intersectionAsync as intersectionP, intersectionByAsync as intersectionByP, intersectionBySync as intersectionBy, intersectionWithAsync as intersectionWithP, mapAsync as mapP, peekAsync as peekP, peekSync as peek, reduceAsync as reduceP, serializeAsync as serializeP, serializeSync as serialize, someAsync as someP, someSync as some, takeAsync as takeP, throttle as throttle$1, toArrayAsync as toArrayP, toArraySync as toArray, toIteratorAsync as toIteratorP, toIteratorSync as toIterator, uniqueAsync as uniqueP, uniqueByAsync as uniqueByP, uniqueWithAsync as uniqueWithP } from "rotery";
4
+ const configure = __toESM(__commonJSMin(((exports, module) => {
6
5
  const { hasOwnProperty } = Object.prototype;
7
6
  const stringify = configure();
8
7
  stringify.configure = configure;
@@ -410,13 +409,10 @@ var require_safe_stable_stringify = __commonJSMin(((exports, module) => {
410
409
  }
411
410
  return stringify;
412
411
  }
413
- }));
414
-
412
+ }))(), 1).configure;
415
413
  //#endregion
416
- //#region node_modules/.pnpm/safe-stable-stringify@2.5.0/node_modules/safe-stable-stringify/esm/wrapper.js
417
- var import_safe_stable_stringify = __toESM(require_safe_stable_stringify(), 1);
418
- const configure = import_safe_stable_stringify.configure;
419
-
414
+ //#region src/json/stable.ts
415
+ const stableStringify = configure({ bigint: true });
420
416
  //#endregion
421
417
  //#region src/result/error.ts
422
418
  const prepare = (result, msg) => {
@@ -475,7 +471,6 @@ Stack trace:`, prepared.options);
475
471
  return this.#formatted;
476
472
  }
477
473
  };
478
-
479
474
  //#endregion
480
475
  //#region src/result/result.ts
481
476
  const never = void 0;
@@ -495,7 +490,7 @@ var Result = class Result {
495
490
  return new Result(false, error, never);
496
491
  }
497
492
  static try(fnOrPromise, onThrow) {
498
- if (!isFunction(fnOrPromise) && !isPromiseLike(fnOrPromise)) {
493
+ if (!isFunction$1(fnOrPromise) && !isPromiseLike(fnOrPromise)) {
499
494
  const error = new TypeError("Argument must be a function or a promise");
500
495
  return this.err(transformError(error, onThrow));
501
496
  }
@@ -629,19 +624,27 @@ var Result = class Result {
629
624
  };
630
625
  const ok = Result.ok;
631
626
  const err = Result.err;
632
-
627
+ const isResult = Result.is;
633
628
  //#endregion
634
- //#region src/common/json.ts
635
- const stringify = configure({ bigint: true });
636
- const safeParse = (text, reviver) => {
637
- return Result.wrap(JSON.parse, Error)(text, reviver).context(`Failed to parse JSON string: ${text.length > 100 ? text.slice(0, 100) + "..." : text}`);
638
- };
639
- const unsafeParse = (text, reviver) => {
640
- const result = safeParse(text, reviver);
641
- if (result.isErr()) return void 0;
642
- return result.unwrap(null);
643
- };
644
-
629
+ //#region src/remeda/hasOwnProperty.ts
630
+ function hasOwnProperty(...args) {
631
+ return purry(hasOwnPropertyImplementation, args);
632
+ }
633
+ function hasOwnPropertyImplementation(data, properties) {
634
+ if (!isObjectType(data)) return false;
635
+ for (const property of properties) if (!Object.hasOwn(data, property)) return false;
636
+ return true;
637
+ }
638
+ //#endregion
639
+ //#region src/remeda/isFunction.ts
640
+ function isFunction$1(data) {
641
+ return typeof data === "function";
642
+ }
643
+ //#endregion
644
+ //#region src/remeda/isPromiseLike.ts
645
+ function isPromiseLike(data) {
646
+ return isObjectType(data) && isFunction(data.then) && Object.getOwnPropertyDescriptor(data, "then")?.get === void 0;
647
+ }
645
648
  //#endregion
646
649
  //#region src/common/error.ts
647
650
  const normalizeError = (error, caller) => {
@@ -654,13 +657,12 @@ const getErrorMessage = (error, message) => {
654
657
  if (isError(error)) return error.message;
655
658
  if (message !== void 0) return message;
656
659
  let msg;
657
- if (isString(error) || isNumber(error) || isBigInt(error) || isBoolean(error) || isSymbol(error)) msg = error.toString();
660
+ if (isString$1(error) || isNumber(error) || isBigInt(error) || isBoolean(error) || isSymbol(error)) msg = error.toString();
658
661
  else if (error === void 0) msg = "undefined";
659
662
  else if (error === null) msg = "null";
660
- else msg = stringify(error);
663
+ else msg = stableStringify(error);
661
664
  return msg;
662
665
  };
663
-
664
666
  //#endregion
665
667
  //#region src/common/math.ts
666
668
  const linear = (value, range) => {
@@ -676,7 +678,10 @@ const scale = (value, inRange, outRange) => {
676
678
  const [outMin, outMax] = outRange;
677
679
  return linear((value - inMin) / (inMax - inMin), [outMin, outMax]);
678
680
  };
679
-
681
+ //#endregion
682
+ //#region src/common/nil.ts
683
+ const nil = Symbol("nil");
684
+ const isNil = (value) => value === nil;
680
685
  //#endregion
681
686
  //#region src/common/parse.ts
682
687
  const parseKey = (input, raw = input) => {
@@ -757,7 +762,6 @@ const parseValueToBoolean = (value, defaultValue) => {
757
762
  if (/^(?:n|no|false|0|off)$/.test(str)) return false;
758
763
  return defaultValue;
759
764
  };
760
-
761
765
  //#endregion
762
766
  //#region src/common/promise.ts
763
767
  const sleep = (ms, callback) => new Promise((resolve) => {
@@ -804,7 +808,7 @@ const createLock = () => {
804
808
  };
805
809
  };
806
810
  const createPromiseWithResolvers = () => {
807
- if (isFunction(Promise.withResolvers)) return Promise.withResolvers();
811
+ if (isFunction$1(Promise.withResolvers)) return Promise.withResolvers();
808
812
  let resolve;
809
813
  let reject;
810
814
  return {
@@ -816,7 +820,6 @@ const createPromiseWithResolvers = () => {
816
820
  reject
817
821
  };
818
822
  };
819
-
820
823
  //#endregion
821
824
  //#region src/common/string.ts
822
825
  const REGEXP_WHITESPACE_ONLY = /^\s*$/;
@@ -864,7 +867,7 @@ function unindent(...params) {
864
867
  let trimStart = true;
865
868
  let trimEnd = true;
866
869
  const unindentImpl = (...params) => {
867
- const lines = splitByLineBreak(isString(params[0]) ? params[0] : concatTemplateStrings(params[0], params.slice(1)));
870
+ const lines = splitByLineBreak(isString$1(params[0]) ? params[0] : concatTemplateStrings(params[0], params.slice(1)));
868
871
  let commonIndent = Number.POSITIVE_INFINITY;
869
872
  let firstContentLine = -1;
870
873
  for (let i = 0; i < lines.length; i++) {
@@ -887,7 +890,7 @@ function unindent(...params) {
887
890
  trimEnd = params[1] !== false;
888
891
  return unindentImpl;
889
892
  }
890
- if (isString(params[0]) || isArray(params[0])) return unindentImpl(...params);
893
+ if (isString$1(params[0]) || isArray(params[0])) return unindentImpl(...params);
891
894
  throw new TypeError(`First parameter has an invalid type: "${typeof params[0]}"`);
892
895
  }
893
896
  function indent(...params) {
@@ -895,7 +898,7 @@ function indent(...params) {
895
898
  let trimStart = true;
896
899
  let trimEnd = true;
897
900
  const indentImpl = (...params) => {
898
- const lines = splitByLineBreak(isString(params[0]) ? params[0] : concatTemplateStrings(params[0], params.slice(1)));
901
+ const lines = splitByLineBreak(isString$1(params[0]) ? params[0] : concatTemplateStrings(params[0], params.slice(1)));
899
902
  const whitespaceLines = lines.map((line) => REGEXP_WHITESPACE_ONLY.test(line));
900
903
  let startIndex = 0;
901
904
  let endIndex = lines.length;
@@ -913,7 +916,7 @@ function indent(...params) {
913
916
  indentString = " ".repeat(params[0]);
914
917
  return indentImpl;
915
918
  }
916
- if (isString(params[0])) {
919
+ if (isString$1(params[0])) {
917
920
  indentString = params[0];
918
921
  return indentImpl;
919
922
  }
@@ -923,14 +926,13 @@ function template(str, ...args) {
923
926
  const [firstArg, fallback] = args;
924
927
  if (isPlainObject(firstArg)) {
925
928
  const mapping = firstArg;
926
- return str.replace(/\{(\w+)\}/g, (_, key) => mapping[key] || ((isFunction(fallback) ? fallback(key) : fallback) ?? key));
929
+ return str.replace(/\{(\w+)\}/g, (_, key) => mapping[key] || ((isFunction$1(fallback) ? fallback(key) : fallback) ?? key));
927
930
  } else return str.replace(/\{(\d+)\}/g, (_, key) => {
928
931
  const index = Number(key);
929
932
  if (Number.isNaN(index)) return key;
930
933
  return args[index];
931
934
  });
932
935
  }
933
-
934
936
  //#endregion
935
937
  //#region src/common/throttle.ts
936
938
  const wrap = (fn, wait, options) => {
@@ -964,6 +966,5 @@ const throttle = (fn, wait = 0, options = {}) => {
964
966
  trailing
965
967
  });
966
968
  };
967
-
968
969
  //#endregion
969
- export { Result as A, linear as C, safeParse as D, normalizeError as E, ok as M, ResultError as N, stringify as O, parseValueToBoolean as S, getErrorMessage as T, createLock as _, concatTemplateStrings as a, sleep as b, joinWithSlash as c, split as d, splitByLineBreak as f, unindent as g, toForwardSlash as h, addSuffix as i, err as j, unsafeParse as k, removePrefix as l, template as m, throttle as n, indent as o, splitWithSlash as p, addPrefix as r, join as s, debounce as t, removeSuffix as u, createPromiseWithResolvers as v, scale as w, parseKeyValuePairs as x, createSingleton as y };
970
+ export { differenceBy as $, pipe as $n, toIterator as $r, isArray as $t, accumulateP as A, mapValues as An, splice as Ar, flatMapP as At, chunkP as B, objOf as Bn, swapProps as Br, groupBy as Bt, isNil as C, isResult as Ci, keys as Cn, sort as Cr, findLast as Ct, getErrorMessage as D, mapKeys as Dn, sortedIndexWith as Dr, firstBy as Dt, scale as E, stableStringify as Ei, map as En, sortedIndexBy as Er, first as Et, awaitAll as F, merge as Fn, stringToPath as Fr, forEachObj as Ft, concatP as G, partialBind as Gn, takeP as Gr, indexBy as Gt, clone as H, omitBy as Hn, takeFirstBy as Hr, hasAtLeast as Ht, buffer as I, mergeAll as In, subtract as Ir, forEachP as It, constant as J, pathOr as Jn, throttle$1 as Jr, intersectionByP as Jt, concurrency as K, partialLastBind as Kn, takeWhile as Kr, intersection as Kt, capitalize as L, mergeDeep as Ln, sum as Lr, fromEntries as Lt, addProp as M, mean as Mn, splitAt as Mr, flattenP as Mt, allPass as N, meanBy as Nn, splitWhen as Nr, floor as Nt, normalizeError as O, mapP as On, sortedLastIndex as Or, flat as Ot, anyPass as P, median as Pn, startsWith as Pr, forEach as Pt, difference as Q, pickBy as Qn, toCamelCase as Qr, invert as Qt, ceil as R, multiply as Rn, sumBy as Rr, fromKeys as Rt, parseValueToBoolean as S, err as Si, join$1 as Sn, someP as Sr, findIndex as St, linear as T, ResultError as Ti, length as Tn, sortedIndex as Tr, findP as Tt, compose as U, once as Un, takeLast as Ur, hasSubObject as Ut, clamp as V, omit as Vn, take as Vr, groupByProp as Vt, concat as W, only as Wn, takeLastWhile as Wr, identity as Wt, debounce$1 as X, peekP as Xn, toArray as Xr, intersectionWith as Xt, countBy as Y, peek as Yn, times as Yr, intersectionP as Yt, defaultTo as Z, pick as Zn, toArrayP as Zr, intersectionWithP as Zt, createLock as _, zipWith as _i, isShallowEqual as _n, set as _r, execute as _t, concatTemplateStrings as a, toUpperCase as ai, isEmpty as an, randomBigInt as ar, doNothing as at, sleep as b, hasOwnProperty as bi, isSymbol as bn, sliceString as br, filterP as bt, joinWithSlash as c, unique as ci, isIncludedIn as cn, range as cr, dropLast as ct, split as d, uniqueP as di, isNot as dn, reduceP as dr, dropWhile as dt, toIteratorP as ei, isBigInt as en, piped as er, differenceByP as et, splitByLineBreak as f, uniqueWith as fi, isNullish as fn, reverse as fr, endsWith as ft, unindent as g, zip as gi, isPromise as gn, serializeP as gr, evolve as gt, toForwardSlash as h, when as hi, isPlainObject as hn, serialize as hr, everyP as ht, addSuffix as i, toTitleCase as ii, isDefined as in, purry$1 as ir, divide as it, add as j, mapWithFeedback as jn, split$1 as jr, flatten as jt, accumulate as k, mapToObj as kn, sortedLastIndexBy as kr, flatMap as kt, removePrefix as l, uniqueBy as li, isNonNull as ln, rankBy as lr, dropLastWhile as lt, template as m, values as mi, isObjectType$1 as mn, sample as mr, every as mt, throttle as n, toLowerCase as ni, isDate as nn, prop as nr, differenceWith as nt, indent as o, truncate as oi, isEmptyish as on, randomInteger as or, drop as ot, splitWithSlash as p, uniqueWithP as pi, isNumber as pn, round as pr, entries as pt, conditional as q, partition as qn, tap as qr, intersectionBy as qt, addPrefix as r, toSnakeCase as ri, isDeepEqual as rn, pullObject as rr, differenceWithP as rt, join as s, uncapitalize as si, isError as sn, randomString as sr, dropFirstBy as st, debounce as t, toKebabCase as ti, isBoolean as tn, product as tr, differenceP as tt, removeSuffix as u, uniqueByP as ui, isNonNullish as un, reduce as ur, dropP as ut, createPromiseWithResolvers as v, isPromiseLike as vi, isStrictEqual as vn, setPath as vr, executeP as vt, nil as w, ok as wi, last as wn, sortBy as wr, findLastIndex as wt, parseKeyValuePairs as x, Result as xi, isTruthy as xn, some as xr, find as xt, createSingleton as y, isFunction$1 as yi, isString$1 as yn, shuffle as yr, filter as yt, chunk as z, nthBy as zn, swapIndices as zr, funnel as zt };
@@ -0,0 +1,25 @@
1
+ import { Si as err, w as nil, xi as Result } from "./chunk-11b9216b.js";
2
+ //#region src/json/safe.ts
3
+ const safeStringify = Result.wrap(JSON.stringify);
4
+ const stringify$1 = (value, replacer, space) => Result.gen(function* () {
5
+ const text = yield* safeStringify(value, replacer, space).context(`Failed to stringify value: ${String(value)}`);
6
+ if (text === void 0) return err(new TypeError(`Value cannot be stringified: ${String(value)}`));
7
+ return text;
8
+ });
9
+ const safeParse = Result.wrap(JSON.parse);
10
+ const parse$1 = (text, reviver) => safeParse(text, reviver).context(`Failed to parse JSON string: ${text.length > 100 ? text.slice(0, 100) + "..." : text}`);
11
+ //#endregion
12
+ //#region src/json/unsafe.ts
13
+ function stringify(value, replacer, space) {
14
+ const text = JSON.stringify(value, replacer, space);
15
+ return text === void 0 ? nil : text;
16
+ }
17
+ const parse = (text, reviver) => {
18
+ try {
19
+ return JSON.parse(text, reviver);
20
+ } catch {
21
+ return nil;
22
+ }
23
+ };
24
+ //#endregion
25
+ export { stringify$1 as i, stringify as n, parse$1 as r, parse as t };
@@ -1,3 +1,4 @@
1
+ import { createRequire } from "node:module";
1
2
  //#region \0rolldown/runtime.js
2
3
  var __create = Object.create;
3
4
  var __defProp = Object.defineProperty;
@@ -8,28 +9,20 @@ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
9
  var __commonJSMin = (cb, mod) => () => (mod || cb((mod = { exports: {} }).exports, mod), mod.exports);
9
10
  var __exportAll = (all, no_symbols) => {
10
11
  let target = {};
11
- for (var name in all) {
12
- __defProp(target, name, {
13
- get: all[name],
14
- enumerable: true
15
- });
16
- }
17
- if (!no_symbols) {
18
- __defProp(target, Symbol.toStringTag, { value: "Module" });
19
- }
12
+ for (var name in all) __defProp(target, name, {
13
+ get: all[name],
14
+ enumerable: true
15
+ });
16
+ if (!no_symbols) __defProp(target, Symbol.toStringTag, { value: "Module" });
20
17
  return target;
21
18
  };
22
19
  var __copyProps = (to, from, except, desc) => {
23
- if (from && typeof from === "object" || typeof from === "function") {
24
- for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
25
- key = keys[i];
26
- if (!__hasOwnProp.call(to, key) && key !== except) {
27
- __defProp(to, key, {
28
- get: ((k) => from[k]).bind(null, key),
29
- enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
30
- });
31
- }
32
- }
20
+ if (from && typeof from === "object" || typeof from === "function") for (var keys = __getOwnPropNames(from), i = 0, n = keys.length, key; i < n; i++) {
21
+ key = keys[i];
22
+ if (!__hasOwnProp.call(to, key) && key !== except) __defProp(to, key, {
23
+ get: ((k) => from[k]).bind(null, key),
24
+ enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable
25
+ });
33
26
  }
34
27
  return to;
35
28
  };
@@ -38,6 +31,6 @@ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__ge
38
31
  value: mod,
39
32
  enumerable: true
40
33
  }) : target, mod));
41
-
34
+ var __require = createRequire(import.meta.url);
42
35
  //#endregion
43
- export { __toESM as i, __exportAll as n, __reExport as r, __commonJSMin as t };
36
+ export { __toESM as a, __require as i, __exportAll as n, __reExport as r, __commonJSMin as t };
@@ -0,0 +1,168 @@
1
+ import { l as Fn, p as TemplateFn, s as AsyncFn, t as index_d_exports } from "./chunk-3c6f28c7.js";
2
+
3
+ //#region src/common/error.d.ts
4
+ declare const normalizeError: (error: unknown, caller?: Function) => Error;
5
+ declare const getErrorMessage: (error: unknown, message?: string) => string;
6
+ //#endregion
7
+ //#region src/common/math.d.ts
8
+ /**
9
+ * @example
10
+ * ```
11
+ * const value = linear(0.5, [0, 2]) // value: 1
12
+ * ```
13
+ */
14
+ declare const linear: (value: number, range: [min: number, max: number]) => number;
15
+ /**
16
+ * @example
17
+ * ```
18
+ * const value = scale(0.5, [0, 1], [200, 400]) // value: 300
19
+ * ```
20
+ */
21
+ declare const scale: (value: number, inRange: [min: number, max: number], outRange: [min: number, max: number]) => number;
22
+ //#endregion
23
+ //#region src/common/nil.d.ts
24
+ type Nil = index_d_exports.Tagged<symbol, "nil">;
25
+ declare const nil: Nil;
26
+ declare const isNil: (value: unknown) => value is Nil;
27
+ //#endregion
28
+ //#region src/common/parse.d.ts
29
+ declare const parseKeyValuePairs: (input: string) => Record<string, string>;
30
+ declare const parseValueToBoolean: <T>(value: unknown, defaultValue: T | boolean) => T | boolean;
31
+ //#endregion
32
+ //#region src/common/promise.d.ts
33
+ interface Singleton<T> {
34
+ (): Promise<T>;
35
+ reset: () => Promise<void>;
36
+ }
37
+ interface Lock {
38
+ run: <T = void>(fn: AsyncFn<T>) => Promise<T>;
39
+ wait: () => Promise<void>;
40
+ isWaiting: () => boolean;
41
+ clear: () => void;
42
+ }
43
+ interface PromiseWithResolvers<T> {
44
+ promise: Promise<T>;
45
+ resolve: (value: T | PromiseLike<T>) => void;
46
+ reject: (reason?: any) => void;
47
+ }
48
+ declare const sleep: (ms: number, callback?: Fn) => Promise<void>;
49
+ declare const createSingleton: <T>(fn: AsyncFn<T>) => Singleton<T>;
50
+ /**
51
+ * @example
52
+ * ```
53
+ * const lock = createLock()
54
+ *
55
+ * lock.run(async () => {
56
+ * await doSomething()
57
+ * })
58
+ *
59
+ * // in anther context:
60
+ * await lock.wait() // it will wait all tasking finished
61
+ * ```
62
+ */
63
+ declare const createLock: () => Lock;
64
+ declare const createPromiseWithResolvers: <T>() => PromiseWithResolvers<T>;
65
+ //#endregion
66
+ //#region src/common/string.d.ts
67
+ declare const addPrefix: (prefix: string, str: string) => string;
68
+ declare const addSuffix: (suffix: string, str: string) => string;
69
+ declare const removePrefix: (prefix: string, str: string) => string;
70
+ declare const removeSuffix: (suffix: string, str: string) => string;
71
+ declare const join: (separator: string, ...paths: string[]) => string;
72
+ declare const split: (separator: string, path: string) => string[];
73
+ declare const toForwardSlash: (str: string) => string;
74
+ declare const joinWithSlash: (...paths: string[]) => string;
75
+ declare const splitWithSlash: (path: string) => string[];
76
+ declare const splitByLineBreak: (str: string) => string[];
77
+ declare const concatTemplateStrings: (template: TemplateStringsArray, values: any[]) => string;
78
+ /**
79
+ * @example
80
+ * ```ts
81
+ * // Default behavior: trim both start and end
82
+ * const str1 = unindent`
83
+ * if (a) {
84
+ * b()
85
+ * }
86
+ * `;
87
+ *
88
+ * // Factory function: custom trim behavior
89
+ * const str2 = unindent(false, false)`
90
+ * if (a) {
91
+ * b()
92
+ * }
93
+ * `;
94
+ *
95
+ * // Only trim start, keep end
96
+ * const str3 = unindent(true, false)(" hello\n world\n");
97
+ * ```
98
+ */
99
+ declare function unindent(str: string): string;
100
+ declare function unindent(template: TemplateStringsArray, ...values: any[]): string;
101
+ declare function unindent(trimStart?: boolean, trimEnd?: boolean): TemplateFn<string> & ((str: string) => string);
102
+ /**
103
+ * @example
104
+ * ```ts
105
+ * // Using indent count with default space character
106
+ * const str1 = indent(2)`
107
+ * if (a) {
108
+ * b()
109
+ * }
110
+ * `;
111
+ *
112
+ * // Using custom indent string directly
113
+ * const str2 = indent(">>")`
114
+ * if (a) {
115
+ * b()
116
+ * }
117
+ * `;
118
+ *
119
+ * // Only trim start, keep end
120
+ * const str3 = indent(2, true, false)("hello\nworld\n");
121
+ * ```
122
+ */
123
+ declare function indent(indentNumber: number, trimStart?: boolean, trimEnd?: boolean): TemplateFn<string> & ((str: string) => string);
124
+ declare function indent(indentString: string, trimStart?: boolean, trimEnd?: boolean): TemplateFn<string> & ((str: string) => string);
125
+ /**
126
+ * @example
127
+ * ```
128
+ * const result = template(
129
+ * 'Hello {0}! My name is {1}.',
130
+ * 'World',
131
+ * 'Alice'
132
+ * ) // Hello World! My name is Alice.
133
+ * ```
134
+ *
135
+ * ```
136
+ * const result = template(
137
+ * '{greet}! My name is {name}.',
138
+ * { greet: 'Hello', name: 'Alice' }
139
+ * ) // Hello! My name is Alice.
140
+ * ```
141
+ *
142
+ * const result = template(
143
+ * '{greet}! My name is {name}.',
144
+ * { greet: 'Hello' }, // name isn't passed hence fallback will be used for name
145
+ * 'placeholder'
146
+ * ) // Hello! My name is placeholder.
147
+ * ```
148
+ */
149
+ declare function template(str: string, mapping: Record<string | number, any>, fallback?: string | ((key: string) => string)): string;
150
+ declare function template(str: string, ...args: (string | number | bigint | undefined | null)[]): string;
151
+ //#endregion
152
+ //#region src/common/throttle.d.ts
153
+ interface WrappedFn<T extends Fn> {
154
+ (...args: Parameters<T>): void;
155
+ cancel: Fn<void>;
156
+ }
157
+ interface Options {
158
+ leading?: boolean;
159
+ trailing?: boolean;
160
+ }
161
+ type DebouncedFn<T extends Fn> = WrappedFn<T>;
162
+ type ThrottledFn<T extends Fn> = WrappedFn<T>;
163
+ type DebounceOptions = Options;
164
+ type ThrottleOptions = Options;
165
+ declare const debounce: <T extends Fn>(fn: T, wait?: number, options?: DebounceOptions) => DebouncedFn<T>;
166
+ declare const throttle: <T extends Fn>(fn: T, wait?: number, options?: ThrottleOptions) => ThrottledFn<T>;
167
+ //#endregion
168
+ export { Nil as A, Singleton as C, sleep as D, createSingleton as E, getErrorMessage as F, normalizeError as I, nil as M, linear as N, parseKeyValuePairs as O, scale as P, PromiseWithResolvers as S, createPromiseWithResolvers as T, splitWithSlash as _, debounce as a, unindent as b, addSuffix as c, join as d, joinWithSlash as f, splitByLineBreak as g, split as h, ThrottledFn as i, isNil as j, parseValueToBoolean as k, concatTemplateStrings as l, removeSuffix as m, DebouncedFn as n, throttle as o, removePrefix as p, ThrottleOptions as r, addPrefix as s, DebounceOptions as t, indent as u, template as v, createLock as w, Lock as x, toForwardSlash as y };
@@ -0,0 +1,10 @@
1
+ import { i as Result } from "./chunk-bd9f56dd.js";
2
+
3
+ //#region src/json/safe.d.ts
4
+ declare const stringify: {
5
+ (value: any, replacer?: (this: any, key: string, value: any) => any, space?: string | number): Result<string, TypeError>;
6
+ (value: any, replacer?: (number | string)[] | null, space?: string | number): Result<string, TypeError>;
7
+ };
8
+ declare const parse: <T = any>(text: string, reviver?: (this: any, key: string, value: any) => any) => Result<T, SyntaxError>;
9
+ //#endregion
10
+ export { stringify as n, parse as t };