@oscarpalmer/atoms 0.147.0 → 0.149.0

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.
@@ -954,6 +954,29 @@ const DEFAULT_CACHE_SIZE = 1024;
954
954
  function throttle(callback, time) {
955
955
  return getLimiter(callback, true, time);
956
956
  }
957
+ function _isResult(value, okValue) {
958
+ if (!isPlainObject(value)) return false;
959
+ return value.ok === okValue && (okValue ? "value" : "error") in value;
960
+ }
961
+ function isError(value, extended) {
962
+ return _isResult(value, false) && (extended === true ? value.original instanceof Error : true);
963
+ }
964
+ /**
965
+ * Is the result ok?
966
+ * @param result Result to check
967
+ * @returns `true` if the result is ok, `false` otherwise
968
+ */
969
+ function isOk(value) {
970
+ return _isResult(value, true);
971
+ }
972
+ /**
973
+ * Is the value a result?
974
+ * @param value Value to check
975
+ * @returns `true` if the value is a result, `false` otherwise
976
+ */
977
+ function isResult(value) {
978
+ return _isResult(value, true) || _isResult(value, false);
979
+ }
957
980
  function assert(condition, message, error) {
958
981
  if (!condition()) throw new (error ?? Error)(message);
959
982
  }
@@ -974,11 +997,17 @@ assert.is = (condition, message, error) => {
974
997
  };
975
998
  function asyncFlow(...fns) {
976
999
  assertFlowFunctions(fns);
977
- return (...args) => asyncWork(args, fns, true);
1000
+ return (...args) => asyncWork(args.map((value) => {
1001
+ if (isError(value)) throw value.error;
1002
+ return isOk(value) ? value.value : value;
1003
+ }), fns, true);
978
1004
  }
979
1005
  function flow(...fns) {
980
1006
  assertFlowFunctions(fns);
981
- return (...args) => work(args, fns, true);
1007
+ return (...args) => work(args.map((value) => {
1008
+ if (isError(value)) throw value.error;
1009
+ return isOk(value) ? value.value : value;
1010
+ }), fns, true);
982
1011
  }
983
1012
  flow.async = asyncFlow;
