@oscarpalmer/atoms 0.206.0 → 0.208.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.
package/dist/index.d.mts CHANGED
@@ -3667,7 +3667,7 @@ export type MemoizedOptions<Callback extends GenericCallback> = {
3667
3667
  */
3668
3668
  export declare function memoize<Callback extends GenericCallback>(callback: Callback, options?: MemoizedOptions<Callback>): Memoized<Callback>;
3669
3669
  //#endregion
3670
- //#region src/internal/result/models.d.ts
3670
+ //#region src/internal/models/result.model.d.ts
3671
3671
  /**
3672
3672
  * An unknown result
3673
3673
  */
@@ -4587,6 +4587,108 @@ export declare function setValue<Data extends PlainObject, Path extends NestedKe
4587
4587
  */
4588
4588
  export declare function setValue<Data extends PlainObject>(data: Data, path: string, value: unknown, ignoreCase?: boolean): Data;
4589
4589
  //#endregion
4590
+ //#region src/internal/models/plan.model.d.ts
4591
+ /**
4592
+ * An asynchronous plan of execution that can yield intermediate results and eventually return a result
4593
+ */
4594
+ type AsyncPlan<Value, Error = unknown> = {
4595
+ /**
4596
+ * Run the plan to completion
4597
+ *
4598
+ * @returns Result
4599
+ */
4600
+ run: () => Promise<Result<Value, Error>>;
4601
+ };
4602
+ /**
4603
+ * A plan of execution that can yield intermediate results and eventually return a result
4604
+ */
4605
+ type Plan<Value, Error = unknown> = {
4606
+ /**
4607
+ * Run the plan to completion
4608
+ *
4609
+ * @returns Result
4610
+ */
4611
+ run: () => Result<Value, Error>;
4612
+ };
4613
+ //#endregion
4614
+ //#region src/plan/index.d.ts
4615
+ /**
4616
+ * Create a plan for an asynchronous generator function
4617
+ *
4618
+ * @param generator Generator to plan for
4619
+ * @returns Generator plan
4620
+ */
4621
+ export declare function asyncPlan<Value = unknown, Error = unknown>(generator: () => AsyncGenerator<unknown, Value, unknown>): AsyncPlan<Value, Error>;
4622
+ /**
4623
+ * Run an asynchronous generator to completion
4624
+ *
4625
+ * @param generator Generator to run
4626
+ * @returns Result
4627
+ */
4628
+ export declare function asyncRun<Value = unknown, Error = unknown>(generator: () => AsyncGenerator<unknown, Value, unknown>): Promise<Result<Value, Error>>;
4629
+ /**
4630
+ * Run an asynchronous plan to completion
4631
+ *
4632
+ * @param plan Plan to run
4633
+ * @returns Result
4634
+ */
4635
+ export declare function asyncRun<Value = unknown, Error = unknown>(plan: AsyncPlan<Value, Error>): Promise<Result<Value, Error>>;
4636
+ /**
4637
+ * Is the value an asynchronous plan?
4638
+ *
4639
+ * @param value Value to check
4640
+ * @returns `true` if the value is an asynchronous plan, otherwise `false`
4641
+ */
4642
+ export declare function isAsyncPlan<Value = unknown, Error = unknown>(value: unknown): value is AsyncPlan<Value, Error>;
4643
+ /**
4644
+ * Is the value an asynchronous generator function?
4645
+ *
4646
+ * @param value Value to check
4647
+ * @returns `true` if the value is an asynchronous generator function, otherwise `false`
4648
+ */
4649
+ export declare function isAsyncGenerator(value: unknown): value is () => AsyncGenerator;
4650
+ /**
4651
+ * Is the value a generator function?
4652
+ *
4653
+ * @param value Value to check
4654
+ * @returns `true` if the value is a generator function, otherwise `false`
4655
+ */
4656
+ export declare function isGenerator(value: unknown): value is () => Generator;
4657
+ /**
4658
+ * Is the value a plan?
4659
+ *
4660
+ * @param value Value to check
4661
+ * @returns `true` if the value is a plan, otherwise `false`
4662
+ */
4663
+ export declare function isPlan<Value = unknown, Error = unknown>(value: unknown): value is Plan<Value, Error>;
4664
+ /**
4665
+ * Create a plan for a generator function
4666
+ *
4667
+ * @param generator Generator to plan for
4668
+ * @returns Generator plan
4669
+ */
4670
+ export declare function plan<Value = unknown, Error = unknown>(generator: () => Generator<unknown, Value, Error>): Plan<Value, Error>;
4671
+ /**
4672
+ * Run a generator to completion
4673
+ *
4674
+ * @param generator Generator to run
4675
+ * @returns Result
4676
+ */
4677
+ export declare function run<Value = unknown, Error = unknown>(generator: () => Generator<unknown, Value, unknown>): Result<Value, Error>;
4678
+ /**
4679
+ * Run a plan to completion
4680
+ *
4681
+ * @param plan Plan to run
4682
+ * @returns Result
4683
+ */
4684
+ export declare function run<Value = unknown, Error = unknown>(plan: Plan<Value, Error>): Result<Value, Error>;
4685
+ export declare namespace plan {
4686
+ export var async: typeof asyncPlan;
4687
+ }
4688
+ export declare namespace run {
4689
+ export var async: typeof asyncRun;
4690
+ }
4691
+ //#endregion
4590
4692
  //#region src/internal/aborter.d.ts
4591
4693
  type Aborter = {
4592
4694
  callback: GenericCallback;
@@ -8317,4 +8419,4 @@ export declare class SizedSet<Value = unknown> extends Set<Value> {
8317
8419
  get(value: Value, update?: boolean): Value | undefined;
8318
8420
  }
8319
8421
  //#endregion
8320
- export { type AsyncLimiter, type Color, type ColorType, type ColorTypeExtended, type ColorValue, type ColorValueExtended, type HSLAColor, type HSLColor, type HWBAColor, type HWBColor, Key$1 as Key, type Limiter, Logger, type RGBAColor, type RGBColor, type Shaken, type Smushed, type Subscription, type SubscriptionParameters, type SubscriptionProperty, type Subscriptions, type SubscriptionsParameters, type TimeLogger, type Unsmushed, push as append, filterAndMap as select, toPromise as fromResult, getRandomFloatingNumber as getRandomFloat, isLogger, isTimeLogger, mapAndFilter as reverseSelect };
8422
+ export { type AsyncLimiter, type Color, type ColorType, type ColorTypeExtended, type ColorValue, type ColorValueExtended, type HSLAColor, type HSLColor, type HWBAColor, type HWBColor, Key$1 as Key, type Limiter, Logger, type Plan, type RGBAColor, type RGBColor, type Shaken, type Smushed, type Subscription, type SubscriptionParameters, type SubscriptionProperty, type Subscriptions, type SubscriptionsParameters, type TimeLogger, type Unsmushed, push as append, filterAndMap as select, toPromise as fromResult, getRandomFloatingNumber as getRandomFloat, isLogger, isTimeLogger, mapAndFilter as reverseSelect };
package/dist/index.mjs CHANGED
@@ -2746,6 +2746,134 @@ function setValue(data, path, value, ignoreCase) {
2746
2746
  return data;
2747
2747
  }
2748
2748
  const SET_EXPRESSION_INDEX = /^\d+$/;
2749
+ const PLAN_MESSAGE_PLAN_INPUT = "plan requires a generator function";
2750
+ const PLAN_MESSAGE_RUN_INPUT = "run requires a plan or a generator function";
2751
+ const PLAN_SYMBOL = Symbol("plan");
2752
+ const PLAN_TYPE_PLAN_ASYNC = "asyncPlan";
2753
+ const PLAN_TYPE_PLAN_SYNC = "plan";
2754
+ //#endregion
2755
+ //#region src/plan/index.ts
2756
+ function AsyncPlan(generator) {
2757
+ this[PLAN_SYMBOL] = {
2758
+ generator,
2759
+ type: PLAN_TYPE_PLAN_ASYNC
2760
+ };
2761
+ }
2762
+ AsyncPlan.prototype.run = runAsyncPlan;
2763
+ function Plan(generator) {
2764
+ this[PLAN_SYMBOL] = {
2765
+ generator,
2766
+ type: PLAN_TYPE_PLAN_SYNC
2767
+ };
2768
+ }
2769
+ Plan.prototype.run = runPlan;
2770
+ function asyncExecute(callback) {
2771
+ return asyncAttempt(async () => {
2772
+ const generator = callback();
2773
+ let lastValue;
2774
+ while (true) {
2775
+ const next = await generator.next();
2776
+ const { done } = next;
2777
+ let value = next.value;
2778
+ if (value instanceof Error) throw value;
2779
+ lastValue = value;
2780
+ if (done === true) break;
2781
+ }
2782
+ return lastValue;
2783
+ });
2784
+ }
2785
+ /**
2786
+ * Create a plan for an asynchronous generator function
2787
+ *
2788
+ * @param generator Generator to plan for
2789
+ * @returns Generator plan
2790
+ */
2791
+ function asyncPlan(generator) {
2792
+ if (!isAsyncGenerator(generator)) throw new Error(PLAN_MESSAGE_PLAN_INPUT);
2793
+ return new AsyncPlan(generator);
2794
+ }
2795
+ async function asyncRun(input) {
2796
+ if (isAsyncPlan(input)) return input.run();
2797
+ if (!isAsyncGenerator(input)) throw new Error(PLAN_MESSAGE_RUN_INPUT);
2798
+ return asyncExecute(input);
2799
+ }
2800
+ function execute(callback) {
2801
+ return attempt(() => {
2802
+ const generator = callback();
2803
+ let lastValue;
2804
+ while (true) {
2805
+ const next = generator.next();
2806
+ const { done } = next;
2807
+ let { value } = next;
2808
+ if (value instanceof Error) throw value;
2809
+ lastValue = value;
2810
+ if (done === true) break;
2811
+ }
2812
+ return lastValue;
2813
+ });
2814
+ }
2815
+ /**
2816
+ * Is the value an asynchronous plan?
2817
+ *
2818
+ * @param value Value to check
2819
+ * @returns `true` if the value is an asynchronous plan, otherwise `false`
2820
+ */
2821
+ function isAsyncPlan(value) {
2822
+ return isPlanInstance(PLAN_TYPE_PLAN_ASYNC, value);
2823
+ }
2824
+ /**
2825
+ * Is the value an asynchronous generator function?
2826
+ *
2827
+ * @param value Value to check
2828
+ * @returns `true` if the value is an asynchronous generator function, otherwise `false`
2829
+ */
2830
+ function isAsyncGenerator(value) {
2831
+ return typeof value === "function" && value.constructor.name === "AsyncGeneratorFunction" && typeof value.prototype.next === "function" && typeof value.prototype.return === "function" && typeof value.prototype.throw === "function";
2832
+ }
2833
+ /**
2834
+ * Is the value a generator function?
2835
+ *
2836
+ * @param value Value to check
2837
+ * @returns `true` if the value is a generator function, otherwise `false`
2838
+ */
2839
+ function isGenerator(value) {
2840
+ return typeof value === "function" && value.constructor.name === "GeneratorFunction" && typeof value.prototype.next === "function" && typeof value.prototype.return === "function" && typeof value.prototype.throw === "function";
2841
+ }
2842
+ /**
2843
+ * Is the value a plan?
2844
+ *
2845
+ * @param value Value to check
2846
+ * @returns `true` if the value is a plan, otherwise `false`
2847
+ */
2848
+ function isPlan(value) {
2849
+ return isPlanInstance(PLAN_TYPE_PLAN_SYNC, value);
2850
+ }
2851
+ function isPlanInstance(type, value) {
2852
+ return typeof value === "object" && value !== null && PLAN_SYMBOL in value && value[PLAN_SYMBOL].type === type;
2853
+ }
2854
+ /**
2855
+ * Create a plan for a generator function
2856
+ *
2857
+ * @param generator Generator to plan for
2858
+ * @returns Generator plan
2859
+ */
2860
+ function plan(generator) {
2861
+ if (!isGenerator(generator)) throw new Error(PLAN_MESSAGE_PLAN_INPUT);
2862
+ return new Plan(generator);
2863
+ }
2864
+ function run(input) {
2865
+ if (isPlan(input)) return input.run();
2866
+ if (!isGenerator(input)) throw new Error(PLAN_MESSAGE_RUN_INPUT);
2867
+ return execute(input);
2868
+ }
2869
+ function runAsyncPlan() {
2870
+ return asyncExecute(this[PLAN_SYMBOL].generator);
2871
+ }
2872
+ function runPlan() {
2873
+ return execute(this[PLAN_SYMBOL].generator);
2874
+ }
2875
+ plan.async = asyncPlan;
2876
+ run.async = asyncRun;
2749
2877
  //#endregion
2750
2878
  //#region src/internal/aborter.ts
2751
2879
  function createAborter(value, onAbort) {
@@ -6493,7 +6621,7 @@ function addToQueue(parameters, signal) {
6493
6621
  reject: rejector,
6494
6622
  resolve: resolver
6495
6623
  });
6496
- if (state.options.autostart) run(state);
6624
+ if (state.options.autostart) run$1(state);
6497
6625
  return {
6498
6626
  id,
6499
6627
  promise
@@ -6681,12 +6809,12 @@ function resumeQueue() {
6681
6809
  }
6682
6810
  state.paused = false;
6683
6811
  const length = min([state.options.concurrency, state.items.length]);
6684
- for (let index = 0; index < length; index += 1) run(state);
6812
+ for (let index = 0; index < length; index += 1) run$1(state);
6685
6813
  }
6686
6814
  function resumeQueues(key) {
6687
6815
  handleQueues(this, QUEUE_HANDLE_RESUME, key);
6688
6816
  }
6689
- async function run(state) {
6817
+ async function run$1(state) {
6690
6818
  if (state.paused || state.runners >= state.options.concurrency) return;
6691
6819
  state.runners += 1;
6692
6820
  let item = state.items.shift();
@@ -6847,4 +6975,4 @@ var SizedSet = class extends Set {
6847
6975
  }
6848
6976
  };
6849
6977
  //#endregion
6850
- export { CancelablePromise, Logger, PromiseTimeoutError, QueueError, RetryError, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SizedMap, SizedSet, push as append, push, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, assertProperty, assign, asyncAttempt, asyncDebounce, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncThrottle, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, copy, count, debounce, deburr, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, filter, filterAndMap, filterAndMap as select, find, findLast, first, firstOrDefault, flatFreeze, flatten, floor, flow, freeze, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayComparison, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getHwbColor, getHwbaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloatingNumber as getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hasValueResult, herald, hexToHsl, hexToHsla, hexToHwb, hexToHwba, hexToRgb, hexToRgba, hslToHex, hslToHwb, hslToHwba, hslToRgb, hslToRgba, hwbToHex, hwbToHsl, hwbToHsla, hwbToRgb, hwbToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeAssigner, initializeCloner, initializeEqualizer, initializeMerger, initializeNormalizer, initializeSorter, initializeTemplater, initializeTransformer, insert, interpolate, intersection, isArrayOrPlainObject, isAsyncOnce, isBeacon, isBeaconSubscription, isColor, isConstructor, isEmpty, isError, isFrozen, isFulfilled, isFuzzy, isHerald, isHeraldEvents, isHeraldSubscription, isHexColor, isHslColor, isHslaColor, isHwbColor, isHwbaColor, isInstanceOf, isKey, isKeyedQueue, isLogger, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTemplateStringsArray, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isObservable, isOk, isOnce, isPlainObject, isPrimitive, isQueue, isQueueInstance, isRejected, isResult, isRgbColor, isRgbaColor, isSorted, isSubscription, isSubscriptions, isTemplateStringsArray, isTimeLogger, isTypedArray, join, kebabCase, keyedQueue, last, lastIndexOf, lastOrDefault, lowerCase, mapAndFilter, mapAndFilter as reverseSelect, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, normalize, ok, omit, once, parse, partition, pascalCase, pick, pipe, promises, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, rgbToHwb, rgbToHwba, round, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, subscriptions, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, transform, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
6978
+ export { CancelablePromise, Logger, PromiseTimeoutError, QueueError, RetryError, SORT_DIRECTION_ASCENDING, SORT_DIRECTION_DESCENDING, SizedMap, SizedSet, push as append, push, assert, assertCondition, assertDefined, assertInstanceOf, assertIs, assertProperty, assign, asyncAttempt, asyncDebounce, asyncFlow, asyncMatchResult, asyncOnce, asyncPipe, asyncPlan, asyncRun, asyncThrottle, attempt, attemptAsyncFlow, attemptAsyncPipe, attemptFlow, attemptPipe, attemptPromise, average, beacon, between, camelCase, cancelable, capitalize, ceil, chunk, clamp, clone, compact, compare, copy, count, debounce, deburr, dedent, delay, deregisterCloner, deregisterComparator, deregisterEqualizer, diff, difference, drop, endsWith, endsWithArray, equal, error, exclude, exists, filter, filterAndMap, filterAndMap as select, find, findLast, first, firstOrDefault, flatFreeze, flatten, floor, flow, freeze, fromQuery, toPromise as fromResult, toPromise, fuzzy, fuzzyMatch, getArray, getArrayComparison, getColor, getForegroundColor, getHexColor, getHexaColor, getHslColor, getHslaColor, getHwbColor, getHwbaColor, getNormalizedHex, getNumber, getRandomBoolean, getRandomCharacters, getRandomColor, getRandomFloatingNumber as getRandomFloat, getRandomHex, getRandomInteger, getRandomItem, getRandomItems, getRgbColor, getRgbaColor, getSortedIndex, getString, getTimedPromise, getUuid, getValue, groupArraysBy, groupBy, handleResult, hasValue, hasValueResult, herald, hexToHsl, hexToHsla, hexToHwb, hexToHwba, hexToRgb, hexToRgba, hslToHex, hslToHwb, hslToHwba, hslToRgb, hslToRgba, hwbToHex, hwbToHsl, hwbToHsla, hwbToRgb, hwbToRgba, ignoreKey, inMap, inSet, includes, includesArray, indexOf, indexOfArray, initializeAssigner, initializeCloner, initializeEqualizer, initializeMerger, initializeNormalizer, initializeSorter, initializeTemplater, initializeTransformer, insert, interpolate, intersection, isArrayOrPlainObject, isAsyncGenerator, isAsyncOnce, isAsyncPlan, isBeacon, isBeaconSubscription, isColor, isConstructor, isEmpty, isError, isFrozen, isFulfilled, isFuzzy, isGenerator, isHerald, isHeraldEvents, isHeraldSubscription, isHexColor, isHslColor, isHslaColor, isHwbColor, isHwbaColor, isInstanceOf, isKey, isKeyedQueue, isLogger, isNonArrayOrPlainObject, isNonConstructor, isNonEmpty, isNonInstanceOf, isNonKey, isNonNullable, isNonNullableOrEmpty, isNonNullableOrWhitespace, isNonNumber, isNonNumerical, isNonObject, isNonPlainObject, isNonPrimitive, isNonTemplateStringsArray, isNonTypedArray, isNullable, isNullableOrEmpty, isNullableOrWhitespace, isNumber, isNumerical, isObject, isObservable, isOk, isOnce, isPlainObject, isPlan, isPrimitive, isQueue, isQueueInstance, isRejected, isResult, isRgbColor, isRgbaColor, isSorted, isSubscription, isSubscriptions, isTemplateStringsArray, isTimeLogger, isTypedArray, join, kebabCase, keyedQueue, last, lastIndexOf, lastOrDefault, lowerCase, mapAndFilter, mapAndFilter as reverseSelect, matchResult, max, median, memoize, merge, min, move, moveIndices, moveToIndex, noop, normalize, ok, omit, once, parse, partition, pascalCase, pick, pipe, plan, promises, queue, range, registerCloner, registerComparator, registerEqualizer, resultPromises, retry, reverse, rgbToHex, rgbToHsl, rgbToHsla, rgbToHwb, rgbToHwba, round, run, setValue, settlePromise, shake, shuffle, single, slice, smush, snakeCase, sort, splice, startsWith, startsWithArray, subscriptions, sum, swap, take, template, throttle, timed, times, titleCase, toMap, toMapArrays, toQuery, toRecord, toRecordArrays, toResult, toSet, toggle, transform, trim, truncate, tryDecode, tryEncode, union, unique, unsmush, unwrap, update, upperCase, words };
@@ -1,5 +1,5 @@
1
1
  import { GenericCallback } from "../../models.mjs";
2
- import { UnwrapValue } from "../result/models.mjs";
2
+ import { UnwrapValue } from "../models/result.model.mjs";
3
3
  //#region src/internal/function/work.d.ts
4
4
  /**
5
5
  * A synchronous _Flow_, a function that pipe a value through a series of functions
@@ -0,0 +1,48 @@
1
+ import { Result } from "./result.model.mjs";
2
+ //#region src/internal/models/plan.model.d.ts
3
+ /**
4
+ * An asynchronous plan of execution that can yield intermediate results and eventually return a result
5
+ */
6
+ export type AsyncPlan<Value, Error = unknown> = {
7
+ /**
8
+ * Run the plan to completion
9
+ *
10
+ * @returns Result
11
+ */
12
+ run: () => Promise<Result<Value, Error>>;
13
+ };
14
+ type AsyncPlanState = {
15
+ generator: () => AsyncGenerator;
16
+ } & BaseState<typeof PLAN_TYPE_PLAN_ASYNC>;
17
+ type BaseState<Type extends PlanType> = {
18
+ type: Type;
19
+ };
20
+ export type InternalAsyncPlan = {
21
+ [PLAN_SYMBOL]: AsyncPlanState;
22
+ } & AsyncPlan<never, never>;
23
+ export type InternalPlan = {
24
+ [PLAN_SYMBOL]: PlanState;
25
+ } & Plan<never, never>;
26
+ /**
27
+ * A plan of execution that can yield intermediate results and eventually return a result
28
+ */
29
+ export type Plan<Value, Error = unknown> = {
30
+ /**
31
+ * Run the plan to completion
32
+ *
33
+ * @returns Result
34
+ */
35
+ run: () => Result<Value, Error>;
36
+ };
37
+ type PlanState = {
38
+ generator: () => Generator;
39
+ } & BaseState<typeof PLAN_TYPE_PLAN_SYNC>;
40
+ export type PlanType = "asyncPlan" | "plan";
41
+ export declare const GENERATOR_NAME_ASYNC = "AsyncGeneratorFunction";
42
+ export declare const GENERATOR_NAME_SYNC = "GeneratorFunction";
43
+ export declare const PLAN_MESSAGE_PLAN_INPUT = "plan requires a generator function";
44
+ export declare const PLAN_MESSAGE_RUN_INPUT = "run requires a plan or a generator function";
45
+ export declare const PLAN_SYMBOL: symbol;
46
+ export declare const PLAN_TYPE_PLAN_ASYNC: PlanType;
47
+ export declare const PLAN_TYPE_PLAN_SYNC: PlanType;
48
+ //#endregion
@@ -0,0 +1,10 @@
1
+ //#region src/internal/models/plan.model.ts
2
+ const GENERATOR_NAME_ASYNC = "AsyncGeneratorFunction";
3
+ const GENERATOR_NAME_SYNC = "GeneratorFunction";
4
+ const PLAN_MESSAGE_PLAN_INPUT = "plan requires a generator function";
5
+ const PLAN_MESSAGE_RUN_INPUT = "run requires a plan or a generator function";
6
+ const PLAN_SYMBOL = Symbol("plan");
7
+ const PLAN_TYPE_PLAN_ASYNC = "asyncPlan";
8
+ const PLAN_TYPE_PLAN_SYNC = "plan";
9
+ //#endregion
10
+ export { GENERATOR_NAME_ASYNC, GENERATOR_NAME_SYNC, PLAN_MESSAGE_PLAN_INPUT, PLAN_MESSAGE_RUN_INPUT, PLAN_SYMBOL, PLAN_TYPE_PLAN_ASYNC, PLAN_TYPE_PLAN_SYNC };
@@ -1,5 +1,5 @@
1
1
  import { GenericCallback } from "../../models.mjs";
2
- //#region src/internal/result/models.d.ts
2
+ //#region src/internal/models/result.model.d.ts
3
3
  /**
4
4
  * An unknown result
5
5
  */
@@ -1,4 +1,4 @@
1
- import { ExtendedResult, Result } from "./models.mjs";
1
+ import { ExtendedResult, Result } from "../models/result.model.mjs";
2
2
  //#region src/internal/result/attempt.d.ts
3
3
  /**
4
4
  * Executes a _Promise_, catching any errors, and returns a result
@@ -1,4 +1,4 @@
1
- import { Err, ExtendedErr, Ok, Result } from "./models.mjs";
1
+ import { Err, ExtendedErr, Ok, Result } from "../models/result.model.mjs";
2
2
  //#region src/internal/result/misc.d.ts
3
3
  /**
4
4
  * Creates an extended error result
@@ -1,5 +1,5 @@
1
1
  import { NestedKeys, NestedValue, PlainObject, ToString } from "../../models.mjs";
2
- import { Result } from "../result/models.mjs";
2
+ import { Result } from "../models/result.model.mjs";
3
3
  //#region src/internal/value/has.d.ts
4
4
  /**
5
5
  * Check if a property is defined in an object
@@ -1,4 +1,4 @@
1
- import { Result } from "../result/models.mjs";
1
+ import { Result } from "../models/result.model.mjs";
2
2
  //#region src/internal/value/misc.d.ts
3
3
  export declare function findKey(needle: string, haystack: object): string;
4
4
  export declare function getNestedValue(data: object, path: string, ignoreCase: boolean): Result<unknown, string>;
@@ -0,0 +1,80 @@
1
+ import { Result } from "../internal/models/result.model.mjs";
2
+ import { AsyncPlan, Plan } from "../internal/models/plan.model.mjs";
3
+ //#region src/plan/index.d.ts
4
+ /**
5
+ * Create a plan for an asynchronous generator function
6
+ *
7
+ * @param generator Generator to plan for
8
+ * @returns Generator plan
9
+ */
10
+ export declare function asyncPlan<Value = unknown, Error = unknown>(generator: () => AsyncGenerator<unknown, Value, unknown>): AsyncPlan<Value, Error>;
11
+ /**
12
+ * Run an asynchronous generator to completion
13
+ *
14
+ * @param generator Generator to run
15
+ * @returns Result
16
+ */
17
+ export declare function asyncRun<Value = unknown, Error = unknown>(generator: () => AsyncGenerator<unknown, Value, unknown>): Promise<Result<Value, Error>>;
18
+ /**
19
+ * Run an asynchronous plan to completion
20
+ *
21
+ * @param plan Plan to run
22
+ * @returns Result
23
+ */
24
+ export declare function asyncRun<Value = unknown, Error = unknown>(plan: AsyncPlan<Value, Error>): Promise<Result<Value, Error>>;
25
+ /**
26
+ * Is the value an asynchronous plan?
27
+ *
28
+ * @param value Value to check
29
+ * @returns `true` if the value is an asynchronous plan, otherwise `false`
30
+ */
31
+ export declare function isAsyncPlan<Value = unknown, Error = unknown>(value: unknown): value is AsyncPlan<Value, Error>;
32
+ /**
33
+ * Is the value an asynchronous generator function?
34
+ *
35
+ * @param value Value to check
36
+ * @returns `true` if the value is an asynchronous generator function, otherwise `false`
37
+ */
38
+ export declare function isAsyncGenerator(value: unknown): value is () => AsyncGenerator;
39
+ /**
40
+ * Is the value a generator function?
41
+ *
42
+ * @param value Value to check
43
+ * @returns `true` if the value is a generator function, otherwise `false`
44
+ */
45
+ export declare function isGenerator(value: unknown): value is () => Generator;
46
+ /**
47
+ * Is the value a plan?
48
+ *
49
+ * @param value Value to check
50
+ * @returns `true` if the value is a plan, otherwise `false`
51
+ */
52
+ export declare function isPlan<Value = unknown, Error = unknown>(value: unknown): value is Plan<Value, Error>;
53
+ /**
54
+ * Create a plan for a generator function
55
+ *
56
+ * @param generator Generator to plan for
57
+ * @returns Generator plan
58
+ */
59
+ export declare function plan<Value = unknown, Error = unknown>(generator: () => Generator<unknown, Value, Error>): Plan<Value, Error>;
60
+ /**
61
+ * Run a generator to completion
62
+ *
63
+ * @param generator Generator to run
64
+ * @returns Result
65
+ */
66
+ export declare function run<Value = unknown, Error = unknown>(generator: () => Generator<unknown, Value, unknown>): Result<Value, Error>;
67
+ /**
68
+ * Run a plan to completion
69
+ *
70
+ * @param plan Plan to run
71
+ * @returns Result
72
+ */
73
+ export declare function run<Value = unknown, Error = unknown>(plan: Plan<Value, Error>): Result<Value, Error>;
74
+ export declare namespace plan {
75
+ export var async: typeof asyncPlan;
76
+ }
77
+ export declare namespace run {
78
+ export var async: typeof asyncRun;
79
+ }
80
+ //#endregion
@@ -0,0 +1,126 @@
1
+ import { asyncAttempt, attempt } from "../internal/result/attempt.mjs";
2
+ import { PLAN_MESSAGE_PLAN_INPUT, PLAN_MESSAGE_RUN_INPUT, PLAN_SYMBOL, PLAN_TYPE_PLAN_ASYNC, PLAN_TYPE_PLAN_SYNC } from "../internal/models/plan.model.mjs";
3
+ //#region src/plan/index.ts
4
+ function AsyncPlan(generator) {
5
+ this[PLAN_SYMBOL] = {
6
+ generator,
7
+ type: PLAN_TYPE_PLAN_ASYNC
8
+ };
9
+ }
10
+ AsyncPlan.prototype.run = runAsyncPlan;
11
+ function Plan(generator) {
12
+ this[PLAN_SYMBOL] = {
13
+ generator,
14
+ type: PLAN_TYPE_PLAN_SYNC
15
+ };
16
+ }
17
+ Plan.prototype.run = runPlan;
18
+ function asyncExecute(callback) {
19
+ return asyncAttempt(async () => {
20
+ const generator = callback();
21
+ let lastValue;
22
+ while (true) {
23
+ const next = await generator.next();
24
+ const { done } = next;
25
+ let value = next.value;
26
+ if (value instanceof Error) throw value;
27
+ lastValue = value;
28
+ if (done === true) break;
29
+ }
30
+ return lastValue;
31
+ });
32
+ }
33
+ /**
34
+ * Create a plan for an asynchronous generator function
35
+ *
36
+ * @param generator Generator to plan for
37
+ * @returns Generator plan
38
+ */
39
+ function asyncPlan(generator) {
40
+ if (!isAsyncGenerator(generator)) throw new Error(PLAN_MESSAGE_PLAN_INPUT);
41
+ return new AsyncPlan(generator);
42
+ }
43
+ async function asyncRun(input) {
44
+ if (isAsyncPlan(input)) return input.run();
45
+ if (!isAsyncGenerator(input)) throw new Error(PLAN_MESSAGE_RUN_INPUT);
46
+ return asyncExecute(input);
47
+ }
48
+ function execute(callback) {
49
+ return attempt(() => {
50
+ const generator = callback();
51
+ let lastValue;
52
+ while (true) {
53
+ const next = generator.next();
54
+ const { done } = next;
55
+ let { value } = next;
56
+ if (value instanceof Error) throw value;
57
+ lastValue = value;
58
+ if (done === true) break;
59
+ }
60
+ return lastValue;
61
+ });
62
+ }
63
+ /**
64
+ * Is the value an asynchronous plan?
65
+ *
66
+ * @param value Value to check
67
+ * @returns `true` if the value is an asynchronous plan, otherwise `false`
68
+ */
69
+ function isAsyncPlan(value) {
70
+ return isPlanInstance(PLAN_TYPE_PLAN_ASYNC, value);
71
+ }
72
+ /**
73
+ * Is the value an asynchronous generator function?
74
+ *
75
+ * @param value Value to check
76
+ * @returns `true` if the value is an asynchronous generator function, otherwise `false`
77
+ */
78
+ function isAsyncGenerator(value) {
79
+ return typeof value === "function" && value.constructor.name === "AsyncGeneratorFunction" && typeof value.prototype.next === "function" && typeof value.prototype.return === "function" && typeof value.prototype.throw === "function";
80
+ }
81
+ /**
82
+ * Is the value a generator function?
83
+ *
84
+ * @param value Value to check
85
+ * @returns `true` if the value is a generator function, otherwise `false`
86
+ */
87
+ function isGenerator(value) {
88
+ return typeof value === "function" && value.constructor.name === "GeneratorFunction" && typeof value.prototype.next === "function" && typeof value.prototype.return === "function" && typeof value.prototype.throw === "function";
89
+ }
90
+ /**
91
+ * Is the value a plan?
92
+ *
93
+ * @param value Value to check
94
+ * @returns `true` if the value is a plan, otherwise `false`
95
+ */
96
+ function isPlan(value) {
97
+ return isPlanInstance(PLAN_TYPE_PLAN_SYNC, value);
98
+ }
99
+ function isPlanInstance(type, value) {
100
+ return typeof value === "object" && value !== null && PLAN_SYMBOL in value && value[PLAN_SYMBOL].type === type;
101
+ }
102
+ /**
103
+ * Create a plan for a generator function
104
+ *
105
+ * @param generator Generator to plan for
106
+ * @returns Generator plan
107
+ */
108
+ function plan(generator) {
109
+ if (!isGenerator(generator)) throw new Error(PLAN_MESSAGE_PLAN_INPUT);
110
+ return new Plan(generator);
111
+ }
112
+ function run(input) {
113
+ if (isPlan(input)) return input.run();
114
+ if (!isGenerator(input)) throw new Error(PLAN_MESSAGE_RUN_INPUT);
115
+ return execute(input);
116
+ }
117
+ function runAsyncPlan() {
118
+ return asyncExecute(this[PLAN_SYMBOL].generator);
119
+ }
120
+ function runPlan() {
121
+ return execute(this[PLAN_SYMBOL].generator);
122
+ }
123
+ plan.async = asyncPlan;
124
+ run.async = asyncRun;
125
+ //#endregion
126
+ export { asyncPlan, asyncRun, isAsyncGenerator, isAsyncPlan, isGenerator, isPlan, plan, run };
@@ -0,0 +1,2 @@
1
+ import { Plan } from "../internal/models/plan.model.mjs";
2
+ export type { Plan };
@@ -0,0 +1 @@
1
+ export {};
@@ -1,4 +1,4 @@
1
- import { Result } from "../internal/result/models.mjs";
1
+ import { Result } from "../internal/models/result.model.mjs";
2
2
  import { Aborter } from "../internal/aborter.mjs";
3
3
  import { CancelablePromise, PromiseParameters } from "./models.mjs";
4
4
  import { toPromise } from "../result/misc.mjs";
@@ -1,5 +1,5 @@
1
1
  import { ArrayOrPlainObject, GenericCallback, Key } from "../models.mjs";
2
- import { Result } from "../internal/result/models.mjs";
2
+ import { Result } from "../internal/models/result.model.mjs";
3
3
  import { Aborter } from "../internal/aborter.mjs";
4
4
  import { PROMISE_TYPE_FULFILLED, PROMISE_TYPE_REJECTED } from "./constants.mjs";
5
5
  //#region src/promise/models.d.ts
@@ -1,4 +1,4 @@
1
- import { AnyResult, ResultMatch } from "../internal/result/models.mjs";
1
+ import { AnyResult, ResultMatch } from "../internal/models/result.model.mjs";
2
2
  //#region src/result/match.d.ts
3
3
  /**
4
4
  * Handles a _Result_ with match callbacks
@@ -1,4 +1,4 @@
1
- import { AnyResult } from "../internal/result/models.mjs";
1
+ import { AnyResult } from "../internal/models/result.model.mjs";
2
2
  import { error, isError, isOk, isResult, ok, unwrap } from "../internal/result/misc.mjs";
3
3
  //#region src/result/misc.d.ts
4
4
  /**
@@ -1,5 +1,5 @@
1
1
  import { GenericCallback } from "../../models.mjs";
2
- import { Result, UnwrapValue } from "../../internal/result/models.mjs";
2
+ import { Result, UnwrapValue } from "../../internal/models/result.model.mjs";
3
3
  //#region src/result/work/flow.d.ts
4
4
  /**
5
5
  * A synchronous _Flow_, a function that attempts to pipe values through a series of functions
@@ -1,5 +1,5 @@
1
1
  import { GenericCallback } from "../../models.mjs";
2
- import { Result, UnwrapValue } from "../../internal/result/models.mjs";
2
+ import { Result, UnwrapValue } from "../../internal/models/result.model.mjs";
3
3
  //#region src/result/work/pipe.d.ts
4
4
  type WrapValue<Value> = Result<UnwrapValue<Value>>;
5
5
  /**
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/atoms",
3
- "version": "0.206.0",
3
+ "version": "0.208.0",
4
4
  "description": "Atomic utilities for making your JavaScript better.",
5
5
  "keywords": [
6
6
  "array",
@@ -149,6 +149,13 @@
149
149
  "types": "./dist/number.d.mts",
150
150
  "default": "./dist/number.mjs"
151
151
  },
152
+ "./plan": {
153
+ "types": "./dist/plan/index.d.mts",
154
+ "default": "./dist/plan/index.mjs"
155
+ },
156
+ "./plan/models": {
157
+ "default": "./dist/plan/models.mjs"
158
+ },
152
159
  "./promise": {
153
160
  "types": "./dist/promise/index.d.mts",
154
161
  "default": "./dist/promise/index.mjs"
@@ -162,7 +169,6 @@
162
169
  "default": "./dist/promise/misc.mjs"
163
170
  },
164
171
  "./promise/models": {
165
- "types": "./dist/promise/models.d.mts",
166
172
  "default": "./dist/promise/models.mjs"
167
173
  },
168
174
  "./promise/timed": {
@@ -198,8 +204,7 @@
198
204
  "default": "./dist/result/misc.mjs"
199
205
  },
200
206
  "./result/models": {
201
- "types": "./dist/internal/result/models.d.mts",
202
- "default": "./dist/internal/result/models.mjs"
207
+ "default": "./dist/internal/models/result.model.mjs"
203
208
  },
204
209
  "./result/pipe": {
205
210
  "types": "./dist/result/work/pipe.d.mts",