@oscarpalmer/atoms 0.209.0 → 0.210.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
@@ -4591,37 +4591,42 @@ export declare function setValue<Data extends PlainObject>(data: Data, path: str
4591
4591
  /**
4592
4592
  * An asynchronous plan of execution that can yield intermediate results and eventually return a result
4593
4593
  */
4594
- type AsyncPlan<Value, Error = unknown> = {
4594
+ type AsyncPlan<Yielded, Returned> = {
4595
4595
  /**
4596
4596
  * Get the asynchronous generator for the plan
4597
4597
  *
4598
4598
  * @returns Asynchronous generator
4599
4599
  */
4600
- [Symbol.asyncIterator]: () => AsyncGenerator<unknown, Value, unknown>;
4600
+ [Symbol.asyncIterator]: () => AsyncGenerator<Yielded, Returned, unknown>;
4601
4601
  /**
4602
4602
  * Run the plan to completion
4603
4603
  *
4604
+ * @throws {PlanError<Yielded, Returned>}
4604
4605
  * @returns Result
4605
4606
  */
4606
- run: () => Promise<Result<Value, Error>>;
4607
+ run: () => Promise<PlanResult<Returned>>;
4607
4608
  };
4608
4609
  /**
4609
4610
  * A plan of execution that can yield intermediate results and eventually return a result
4610
4611
  */
4611
- type Plan<Value, Error = unknown> = {
4612
+ type Plan<Yielded, Returned> = {
4612
4613
  /**
4613
4614
  * Get the generator for the plan
4614
4615
  *
4615
4616
  * @returns Generator
4616
4617
  */
4617
- [Symbol.iterator]: () => Generator<unknown, Value, unknown>;
4618
+ [Symbol.iterator]: () => Generator<Yielded, Returned, unknown>;
4618
4619
  /**
4619
4620
  * Run the plan to completion
4620
4621
  *
4622
+ * @throws {PlanError<Yielded, Returned>}
4621
4623
  * @returns Result
4622
4624
  */
4623
- run: () => Result<Value, Error>;
4625
+ run: () => PlanResult<Returned>;
4624
4626
  };
4627
+ type PlanErrorValues<Original> = Original extends Error ? Original : never;
4628
+ type PlanError<Yielded, Returned> = PlanErrorValues<Yielded> | PlanErrorValues<Returned> | Error;
4629
+ type PlanResult<Returned> = Returned extends Error ? never : Returned;
4625
4630
  //#endregion
4626
4631
  //#region src/plan/index.d.ts
4627
4632
  /**
@@ -4630,28 +4635,51 @@ type Plan<Value, Error = unknown> = {
4630
4635
  * @param generator Generator to plan for
4631
4636
  * @returns Generator plan
4632
4637
  */
4633
- export declare function asyncPlan<Value = unknown, Error = unknown>(generator: () => AsyncGenerator<unknown, Value, unknown>): AsyncPlan<Value, Error>;
4638
+ export declare function plan<Yielded, Returned>(generator: () => AsyncGenerator<Yielded, Returned>): AsyncPlan<Yielded, Returned>;
4639
+ /**
4640
+ * Create a plan for a generator function
4641
+ *
4642
+ * @param generator Generator to plan for
4643
+ * @returns Generator plan
4644
+ */
4645
+ export declare function plan<Yielded, Returned>(generator: () => Generator<Yielded, Returned>): Plan<Yielded, Returned>;
4634
4646
  /**
4635
4647
  * Run an asynchronous generator to completion
4636
4648
  *
4637
4649
  * @param generator Generator to run
4638
4650
  * @returns Result
4639
4651
  */
4640
- export declare function asyncRun<Value = unknown, Error = unknown>(generator: () => AsyncGenerator<unknown, Value, unknown>): Promise<Result<Value, Error>>;
4652
+ export declare function run<Yielded, Returned>(generator: () => AsyncGenerator<Yielded, Returned>): Promise<PlanResult<Returned> | PlanError<Yielded, Returned>>;
4641
4653
  /**
4642
4654
  * Run an asynchronous plan to completion
4643
4655
  *
4644
4656
  * @param plan Plan to run
4645
4657
  * @returns Result
4646
4658
  */
4647
- export declare function asyncRun<Value = unknown, Error = unknown>(plan: AsyncPlan<Value, Error>): Promise<Result<Value, Error>>;
4659
+ export declare function run<Yielded, Returned>(plan: AsyncPlan<Yielded, Returned>): Promise<PlanResult<Returned> | PlanError<Yielded, Returned>>;
4648
4660
  /**
4649
- * Is the value an asynchronous plan?
4661
+ * Run a generator to completion
4650
4662
  *
4651
- * @param value Value to check
4652
- * @returns `true` if the value is an asynchronous plan, otherwise `false`
4663
+ * @param generator Generator to run
4664
+ * @returns Result
4653
4665
  */
4654
- export declare function isAsyncPlan<Value = unknown, Error = unknown>(value: unknown): value is AsyncPlan<Value, Error>;
4666
+ export declare function run<Yielded, Returned>(generator: () => Generator<Yielded, Returned>): PlanResult<Returned> | PlanError<Yielded, Returned>;
4667
+ /**
4668
+ * Run a plan to completion
4669
+ *
4670
+ * @param plan Plan to run
4671
+ * @returns Result
4672
+ */
4673
+ export declare function run<Yielded, Returned>(plan: Plan<Yielded, Returned>): PlanResult<Returned> | PlanError<Yielded, Returned>;
4674
+ //#endregion
4675
+ //#region src/internal/plan.d.ts
4676
+ /**
4677
+ * Create an immediately failing generator
4678
+ *
4679
+ * @param reason Failure reason
4680
+ * @returns Failing generator
4681
+ */
4682
+ export declare function fail<Reason>(reason: Reason): Generator<never, never>;
4655
4683
  /**
4656
4684
  * Is the value an asynchronous generator function?
4657
4685
  *
@@ -4659,6 +4687,13 @@ export declare function isAsyncPlan<Value = unknown, Error = unknown>(value: unk
4659
4687
  * @returns `true` if the value is an asynchronous generator function, otherwise `false`
4660
4688
  */
4661
4689
  export declare function isAsyncGenerator(value: unknown): value is () => AsyncGenerator;
4690
+ /**
4691
+ * Is the value an asynchronous plan?
4692
+ *
4693
+ * @param value Value to check
4694
+ * @returns `true` if the value is an asynchronous plan, otherwise `false`
4695
+ */
4696
+ export declare function isAsyncPlan<Yielded = unknown, Returned = unknown>(value: unknown): value is AsyncPlan<Yielded, Returned>;
4662
4697
  /**
4663
4698
  * Is the value a generator function?
4664
4699
  *
@@ -4672,34 +4707,14 @@ export declare function isGenerator(value: unknown): value is () => Generator;
4672
4707
  * @param value Value to check
4673
4708
  * @returns `true` if the value is a plan, otherwise `false`
4674
4709
  */
4675
- export declare function isPlan<Value = unknown, Error = unknown>(value: unknown): value is Plan<Value, Error>;
4676
- /**
4677
- * Create a plan for a generator function
4678
- *
4679
- * @param generator Generator to plan for
4680
- * @returns Generator plan
4681
- */
4682
- export declare function plan<Value = unknown, Error = unknown>(generator: () => Generator<unknown, Value, Error>): Plan<Value, Error>;
4710
+ export declare function isPlan<Yielded = unknown, Returned = unknown>(value: unknown): value is Plan<Yielded, Returned>;
4683
4711
  /**
4684
- * Run a generator to completion
4712
+ * Create an immediately succeeding generator
4685
4713
  *
4686
- * @param generator Generator to run
4687
- * @returns Result
4714
+ * @param value Success value
4715
+ * @returns Succeeding generator
4688
4716
  */
4689
- export declare function run<Value = unknown, Error = unknown>(generator: () => Generator<unknown, Value, unknown>): Result<Value, Error>;
4690
- /**
4691
- * Run a plan to completion
4692
- *
4693
- * @param plan Plan to run
4694
- * @returns Result
4695
- */
4696
- export declare function run<Value = unknown, Error = unknown>(plan: Plan<Value, Error>): Result<Value, Error>;
4697
- export declare namespace plan {
4698
- export var async: typeof asyncPlan;
4699
- }
4700
- export declare namespace run {
4701
- export var async: typeof asyncRun;
4702
- }
4717
+ export declare function succeed<Value>(value: Value): Generator<never, Value>;
4703
4718
  //#endregion
4704
4719
  //#region src/internal/aborter.d.ts
4705
4720
  type Aborter = {
@@ -8431,4 +8446,4 @@ export declare class SizedSet<Value = unknown> extends Set<Value> {
8431
8446
  get(value: Value, update?: boolean): Value | undefined;
8432
8447
  }
8433
8448
  //#endregion
8434
- 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 };
8449
+ export { type AsyncLimiter, type AsyncPlan, 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
@@ -2756,93 +2756,35 @@ const PLAN_SYMBOL = Symbol("plan");
2756
2756
  const PLAN_TYPE_PLAN_ASYNC = "asyncPlan";
2757
2757
  const PLAN_TYPE_PLAN_SYNC = "plan";
2758
2758
  //#endregion
2759
- //#region src/plan/index.ts
2760
- function AsyncPlan(generator) {
2761
- this[PLAN_SYMBOL] = {
2762
- generator,
2763
- type: PLAN_TYPE_PLAN_ASYNC
2764
- };
2765
- }
2766
- AsyncPlan.prototype[Symbol.asyncIterator] = function() {
2767
- return this[PLAN_SYMBOL].generator();
2768
- };
2769
- AsyncPlan.prototype.run = runAsyncPlan;
2770
- function Plan(generator) {
2771
- this[PLAN_SYMBOL] = {
2772
- generator,
2773
- type: PLAN_TYPE_PLAN_SYNC
2774
- };
2775
- }
2776
- Plan.prototype[Symbol.iterator] = function() {
2777
- return this[PLAN_SYMBOL].generator();
2778
- };
2779
- Plan.prototype.run = runPlan;
2780
- function asyncExecute(callback) {
2781
- return asyncAttempt(async () => {
2782
- const generator = callback();
2783
- let lastValue;
2784
- while (true) {
2785
- const next = await generator.next();
2786
- const { done } = next;
2787
- let value = next.value;
2788
- if (value instanceof Error) throw value;
2789
- if (isError(value)) throw value.error;
2790
- if (isOk(value)) value = value.value;
2791
- lastValue = value;
2792
- if (done === true) break;
2793
- }
2794
- return lastValue;
2795
- });
2796
- }
2759
+ //#region src/internal/plan.ts
2797
2760
  /**
2798
- * Create a plan for an asynchronous generator function
2761
+ * Create an immediately failing generator
2799
2762
  *
2800
- * @param generator Generator to plan for
2801
- * @returns Generator plan
2763
+ * @param reason Failure reason
2764
+ * @returns Failing generator
2802
2765
  */
2803
- function asyncPlan(generator) {
2804
- if (!isAsyncGenerator(generator)) throw new Error(PLAN_MESSAGE_PLAN_INPUT);
2805
- return new AsyncPlan(generator);
2806
- }
2807
- async function asyncRun(input) {
2808
- if (isAsyncPlan(input)) return input.run();
2809
- if (!isAsyncGenerator(input)) throw new Error(PLAN_MESSAGE_RUN_INPUT);
2810
- return asyncExecute(input);
2811
- }
2812
- function execute(callback) {
2813
- return attempt(() => {
2814
- const generator = callback();
2815
- let lastValue;
2816
- while (true) {
2817
- const next = generator.next();
2818
- const { done } = next;
2819
- let { value } = next;
2820
- if (value instanceof Error) throw value;
2821
- if (isError(value)) throw value.error;
2822
- if (isOk(value)) value = value.value;
2823
- lastValue = value;
2824
- if (done === true) break;
2825
- }
2826
- return lastValue;
2827
- });
2766
+ function fail(reason) {
2767
+ return (function* () {
2768
+ throw reason;
2769
+ })();
2828
2770
  }
2829
2771
  /**
2830
- * Is the value an asynchronous plan?
2772
+ * Is the value an asynchronous generator function?
2831
2773
  *
2832
2774
  * @param value Value to check
2833
- * @returns `true` if the value is an asynchronous plan, otherwise `false`
2775
+ * @returns `true` if the value is an asynchronous generator function, otherwise `false`
2834
2776
  */
2835
- function isAsyncPlan(value) {
2836
- return isPlanInstance(PLAN_TYPE_PLAN_ASYNC, value);
2777
+ function isAsyncGenerator(value) {
2778
+ return isGeneratorInstance(GENERATOR_NAME_ASYNC, value);
2837
2779
  }
2838
2780
  /**
2839
- * Is the value an asynchronous generator function?
2781
+ * Is the value an asynchronous plan?
2840
2782
  *
2841
2783
  * @param value Value to check
2842
- * @returns `true` if the value is an asynchronous generator function, otherwise `false`
2784
+ * @returns `true` if the value is an asynchronous plan, otherwise `false`
2843
2785
  */
2844
- function isAsyncGenerator(value) {
2845
- return isGeneratorInstance(GENERATOR_NAME_ASYNC, value);
2786
+ function isAsyncPlan(value) {
2787
+ return isPlanInstance(PLAN_TYPE_PLAN_ASYNC, value);
2846
2788
  }
2847
2789
  /**
2848
2790
  * Is the value a generator function?
@@ -2869,19 +2811,92 @@ function isPlanInstance(type, value) {
2869
2811
  return typeof value === "object" && value !== null && PLAN_SYMBOL in value && value[PLAN_SYMBOL].type === type;
2870
2812
  }
2871
2813
  /**
2872
- * Create a plan for a generator function
2814
+ * Create an immediately succeeding generator
2873
2815
  *
2874
- * @param generator Generator to plan for
2875
- * @returns Generator plan
2816
+ * @param value Success value
2817
+ * @returns Succeeding generator
2876
2818
  */
2819
+ function succeed(value) {
2820
+ return (function* () {
2821
+ return value;
2822
+ })();
2823
+ }
2824
+ //#endregion
2825
+ //#region src/plan/index.ts
2826
+ function AsyncPlan(generator) {
2827
+ this[PLAN_SYMBOL] = {
2828
+ generator,
2829
+ type: PLAN_TYPE_PLAN_ASYNC
2830
+ };
2831
+ }
2832
+ AsyncPlan.prototype[Symbol.asyncIterator] = function() {
2833
+ return this[PLAN_SYMBOL].generator();
2834
+ };
2835
+ AsyncPlan.prototype.run = runAsyncPlan;
2836
+ function Plan(generator) {
2837
+ this[PLAN_SYMBOL] = {
2838
+ generator,
2839
+ type: PLAN_TYPE_PLAN_SYNC
2840
+ };
2841
+ }
2842
+ Plan.prototype[Symbol.iterator] = function() {
2843
+ return this[PLAN_SYMBOL].generator();
2844
+ };
2845
+ Plan.prototype.run = runPlan;
2846
+ async function asyncExecute(callback) {
2847
+ const generator = callback();
2848
+ let success = true;
2849
+ let lastValue;
2850
+ try {
2851
+ while (true) {
2852
+ const next = await generator.next(lastValue);
2853
+ const { done } = next;
2854
+ let { value } = next;
2855
+ if (value instanceof Error) throw value;
2856
+ lastValue = value;
2857
+ if (done === true) break;
2858
+ }
2859
+ } catch (error) {
2860
+ lastValue = error;
2861
+ success = false;
2862
+ } finally {
2863
+ generator?.return(lastValue);
2864
+ }
2865
+ if (success) return lastValue;
2866
+ throw lastValue;
2867
+ }
2868
+ function execute(callback) {
2869
+ const generator = callback();
2870
+ let success = true;
2871
+ let lastValue;
2872
+ try {
2873
+ while (true) {
2874
+ const next = generator.next(lastValue);
2875
+ const done = next.done === true;
2876
+ let { value } = next;
2877
+ if (value instanceof Error) throw value;
2878
+ lastValue = value;
2879
+ if (done) break;
2880
+ }
2881
+ } catch (error) {
2882
+ lastValue = error;
2883
+ success = false;
2884
+ } finally {
2885
+ generator.return(lastValue);
2886
+ }
2887
+ if (success) return lastValue;
2888
+ throw lastValue;
2889
+ }
2877
2890
  function plan(generator) {
2878
- if (!isGenerator(generator)) throw new Error(PLAN_MESSAGE_PLAN_INPUT);
2879
- return new Plan(generator);
2891
+ if (isAsyncGenerator(generator)) return new AsyncPlan(generator);
2892
+ if (isGenerator(generator)) return new Plan(generator);
2893
+ throw new Error(PLAN_MESSAGE_PLAN_INPUT);
2880
2894
  }
2881
2895
  function run(input) {
2882
- if (isPlan(input)) return input.run();
2883
- if (!isGenerator(input)) throw new Error(PLAN_MESSAGE_RUN_INPUT);
2884
- return execute(input);
2896
+ if (isAsyncPlan(input) || isPlan(input)) return input.run();
2897
+ if (isAsyncGenerator(input)) return asyncExecute(input);
2898
+ if (isGenerator(input)) return execute(input);
2899
+ throw new Error(PLAN_MESSAGE_RUN_INPUT);
2885
2900
  }
2886
2901
  function runAsyncPlan() {
2887
2902
  return asyncExecute(this[PLAN_SYMBOL].generator);
@@ -2889,8 +2904,6 @@ function runAsyncPlan() {
2889
2904
  function runPlan() {
2890
2905
  return execute(this[PLAN_SYMBOL].generator);
2891
2906
  }
2892
- plan.async = asyncPlan;
2893
- run.async = asyncRun;
2894
2907
  //#endregion
2895
2908
  //#region src/internal/aborter.ts
2896
2909
  function createAborter(value, onAbort) {
@@ -6992,4 +7005,4 @@ var SizedSet = class extends Set {
6992
7005
  }
6993
7006
  };
6994
7007
  //#endregion
6995
- 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 };
7008
+ 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, fail, 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, succeed, 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,21 +1,21 @@
1
- import { Result } from "./result.model.mjs";
2
1
  //#region src/internal/models/plan.model.d.ts
3
2
  /**
4
3
  * An asynchronous plan of execution that can yield intermediate results and eventually return a result
5
4
  */
6
- export type AsyncPlan<Value, Error = unknown> = {
5
+ export type AsyncPlan<Yielded, Returned> = {
7
6
  /**
8
7
  * Get the asynchronous generator for the plan
9
8
  *
10
9
  * @returns Asynchronous generator
11
10
  */
12
- [Symbol.asyncIterator]: () => AsyncGenerator<unknown, Value, unknown>;
11
+ [Symbol.asyncIterator]: () => AsyncGenerator<Yielded, Returned, unknown>;
13
12
  /**
14
13
  * Run the plan to completion
15
14
  *
15
+ * @throws {PlanError<Yielded, Returned>}
16
16
  * @returns Result
17
17
  */
18
- run: () => Promise<Result<Value, Error>>;
18
+ run: () => Promise<PlanResult<Returned>>;
19
19
  };
20
20
  type AsyncPlanState = {
21
21
  generator: () => AsyncGenerator;
@@ -32,24 +32,28 @@ export type InternalPlan = {
32
32
  /**
33
33
  * A plan of execution that can yield intermediate results and eventually return a result
34
34
  */
35
- export type Plan<Value, Error = unknown> = {
35
+ export type Plan<Yielded, Returned> = {
36
36
  /**
37
37
  * Get the generator for the plan
38
38
  *
39
39
  * @returns Generator
40
40
  */
41
- [Symbol.iterator]: () => Generator<unknown, Value, unknown>;
41
+ [Symbol.iterator]: () => Generator<Yielded, Returned, unknown>;
42
42
  /**
43
43
  * Run the plan to completion
44
44
  *
45
+ * @throws {PlanError<Yielded, Returned>}
45
46
  * @returns Result
46
47
  */
47
- run: () => Result<Value, Error>;
48
+ run: () => PlanResult<Returned>;
48
49
  };
50
+ type PlanErrorValues<Original> = Original extends Error ? Original : never;
51
+ export type PlanError<Yielded, Returned> = PlanErrorValues<Yielded> | PlanErrorValues<Returned> | Error;
52
+ export type PlanResult<Returned> = Returned extends Error ? never : Returned;
49
53
  type PlanState = {
50
54
  generator: () => Generator;
51
55
  } & BaseState<typeof PLAN_TYPE_PLAN_SYNC>;
52
- export type PlanType = "asyncPlan" | "plan";
56
+ export type PlanType = "asyncPlan" | "plan" | "stop";
53
57
  export declare const GENERATOR_NAME_ASYNC = "AsyncGeneratorFunction";
54
58
  export declare const GENERATOR_NAME_SYNC = "GeneratorFunction";
55
59
  export declare const PLAN_MESSAGE_PLAN_INPUT = "plan requires a generator function";
@@ -0,0 +1,45 @@
1
+ import { AsyncPlan, Plan } from "./models/plan.model.mjs";
2
+ //#region src/internal/plan.d.ts
3
+ /**
4
+ * Create an immediately failing generator
5
+ *
6
+ * @param reason Failure reason
7
+ * @returns Failing generator
8
+ */
9
+ export declare function fail<Reason>(reason: Reason): Generator<never, never>;
10
+ /**
11
+ * Is the value an asynchronous generator function?
12
+ *
13
+ * @param value Value to check
14
+ * @returns `true` if the value is an asynchronous generator function, otherwise `false`
15
+ */
16
+ export declare function isAsyncGenerator(value: unknown): value is () => AsyncGenerator;
17
+ /**
18
+ * Is the value an asynchronous plan?
19
+ *
20
+ * @param value Value to check
21
+ * @returns `true` if the value is an asynchronous plan, otherwise `false`
22
+ */
23
+ export declare function isAsyncPlan<Yielded = unknown, Returned = unknown>(value: unknown): value is AsyncPlan<Yielded, Returned>;
24
+ /**
25
+ * Is the value a generator function?
26
+ *
27
+ * @param value Value to check
28
+ * @returns `true` if the value is a generator function, otherwise `false`
29
+ */
30
+ export declare function isGenerator(value: unknown): value is () => Generator;
31
+ /**
32
+ * Is the value a plan?
33
+ *
34
+ * @param value Value to check
35
+ * @returns `true` if the value is a plan, otherwise `false`
36
+ */
37
+ export declare function isPlan<Yielded = unknown, Returned = unknown>(value: unknown): value is Plan<Yielded, Returned>;
38
+ /**
39
+ * Create an immediately succeeding generator
40
+ *
41
+ * @param value Success value
42
+ * @returns Succeeding generator
43
+ */
44
+ export declare function succeed<Value>(value: Value): Generator<never, Value>;
45
+ //#endregion
@@ -0,0 +1,68 @@
1
+ import { GENERATOR_NAME_ASYNC, GENERATOR_NAME_SYNC, PLAN_SYMBOL, PLAN_TYPE_PLAN_ASYNC, PLAN_TYPE_PLAN_SYNC } from "./models/plan.model.mjs";
2
+ //#region src/internal/plan.ts
3
+ /**
4
+ * Create an immediately failing generator
5
+ *
6
+ * @param reason Failure reason
7
+ * @returns Failing generator
8
+ */
9
+ function fail(reason) {
10
+ return (function* () {
11
+ throw reason;
12
+ })();
13
+ }
14
+ /**
15
+ * Is the value an asynchronous generator function?
16
+ *
17
+ * @param value Value to check
18
+ * @returns `true` if the value is an asynchronous generator function, otherwise `false`
19
+ */
20
+ function isAsyncGenerator(value) {
21
+ return isGeneratorInstance(GENERATOR_NAME_ASYNC, value);
22
+ }
23
+ /**
24
+ * Is the value an asynchronous plan?
25
+ *
26
+ * @param value Value to check
27
+ * @returns `true` if the value is an asynchronous plan, otherwise `false`
28
+ */
29
+ function isAsyncPlan(value) {
30
+ return isPlanInstance(PLAN_TYPE_PLAN_ASYNC, value);
31
+ }
32
+ /**
33
+ * Is the value a generator function?
34
+ *
35
+ * @param value Value to check
36
+ * @returns `true` if the value is a generator function, otherwise `false`
37
+ */
38
+ function isGenerator(value) {
39
+ return isGeneratorInstance(GENERATOR_NAME_SYNC, value);
40
+ }
41
+ function isGeneratorInstance(name, value) {
42
+ return typeof value === "function" && value !== null && value.constructor.name === name && typeof value.prototype.next === "function" && typeof value.prototype.return === "function" && typeof value.prototype.throw === "function";
43
+ }
44
+ /**
45
+ * Is the value a plan?
46
+ *
47
+ * @param value Value to check
48
+ * @returns `true` if the value is a plan, otherwise `false`
49
+ */
50
+ function isPlan(value) {
51
+ return isPlanInstance(PLAN_TYPE_PLAN_SYNC, value);
52
+ }
53
+ function isPlanInstance(type, value) {
54
+ return typeof value === "object" && value !== null && PLAN_SYMBOL in value && value[PLAN_SYMBOL].type === type;
55
+ }
56
+ /**
57
+ * Create an immediately succeeding generator
58
+ *
59
+ * @param value Success value
60
+ * @returns Succeeding generator
61
+ */
62
+ function succeed(value) {
63
+ return (function* () {
64
+ return value;
65
+ })();
66
+ }
67
+ //#endregion
68
+ export { fail, isAsyncGenerator, isAsyncPlan, isGenerator, isPlan, succeed };
@@ -1,5 +1,4 @@
1
- import { Result } from "../internal/models/result.model.mjs";
2
- import { AsyncPlan, Plan } from "../internal/models/plan.model.mjs";
1
+ import { AsyncPlan, Plan, PlanError, PlanResult } from "../internal/models/plan.model.mjs";
3
2
  //#region src/plan/index.d.ts
4
3
  /**
5
4
  * Create a plan for an asynchronous generator function
@@ -7,74 +6,40 @@ import { AsyncPlan, Plan } from "../internal/models/plan.model.mjs";
7
6
  * @param generator Generator to plan for
8
7
  * @returns Generator plan
9
8
  */
10
- export declare function asyncPlan<Value = unknown, Error = unknown>(generator: () => AsyncGenerator<unknown, Value, unknown>): AsyncPlan<Value, Error>;
9
+ export declare function plan<Yielded, Returned>(generator: () => AsyncGenerator<Yielded, Returned>): AsyncPlan<Yielded, Returned>;
10
+ /**
11
+ * Create a plan for a generator function
12
+ *
13
+ * @param generator Generator to plan for
14
+ * @returns Generator plan
15
+ */
16
+ export declare function plan<Yielded, Returned>(generator: () => Generator<Yielded, Returned>): Plan<Yielded, Returned>;
11
17
  /**
12
18
  * Run an asynchronous generator to completion
13
19
  *
14
20
  * @param generator Generator to run
15
21
  * @returns Result
16
22
  */
17
- export declare function asyncRun<Value = unknown, Error = unknown>(generator: () => AsyncGenerator<unknown, Value, unknown>): Promise<Result<Value, Error>>;
23
+ export declare function run<Yielded, Returned>(generator: () => AsyncGenerator<Yielded, Returned>): Promise<PlanResult<Returned> | PlanError<Yielded, Returned>>;
18
24
  /**
19
25
  * Run an asynchronous plan to completion
20
26
  *
21
27
  * @param plan Plan to run
22
28
  * @returns Result
23
29
  */
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>;
30
+ export declare function run<Yielded, Returned>(plan: AsyncPlan<Yielded, Returned>): Promise<PlanResult<Returned> | PlanError<Yielded, Returned>>;
60
31
  /**
61
32
  * Run a generator to completion
62
33
  *
63
34
  * @param generator Generator to run
64
35
  * @returns Result
65
36
  */
66
- export declare function run<Value = unknown, Error = unknown>(generator: () => Generator<unknown, Value, unknown>): Result<Value, Error>;
37
+ export declare function run<Yielded, Returned>(generator: () => Generator<Yielded, Returned>): PlanResult<Returned> | PlanError<Yielded, Returned>;
67
38
  /**
68
39
  * Run a plan to completion
69
40
  *
70
41
  * @param plan Plan to run
71
42
  * @returns Result
72
43
  */
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
- }
44
+ export declare function run<Yielded, Returned>(plan: Plan<Yielded, Returned>): PlanResult<Returned> | PlanError<Yielded, Returned>;
80
45
  //#endregion
@@ -1,7 +1,5 @@
1
- import { isError, isOk } from "../internal/result/misc.mjs";
2
- import "../result/misc.mjs";
3
- import { asyncAttempt, attempt } from "../internal/result/attempt.mjs";
4
- import { GENERATOR_NAME_ASYNC, GENERATOR_NAME_SYNC, PLAN_MESSAGE_PLAN_INPUT, PLAN_MESSAGE_RUN_INPUT, PLAN_SYMBOL, PLAN_TYPE_PLAN_ASYNC, PLAN_TYPE_PLAN_SYNC } from "../internal/models/plan.model.mjs";
1
+ 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";
2
+ import { isAsyncGenerator, isAsyncPlan, isGenerator, isPlan } from "../internal/plan.mjs";
5
3
  //#region src/plan/index.ts
6
4
  function AsyncPlan(generator) {
7
5
  this[PLAN_SYMBOL] = {
@@ -23,111 +21,60 @@ Plan.prototype[Symbol.iterator] = function() {
23
21
  return this[PLAN_SYMBOL].generator();
24
22
  };
25
23
  Plan.prototype.run = runPlan;
26
- function asyncExecute(callback) {
27
- return asyncAttempt(async () => {
28
- const generator = callback();
29
- let lastValue;
24
+ async function asyncExecute(callback) {
25
+ const generator = callback();
26
+ let success = true;
27
+ let lastValue;
28
+ try {
30
29
  while (true) {
31
- const next = await generator.next();
30
+ const next = await generator.next(lastValue);
32
31
  const { done } = next;
33
- let value = next.value;
32
+ let { value } = next;
34
33
  if (value instanceof Error) throw value;
35
- if (isError(value)) throw value.error;
36
- if (isOk(value)) value = value.value;
37
34
  lastValue = value;
38
35
  if (done === true) break;
39
36
  }
40
- return lastValue;
41
- });
42
- }
43
- /**
44
- * Create a plan for an asynchronous generator function
45
- *
46
- * @param generator Generator to plan for
47
- * @returns Generator plan
48
- */
49
- function asyncPlan(generator) {
50
- if (!isAsyncGenerator(generator)) throw new Error(PLAN_MESSAGE_PLAN_INPUT);
51
- return new AsyncPlan(generator);
52
- }
53
- async function asyncRun(input) {
54
- if (isAsyncPlan(input)) return input.run();
55
- if (!isAsyncGenerator(input)) throw new Error(PLAN_MESSAGE_RUN_INPUT);
56
- return asyncExecute(input);
37
+ } catch (error) {
38
+ lastValue = error;
39
+ success = false;
40
+ } finally {
41
+ generator?.return(lastValue);
42
+ }
43
+ if (success) return lastValue;
44
+ throw lastValue;
57
45
  }
58
46
  function execute(callback) {
59
- return attempt(() => {
60
- const generator = callback();
61
- let lastValue;
47
+ const generator = callback();
48
+ let success = true;
49
+ let lastValue;
50
+ try {
62
51
  while (true) {
63
- const next = generator.next();
64
- const { done } = next;
52
+ const next = generator.next(lastValue);
53
+ const done = next.done === true;
65
54
  let { value } = next;
66
55
  if (value instanceof Error) throw value;
67
- if (isError(value)) throw value.error;
68
- if (isOk(value)) value = value.value;
69
56
  lastValue = value;
70
- if (done === true) break;
57
+ if (done) break;
71
58
  }
72
- return lastValue;
73
- });
74
- }
75
- /**
76
- * Is the value an asynchronous plan?
77
- *
78
- * @param value Value to check
79
- * @returns `true` if the value is an asynchronous plan, otherwise `false`
80
- */
81
- function isAsyncPlan(value) {
82
- return isPlanInstance(PLAN_TYPE_PLAN_ASYNC, value);
83
- }
84
- /**
85
- * Is the value an asynchronous generator function?
86
- *
87
- * @param value Value to check
88
- * @returns `true` if the value is an asynchronous generator function, otherwise `false`
89
- */
90
- function isAsyncGenerator(value) {
91
- return isGeneratorInstance(GENERATOR_NAME_ASYNC, value);
92
- }
93
- /**
94
- * Is the value a generator function?
95
- *
96
- * @param value Value to check
97
- * @returns `true` if the value is a generator function, otherwise `false`
98
- */
99
- function isGenerator(value) {
100
- return isGeneratorInstance(GENERATOR_NAME_SYNC, value);
101
- }
102
- function isGeneratorInstance(name, value) {
103
- return typeof value === "function" && value !== null && value.constructor.name === name && typeof value.prototype.next === "function" && typeof value.prototype.return === "function" && typeof value.prototype.throw === "function";
104
- }
105
- /**
106
- * Is the value a plan?
107
- *
108
- * @param value Value to check
109
- * @returns `true` if the value is a plan, otherwise `false`
110
- */
111
- function isPlan(value) {
112
- return isPlanInstance(PLAN_TYPE_PLAN_SYNC, value);
113
- }
114
- function isPlanInstance(type, value) {
115
- return typeof value === "object" && value !== null && PLAN_SYMBOL in value && value[PLAN_SYMBOL].type === type;
59
+ } catch (error) {
60
+ lastValue = error;
61
+ success = false;
62
+ } finally {
63
+ generator.return(lastValue);
64
+ }
65
+ if (success) return lastValue;
66
+ throw lastValue;
116
67
  }
117
- /**
118
- * Create a plan for a generator function
119
- *
120
- * @param generator Generator to plan for
121
- * @returns Generator plan
122
- */
123
68
  function plan(generator) {
124
- if (!isGenerator(generator)) throw new Error(PLAN_MESSAGE_PLAN_INPUT);
125
- return new Plan(generator);
69
+ if (isAsyncGenerator(generator)) return new AsyncPlan(generator);
70
+ if (isGenerator(generator)) return new Plan(generator);
71
+ throw new Error(PLAN_MESSAGE_PLAN_INPUT);
126
72
  }
127
73
  function run(input) {
128
- if (isPlan(input)) return input.run();
129
- if (!isGenerator(input)) throw new Error(PLAN_MESSAGE_RUN_INPUT);
130
- return execute(input);
74
+ if (isAsyncPlan(input) || isPlan(input)) return input.run();
75
+ if (isAsyncGenerator(input)) return asyncExecute(input);
76
+ if (isGenerator(input)) return execute(input);
77
+ throw new Error(PLAN_MESSAGE_RUN_INPUT);
131
78
  }
132
79
  function runAsyncPlan() {
133
80
  return asyncExecute(this[PLAN_SYMBOL].generator);
@@ -135,7 +82,5 @@ function runAsyncPlan() {
135
82
  function runPlan() {
136
83
  return execute(this[PLAN_SYMBOL].generator);
137
84
  }
138
- plan.async = asyncPlan;
139
- run.async = asyncRun;
140
85
  //#endregion
141
- export { asyncPlan, asyncRun, isAsyncGenerator, isAsyncPlan, isGenerator, isPlan, plan, run };
86
+ export { plan, run };
@@ -0,0 +1,2 @@
1
+ import { isAsyncGenerator, isAsyncPlan, isGenerator, isPlan } from "../internal/plan.mjs";
2
+ export { isAsyncGenerator, isAsyncPlan, isGenerator, isPlan };
@@ -0,0 +1,2 @@
1
+ import { isAsyncGenerator, isAsyncPlan, isGenerator, isPlan } from "../internal/plan.mjs";
2
+ export { isAsyncGenerator, isAsyncPlan, isGenerator, isPlan };
@@ -0,0 +1,2 @@
1
+ import { fail, succeed } from "../internal/plan.mjs";
2
+ export { fail, succeed };
@@ -0,0 +1,2 @@
1
+ import { fail, succeed } from "../internal/plan.mjs";
2
+ export { fail, succeed };
@@ -1,2 +1,2 @@
1
- import { Plan } from "../internal/models/plan.model.mjs";
2
- export type { Plan };
1
+ import { AsyncPlan, Plan } from "../internal/models/plan.model.mjs";
2
+ export type { AsyncPlan, Plan };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@oscarpalmer/atoms",
3
- "version": "0.209.0",
3
+ "version": "0.210.0",
4
4
  "description": "Atomic utilities for making your JavaScript better.",
5
5
  "keywords": [
6
6
  "array",
@@ -153,6 +153,14 @@
153
153
  "types": "./dist/plan/index.d.mts",
154
154
  "default": "./dist/plan/index.mjs"
155
155
  },
156
+ "./plan/is": {
157
+ "types": "./dist/plan/is.d.mts",
158
+ "default": "./dist/plan/is.mjs"
159
+ },
160
+ "./plan/misc": {
161
+ "types": "./dist/plan/misc.d.mts",
162
+ "default": "./dist/plan/misc.mjs"
163
+ },
156
164
  "./plan/models": {
157
165
  "default": "./dist/plan/models.mjs"
158
166
  },
@@ -297,7 +305,7 @@
297
305
  "devDependencies": {
298
306
  "@types/node": "^26.6",
299
307
  "@vitest/coverage-istanbul": "5.0.1",
300
- "eslint": "^10.11",
308
+ "eslint": "^10.12",
301
309
  "jsdom": "^30.1",
302
310
  "tsdown": "^0.23",
303
311
  "typescript": "^7",