984
1013
  async function asyncPipe(value, ...pipes) {
@@ -992,26 +1021,38 @@ function pipe(value, ...pipes) {
992
1021
  pipe.async = asyncPipe;
993
1022
  async function asyncWork(initial, functions, flow) {
994
1023
  const { length } = functions;
995
- let transformed = initial;
1024
+ let transformed = unwrapValue(initial);
996
1025
  for (let index = 0; index < length; index += 1) {
997
1026
  const fn = functions[index];
998
- transformed = flow && index === 0 && Array.isArray(initial) ? await fn(...initial) : await fn(transformed);
1027
+ transformed = unwrapValue(flow && index === 0 && Array.isArray(initial) ? await fn(...initial) : await fn(transformed));
999
1028
  }
1000
1029
  return transformed;
1001
1030
  }
1031
+ function unwrapValue(value, flow, nested) {
1032
+ if (typeof value === "function") {
1033
+ if (nested != null) throw new TypeError(MESSAGE_NESTING);
1034
+ return unwrapValue(value(), flow, true);
1035
+ }
1036
+ if (flow != null && value instanceof Promise) throw new TypeError(flow ? MESSAGE_FLOW_PROMISE : MESSAGE_PIPE_PROMISE);
1037
+ if (isError(value)) throw value.error;
1038
+ return isOk(value) ? value.value : value;
1039
+ }
1002
1040
  function work(initial, functions, flow) {
1003
1041
  const { length } = functions;
1004
- let transformed = initial;
1042
+ let transformed = unwrapValue(initial, flow);
1005
1043
  for (let index = 0; index < length; index += 1) {
1006
1044
  const fn = functions[index];
1007
- transformed = flow && index === 0 && Array.isArray(initial) ? fn(...initial) : fn(transformed);
1045
+ transformed = unwrapValue(flow && index === 0 && Array.isArray(initial) ? fn(...initial) : fn(transformed), flow);
1008
1046
  }
1009
1047
  return transformed;
1010
1048
  }
1011
- const MESSAGE_FLOW = "Flow expected to receive an array of functions";
1012
- const MESSAGE_PIPE = "Pipe expected to receive an array of functions";
1013
- const assertFlowFunctions = assert.condition((value) => Array.isArray(value) && value.every((item) => typeof item === "function"), MESSAGE_FLOW, TypeError);
1014
- const assertPipeFunctions = assert.condition((value) => Array.isArray(value) && value.every((item) => typeof item === "function"), MESSAGE_PIPE, TypeError);
1049
+ const MESSAGE_FLOW_ARRAY = "Flow expected to receive an array of functions";
1050
+ const MESSAGE_FLOW_PROMISE = "Synchronous Flow received a promise. Use `flow.async` instead.";
1051
+ const MESSAGE_NESTING = "Return values are too deeply nested.";
1052
+ const MESSAGE_PIPE_ARRAY = "Pipe expected to receive an array of functions";
1053
+ const MESSAGE_PIPE_PROMISE = "Synchronous Pipe received a promise. Use `pipe.async` instead.";
1054
+ const assertFlowFunctions = assert.condition((value) => Array.isArray(value) && value.every((item) => typeof item === "function"), MESSAGE_FLOW_ARRAY, TypeError);
1055
+ const assertPipeFunctions = assert.condition((value) => Array.isArray(value) && value.every((item) => typeof item === "function"), MESSAGE_PIPE_ARRAY, TypeError);
1015
1056
  /**
1016
1057
  * A function that does nothing, which can be useful, I guess…
1017
1058
  */
@@ -3495,10 +3536,67 @@ const ALPHABET = "abcdefghijklmnopqrstuvwxyz";
3495
3536
  const BOOLEAN_MODIFIER = .5;
3496
3537
  const HEX_CHARACTERS = "0123456789ABCDEF";
3497
3538
  const HEX_MAXIMUM = 15;
3498
- function _isResult(value, okValue) {
3499
- if (!isPlainObject(value)) return false;
3500
- return value.ok === okValue && (okValue ? "value" : "error") in value;
3539
+ async function asyncMatchResult(result, first, error) {
3540
+ let value;
3541
+ if (typeof result === "function") value = await result();
3542
+ else if (result instanceof Promise) value = await result;
3543
+ else value = result;
3544
+ if (!isResult(value)) throw new Error(MESSAGE_RESULT);
3545
+ const hasObj = typeof first === "object" && first !== null;
3546
+ const okHandler = hasObj ? first.ok : first;
3547
+ const errorHandler = hasObj ? first.error : error;
3548
+ if (isOk(value)) return okHandler(value.value);
3549
+ return errorHandler(value.error, value.original);
3550
+ }
3551
+ function matchResult(result, first, error) {
3552
+ const value = typeof result === "function" ? result() : result;
3553
+ if (!isResult(value)) throw new Error(MESSAGE_RESULT);
3554
+ const hasObj = typeof first === "object" && first !== null;
3555
+ const okHandler = hasObj ? first.ok : first;
3556
+ const errorHandler = hasObj ? first.error : error;
3557
+ if (isOk(value)) return okHandler(value.value);
3558
+ return errorHandler(value.error, value.original);
3559
+ }
3560
+ matchResult.async = asyncMatchResult;
3561
+ const MESSAGE_RESULT = "`result.match` expected a Result or a function that returns a Result";
3562
+ function attemptAsyncFlow(...fns) {
3563
+ let Flow;
3564
+ return (...args) => attempt.async(() => {
3565
+ Flow ??= flow.async(...fns);
3566
+ return Flow(...args.map((value) => {
3567
+ if (isError(value)) throw value.error;
3568
+ return isOk(value) ? value.value : value;
3569
+ }));
3570
+ });
3571
+ }
3572
+ function attemptFlow(...fns) {
3573
+ let Flow;
3574
+ return (...args) => attempt(() => {
3575
+ Flow ??= flow(...fns);
3576
+ return Flow(...args.map((value) => {
3577
+ if (isError(value)) throw value.error;
3578
+ return isOk(value) ? value.value : value;
3579
+ }));
3580
+ });
3581
+ }
3582
+ attemptFlow.async = attemptAsyncFlow;
3583
+ async function attemptAsyncPipe(initial, first, ...seconds) {
3584
+ return attempt.async(() => {
3585
+ if (isError(initial)) throw initial.error;
3586
+ const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
3587
+ if (first == null) return value;
3588
+ return pipe.async(value, ...[first, ...seconds]);
3589
+ });
3501
3590
  }
3591
+ function attemptPipe(initial, first, ...seconds) {
3592
+ return attempt(() => {
3593
+ if (isError(initial)) throw initial.error;
3594
+ const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
3595
+ if (first == null) return value;
3596
+ return pipe(value, ...[first, ...seconds]);
3597
+ });
3598
+ }
3599
+ attemptPipe.async = attemptAsyncPipe;
3502
3600
  async function asyncAttempt(value, err) {
3503
3601
  try {
3504
3602
  let result = typeof value === "function" ? value() : await value;
@@ -3516,6 +3614,9 @@ function attempt(callback, err) {
3516
3614
  }
3517
3615
  }
3518
3616
  attempt.async = asyncAttempt;
3617
+ attempt.flow = attemptFlow;
3618
+ attempt.match = matchResult;
3619
+ attempt.pipe = attemptPipe;
3519
3620
  attempt.promise = attemptPromise;
3520
3621
  function error(value, original) {
3521
3622
  return getError(value, original);
@@ -3528,25 +3629,6 @@ function getError(value, original) {
3528
3629
  if (original instanceof Error) errorResult.original = original;
3529
3630
  return errorResult;
3530
3631
  }
3531
- function isError(value, extended) {
3532
- return _isResult(value, false) && (extended === true ? value.original instanceof Error : true);
3533
- }
3534
- /**
3535
- * Is the result ok?
3536
- * @param result Result to check
3537
- * @returns `true` if the result is ok, `false` otherwise
3538
- */
3539
- function isOk(value) {
3540
- return _isResult(value, true);
3541
- }
3542
- /**
3543
- * Is the value a result?
3544
- * @param value Value to check
3545
- * @returns `true` if the value is a result, `false` otherwise
3546
- */
3547
- function isResult(value) {
3548
- return _isResult(value, true) || _isResult(value, false);
3549
- }
3550
3632
  /**
3551
3633
  * Creates an ok result
3552
3634
  * @param value Value
@@ -1,11 +1,18 @@
1
1
  import { assert } from "./assert.js";
2
+ import { isError, isOk } from "../internal/result.js";
2
3
  function asyncFlow(...fns) {
3
4
  assertFlowFunctions(fns);
4
- return (...args) => asyncWork(args, fns, true);
5
+ return (...args) => asyncWork(args.map((value) => {
6
+ if (isError(value)) throw value.error;
7
+ return isOk(value) ? value.value : value;
8
+ }), fns, true);
5
9
  }
6
10
  function flow(...fns) {
7
11
  assertFlowFunctions(fns);
8
- return (...args) => work(args, fns, true);
12
+ return (...args) => work(args.map((value) => {
13
+ if (isError(value)) throw value.error;
14
+ return isOk(value) ? value.value : value;
15
+ }), fns, true);
9
16
  }
10
17
  flow.async = asyncFlow;
11
18
  async function asyncPipe(value, ...pipes) {
@@ -19,24 +26,36 @@ function pipe(value, ...pipes) {
19
26
  pipe.async = asyncPipe;
20
27
  async function asyncWork(initial, functions, flow) {
21
28
  const { length } = functions;
22
- let transformed = initial;
29
+ let transformed = unwrapValue(initial);
23
30
  for (let index = 0; index < length; index += 1) {
24
31
  const fn = functions[index];
25
- transformed = flow && index === 0 && Array.isArray(initial) ? await fn(...initial) : await fn(transformed);
32
+ transformed = unwrapValue(flow && index === 0 && Array.isArray(initial) ? await fn(...initial) : await fn(transformed));
26
33
  }
27
34
  return transformed;
28
35
  }
36
+ function unwrapValue(value, flow, nested) {
37
+ if (typeof value === "function") {
38
+ if (nested != null) throw new TypeError(MESSAGE_NESTING);
39
+ return unwrapValue(value(), flow, true);
40
+ }
41
+ if (flow != null && value instanceof Promise) throw new TypeError(flow ? MESSAGE_FLOW_PROMISE : MESSAGE_PIPE_PROMISE);
42
+ if (isError(value)) throw value.error;
43
+ return isOk(value) ? value.value : value;
44
+ }
29
45
  function work(initial, functions, flow) {
30
46
  const { length } = functions;
31
- let transformed = initial;
47
+ let transformed = unwrapValue(initial, flow);
32
48
  for (let index = 0; index < length; index += 1) {
33
49
  const fn = functions[index];
34
- transformed = flow && index === 0 && Array.isArray(initial) ? fn(...initial) : fn(transformed);
50
+ transformed = unwrapValue(flow && index === 0 && Array.isArray(initial) ? fn(...initial) : fn(transformed), flow);
35
51
  }
36
52
  return transformed;
37
53
  }
38
- var MESSAGE_FLOW = "Flow expected to receive an array of functions";
39
- var MESSAGE_PIPE = "Pipe expected to receive an array of functions";
40
- var assertFlowFunctions = assert.condition((value) => Array.isArray(value) && value.every((item) => typeof item === "function"), MESSAGE_FLOW, TypeError);
41
- var assertPipeFunctions = assert.condition((value) => Array.isArray(value) && value.every((item) => typeof item === "function"), MESSAGE_PIPE, TypeError);
54
+ var MESSAGE_FLOW_ARRAY = "Flow expected to receive an array of functions";
55
+ var MESSAGE_FLOW_PROMISE = "Synchronous Flow received a promise. Use `flow.async` instead.";
56
+ var MESSAGE_NESTING = "Return values are too deeply nested.";
57
+ var MESSAGE_PIPE_ARRAY = "Pipe expected to receive an array of functions";
58
+ var MESSAGE_PIPE_PROMISE = "Synchronous Pipe received a promise. Use `pipe.async` instead.";
59
+ var assertFlowFunctions = assert.condition((value) => Array.isArray(value) && value.every((item) => typeof item === "function"), MESSAGE_FLOW_ARRAY, TypeError);
60
+ var assertPipeFunctions = assert.condition((value) => Array.isArray(value) && value.every((item) => typeof item === "function"), MESSAGE_PIPE_ARRAY, TypeError);
42
61
  export { flow, pipe };
package/dist/index.js CHANGED
@@ -41,6 +41,7 @@ import { debounce } from "./function/debounce.js";
41
41
  import { SizedMap } from "./sized/map.js";
42
42
  import { memoize } from "./function/memoize.js";
43
43
  import { throttle } from "./function/throttle.js";
44
+ import { isError, isOk, isResult } from "./internal/result.js";
44
45
  import { flow, pipe } from "./function/work.js";
45
46
  import { equal } from "./internal/value/equal.js";
46
47
  import { getValue } from "./internal/value/get.js";
@@ -63,6 +64,6 @@ import { CancelablePromise, PromiseTimeoutError, attemptPromise, cancelable, del
63
64
  import { fromQuery, toQuery } from "./query.js";
64
65
  import { QueueError, queue } from "./queue.js";
65
66
  import { getRandomBoolean, getRandomCharacters, getRandomColor, getRandomHex, getRandomItem, getRandomItems } from "./random.js";
66
- import { attempt, error, isError, isOk, isResult, ok, unwrap } from "./result.js";
67
+ import { attempt, error, ok, unwrap } from "./result/index.js";
67
68
  import { SizedSet } from "./sized/set.js";
68
69
  export { CancelablePromise, frame_rate_default as FRAME_RATE_MS, PromiseTimeoutError, QueueError, SizedMap, SizedSet, attempt, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, count, debounce, delay, diff, endsWith, equal, error, exists, filter, find, flatten, floor, flow, fromQuery, getArray, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getString, getUuid, getValue, groupBy, hexToHsl, hexToHsla, hexToRgb, hexToRgba, hslToHex, hslToRgb, hslToRgba, ignoreKey, includes, indexOf, insert, isArrayOrPlainObject, isColor, isConstructor, isEmpty, isError, isFulfilled, isHexColor, isHslColor, isHslLike, isHslaColor, isInstanceOf, isKey, isNonNullable, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isOk, isPlainObject, isPrimitive, isRejected, isResult, isRgbColor, isRgbLike, isRgbaColor, isTypedArray, join, kebabCase, logger, lowerCase, max, median, memoize, merge, min, noop, ok, omit, parse, partition, pascalCase, pick, pipe, promises, push, queue, range, rgbToHex, rgbToHsl, rgbToHsla, round, select, setValue, shuffle, smush, snakeCase, sort, splice, startsWith, sum, template, throttle, timed, times, titleCase, toMap, toQuery, toRecord, toSet, toggle, trim, truncate, tryDecode, tryEncode, unique, unsmush, unwrap, update, upperCase, words };
@@ -0,0 +1,25 @@
1
+ import { isPlainObject } from "./is.js";
2
+ function _isResult(value, okValue) {
3
+ if (!isPlainObject(value)) return false;
4
+ return value.ok === okValue && (okValue ? "value" : "error") in value;
5
+ }
6
+ function isError(value, extended) {
7
+ return _isResult(value, false) && (extended === true ? value.original instanceof Error : true);
8
+ }
9
+ /**
10
+ * Is the result ok?
11
+ * @param result Result to check
12
+ * @returns `true` if the result is ok, `false` otherwise
13
+ */
14
+ function isOk(value) {
15
+ return _isResult(value, true);
16
+ }
17
+ /**
18
+ * Is the value a result?
19
+ * @param value Value to check
20
+ * @returns `true` if the value is a result, `false` otherwise
21
+ */
22
+ function isResult(value) {
23
+ return _isResult(value, true) || _isResult(value, false);
24
+ }
25
+ export { isError, isOk, isResult };
@@ -1,9 +1,8 @@
1
- import { isPlainObject } from "./internal/is.js";
2
- import { attemptPromise } from "./promise.js";
3
- function _isResult(value, okValue) {
4
- if (!isPlainObject(value)) return false;
5
- return value.ok === okValue && (okValue ? "value" : "error") in value;
6
- }
1
+ import { isError, isOk, isResult } from "../internal/result.js";
2
+ import { attemptPromise } from "../promise.js";
3
+ import { matchResult } from "./match.js";
4
+ import { attemptFlow } from "./work/flow.js";
5
+ import { attemptPipe } from "./work/pipe.js";
7
6
  async function asyncAttempt(value, err) {
8
7
  try {
9
8
  let result = typeof value === "function" ? value() : await value;
@@ -21,6 +20,9 @@ function attempt(callback, err) {
21
20
  }
22
21
  }
23
22
  attempt.async = asyncAttempt;
23
+ attempt.flow = attemptFlow;
24
+ attempt.match = matchResult;
25
+ attempt.pipe = attemptPipe;
24
26
  attempt.promise = attemptPromise;
25
27
  function error(value, original) {
26
28
  return getError(value, original);
@@ -33,25 +35,6 @@ function getError(value, original) {
33
35
  if (original instanceof Error) errorResult.original = original;
34
36
  return errorResult;
35
37
  }
36
- function isError(value, extended) {
37
- return _isResult(value, false) && (extended === true ? value.original instanceof Error : true);
38
- }
39
- /**
40
- * Is the result ok?
41
- * @param result Result to check
42
- * @returns `true` if the result is ok, `false` otherwise
43
- */
44
- function isOk(value) {
45
- return _isResult(value, true);
46
- }
47
- /**
48
- * Is the value a result?
49
- * @param value Value to check
50
- * @returns `true` if the value is a result, `false` otherwise
51
- */
52
- function isResult(value) {
53
- return _isResult(value, true) || _isResult(value, false);
54
- }
55
38
  /**
56
39
  * Creates an ok result
57
40
  * @param value Value
@@ -0,0 +1,25 @@
1
+ import { isOk, isResult } from "../internal/result.js";
2
+ async function asyncMatchResult(result, first, error) {
3
+ let value;
4
+ if (typeof result === "function") value = await result();
5
+ else if (result instanceof Promise) value = await result;
6
+ else value = result;
7
+ if (!isResult(value)) throw new Error(MESSAGE_RESULT);
8
+ const hasObj = typeof first === "object" && first !== null;
9
+ const okHandler = hasObj ? first.ok : first;
10
+ const errorHandler = hasObj ? first.error : error;
11
+ if (isOk(value)) return okHandler(value.value);
12
+ return errorHandler(value.error, value.original);
13
+ }
14
+ function matchResult(result, first, error) {
15
+ const value = typeof result === "function" ? result() : result;
16
+ if (!isResult(value)) throw new Error(MESSAGE_RESULT);
17
+ const hasObj = typeof first === "object" && first !== null;
18
+ const okHandler = hasObj ? first.ok : first;
19
+ const errorHandler = hasObj ? first.error : error;
20
+ if (isOk(value)) return okHandler(value.value);
21
+ return errorHandler(value.error, value.original);
22
+ }
23
+ matchResult.async = asyncMatchResult;
24
+ var MESSAGE_RESULT = "`result.match` expected a Result or a function that returns a Result";
25
+ export { matchResult };
File without changes
@@ -0,0 +1,25 @@
1
+ import { isError, isOk } from "../../internal/result.js";
2
+ import { flow } from "../../function/work.js";
3
+ import { attempt } from "../index.js";
4
+ function attemptAsyncFlow(...fns) {
5
+ let Flow;
6
+ return (...args) => attempt.async(() => {
7
+ Flow ??= flow.async(...fns);
8
+ return Flow(...args.map((value) => {
9
+ if (isError(value)) throw value.error;
10
+ return isOk(value) ? value.value : value;
11
+ }));
12
+ });
13
+ }
14
+ function attemptFlow(...fns) {
15
+ let Flow;
16
+ return (...args) => attempt(() => {
17
+ Flow ??= flow(...fns);
18
+ return Flow(...args.map((value) => {
19
+ if (isError(value)) throw value.error;
20
+ return isOk(value) ? value.value : value;
21
+ }));
22
+ });
23
+ }
24
+ attemptFlow.async = attemptAsyncFlow;
25
+ export { attemptFlow };
@@ -0,0 +1,21 @@
1
+ import { isError, isOk } from "../../internal/result.js";
2
+ import { pipe } from "../../function/work.js";
3
+ import { attempt } from "../index.js";
4
+ async function attemptAsyncPipe(initial, first, ...seconds) {
5
+ return attempt.async(() => {
6
+ if (isError(initial)) throw initial.error;
7
+ const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
8
+ if (first == null) return value;
9
+ return pipe.async(value, ...[first, ...seconds]);
10
+ });
11
+ }
12
+ function attemptPipe(initial, first, ...seconds) {
13
+ return attempt(() => {
14
+ if (isError(initial)) throw initial.error;
15
+ const value = typeof initial === "function" ? initial() : isOk(initial) ? initial.value : initial;
16
+ if (first == null) return value;
17
+ return pipe(value, ...[first, ...seconds]);
18
+ });
19
+ }
20
+ attemptPipe.async = attemptAsyncPipe;
21
+ export { attemptPipe };
package/package.json CHANGED
@@ -110,8 +110,8 @@
110
110
  "default": "./dist/random.js"
111
111
  },
112
112
  "./result": {
113
- "types": "./types/result.d.ts",
114
- "default": "./dist/result.js"
113
+ "types": "./types/result/index.d.ts",
114
+ "default": "./dist/result/index.js"
115
115
  },
116
116
  "./sized/map": {
117
117
  "types": "./types/sized/map.d.ts",
@@ -192,5 +192,5 @@
192
192
  },
193
193
  "type": "module",
194
194
  "types": "./types/index.d.ts",
195
- "version": "0.147.0"
195
+ "version": "0.149.0"
196
196
  }