@kdtlabs/utils 0.0.4 → 0.0.6
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/SKILL.md +12 -9
- package/dist/arrays/comparators.d.ts +8 -0
- package/dist/arrays/comparators.d.ts.map +1 -0
- package/{arrays → dist/arrays}/index.d.ts +1 -0
- package/dist/arrays/index.d.ts.map +1 -0
- package/{common → dist/common}/assertions.d.ts +1 -1
- package/{common → dist/common}/assertions.d.ts.map +1 -1
- package/{common → dist/common}/types.d.ts +1 -1
- package/{common → dist/common}/types.d.ts.map +1 -1
- package/{functions → dist/functions}/executions.d.ts +1 -1
- package/{functions → dist/functions}/executions.d.ts.map +1 -1
- package/dist/index.js +14 -0
- package/dist/index.js.map +101 -0
- package/{objects → dist/objects}/transformations.d.ts +1 -1
- package/{objects → dist/objects}/transformations.d.ts.map +1 -1
- package/{objects → dist/objects}/types.d.ts +1 -1
- package/{objects → dist/objects}/types.d.ts.map +1 -1
- package/{promises → dist/promises}/deferred.d.ts +1 -1
- package/{promises → dist/promises}/deferred.d.ts.map +1 -1
- package/{promises → dist/promises}/timers.d.ts +1 -1
- package/{promises → dist/promises}/timers.d.ts.map +1 -1
- package/{serializer → dist/serializer}/context.d.ts +1 -1
- package/{serializer → dist/serializer}/context.d.ts.map +1 -1
- package/{serializer → dist/serializer}/serialize.d.ts +1 -1
- package/{serializer → dist/serializer}/serialize.d.ts.map +1 -1
- package/{serializer → dist/serializer}/serializers/array.d.ts +1 -1
- package/{serializer → dist/serializer}/serializers/array.d.ts.map +1 -1
- package/{serializer → dist/serializer}/serializers/binary.d.ts +1 -1
- package/dist/serializer/serializers/binary.d.ts.map +1 -0
- package/{serializer → dist/serializer}/serializers/blob.d.ts +1 -1
- package/dist/serializer/serializers/blob.d.ts.map +1 -0
- package/{serializer → dist/serializer}/serializers/collection.d.ts +1 -1
- package/{serializer → dist/serializer}/serializers/collection.d.ts.map +1 -1
- package/{serializer → dist/serializer}/serializers/compound.d.ts +1 -1
- package/{serializer → dist/serializer}/serializers/compound.d.ts.map +1 -1
- package/{serializer → dist/serializer}/serializers/error.d.ts +1 -1
- package/{serializer → dist/serializer}/serializers/error.d.ts.map +1 -1
- package/{serializer → dist/serializer}/serializers/function.d.ts +1 -1
- package/{serializer → dist/serializer}/serializers/function.d.ts.map +1 -1
- package/{serializer → dist/serializer}/serializers/leaf-object.d.ts +1 -1
- package/{serializer → dist/serializer}/serializers/leaf-object.d.ts.map +1 -1
- package/{serializer → dist/serializer}/serializers/number.d.ts +1 -1
- package/dist/serializer/serializers/number.d.ts.map +1 -0
- package/{serializer → dist/serializer}/serializers/object.d.ts +1 -1
- package/{serializer → dist/serializer}/serializers/object.d.ts.map +1 -1
- package/{serializer → dist/serializer}/serializers/opaque.d.ts +1 -1
- package/dist/serializer/serializers/opaque.d.ts.map +1 -0
- package/{serializer → dist/serializer}/serializers/primitive.d.ts +1 -1
- package/{serializer → dist/serializer}/serializers/primitive.d.ts.map +1 -1
- package/{serializer → dist/serializer}/types.d.ts +1 -1
- package/{serializer → dist/serializer}/types.d.ts.map +1 -1
- package/{serializer → dist/serializer}/utils.d.ts +1 -1
- package/{serializer → dist/serializer}/utils.d.ts.map +1 -1
- package/{strings → dist/strings}/index.d.ts +1 -0
- package/{strings → dist/strings}/index.d.ts.map +1 -1
- package/{strings → dist/strings}/manipulations.d.ts +2 -0
- package/{strings → dist/strings}/manipulations.d.ts.map +1 -1
- package/dist/strings/strip-ansi.d.ts +2 -0
- package/dist/strings/strip-ansi.d.ts.map +1 -0
- package/{system → dist/system}/fetch.d.ts +2 -2
- package/{system → dist/system}/fetch.d.ts.map +1 -1
- package/dist/system/types.d.ts +3 -0
- package/{system → dist/system}/types.d.ts.map +1 -1
- package/{times → dist/times}/conversions.d.ts +1 -1
- package/{times → dist/times}/conversions.d.ts.map +1 -1
- package/package.json +11 -73
- package/src/arrays/accessors.ts +25 -0
- package/src/arrays/comparators.ts +53 -0
- package/src/arrays/conversions.ts +16 -0
- package/src/arrays/factories.ts +13 -0
- package/src/arrays/guards.ts +7 -0
- package/src/arrays/index.ts +9 -0
- package/src/arrays/operations.ts +103 -0
- package/src/arrays/set-operations.ts +11 -0
- package/src/arrays/types.ts +21 -0
- package/src/buffers/conversions.ts +26 -0
- package/src/buffers/guards.ts +13 -0
- package/src/buffers/index.ts +5 -0
- package/src/buffers/operations.ts +44 -0
- package/src/buffers/types.ts +1 -0
- package/src/collections/fifo-map.ts +33 -0
- package/src/collections/fifo-set.ts +29 -0
- package/src/collections/guards.ts +11 -0
- package/src/collections/index.ts +10 -0
- package/src/collections/linked-base.ts +117 -0
- package/src/collections/linked-map.ts +82 -0
- package/src/collections/linked-set.ts +69 -0
- package/src/collections/lru-map.ts +36 -0
- package/src/collections/lru-set.ts +25 -0
- package/src/collections/types.ts +12 -0
- package/src/common/assertions.ts +11 -0
- package/src/common/guards.ts +58 -0
- package/src/common/index.ts +5 -0
- package/src/common/transformations.ts +20 -0
- package/src/common/types.ts +3 -0
- package/src/core/constants.ts +1 -0
- package/src/core/conversions.ts +9 -0
- package/src/core/guards.ts +57 -0
- package/src/core/index.ts +5 -0
- package/src/core/types.ts +15 -0
- package/src/errors/base-error.ts +48 -0
- package/src/errors/factories.ts +74 -0
- package/src/errors/guards.ts +12 -0
- package/src/errors/index.ts +7 -0
- package/src/errors/operations.ts +15 -0
- package/src/errors/stringify.ts +131 -0
- package/src/errors/types.ts +11 -0
- package/src/events/emitter.ts +117 -0
- package/src/events/index.ts +2 -0
- package/src/events/types.ts +11 -0
- package/src/functions/compositions.ts +17 -0
- package/src/functions/debounce.ts +34 -0
- package/src/functions/executions.ts +12 -0
- package/src/functions/guards.ts +5 -0
- package/src/functions/index.ts +11 -0
- package/src/functions/memoize.ts +33 -0
- package/src/functions/once.ts +33 -0
- package/src/functions/pipe.ts +39 -0
- package/src/functions/throttle.ts +59 -0
- package/src/functions/timer-state.ts +33 -0
- package/src/functions/types.ts +8 -0
- package/src/index.ts +16 -0
- package/src/json-rpc/constants.ts +15 -0
- package/src/json-rpc/factories.ts +22 -0
- package/src/json-rpc/guards.ts +58 -0
- package/src/json-rpc/index.ts +5 -0
- package/src/json-rpc/types.ts +48 -0
- package/src/numbers/bigint-math.ts +163 -0
- package/src/numbers/constants.ts +14 -0
- package/src/numbers/conversions.ts +83 -0
- package/src/numbers/factories.ts +6 -0
- package/src/numbers/formats.ts +52 -0
- package/src/numbers/guards.ts +22 -0
- package/src/numbers/index.ts +10 -0
- package/src/numbers/maths.ts +28 -0
- package/src/numbers/ranges.ts +17 -0
- package/src/numbers/types.ts +7 -0
- package/src/objects/deep-merge.ts +76 -0
- package/src/objects/guards.ts +21 -0
- package/src/objects/index.ts +5 -0
- package/src/objects/transformations.ts +34 -0
- package/src/objects/types.ts +33 -0
- package/src/promises/abortable.ts +37 -0
- package/src/promises/compositions.ts +18 -0
- package/src/promises/deferred.ts +131 -0
- package/src/promises/guards.ts +8 -0
- package/src/promises/index.ts +10 -0
- package/src/promises/pipe.ts +39 -0
- package/src/promises/poll.ts +92 -0
- package/src/promises/retry.ts +138 -0
- package/src/promises/timers.ts +16 -0
- package/src/promises/types.ts +1 -0
- package/src/serializer/constants.ts +5 -0
- package/src/serializer/context.ts +24 -0
- package/src/serializer/index.ts +8 -0
- package/src/serializer/serialize.ts +51 -0
- package/src/serializer/serializers/array.ts +17 -0
- package/src/serializer/serializers/binary.ts +24 -0
- package/src/serializer/serializers/blob.ts +18 -0
- package/src/serializer/serializers/collection.ts +25 -0
- package/src/serializer/serializers/compound.ts +79 -0
- package/src/serializer/serializers/error.ts +75 -0
- package/src/serializer/serializers/function.ts +13 -0
- package/src/serializer/serializers/index.ts +12 -0
- package/src/serializer/serializers/leaf-object.ts +18 -0
- package/src/serializer/serializers/number.ts +14 -0
- package/src/serializer/serializers/object.ts +62 -0
- package/src/serializer/serializers/opaque.ts +36 -0
- package/src/serializer/serializers/primitive.ts +32 -0
- package/src/serializer/symbol-registry.ts +28 -0
- package/src/serializer/types.ts +42 -0
- package/src/serializer/utils.ts +15 -0
- package/src/strings/constants.ts +1 -0
- package/src/strings/factories.ts +9 -0
- package/src/strings/guards.ts +51 -0
- package/src/strings/index.ts +7 -0
- package/src/strings/manipulations.ts +145 -0
- package/src/strings/strip-ansi.ts +14 -0
- package/src/strings/types.ts +3 -0
- package/src/system/env.ts +32 -0
- package/src/system/fetch.ts +23 -0
- package/src/system/graceful-exit.ts +46 -0
- package/src/system/index.ts +6 -0
- package/src/system/path.ts +12 -0
- package/src/system/types.ts +3 -0
- package/src/times/constants.ts +6 -0
- package/src/times/conversions.ts +85 -0
- package/src/times/factories.ts +3 -0
- package/src/times/guards.ts +3 -0
- package/src/times/index.ts +5 -0
- package/src/times/operations.ts +9 -0
- package/CHANGELOG.md +0 -57
- package/arrays/index.d.ts.map +0 -1
- package/arrays/index.js +0 -4
- package/arrays/index.js.map +0 -9
- package/buffers/index.js +0 -4
- package/buffers/index.js.map +0 -9
- package/chunk-25ja9350.js +0 -4
- package/chunk-25ja9350.js.map +0 -13
- package/chunk-3w6nt7kb.js +0 -4
- package/chunk-3w6nt7kb.js.map +0 -12
- package/chunk-5txwcr6j.js +0 -4
- package/chunk-5txwcr6j.js.map +0 -17
- package/chunk-6dxad51h.js +0 -4
- package/chunk-6dxad51h.js.map +0 -12
- package/chunk-6kdnnxe0.js +0 -4
- package/chunk-6kdnnxe0.js.map +0 -17
- package/chunk-7cndek91.js +0 -4
- package/chunk-7cndek91.js.map +0 -15
- package/chunk-bee0nxse.js +0 -6
- package/chunk-bee0nxse.js.map +0 -14
- package/chunk-bjmntg2y.js +0 -4
- package/chunk-bjmntg2y.js.map +0 -18
- package/chunk-d0d0d285.js +0 -4
- package/chunk-d0d0d285.js.map +0 -26
- package/chunk-jny2gdyy.js +0 -4
- package/chunk-jny2gdyy.js.map +0 -12
- package/chunk-kbzgn0z4.js +0 -4
- package/chunk-kbzgn0z4.js.map +0 -10
- package/chunk-qmbgp0vr.js +0 -4
- package/chunk-qmbgp0vr.js.map +0 -12
- package/chunk-qn6n0ff5.js +0 -4
- package/chunk-qn6n0ff5.js.map +0 -17
- package/chunk-r3maskdb.js +0 -5
- package/chunk-r3maskdb.js.map +0 -13
- package/chunk-st3dxvqt.js +0 -4
- package/chunk-st3dxvqt.js.map +0 -14
- package/chunk-xp18wdk6.js +0 -4
- package/chunk-xp18wdk6.js.map +0 -12
- package/collections/index.js +0 -4
- package/collections/index.js.map +0 -9
- package/common/index.js +0 -4
- package/common/index.js.map +0 -9
- package/core/index.js +0 -4
- package/core/index.js.map +0 -9
- package/errors/index.js +0 -4
- package/errors/index.js.map +0 -9
- package/events/index.js +0 -4
- package/events/index.js.map +0 -9
- package/functions/index.js +0 -4
- package/functions/index.js.map +0 -9
- package/index.js +0 -4
- package/index.js.map +0 -9
- package/json-rpc/index.js +0 -4
- package/json-rpc/index.js.map +0 -9
- package/meta.json +0 -2998
- package/meta.md +0 -1816
- package/numbers/index.js +0 -4
- package/numbers/index.js.map +0 -9
- package/objects/index.js +0 -4
- package/objects/index.js.map +0 -9
- package/promises/index.js +0 -4
- package/promises/index.js.map +0 -9
- package/serializer/index.js +0 -4
- package/serializer/index.js.map +0 -9
- package/serializer/serializers/binary.d.ts.map +0 -1
- package/serializer/serializers/blob.d.ts.map +0 -1
- package/serializer/serializers/number.d.ts.map +0 -1
- package/serializer/serializers/opaque.d.ts.map +0 -1
- package/strings/index.js +0 -4
- package/strings/index.js.map +0 -9
- package/system/index.js +0 -4
- package/system/index.js.map +0 -9
- package/system/types.d.ts +0 -3
- package/times/index.js +0 -4
- package/times/index.js.map +0 -9
- /package/{arrays → dist/arrays}/accessors.d.ts +0 -0
- /package/{arrays → dist/arrays}/accessors.d.ts.map +0 -0
- /package/{arrays → dist/arrays}/conversions.d.ts +0 -0
- /package/{arrays → dist/arrays}/conversions.d.ts.map +0 -0
- /package/{arrays → dist/arrays}/factories.d.ts +0 -0
- /package/{arrays → dist/arrays}/factories.d.ts.map +0 -0
- /package/{arrays → dist/arrays}/guards.d.ts +0 -0
- /package/{arrays → dist/arrays}/guards.d.ts.map +0 -0
- /package/{arrays → dist/arrays}/operations.d.ts +0 -0
- /package/{arrays → dist/arrays}/operations.d.ts.map +0 -0
- /package/{arrays → dist/arrays}/set-operations.d.ts +0 -0
- /package/{arrays → dist/arrays}/set-operations.d.ts.map +0 -0
- /package/{arrays → dist/arrays}/types.d.ts +0 -0
- /package/{arrays → dist/arrays}/types.d.ts.map +0 -0
- /package/{buffers → dist/buffers}/conversions.d.ts +0 -0
- /package/{buffers → dist/buffers}/conversions.d.ts.map +0 -0
- /package/{buffers → dist/buffers}/guards.d.ts +0 -0
- /package/{buffers → dist/buffers}/guards.d.ts.map +0 -0
- /package/{buffers → dist/buffers}/index.d.ts +0 -0
- /package/{buffers → dist/buffers}/index.d.ts.map +0 -0
- /package/{buffers → dist/buffers}/operations.d.ts +0 -0
- /package/{buffers → dist/buffers}/operations.d.ts.map +0 -0
- /package/{buffers → dist/buffers}/types.d.ts +0 -0
- /package/{buffers → dist/buffers}/types.d.ts.map +0 -0
- /package/{collections → dist/collections}/fifo-map.d.ts +0 -0
- /package/{collections → dist/collections}/fifo-map.d.ts.map +0 -0
- /package/{collections → dist/collections}/fifo-set.d.ts +0 -0
- /package/{collections → dist/collections}/fifo-set.d.ts.map +0 -0
- /package/{collections → dist/collections}/guards.d.ts +0 -0
- /package/{collections → dist/collections}/guards.d.ts.map +0 -0
- /package/{collections → dist/collections}/index.d.ts +0 -0
- /package/{collections → dist/collections}/index.d.ts.map +0 -0
- /package/{collections → dist/collections}/linked-base.d.ts +0 -0
- /package/{collections → dist/collections}/linked-base.d.ts.map +0 -0
- /package/{collections → dist/collections}/linked-map.d.ts +0 -0
- /package/{collections → dist/collections}/linked-map.d.ts.map +0 -0
- /package/{collections → dist/collections}/linked-set.d.ts +0 -0
- /package/{collections → dist/collections}/linked-set.d.ts.map +0 -0
- /package/{collections → dist/collections}/lru-map.d.ts +0 -0
- /package/{collections → dist/collections}/lru-map.d.ts.map +0 -0
- /package/{collections → dist/collections}/lru-set.d.ts +0 -0
- /package/{collections → dist/collections}/lru-set.d.ts.map +0 -0
- /package/{collections → dist/collections}/types.d.ts +0 -0
- /package/{collections → dist/collections}/types.d.ts.map +0 -0
- /package/{common → dist/common}/guards.d.ts +0 -0
- /package/{common → dist/common}/guards.d.ts.map +0 -0
- /package/{common → dist/common}/index.d.ts +0 -0
- /package/{common → dist/common}/index.d.ts.map +0 -0
- /package/{common → dist/common}/transformations.d.ts +0 -0
- /package/{common → dist/common}/transformations.d.ts.map +0 -0
- /package/{core → dist/core}/constants.d.ts +0 -0
- /package/{core → dist/core}/constants.d.ts.map +0 -0
- /package/{core → dist/core}/conversions.d.ts +0 -0
- /package/{core → dist/core}/conversions.d.ts.map +0 -0
- /package/{core → dist/core}/guards.d.ts +0 -0
- /package/{core → dist/core}/guards.d.ts.map +0 -0
- /package/{core → dist/core}/index.d.ts +0 -0
- /package/{core → dist/core}/index.d.ts.map +0 -0
- /package/{core → dist/core}/types.d.ts +0 -0
- /package/{core → dist/core}/types.d.ts.map +0 -0
- /package/{errors → dist/errors}/base-error.d.ts +0 -0
- /package/{errors → dist/errors}/base-error.d.ts.map +0 -0
- /package/{errors → dist/errors}/factories.d.ts +0 -0
- /package/{errors → dist/errors}/factories.d.ts.map +0 -0
- /package/{errors → dist/errors}/guards.d.ts +0 -0
- /package/{errors → dist/errors}/guards.d.ts.map +0 -0
- /package/{errors → dist/errors}/index.d.ts +0 -0
- /package/{errors → dist/errors}/index.d.ts.map +0 -0
- /package/{errors → dist/errors}/operations.d.ts +0 -0
- /package/{errors → dist/errors}/operations.d.ts.map +0 -0
- /package/{errors → dist/errors}/stringify.d.ts +0 -0
- /package/{errors → dist/errors}/stringify.d.ts.map +0 -0
- /package/{errors → dist/errors}/types.d.ts +0 -0
- /package/{errors → dist/errors}/types.d.ts.map +0 -0
- /package/{events → dist/events}/emitter.d.ts +0 -0
- /package/{events → dist/events}/emitter.d.ts.map +0 -0
- /package/{events → dist/events}/index.d.ts +0 -0
- /package/{events → dist/events}/index.d.ts.map +0 -0
- /package/{events → dist/events}/types.d.ts +0 -0
- /package/{events → dist/events}/types.d.ts.map +0 -0
- /package/{functions → dist/functions}/compositions.d.ts +0 -0
- /package/{functions → dist/functions}/compositions.d.ts.map +0 -0
- /package/{functions → dist/functions}/debounce.d.ts +0 -0
- /package/{functions → dist/functions}/debounce.d.ts.map +0 -0
- /package/{functions → dist/functions}/guards.d.ts +0 -0
- /package/{functions → dist/functions}/guards.d.ts.map +0 -0
- /package/{functions → dist/functions}/index.d.ts +0 -0
- /package/{functions → dist/functions}/index.d.ts.map +0 -0
- /package/{functions → dist/functions}/memoize.d.ts +0 -0
- /package/{functions → dist/functions}/memoize.d.ts.map +0 -0
- /package/{functions → dist/functions}/once.d.ts +0 -0
- /package/{functions → dist/functions}/once.d.ts.map +0 -0
- /package/{functions → dist/functions}/pipe.d.ts +0 -0
- /package/{functions → dist/functions}/pipe.d.ts.map +0 -0
- /package/{functions → dist/functions}/throttle.d.ts +0 -0
- /package/{functions → dist/functions}/throttle.d.ts.map +0 -0
- /package/{functions → dist/functions}/timer-state.d.ts +0 -0
- /package/{functions → dist/functions}/timer-state.d.ts.map +0 -0
- /package/{functions → dist/functions}/types.d.ts +0 -0
- /package/{functions → dist/functions}/types.d.ts.map +0 -0
- /package/{index.d.ts → dist/index.d.ts} +0 -0
- /package/{index.d.ts.map → dist/index.d.ts.map} +0 -0
- /package/{json-rpc → dist/json-rpc}/constants.d.ts +0 -0
- /package/{json-rpc → dist/json-rpc}/constants.d.ts.map +0 -0
- /package/{json-rpc → dist/json-rpc}/factories.d.ts +0 -0
- /package/{json-rpc → dist/json-rpc}/factories.d.ts.map +0 -0
- /package/{json-rpc → dist/json-rpc}/guards.d.ts +0 -0
- /package/{json-rpc → dist/json-rpc}/guards.d.ts.map +0 -0
- /package/{json-rpc → dist/json-rpc}/index.d.ts +0 -0
- /package/{json-rpc → dist/json-rpc}/index.d.ts.map +0 -0
- /package/{json-rpc → dist/json-rpc}/types.d.ts +0 -0
- /package/{json-rpc → dist/json-rpc}/types.d.ts.map +0 -0
- /package/{numbers → dist/numbers}/bigint-math.d.ts +0 -0
- /package/{numbers → dist/numbers}/bigint-math.d.ts.map +0 -0
- /package/{numbers → dist/numbers}/constants.d.ts +0 -0
- /package/{numbers → dist/numbers}/constants.d.ts.map +0 -0
- /package/{numbers → dist/numbers}/conversions.d.ts +0 -0
- /package/{numbers → dist/numbers}/conversions.d.ts.map +0 -0
- /package/{numbers → dist/numbers}/factories.d.ts +0 -0
- /package/{numbers → dist/numbers}/factories.d.ts.map +0 -0
- /package/{numbers → dist/numbers}/formats.d.ts +0 -0
- /package/{numbers → dist/numbers}/formats.d.ts.map +0 -0
- /package/{numbers → dist/numbers}/guards.d.ts +0 -0
- /package/{numbers → dist/numbers}/guards.d.ts.map +0 -0
- /package/{numbers → dist/numbers}/index.d.ts +0 -0
- /package/{numbers → dist/numbers}/index.d.ts.map +0 -0
- /package/{numbers → dist/numbers}/maths.d.ts +0 -0
- /package/{numbers → dist/numbers}/maths.d.ts.map +0 -0
- /package/{numbers → dist/numbers}/ranges.d.ts +0 -0
- /package/{numbers → dist/numbers}/ranges.d.ts.map +0 -0
- /package/{numbers → dist/numbers}/types.d.ts +0 -0
- /package/{numbers → dist/numbers}/types.d.ts.map +0 -0
- /package/{objects → dist/objects}/deep-merge.d.ts +0 -0
- /package/{objects → dist/objects}/deep-merge.d.ts.map +0 -0
- /package/{objects → dist/objects}/guards.d.ts +0 -0
- /package/{objects → dist/objects}/guards.d.ts.map +0 -0
- /package/{objects → dist/objects}/index.d.ts +0 -0
- /package/{objects → dist/objects}/index.d.ts.map +0 -0
- /package/{promises → dist/promises}/abortable.d.ts +0 -0
- /package/{promises → dist/promises}/abortable.d.ts.map +0 -0
- /package/{promises → dist/promises}/compositions.d.ts +0 -0
- /package/{promises → dist/promises}/compositions.d.ts.map +0 -0
- /package/{promises → dist/promises}/guards.d.ts +0 -0
- /package/{promises → dist/promises}/guards.d.ts.map +0 -0
- /package/{promises → dist/promises}/index.d.ts +0 -0
- /package/{promises → dist/promises}/index.d.ts.map +0 -0
- /package/{promises → dist/promises}/pipe.d.ts +0 -0
- /package/{promises → dist/promises}/pipe.d.ts.map +0 -0
- /package/{promises → dist/promises}/poll.d.ts +0 -0
- /package/{promises → dist/promises}/poll.d.ts.map +0 -0
- /package/{promises → dist/promises}/retry.d.ts +0 -0
- /package/{promises → dist/promises}/retry.d.ts.map +0 -0
- /package/{promises → dist/promises}/types.d.ts +0 -0
- /package/{promises → dist/promises}/types.d.ts.map +0 -0
- /package/{serializer → dist/serializer}/constants.d.ts +0 -0
- /package/{serializer → dist/serializer}/constants.d.ts.map +0 -0
- /package/{serializer → dist/serializer}/index.d.ts +0 -0
- /package/{serializer → dist/serializer}/index.d.ts.map +0 -0
- /package/{serializer → dist/serializer}/serializers/index.d.ts +0 -0
- /package/{serializer → dist/serializer}/serializers/index.d.ts.map +0 -0
- /package/{serializer → dist/serializer}/symbol-registry.d.ts +0 -0
- /package/{serializer → dist/serializer}/symbol-registry.d.ts.map +0 -0
- /package/{strings → dist/strings}/constants.d.ts +0 -0
- /package/{strings → dist/strings}/constants.d.ts.map +0 -0
- /package/{strings → dist/strings}/factories.d.ts +0 -0
- /package/{strings → dist/strings}/factories.d.ts.map +0 -0
- /package/{strings → dist/strings}/guards.d.ts +0 -0
- /package/{strings → dist/strings}/guards.d.ts.map +0 -0
- /package/{strings → dist/strings}/types.d.ts +0 -0
- /package/{strings → dist/strings}/types.d.ts.map +0 -0
- /package/{system → dist/system}/env.d.ts +0 -0
- /package/{system → dist/system}/env.d.ts.map +0 -0
- /package/{system → dist/system}/graceful-exit.d.ts +0 -0
- /package/{system → dist/system}/graceful-exit.d.ts.map +0 -0
- /package/{system → dist/system}/index.d.ts +0 -0
- /package/{system → dist/system}/index.d.ts.map +0 -0
- /package/{system → dist/system}/path.d.ts +0 -0
- /package/{system → dist/system}/path.d.ts.map +0 -0
- /package/{times → dist/times}/constants.d.ts +0 -0
- /package/{times → dist/times}/constants.d.ts.map +0 -0
- /package/{times → dist/times}/factories.d.ts +0 -0
- /package/{times → dist/times}/factories.d.ts.map +0 -0
- /package/{times → dist/times}/guards.d.ts +0 -0
- /package/{times → dist/times}/guards.d.ts.map +0 -0
- /package/{times → dist/times}/index.d.ts +0 -0
- /package/{times → dist/times}/index.d.ts.map +0 -0
- /package/{times → dist/times}/operations.d.ts +0 -0
- /package/{times → dist/times}/operations.d.ts.map +0 -0
|
@@ -0,0 +1,83 @@
|
|
|
1
|
+
import type { Numberish } from './types'
|
|
2
|
+
import { SUBSCRIPT_CHARS } from './constants'
|
|
3
|
+
import { roundTo } from './maths'
|
|
4
|
+
|
|
5
|
+
export function toSubscriptDigits(input: Numberish) {
|
|
6
|
+
let result = ''
|
|
7
|
+
|
|
8
|
+
for (const char of input.toString()) {
|
|
9
|
+
result += SUBSCRIPT_CHARS[char] ?? char
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return result
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export function parseExponential(input: Numberish) {
|
|
16
|
+
const str = input.toString().toLowerCase()
|
|
17
|
+
const [mantissa, rawExp] = str.split('e')
|
|
18
|
+
|
|
19
|
+
if (rawExp === undefined) {
|
|
20
|
+
return str
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
const [rawInt, fracPart = ''] = mantissa?.split('.') ?? []
|
|
24
|
+
|
|
25
|
+
if (!rawInt) {
|
|
26
|
+
return str
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
const sign = rawInt.startsWith('-') ? '-' : ''
|
|
30
|
+
const intPart = sign ? rawInt.slice(1) : rawInt
|
|
31
|
+
const exp = Number(rawExp)
|
|
32
|
+
|
|
33
|
+
if (exp >= 0) {
|
|
34
|
+
const neededZeros = Math.max(0, exp - fracPart.length)
|
|
35
|
+
const padded = fracPart + '0'.repeat(neededZeros)
|
|
36
|
+
|
|
37
|
+
if (padded.length > exp) {
|
|
38
|
+
return `${sign}${intPart}${padded.slice(0, exp)}.${padded.slice(exp)}`
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
return `${sign}${intPart}${padded}`
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
const absExp = -exp
|
|
45
|
+
const digits = intPart + fracPart
|
|
46
|
+
const totalLeadingZeros = Math.max(0, absExp - intPart.length)
|
|
47
|
+
|
|
48
|
+
return `${sign}0.${'0'.repeat(totalLeadingZeros)}${digits}`
|
|
49
|
+
}
|
|
50
|
+
|
|
51
|
+
export function toOrdinal(n: number) {
|
|
52
|
+
const remainder100 = Math.abs(n) % 100
|
|
53
|
+
const remainder10 = remainder100 % 10
|
|
54
|
+
|
|
55
|
+
if (remainder100 >= 11 && remainder100 <= 13) {
|
|
56
|
+
return `${n}th`
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
switch (remainder10) {
|
|
60
|
+
case 1:
|
|
61
|
+
return `${n}st`
|
|
62
|
+
case 2:
|
|
63
|
+
return `${n}nd`
|
|
64
|
+
case 3:
|
|
65
|
+
return `${n}rd`
|
|
66
|
+
default:
|
|
67
|
+
return `${n}th`
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
export function toPercent(value: number, total: number, decimals?: number) {
|
|
72
|
+
if (total === 0) {
|
|
73
|
+
return 0
|
|
74
|
+
}
|
|
75
|
+
|
|
76
|
+
const result = (value / total) * 100
|
|
77
|
+
|
|
78
|
+
if (decimals === undefined) {
|
|
79
|
+
return result
|
|
80
|
+
}
|
|
81
|
+
|
|
82
|
+
return roundTo(result, decimals)
|
|
83
|
+
}
|
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
import type { Numberish } from './types'
|
|
2
|
+
import { parseExponential, toSubscriptDigits } from './conversions'
|
|
3
|
+
|
|
4
|
+
export function countLeadingZeros(input: string) {
|
|
5
|
+
let count = 0
|
|
6
|
+
|
|
7
|
+
for (let i = 0; i < input.length && input[i] === '0'; i++) {
|
|
8
|
+
count++
|
|
9
|
+
}
|
|
10
|
+
|
|
11
|
+
return count
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
export interface FormatNumberOptions extends Intl.NumberFormatOptions {
|
|
15
|
+
formatLeadingZeros?: (count: number) => string
|
|
16
|
+
groupFractionLeadingZeros?: boolean
|
|
17
|
+
locales?: Intl.LocalesArgument
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
export function formatNumber(input: Numberish, options_: FormatNumberOptions = {}) {
|
|
21
|
+
const { formatLeadingZeros = (count: number) => `0${toSubscriptDigits(count)}`, groupFractionLeadingZeros = true, locales = 'en-US', maximumFractionDigits = 4, ...options } = options_
|
|
22
|
+
|
|
23
|
+
const formatInput = (digits: number) => (
|
|
24
|
+
new Intl.NumberFormat(locales, { ...options, maximumFractionDigits: digits }).format(input as Intl.StringNumericLiteral)
|
|
25
|
+
)
|
|
26
|
+
|
|
27
|
+
if (!groupFractionLeadingZeros) {
|
|
28
|
+
return formatInput(maximumFractionDigits)
|
|
29
|
+
}
|
|
30
|
+
|
|
31
|
+
const numericStr = parseExponential(input)
|
|
32
|
+
const [, fractionPart = ''] = numericStr.split('.', 2)
|
|
33
|
+
const leadingZerosCount = countLeadingZeros(fractionPart)
|
|
34
|
+
|
|
35
|
+
if (leadingZerosCount <= 1) {
|
|
36
|
+
return formatInput(maximumFractionDigits)
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
const replaceFractionZeros = (part: Intl.NumberFormatPart) => {
|
|
40
|
+
if (part.type === 'fraction') {
|
|
41
|
+
return `${formatLeadingZeros(leadingZerosCount)}${part.value.slice(leadingZerosCount)}`
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
return part.value
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
const parts = new Intl.NumberFormat(locales, {
|
|
48
|
+
...options, maximumFractionDigits: maximumFractionDigits + leadingZerosCount,
|
|
49
|
+
})
|
|
50
|
+
|
|
51
|
+
return parts.formatToParts(input as Intl.StringNumericLiteral).map(replaceFractionZeros).join('')
|
|
52
|
+
}
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
import type { Numberish, NumberString, Percentage } from './types'
|
|
2
|
+
import { isBigInt, isNumber, isString } from '../core'
|
|
3
|
+
import { SPECIAL_NUMBER_STRINGS } from './constants'
|
|
4
|
+
|
|
5
|
+
// eslint-disable-next-line security/detect-unsafe-regex -- anchored regex with no backtracking risk on bounded input
|
|
6
|
+
const NUMERIC_PATTERN = /^[+-]?(?:\d+(?:\.\d*)?|\.\d+)(?:e[+-]?\d+)?$/iu
|
|
7
|
+
|
|
8
|
+
export const isSpecialNumberString = (value: string) => SPECIAL_NUMBER_STRINGS.has(value)
|
|
9
|
+
|
|
10
|
+
export function isNumberString<TStrict extends boolean = true>(value: string): value is NumberString<TStrict> {
|
|
11
|
+
if (isSpecialNumberString(value)) {
|
|
12
|
+
return true
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
return NUMERIC_PATTERN.test(value)
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const isNumberish = <TStrict extends boolean = true>(input: unknown): input is Numberish<TStrict> => (
|
|
19
|
+
isNumber(input) || isBigInt(input) || (isString(input) && isNumberString(input))
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
export const isPercentage = (value: number): value is Percentage => value >= 0 && value <= 100
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
export * from './bigint-math'
|
|
2
|
+
export * from './constants'
|
|
3
|
+
export * from './conversions'
|
|
4
|
+
export * from './factories'
|
|
5
|
+
export * from './formats'
|
|
6
|
+
export * from './guards'
|
|
7
|
+
export * from './maths'
|
|
8
|
+
export * from './ranges'
|
|
9
|
+
|
|
10
|
+
export type * from './types'
|
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
import { transform } from '../functions'
|
|
2
|
+
|
|
3
|
+
export const sum = (array: number[]) => array.reduce((a, b) => a + b, 0)
|
|
4
|
+
|
|
5
|
+
export const avg = (array: number[]) => (array.length === 0 ? 0 : sum(array) / array.length)
|
|
6
|
+
|
|
7
|
+
export const clamp = (value: number, min: number, max: number) => Math.min(Math.max(value, min), max)
|
|
8
|
+
|
|
9
|
+
export const roundTo = (value: number, decimals: number) => (
|
|
10
|
+
transform(10 ** decimals, (factor) => Math.round(value * factor) / factor)
|
|
11
|
+
)
|
|
12
|
+
|
|
13
|
+
export const lerp = (start: number, end: number, t: number) => start + (end - start) * t
|
|
14
|
+
|
|
15
|
+
export function median(array: number[]) {
|
|
16
|
+
if (array.length === 0) {
|
|
17
|
+
return 0
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
const sorted = [...array].toSorted((a, b) => a - b)
|
|
21
|
+
const mid = Math.floor(sorted.length / 2)
|
|
22
|
+
|
|
23
|
+
if (sorted.length % 2 === 0) {
|
|
24
|
+
return (sorted[mid - 1]! + sorted[mid]!) / 2
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
return sorted[mid]!
|
|
28
|
+
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
import { notNullish } from '../core'
|
|
2
|
+
|
|
3
|
+
export function isValidRange<T extends bigint | number>(start: T, end: T, inclusive = true, min?: T, max?: T) {
|
|
4
|
+
if (notNullish(min) && start < min) {
|
|
5
|
+
return false
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
if (notNullish(max) && end > max) {
|
|
9
|
+
return false
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
return inclusive ? start <= end : start < end
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export const isInRange = <T extends bigint | number>(value: T, min: T, max: T, inclusive = true) => (
|
|
16
|
+
inclusive ? value >= min && value <= max : value > min && value < max
|
|
17
|
+
)
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
export type SpecialNumberString = '+Infinity' | '-Infinity' | 'Infinity' | 'NaN'
|
|
2
|
+
|
|
3
|
+
export type NumberString<TStrict extends boolean = false> = SpecialNumberString | (TStrict extends true ? `${number}` : string)
|
|
4
|
+
|
|
5
|
+
export type Numberish<TStrict extends boolean = false> = NumberString<TStrict> | bigint | number
|
|
6
|
+
|
|
7
|
+
export type Percentage = { __brand: 'Percentage' } & number
|
|
@@ -0,0 +1,76 @@
|
|
|
1
|
+
import type { AnyObject, DeepPartial } from './types'
|
|
2
|
+
import { isArray } from '../arrays'
|
|
3
|
+
import { unique } from '../arrays/set-operations'
|
|
4
|
+
import { isPlainObject } from './guards'
|
|
5
|
+
|
|
6
|
+
export type DeepMergeArrayMode = 'merge' | 'merge-dedupe' | 'replace'
|
|
7
|
+
|
|
8
|
+
export interface DeepMergeOptions {
|
|
9
|
+
arrayMode?: DeepMergeArrayMode
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const DANGEROUS_KEYS = new Set(['__proto__', 'constructor', 'prototype'])
|
|
13
|
+
|
|
14
|
+
function mergeArrays(base: unknown[], override: unknown[], arrayMode: DeepMergeArrayMode): unknown[] {
|
|
15
|
+
if (arrayMode === 'replace') {
|
|
16
|
+
return override.map(deepCloneValue)
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const merged = [...base, ...override]
|
|
20
|
+
const deduped = arrayMode === 'merge-dedupe' ? unique(merged) : merged
|
|
21
|
+
|
|
22
|
+
return deduped.map(deepCloneValue)
|
|
23
|
+
}
|
|
24
|
+
|
|
25
|
+
function deepCloneValue(value: unknown): unknown {
|
|
26
|
+
if (isPlainObject(value)) {
|
|
27
|
+
const cloned: Record<string, unknown> = {}
|
|
28
|
+
|
|
29
|
+
for (const key of Object.keys(value)) {
|
|
30
|
+
if (!DANGEROUS_KEYS.has(key)) {
|
|
31
|
+
cloned[key] = deepCloneValue(value[key])
|
|
32
|
+
}
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
return cloned
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if (isArray(value)) {
|
|
39
|
+
return value.map(deepCloneValue)
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
return value
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
function mergeRecursive(base: Record<string, unknown>, override: Record<string, unknown>, arrayMode: DeepMergeArrayMode): Record<string, unknown> {
|
|
46
|
+
const result: Record<string, unknown> = {}
|
|
47
|
+
|
|
48
|
+
for (const key of Object.keys(base)) {
|
|
49
|
+
if (!DANGEROUS_KEYS.has(key)) {
|
|
50
|
+
result[key] = deepCloneValue(base[key])
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
for (const key of Object.keys(override)) {
|
|
55
|
+
if (DANGEROUS_KEYS.has(key)) {
|
|
56
|
+
continue
|
|
57
|
+
}
|
|
58
|
+
|
|
59
|
+
const baseVal = result[key]
|
|
60
|
+
const overrideVal = override[key]
|
|
61
|
+
|
|
62
|
+
if (isPlainObject(baseVal) && isPlainObject(overrideVal)) {
|
|
63
|
+
result[key] = mergeRecursive(baseVal, overrideVal, arrayMode)
|
|
64
|
+
} else if (isArray(baseVal) && isArray(overrideVal)) {
|
|
65
|
+
result[key] = mergeArrays(baseVal, overrideVal, arrayMode)
|
|
66
|
+
} else {
|
|
67
|
+
result[key] = deepCloneValue(overrideVal)
|
|
68
|
+
}
|
|
69
|
+
}
|
|
70
|
+
|
|
71
|
+
return result
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
export const deepMerge = <T extends AnyObject>(base: T, override: DeepPartial<T>, { arrayMode = 'replace' }: DeepMergeOptions = {}): T => (
|
|
75
|
+
mergeRecursive(base, override as Record<string, unknown>, arrayMode) as T
|
|
76
|
+
)
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
import type { AnyObject, UnknownObject } from './types'
|
|
2
|
+
import { isArray } from '../arrays'
|
|
3
|
+
import { toString } from '../core'
|
|
4
|
+
|
|
5
|
+
export const isObject = (value: unknown): value is AnyObject => value !== null && typeof value === 'object' && !isArray(value)
|
|
6
|
+
|
|
7
|
+
export const isPlainObject = (value: unknown): value is UnknownObject => {
|
|
8
|
+
if (toString(value) !== '[object Object]') {
|
|
9
|
+
return false
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const proto = Object.getPrototypeOf(value)
|
|
13
|
+
|
|
14
|
+
return proto === null || proto === Object.prototype
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
export const isEmptyObject = (value: AnyObject) => Object.keys(value).length === 0
|
|
18
|
+
|
|
19
|
+
export const isKeyOf = <T extends AnyObject>(obj: T, name: PropertyKey): name is keyof T => name in obj
|
|
20
|
+
|
|
21
|
+
export const isKeysOf = <T extends PropertyKey>(data: AnyObject, ...keys: T[]): data is Record<T, unknown> => keys.every((key) => isKeyOf(data, key))
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { AnyObject, FilterPredicate } from './types'
|
|
2
|
+
import { isNullish, type Nullish } from '../core'
|
|
3
|
+
|
|
4
|
+
export const entries = <O extends AnyObject>(obj: O) => Object.entries(obj) as Array<[keyof O, O[keyof O]]>
|
|
5
|
+
|
|
6
|
+
export const filter = <O extends AnyObject>(obj: O, predicate: FilterPredicate<O, keyof O>): Partial<O> => (
|
|
7
|
+
Object.fromEntries(entries(obj).filter(([key, value], index) => predicate(key, value, index))) as Partial<O>
|
|
8
|
+
)
|
|
9
|
+
|
|
10
|
+
export const filterByValue = <O extends AnyObject>(obj: O, predicate: (value: O[keyof O]) => boolean) => filter(obj, (_, value) => predicate(value))
|
|
11
|
+
|
|
12
|
+
export const pick = <O extends AnyObject, K extends keyof O>(obj: O, ...keys: K[]) => {
|
|
13
|
+
const set = new Set<PropertyKey>(keys)
|
|
14
|
+
|
|
15
|
+
return filter(obj, (key) => set.has(key)) as Pick<O, K>
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
export const omit = <O extends AnyObject, K extends keyof O>(object: O, ...keys: K[]) => {
|
|
19
|
+
const set = new Set<PropertyKey>(keys)
|
|
20
|
+
|
|
21
|
+
return filter(object, (key) => !set.has(key)) as Omit<O, K>
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
export const map = <K extends PropertyKey, V, NK extends PropertyKey, NV>(obj: Record<K, V>, fn: (k: K, v: V, i: number) => [NK, NV]) => (
|
|
25
|
+
Object.fromEntries(entries(obj).map(([k, v], i) => fn(k, v, i))) as Record<NK, NV>
|
|
26
|
+
)
|
|
27
|
+
|
|
28
|
+
export function resolveOptions<T extends AnyObject>(options: Nullish<T | boolean>, defaultValue: T | false): T | false {
|
|
29
|
+
if (options === false) {
|
|
30
|
+
return false
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
return isNullish(options) || options === true ? defaultValue : options
|
|
34
|
+
}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
import type { Primitive } from '../core'
|
|
2
|
+
|
|
3
|
+
export type PartialBy<T, K extends keyof T> = Omit<T, K> & Partial<Pick<T, K>>
|
|
4
|
+
|
|
5
|
+
export type RequiredBy<T, K extends keyof T> = Omit<T, K> & Required<Pick<T, K>>
|
|
6
|
+
|
|
7
|
+
export type Mutable<T> = { -readonly [K in keyof T]: T[K] }
|
|
8
|
+
|
|
9
|
+
export type DeepPartial<T> = T extends object ? { [K in keyof T]?: DeepPartial<T[K]> } : T
|
|
10
|
+
|
|
11
|
+
export type DeepReadonly<T> = T extends Primitive ? T : T extends Array<infer U> ? ReadonlyArray<DeepReadonly<U>> : { readonly [K in keyof T]: DeepReadonly<T[K]> }
|
|
12
|
+
|
|
13
|
+
export type KeysOfType<T, V> = { [K in keyof T]-?: T[K] extends V ? K : never }[keyof T]
|
|
14
|
+
|
|
15
|
+
export type StringKeys<T> = Extract<keyof T, string>
|
|
16
|
+
|
|
17
|
+
export type Dictionary<T = unknown> = Record<string, T>
|
|
18
|
+
|
|
19
|
+
export type DiscriminateUnion<T, K extends keyof T, V extends T[K]> = T extends Record<K, V> ? T : never
|
|
20
|
+
|
|
21
|
+
export type AnyObject = Record<string, any>
|
|
22
|
+
|
|
23
|
+
export type UnknownObject = Record<string, unknown>
|
|
24
|
+
|
|
25
|
+
export type Constructor<T> = new (...args: any[]) => T
|
|
26
|
+
|
|
27
|
+
export type ClassMethods<T> = { [K in keyof T]: T[K] extends (...args: any[]) => any ? K : never }[keyof T]
|
|
28
|
+
|
|
29
|
+
export type ClassMethodArgs<T, M extends ClassMethods<T>> = T[M] extends (...args: infer A) => any ? A : never
|
|
30
|
+
|
|
31
|
+
export type ClassMethodReturn<T, M extends ClassMethods<T>> = T[M] extends (...args: any[]) => infer R ? R : never
|
|
32
|
+
|
|
33
|
+
export type FilterPredicate<O, K extends keyof O> = (key: K, value: O[K], index: number) => boolean
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import { createAbortError, ensureError, type Errorable } from '../errors'
|
|
2
|
+
|
|
3
|
+
export function abortable<T>(promise: Promise<T>, signal?: AbortSignal, error?: Errorable): Promise<T> {
|
|
4
|
+
if (!signal) {
|
|
5
|
+
return promise
|
|
6
|
+
}
|
|
7
|
+
|
|
8
|
+
const createError = () => (error ? ensureError(error) : (signal.reason ?? createAbortError()))
|
|
9
|
+
|
|
10
|
+
if (signal.aborted) {
|
|
11
|
+
return Promise.reject(createError())
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return new Promise<T>((resolve, reject) => {
|
|
15
|
+
let isSettled = false
|
|
16
|
+
let onAbort: () => void
|
|
17
|
+
|
|
18
|
+
const cleanup = (afterCleanup?: () => void) => {
|
|
19
|
+
if (!isSettled) {
|
|
20
|
+
isSettled = true
|
|
21
|
+
signal.removeEventListener('abort', onAbort)
|
|
22
|
+
afterCleanup?.()
|
|
23
|
+
}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
onAbort = () => {
|
|
27
|
+
cleanup(() => reject(createError()))
|
|
28
|
+
}
|
|
29
|
+
|
|
30
|
+
signal.addEventListener('abort', onAbort)
|
|
31
|
+
|
|
32
|
+
promise.then(
|
|
33
|
+
(value) => cleanup(() => resolve(value)),
|
|
34
|
+
(error_) => cleanup(() => reject(error_)),
|
|
35
|
+
)
|
|
36
|
+
})
|
|
37
|
+
}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { Awaitable } from './types'
|
|
2
|
+
|
|
3
|
+
export const pTap = <T>(fn: (value: T) => Awaitable<unknown>) => async (value: T): Promise<T> => {
|
|
4
|
+
return Promise.resolve(fn(value)).then(() => value)
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
pTap.catch = (fn: (error: unknown) => Awaitable<unknown>) => async (error: unknown): Promise<never> => {
|
|
8
|
+
await fn(error)
|
|
9
|
+
throw error
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export async function tryCatchAsync<T>(fn: () => Awaitable<T>, fallback: (error: unknown) => Awaitable<T>) {
|
|
13
|
+
try {
|
|
14
|
+
return await fn()
|
|
15
|
+
} catch (error) {
|
|
16
|
+
return await fallback(error)
|
|
17
|
+
}
|
|
18
|
+
}
|
|
@@ -0,0 +1,131 @@
|
|
|
1
|
+
import { combineSignals, createAbortController, createAbortError, type Errorable } from '../errors'
|
|
2
|
+
|
|
3
|
+
export interface DeferredPromiseOptions<T> {
|
|
4
|
+
onCallbackError?: (error: unknown) => void
|
|
5
|
+
onReject?: (reason: unknown) => void
|
|
6
|
+
onResolve?: (value: PromiseLike<T> | T) => void
|
|
7
|
+
onSettle?: () => void
|
|
8
|
+
signal?: AbortSignal
|
|
9
|
+
synchronousCallbacks?: boolean
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export interface DeferredPromise<T> extends Promise<T> {
|
|
13
|
+
isPending: boolean
|
|
14
|
+
isRejected: boolean
|
|
15
|
+
isResolved: boolean
|
|
16
|
+
isSettled: boolean
|
|
17
|
+
reject: (reason?: unknown) => void
|
|
18
|
+
resolve: (value: PromiseLike<T> | T) => void
|
|
19
|
+
}
|
|
20
|
+
|
|
21
|
+
export function cleanupAbortSignal(signal: AbortSignal | undefined, abortHandler: (() => void) | undefined) {
|
|
22
|
+
if (abortHandler) {
|
|
23
|
+
signal?.removeEventListener('abort', abortHandler)
|
|
24
|
+
}
|
|
25
|
+
}
|
|
26
|
+
|
|
27
|
+
export function setupAbortSignal(signal: AbortSignal | undefined, onAbort: () => void) {
|
|
28
|
+
const abortHandler = () => onAbort()
|
|
29
|
+
|
|
30
|
+
if (signal?.aborted) {
|
|
31
|
+
onAbort()
|
|
32
|
+
} else {
|
|
33
|
+
signal?.addEventListener('abort', abortHandler)
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
return abortHandler
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
export function invokeSettleCallback(cb: () => void, onSettle: (() => void) | undefined, onCallbackError: ((error: unknown) => void) | undefined, synchronousCallbacks: boolean) {
|
|
40
|
+
const callback = () => {
|
|
41
|
+
try {
|
|
42
|
+
cb()
|
|
43
|
+
} catch (error) {
|
|
44
|
+
onCallbackError?.(error)
|
|
45
|
+
}
|
|
46
|
+
|
|
47
|
+
try {
|
|
48
|
+
onSettle?.()
|
|
49
|
+
} catch (error) {
|
|
50
|
+
onCallbackError?.(error)
|
|
51
|
+
}
|
|
52
|
+
}
|
|
53
|
+
|
|
54
|
+
if (synchronousCallbacks) {
|
|
55
|
+
callback()
|
|
56
|
+
} else {
|
|
57
|
+
queueMicrotask(callback)
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
export function createDeferred<T>({ onCallbackError, onReject, onResolve, onSettle, signal, synchronousCallbacks = false }: DeferredPromiseOptions<T> = {}): DeferredPromise<T> {
|
|
62
|
+
let resolveFn: (value: PromiseLike<T> | T) => void
|
|
63
|
+
let rejectFn: (reason?: unknown) => void
|
|
64
|
+
let abortHandler: (() => void) | undefined
|
|
65
|
+
|
|
66
|
+
let isSettled = false
|
|
67
|
+
let isResolved = false
|
|
68
|
+
let isRejected = false
|
|
69
|
+
|
|
70
|
+
const promise = <DeferredPromise<T>> new Promise<T>((resolve, reject) => {
|
|
71
|
+
resolveFn = resolve
|
|
72
|
+
rejectFn = reject
|
|
73
|
+
})
|
|
74
|
+
|
|
75
|
+
const afterSettle = (cb: () => void) => {
|
|
76
|
+
cleanupAbortSignal(signal, abortHandler)
|
|
77
|
+
invokeSettleCallback(cb, onSettle, onCallbackError, synchronousCallbacks)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
Object.defineProperty(promise, 'isSettled', { enumerable: true, get: () => isSettled })
|
|
81
|
+
Object.defineProperty(promise, 'isPending', { enumerable: true, get: () => !isSettled })
|
|
82
|
+
Object.defineProperty(promise, 'isResolved', { enumerable: true, get: () => isResolved })
|
|
83
|
+
Object.defineProperty(promise, 'isRejected', { enumerable: true, get: () => isRejected })
|
|
84
|
+
|
|
85
|
+
promise.resolve = (value: PromiseLike<T> | T) => {
|
|
86
|
+
if (isSettled) {
|
|
87
|
+
return
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
isSettled = true
|
|
91
|
+
isResolved = true
|
|
92
|
+
|
|
93
|
+
resolveFn(value)
|
|
94
|
+
afterSettle(() => onResolve?.(value))
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
promise.reject = (reason?: unknown) => {
|
|
98
|
+
if (isSettled) {
|
|
99
|
+
return
|
|
100
|
+
}
|
|
101
|
+
|
|
102
|
+
isSettled = true
|
|
103
|
+
isRejected = true
|
|
104
|
+
|
|
105
|
+
rejectFn(reason)
|
|
106
|
+
afterSettle(() => onReject?.(reason))
|
|
107
|
+
}
|
|
108
|
+
|
|
109
|
+
abortHandler = setupAbortSignal(signal, () => {
|
|
110
|
+
promise.reject(signal?.reason ?? createAbortError())
|
|
111
|
+
})
|
|
112
|
+
|
|
113
|
+
return promise
|
|
114
|
+
}
|
|
115
|
+
|
|
116
|
+
export interface DeferredPromiseWithTimeoutOptions<T> extends DeferredPromiseOptions<T> {
|
|
117
|
+
error?: Errorable
|
|
118
|
+
}
|
|
119
|
+
|
|
120
|
+
export const createDeferredWithTimeout = <T>(ms: number, { error, signal, ...options }: DeferredPromiseWithTimeoutOptions<T> = {}) => {
|
|
121
|
+
const timeoutController = createAbortController(ms, error)
|
|
122
|
+
|
|
123
|
+
return createDeferred<T>({
|
|
124
|
+
...options,
|
|
125
|
+
onSettle() {
|
|
126
|
+
timeoutController.abort()
|
|
127
|
+
options.onSettle?.()
|
|
128
|
+
},
|
|
129
|
+
signal: combineSignals(signal, timeoutController.signal),
|
|
130
|
+
})
|
|
131
|
+
}
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
import { isFunction } from '../functions'
|
|
2
|
+
import { isObject } from '../objects'
|
|
3
|
+
|
|
4
|
+
export const isPromiseLike = <T>(value: unknown): value is PromiseLike<T> => isObject(value) && isFunction(value.then)
|
|
5
|
+
|
|
6
|
+
export const isPromise = <T>(value: unknown): value is Promise<T> => (
|
|
7
|
+
isObject(value) && isFunction(value.then) && isFunction(value.catch) && isFunction(value.finally)
|
|
8
|
+
)
|