effect 3.10.18 → 3.11.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/cjs/Array.js +206 -0
- package/dist/cjs/Array.js.map +1 -1
- package/dist/cjs/BigDecimal.js +181 -24
- package/dist/cjs/BigDecimal.js.map +1 -1
- package/dist/cjs/BigInt.js +54 -0
- package/dist/cjs/BigInt.js.map +1 -1
- package/dist/cjs/Boolean.js +24 -0
- package/dist/cjs/Boolean.js.map +1 -1
- package/dist/cjs/Brand.js +4 -0
- package/dist/cjs/Brand.js.map +1 -1
- package/dist/cjs/Channel.js +44 -4
- package/dist/cjs/Channel.js.map +1 -1
- package/dist/cjs/Chunk.js +8 -0
- package/dist/cjs/Chunk.js.map +1 -1
- package/dist/cjs/Config.js +10 -1
- package/dist/cjs/Config.js.map +1 -1
- package/dist/cjs/Context.js +50 -1
- package/dist/cjs/Context.js.map +1 -1
- package/dist/cjs/Cron.js +81 -67
- package/dist/cjs/Cron.js.map +1 -1
- package/dist/cjs/Data.js +14 -0
- package/dist/cjs/Data.js.map +1 -1
- package/dist/cjs/DateTime.js +178 -664
- package/dist/cjs/DateTime.js.map +1 -1
- package/dist/cjs/Duration.js +2 -0
- package/dist/cjs/Duration.js.map +1 -1
- package/dist/cjs/Effect.js +296 -4
- package/dist/cjs/Effect.js.map +1 -1
- package/dist/cjs/Either.js +38 -2
- package/dist/cjs/Either.js.map +1 -1
- package/dist/cjs/FiberHandle.js +6 -0
- package/dist/cjs/FiberHandle.js.map +1 -1
- package/dist/cjs/FiberMap.js +6 -0
- package/dist/cjs/FiberMap.js.map +1 -1
- package/dist/cjs/FiberSet.js +6 -0
- package/dist/cjs/FiberSet.js.map +1 -1
- package/dist/cjs/Function.js +34 -0
- package/dist/cjs/Function.js.map +1 -1
- package/dist/cjs/GlobalValue.js +2 -0
- package/dist/cjs/GlobalValue.js.map +1 -1
- package/dist/cjs/HashMap.js.map +1 -1
- package/dist/cjs/Inspectable.js +8 -4
- package/dist/cjs/Inspectable.js.map +1 -1
- package/dist/cjs/Iterable.js +18 -0
- package/dist/cjs/Iterable.js.map +1 -1
- package/dist/cjs/JSONSchema.js.map +1 -1
- package/dist/cjs/List.js +4 -0
- package/dist/cjs/List.js.map +1 -1
- package/dist/cjs/Logger.js +26 -0
- package/dist/cjs/Logger.js.map +1 -1
- package/dist/cjs/Mailbox.js +2 -0
- package/dist/cjs/Mailbox.js.map +1 -1
- package/dist/cjs/ManagedRuntime.js +2 -0
- package/dist/cjs/ManagedRuntime.js.map +1 -1
- package/dist/cjs/Metric.js +10 -0
- package/dist/cjs/Metric.js.map +1 -1
- package/dist/cjs/Micro.js +1104 -1069
- package/dist/cjs/Micro.js.map +1 -1
- package/dist/cjs/Number.js +44 -0
- package/dist/cjs/Number.js.map +1 -1
- package/dist/cjs/Option.js +70 -0
- package/dist/cjs/Option.js.map +1 -1
- package/dist/cjs/Order.js +2 -0
- package/dist/cjs/Order.js.map +1 -1
- package/dist/cjs/Ordering.js +4 -0
- package/dist/cjs/Ordering.js.map +1 -1
- package/dist/cjs/Predicate.js +68 -0
- package/dist/cjs/Predicate.js.map +1 -1
- package/dist/cjs/Random.js +4 -0
- package/dist/cjs/Random.js.map +1 -1
- package/dist/cjs/RateLimiter.js +4 -0
- package/dist/cjs/RateLimiter.js.map +1 -1
- package/dist/cjs/RcMap.js +2 -0
- package/dist/cjs/RcMap.js.map +1 -1
- package/dist/cjs/RcRef.js +2 -0
- package/dist/cjs/RcRef.js.map +1 -1
- package/dist/cjs/Record.js +56 -0
- package/dist/cjs/Record.js.map +1 -1
- package/dist/cjs/Redacted.js +8 -0
- package/dist/cjs/Redacted.js.map +1 -1
- package/dist/cjs/RegExp.js +4 -0
- package/dist/cjs/RegExp.js.map +1 -1
- package/dist/cjs/Request.js +4 -0
- package/dist/cjs/Request.js.map +1 -1
- package/dist/cjs/RequestResolver.js +2 -0
- package/dist/cjs/RequestResolver.js.map +1 -1
- package/dist/cjs/Runtime.js +6 -0
- package/dist/cjs/Runtime.js.map +1 -1
- package/dist/cjs/STM.js.map +1 -1
- package/dist/cjs/Schema.js +91 -8
- package/dist/cjs/Schema.js.map +1 -1
- package/dist/cjs/Sink.js +9 -1
- package/dist/cjs/Sink.js.map +1 -1
- package/dist/cjs/Stream.js +179 -7
- package/dist/cjs/Stream.js.map +1 -1
- package/dist/cjs/String.js +62 -0
- package/dist/cjs/String.js.map +1 -1
- package/dist/cjs/Struct.js +12 -0
- package/dist/cjs/Struct.js.map +1 -1
- package/dist/cjs/Symbol.js +2 -0
- package/dist/cjs/Symbol.js.map +1 -1
- package/dist/cjs/Trie.js +56 -0
- package/dist/cjs/Trie.js.map +1 -1
- package/dist/cjs/Tuple.js +18 -0
- package/dist/cjs/Tuple.js.map +1 -1
- package/dist/cjs/Utils.js +7 -1
- package/dist/cjs/Utils.js.map +1 -1
- package/dist/cjs/internal/channel/channelExecutor.js +5 -9
- package/dist/cjs/internal/channel/channelExecutor.js.map +1 -1
- package/dist/cjs/internal/channel.js +156 -130
- package/dist/cjs/internal/channel.js.map +1 -1
- package/dist/cjs/internal/config.js +13 -4
- package/dist/cjs/internal/config.js.map +1 -1
- package/dist/cjs/internal/context.js +46 -3
- package/dist/cjs/internal/context.js.map +1 -1
- package/dist/cjs/internal/dateTime.js +747 -0
- package/dist/cjs/internal/dateTime.js.map +1 -0
- package/dist/cjs/internal/fiberRuntime.js +34 -11
- package/dist/cjs/internal/fiberRuntime.js.map +1 -1
- package/dist/cjs/internal/groupBy.js +9 -3
- package/dist/cjs/internal/groupBy.js.map +1 -1
- package/dist/cjs/internal/layer.js +1 -1
- package/dist/cjs/internal/layer.js.map +1 -1
- package/dist/cjs/internal/mailbox.js +1 -1
- package/dist/cjs/internal/mailbox.js.map +1 -1
- package/dist/cjs/internal/sink.js +25 -21
- package/dist/cjs/internal/sink.js.map +1 -1
- package/dist/cjs/internal/stream.js +70 -71
- package/dist/cjs/internal/stream.js.map +1 -1
- package/dist/cjs/internal/version.js +1 -1
- package/dist/cjs/internal/version.js.map +1 -1
- package/dist/dts/Array.d.ts +534 -0
- package/dist/dts/Array.d.ts.map +1 -1
- package/dist/dts/BigDecimal.d.ts +172 -1
- package/dist/dts/BigDecimal.d.ts.map +1 -1
- package/dist/dts/BigInt.d.ts +114 -0
- package/dist/dts/BigInt.d.ts.map +1 -1
- package/dist/dts/Boolean.d.ts +56 -0
- package/dist/dts/Boolean.d.ts.map +1 -1
- package/dist/dts/Brand.d.ts +6 -0
- package/dist/dts/Brand.d.ts.map +1 -1
- package/dist/dts/Channel.d.ts +66 -5
- package/dist/dts/Channel.d.ts.map +1 -1
- package/dist/dts/Chunk.d.ts +30 -0
- package/dist/dts/Chunk.d.ts.map +1 -1
- package/dist/dts/Config.d.ts +25 -1
- package/dist/dts/Config.d.ts.map +1 -1
- package/dist/dts/Context.d.ts +155 -0
- package/dist/dts/Context.d.ts.map +1 -1
- package/dist/dts/Cron.d.ts +21 -6
- package/dist/dts/Cron.d.ts.map +1 -1
- package/dist/dts/Data.d.ts +26 -0
- package/dist/dts/Data.d.ts.map +1 -1
- package/dist/dts/DateTime.d.ts +192 -49
- package/dist/dts/DateTime.d.ts.map +1 -1
- package/dist/dts/Duration.d.ts +2 -0
- package/dist/dts/Duration.d.ts.map +1 -1
- package/dist/dts/Effect.d.ts +658 -1
- package/dist/dts/Effect.d.ts.map +1 -1
- package/dist/dts/Either.d.ts +84 -2
- package/dist/dts/Either.d.ts.map +1 -1
- package/dist/dts/FiberHandle.d.ts +6 -0
- package/dist/dts/FiberHandle.d.ts.map +1 -1
- package/dist/dts/FiberMap.d.ts +6 -0
- package/dist/dts/FiberMap.d.ts.map +1 -1
- package/dist/dts/FiberSet.d.ts +6 -0
- package/dist/dts/FiberSet.d.ts.map +1 -1
- package/dist/dts/Function.d.ts +50 -0
- package/dist/dts/Function.d.ts.map +1 -1
- package/dist/dts/GlobalValue.d.ts +2 -0
- package/dist/dts/GlobalValue.d.ts.map +1 -1
- package/dist/dts/HashMap.d.ts +6 -0
- package/dist/dts/HashMap.d.ts.map +1 -1
- package/dist/dts/Inspectable.d.ts.map +1 -1
- package/dist/dts/Iterable.d.ts +26 -0
- package/dist/dts/Iterable.d.ts.map +1 -1
- package/dist/dts/JSONSchema.d.ts +1 -0
- package/dist/dts/JSONSchema.d.ts.map +1 -1
- package/dist/dts/List.d.ts +20 -0
- package/dist/dts/List.d.ts.map +1 -1
- package/dist/dts/Logger.d.ts +34 -0
- package/dist/dts/Logger.d.ts.map +1 -1
- package/dist/dts/Mailbox.d.ts +2 -0
- package/dist/dts/Mailbox.d.ts.map +1 -1
- package/dist/dts/ManagedRuntime.d.ts +2 -0
- package/dist/dts/ManagedRuntime.d.ts.map +1 -1
- package/dist/dts/Metric.d.ts +18 -0
- package/dist/dts/Metric.d.ts.map +1 -1
- package/dist/dts/Micro.d.ts +880 -863
- package/dist/dts/Micro.d.ts.map +1 -1
- package/dist/dts/Number.d.ts +104 -0
- package/dist/dts/Number.d.ts.map +1 -1
- package/dist/dts/Option.d.ts +142 -0
- package/dist/dts/Option.d.ts.map +1 -1
- package/dist/dts/Order.d.ts +2 -0
- package/dist/dts/Order.d.ts.map +1 -1
- package/dist/dts/Ordering.d.ts +8 -0
- package/dist/dts/Ordering.d.ts.map +1 -1
- package/dist/dts/Predicate.d.ts +104 -0
- package/dist/dts/Predicate.d.ts.map +1 -1
- package/dist/dts/Random.d.ts +4 -0
- package/dist/dts/Random.d.ts.map +1 -1
- package/dist/dts/RateLimiter.d.ts +4 -0
- package/dist/dts/RateLimiter.d.ts.map +1 -1
- package/dist/dts/RcMap.d.ts +6 -0
- package/dist/dts/RcMap.d.ts.map +1 -1
- package/dist/dts/RcRef.d.ts +2 -0
- package/dist/dts/RcRef.d.ts.map +1 -1
- package/dist/dts/Record.d.ts +136 -0
- package/dist/dts/Record.d.ts.map +1 -1
- package/dist/dts/Redacted.d.ts +8 -0
- package/dist/dts/Redacted.d.ts.map +1 -1
- package/dist/dts/RegExp.d.ts +4 -0
- package/dist/dts/RegExp.d.ts.map +1 -1
- package/dist/dts/Request.d.ts +4 -0
- package/dist/dts/Request.d.ts.map +1 -1
- package/dist/dts/RequestResolver.d.ts +6 -0
- package/dist/dts/RequestResolver.d.ts.map +1 -1
- package/dist/dts/Runtime.d.ts +18 -0
- package/dist/dts/Runtime.d.ts.map +1 -1
- package/dist/dts/STM.d.ts +2 -0
- package/dist/dts/STM.d.ts.map +1 -1
- package/dist/dts/Schema.d.ts +90 -0
- package/dist/dts/Schema.d.ts.map +1 -1
- package/dist/dts/Sink.d.ts +8 -0
- package/dist/dts/Sink.d.ts.map +1 -1
- package/dist/dts/Stream.d.ts +394 -32
- package/dist/dts/Stream.d.ts.map +1 -1
- package/dist/dts/String.d.ts +94 -0
- package/dist/dts/String.d.ts.map +1 -1
- package/dist/dts/Struct.d.ts +24 -0
- package/dist/dts/Struct.d.ts.map +1 -1
- package/dist/dts/Symbol.d.ts +2 -0
- package/dist/dts/Symbol.d.ts.map +1 -1
- package/dist/dts/Trie.d.ts +132 -0
- package/dist/dts/Trie.d.ts.map +1 -1
- package/dist/dts/Tuple.d.ts +42 -0
- package/dist/dts/Tuple.d.ts.map +1 -1
- package/dist/dts/Types.d.ts +24 -0
- package/dist/dts/Types.d.ts.map +1 -1
- package/dist/dts/Utils.d.ts +4 -0
- package/dist/dts/Utils.d.ts.map +1 -1
- package/dist/dts/internal/context.d.ts +1 -1
- package/dist/dts/internal/context.d.ts.map +1 -1
- package/dist/dts/internal/dateTime.d.ts +2 -0
- package/dist/dts/internal/dateTime.d.ts.map +1 -0
- package/dist/dts/internal/fiberRuntime.d.ts.map +1 -1
- package/dist/dts/internal/stream.d.ts.map +1 -1
- package/dist/esm/Array.js +208 -0
- package/dist/esm/Array.js.map +1 -1
- package/dist/esm/BigDecimal.js +175 -20
- package/dist/esm/BigDecimal.js.map +1 -1
- package/dist/esm/BigInt.js +54 -0
- package/dist/esm/BigInt.js.map +1 -1
- package/dist/esm/Boolean.js +24 -0
- package/dist/esm/Boolean.js.map +1 -1
- package/dist/esm/Brand.js +4 -0
- package/dist/esm/Brand.js.map +1 -1
- package/dist/esm/Channel.js +42 -2
- package/dist/esm/Channel.js.map +1 -1
- package/dist/esm/Chunk.js +8 -0
- package/dist/esm/Chunk.js.map +1 -1
- package/dist/esm/Config.js +9 -0
- package/dist/esm/Config.js.map +1 -1
- package/dist/esm/Context.js +49 -0
- package/dist/esm/Context.js.map +1 -1
- package/dist/esm/Cron.js +81 -67
- package/dist/esm/Cron.js.map +1 -1
- package/dist/esm/Data.js +16 -0
- package/dist/esm/Data.js.map +1 -1
- package/dist/esm/DateTime.js +176 -627
- package/dist/esm/DateTime.js.map +1 -1
- package/dist/esm/Duration.js +2 -0
- package/dist/esm/Duration.js.map +1 -1
- package/dist/esm/Effect.js +297 -0
- package/dist/esm/Effect.js.map +1 -1
- package/dist/esm/Either.js +40 -2
- package/dist/esm/Either.js.map +1 -1
- package/dist/esm/FiberHandle.js +6 -0
- package/dist/esm/FiberHandle.js.map +1 -1
- package/dist/esm/FiberMap.js +6 -0
- package/dist/esm/FiberMap.js.map +1 -1
- package/dist/esm/FiberSet.js +6 -0
- package/dist/esm/FiberSet.js.map +1 -1
- package/dist/esm/Function.js +34 -0
- package/dist/esm/Function.js.map +1 -1
- package/dist/esm/GlobalValue.js +2 -0
- package/dist/esm/GlobalValue.js.map +1 -1
- package/dist/esm/HashMap.js.map +1 -1
- package/dist/esm/Inspectable.js +8 -4
- package/dist/esm/Inspectable.js.map +1 -1
- package/dist/esm/Iterable.js +18 -0
- package/dist/esm/Iterable.js.map +1 -1
- package/dist/esm/JSONSchema.js.map +1 -1
- package/dist/esm/List.js +4 -0
- package/dist/esm/List.js.map +1 -1
- package/dist/esm/Logger.js +26 -0
- package/dist/esm/Logger.js.map +1 -1
- package/dist/esm/Mailbox.js +2 -0
- package/dist/esm/Mailbox.js.map +1 -1
- package/dist/esm/ManagedRuntime.js +2 -0
- package/dist/esm/ManagedRuntime.js.map +1 -1
- package/dist/esm/Metric.js +10 -0
- package/dist/esm/Metric.js.map +1 -1
- package/dist/esm/Micro.js +1077 -1037
- package/dist/esm/Micro.js.map +1 -1
- package/dist/esm/Number.js +44 -0
- package/dist/esm/Number.js.map +1 -1
- package/dist/esm/Option.js +72 -0
- package/dist/esm/Option.js.map +1 -1
- package/dist/esm/Order.js +2 -0
- package/dist/esm/Order.js.map +1 -1
- package/dist/esm/Ordering.js +4 -0
- package/dist/esm/Ordering.js.map +1 -1
- package/dist/esm/Predicate.js +68 -0
- package/dist/esm/Predicate.js.map +1 -1
- package/dist/esm/Random.js +4 -0
- package/dist/esm/Random.js.map +1 -1
- package/dist/esm/RateLimiter.js +4 -0
- package/dist/esm/RateLimiter.js.map +1 -1
- package/dist/esm/RcMap.js +2 -0
- package/dist/esm/RcMap.js.map +1 -1
- package/dist/esm/RcRef.js +2 -0
- package/dist/esm/RcRef.js.map +1 -1
- package/dist/esm/Record.js +56 -0
- package/dist/esm/Record.js.map +1 -1
- package/dist/esm/Redacted.js +8 -0
- package/dist/esm/Redacted.js.map +1 -1
- package/dist/esm/RegExp.js +4 -0
- package/dist/esm/RegExp.js.map +1 -1
- package/dist/esm/Request.js +4 -0
- package/dist/esm/Request.js.map +1 -1
- package/dist/esm/RequestResolver.js +2 -0
- package/dist/esm/RequestResolver.js.map +1 -1
- package/dist/esm/Runtime.js +6 -0
- package/dist/esm/Runtime.js.map +1 -1
- package/dist/esm/STM.js.map +1 -1
- package/dist/esm/Schema.js +88 -0
- package/dist/esm/Schema.js.map +1 -1
- package/dist/esm/Sink.js +8 -0
- package/dist/esm/Sink.js.map +1 -1
- package/dist/esm/Stream.js +183 -5
- package/dist/esm/Stream.js.map +1 -1
- package/dist/esm/String.js +62 -0
- package/dist/esm/String.js.map +1 -1
- package/dist/esm/Struct.js +12 -0
- package/dist/esm/Struct.js.map +1 -1
- package/dist/esm/Symbol.js +2 -0
- package/dist/esm/Symbol.js.map +1 -1
- package/dist/esm/Trie.js +56 -0
- package/dist/esm/Trie.js.map +1 -1
- package/dist/esm/Tuple.js +22 -0
- package/dist/esm/Tuple.js.map +1 -1
- package/dist/esm/Utils.js +5 -0
- package/dist/esm/Utils.js.map +1 -1
- package/dist/esm/internal/channel/channelExecutor.js +5 -7
- package/dist/esm/internal/channel/channelExecutor.js.map +1 -1
- package/dist/esm/internal/channel.js +152 -129
- package/dist/esm/internal/channel.js.map +1 -1
- package/dist/esm/internal/config.js +11 -3
- package/dist/esm/internal/config.js.map +1 -1
- package/dist/esm/internal/context.js +42 -2
- package/dist/esm/internal/context.js.map +1 -1
- package/dist/esm/internal/dateTime.js +704 -0
- package/dist/esm/internal/dateTime.js.map +1 -0
- package/dist/esm/internal/fiberRuntime.js +31 -9
- package/dist/esm/internal/fiberRuntime.js.map +1 -1
- package/dist/esm/internal/groupBy.js +9 -3
- package/dist/esm/internal/groupBy.js.map +1 -1
- package/dist/esm/internal/layer.js +1 -1
- package/dist/esm/internal/layer.js.map +1 -1
- package/dist/esm/internal/mailbox.js +1 -1
- package/dist/esm/internal/mailbox.js.map +1 -1
- package/dist/esm/internal/sink.js +23 -20
- package/dist/esm/internal/sink.js.map +1 -1
- package/dist/esm/internal/stream.js +66 -69
- package/dist/esm/internal/stream.js.map +1 -1
- package/dist/esm/internal/version.js +1 -1
- package/dist/esm/internal/version.js.map +1 -1
- package/package.json +1 -1
- package/src/Array.ts +534 -0
- package/src/BigDecimal.ts +247 -21
- package/src/BigInt.ts +114 -0
- package/src/Boolean.ts +56 -0
- package/src/Brand.ts +6 -0
- package/src/Channel.ts +81 -5
- package/src/Chunk.ts +32 -0
- package/src/Config.ts +26 -1
- package/src/Context.ts +163 -0
- package/src/Cron.ts +91 -68
- package/src/Data.ts +26 -0
- package/src/DateTime.ts +307 -757
- package/src/Duration.ts +2 -0
- package/src/Effect.ts +910 -1
- package/src/Either.ts +84 -2
- package/src/FiberHandle.ts +6 -0
- package/src/FiberMap.ts +6 -0
- package/src/FiberSet.ts +6 -0
- package/src/Function.ts +50 -0
- package/src/GlobalValue.ts +2 -0
- package/src/HashMap.ts +6 -0
- package/src/Inspectable.ts +11 -7
- package/src/Iterable.ts +26 -0
- package/src/JSONSchema.ts +1 -0
- package/src/List.ts +24 -0
- package/src/Logger.ts +34 -0
- package/src/Mailbox.ts +2 -0
- package/src/ManagedRuntime.ts +2 -0
- package/src/Metric.ts +18 -0
- package/src/Micro.ts +2007 -1745
- package/src/Number.ts +104 -0
- package/src/Option.ts +142 -0
- package/src/Order.ts +2 -0
- package/src/Ordering.ts +8 -0
- package/src/Predicate.ts +104 -0
- package/src/Random.ts +4 -0
- package/src/RateLimiter.ts +4 -0
- package/src/RcMap.ts +6 -0
- package/src/RcRef.ts +2 -0
- package/src/Record.ts +136 -0
- package/src/Redacted.ts +8 -0
- package/src/RegExp.ts +4 -0
- package/src/Request.ts +4 -0
- package/src/RequestResolver.ts +6 -0
- package/src/Runtime.ts +18 -0
- package/src/STM.ts +2 -0
- package/src/Schema.ts +124 -0
- package/src/Sink.ts +11 -0
- package/src/Stream.ts +399 -44
- package/src/String.ts +94 -0
- package/src/Struct.ts +24 -0
- package/src/Symbol.ts +2 -0
- package/src/Trie.ts +132 -0
- package/src/Tuple.ts +42 -0
- package/src/Types.ts +24 -0
- package/src/Utils.ts +8 -0
- package/src/internal/channel/channelExecutor.ts +37 -33
- package/src/internal/channel.ts +504 -467
- package/src/internal/config.ts +18 -6
- package/src/internal/context.ts +56 -4
- package/src/internal/dateTime.ts +1126 -0
- package/src/internal/fiberRuntime.ts +35 -16
- package/src/internal/groupBy.ts +13 -22
- package/src/internal/layer.ts +5 -8
- package/src/internal/mailbox.ts +6 -4
- package/src/internal/sink.ts +55 -35
- package/src/internal/stream.ts +299 -299
- package/src/internal/version.ts +1 -1
package/src/Micro.ts
CHANGED
|
@@ -4,28 +4,33 @@
|
|
|
4
4
|
* @since 3.4.0
|
|
5
5
|
* @experimental
|
|
6
6
|
*/
|
|
7
|
-
import
|
|
7
|
+
import * as Arr from "effect/Array"
|
|
8
|
+
import type { Channel } from "./Channel.js"
|
|
8
9
|
import * as Context from "./Context.js"
|
|
9
|
-
import type { Effect,
|
|
10
|
+
import type { Effect, EffectUnify, EffectUnifyIgnore } from "./Effect.js"
|
|
10
11
|
import * as Effectable from "./Effectable.js"
|
|
11
12
|
import * as Either from "./Either.js"
|
|
12
|
-
import
|
|
13
|
+
import * as Equal from "./Equal.js"
|
|
14
|
+
import type { LazyArg } from "./Function.js"
|
|
15
|
+
import { constTrue, constVoid, dual, identity } from "./Function.js"
|
|
13
16
|
import { globalValue } from "./GlobalValue.js"
|
|
17
|
+
import * as Hash from "./Hash.js"
|
|
14
18
|
import type { TypeLambda } from "./HKT.js"
|
|
15
19
|
import type { Inspectable } from "./Inspectable.js"
|
|
16
|
-
import { NodeInspectSymbol, toStringUnknown } from "./Inspectable.js"
|
|
20
|
+
import { format, NodeInspectSymbol, toStringUnknown } from "./Inspectable.js"
|
|
21
|
+
import * as InternalContext from "./internal/context.js"
|
|
17
22
|
import * as doNotation from "./internal/doNotation.js"
|
|
18
23
|
import { StructuralPrototype } from "./internal/effectable.js"
|
|
19
|
-
import { SingleShotGen } from "./internal/singleShotGen.js"
|
|
20
24
|
import * as Option from "./Option.js"
|
|
21
|
-
import {
|
|
22
|
-
import {
|
|
23
|
-
import type {
|
|
24
|
-
import
|
|
25
|
-
import type {
|
|
26
|
-
import type {
|
|
25
|
+
import type { Pipeable } from "./Pipeable.js"
|
|
26
|
+
import { pipeArguments } from "./Pipeable.js"
|
|
27
|
+
import type { Predicate, Refinement } from "./Predicate.js"
|
|
28
|
+
import { hasProperty, isIterable, isTagged } from "./Predicate.js"
|
|
29
|
+
import type { Sink } from "./Sink.js"
|
|
30
|
+
import type { Stream } from "./Stream.js"
|
|
31
|
+
import type { Concurrency, Covariant, Equals, NotFunction, Simplify } from "./Types.js"
|
|
27
32
|
import type * as Unify from "./Unify.js"
|
|
28
|
-
import { YieldWrap, yieldWrapGet } from "./Utils.js"
|
|
33
|
+
import { SingleShotGen, YieldWrap, yieldWrapGet } from "./Utils.js"
|
|
29
34
|
|
|
30
35
|
/**
|
|
31
36
|
* @since 3.4.0
|
|
@@ -44,16 +49,18 @@ export type TypeId = typeof TypeId
|
|
|
44
49
|
/**
|
|
45
50
|
* @since 3.4.0
|
|
46
51
|
* @experimental
|
|
47
|
-
* @category
|
|
52
|
+
* @category MicroExit
|
|
48
53
|
*/
|
|
49
|
-
export const
|
|
54
|
+
export const MicroExitTypeId: unique symbol = Symbol.for(
|
|
55
|
+
"effect/Micro/MicroExit"
|
|
56
|
+
)
|
|
50
57
|
|
|
51
58
|
/**
|
|
52
59
|
* @since 3.4.0
|
|
53
60
|
* @experimental
|
|
54
|
-
* @category
|
|
61
|
+
* @category MicroExit
|
|
55
62
|
*/
|
|
56
|
-
export type
|
|
63
|
+
export type MicroExitTypeId = typeof TypeId
|
|
57
64
|
|
|
58
65
|
/**
|
|
59
66
|
* A lightweight alternative to the `Effect` data type, with a subset of the functionality.
|
|
@@ -64,7 +71,6 @@ export type runSymbol = typeof runSymbol
|
|
|
64
71
|
*/
|
|
65
72
|
export interface Micro<out A, out E = never, out R = never> extends Effect<A, E, R> {
|
|
66
73
|
readonly [TypeId]: Micro.Variance<A, E, R>
|
|
67
|
-
[runSymbol](env: Env<any>, onExit: (exit: MicroExit<A, E>) => void): void
|
|
68
74
|
[Symbol.iterator](): MicroIterator<Micro<A, E, R>>
|
|
69
75
|
[Unify.typeSymbol]?: unknown
|
|
70
76
|
[Unify.unifySymbol]?: MicroUnify<this>
|
|
@@ -144,58 +150,6 @@ export interface MicroIterator<T extends Micro<any, any, any>> {
|
|
|
144
150
|
next(...args: ReadonlyArray<any>): IteratorResult<YieldWrap<T>, Micro.Success<T>>
|
|
145
151
|
}
|
|
146
152
|
|
|
147
|
-
/**
|
|
148
|
-
* @since 3.8.4
|
|
149
|
-
* @experimental
|
|
150
|
-
* @category models
|
|
151
|
-
*/
|
|
152
|
-
export interface MicroClass {
|
|
153
|
-
new<A, E = never, R = never>(): Micro<A, E, R>
|
|
154
|
-
}
|
|
155
|
-
|
|
156
|
-
// ----------------------------------------------------------------------------
|
|
157
|
-
// Microable
|
|
158
|
-
// ----------------------------------------------------------------------------
|
|
159
|
-
|
|
160
|
-
const MicroProto = {
|
|
161
|
-
...Effectable.EffectPrototype,
|
|
162
|
-
_op: "Micro",
|
|
163
|
-
[TypeId]: {
|
|
164
|
-
_A: identity,
|
|
165
|
-
_E: identity,
|
|
166
|
-
_R: identity
|
|
167
|
-
},
|
|
168
|
-
[Symbol.iterator]() {
|
|
169
|
-
return new SingleShotGen(new YieldWrap(this)) as any
|
|
170
|
-
}
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
const MicroBase: MicroClass = (function() {
|
|
174
|
-
function Base() {}
|
|
175
|
-
Base.prototype = MicroProto
|
|
176
|
-
return Base as any
|
|
177
|
-
})()
|
|
178
|
-
|
|
179
|
-
/**
|
|
180
|
-
* @since 3.8.4
|
|
181
|
-
* @experimental
|
|
182
|
-
* @category constructors
|
|
183
|
-
*/
|
|
184
|
-
export abstract class Class<out A, out E = never, out R = never> extends MicroBase<A, E, R> {
|
|
185
|
-
/**
|
|
186
|
-
* @since 3.8.4
|
|
187
|
-
* @experimental
|
|
188
|
-
*/
|
|
189
|
-
abstract asMicro(): Micro<A, E, R>
|
|
190
|
-
/**
|
|
191
|
-
* @since 3.8.4
|
|
192
|
-
* @experimental
|
|
193
|
-
*/
|
|
194
|
-
[runSymbol](env: Env<any>, onExit: (exit: MicroExit<A, E>) => void): void {
|
|
195
|
-
this.asMicro()[runSymbol](env, onExit)
|
|
196
|
-
}
|
|
197
|
-
}
|
|
198
|
-
|
|
199
153
|
// ----------------------------------------------------------------------------
|
|
200
154
|
// MicroCause
|
|
201
155
|
// ----------------------------------------------------------------------------
|
|
@@ -221,7 +175,10 @@ export type MicroCauseTypeId = typeof MicroCauseTypeId
|
|
|
221
175
|
* @experimental
|
|
222
176
|
* @category MicroCause
|
|
223
177
|
*/
|
|
224
|
-
export type MicroCause<E> =
|
|
178
|
+
export type MicroCause<E> =
|
|
179
|
+
| MicroCause.Die
|
|
180
|
+
| MicroCause.Fail<E>
|
|
181
|
+
| MicroCause.Interrupt
|
|
225
182
|
|
|
226
183
|
/**
|
|
227
184
|
* @since 3.6.6
|
|
@@ -302,7 +259,12 @@ abstract class MicroCauseImpl<Tag extends string, E> extends globalThis.Error im
|
|
|
302
259
|
message = originalError.message as string
|
|
303
260
|
const messageLines = message.split("\n").length
|
|
304
261
|
stack = originalError.stack
|
|
305
|
-
? `(${causeName}) ${
|
|
262
|
+
? `(${causeName}) ${
|
|
263
|
+
originalError.stack
|
|
264
|
+
.split("\n")
|
|
265
|
+
.slice(0, messageLines + 3)
|
|
266
|
+
.join("\n")
|
|
267
|
+
}`
|
|
306
268
|
: `${name}: ${message}`
|
|
307
269
|
} else {
|
|
308
270
|
name = causeName
|
|
@@ -329,7 +291,10 @@ abstract class MicroCauseImpl<Tag extends string, E> extends globalThis.Error im
|
|
|
329
291
|
}
|
|
330
292
|
|
|
331
293
|
class FailImpl<E> extends MicroCauseImpl<"Fail", E> implements MicroCause.Fail<E> {
|
|
332
|
-
constructor(
|
|
294
|
+
constructor(
|
|
295
|
+
readonly error: E,
|
|
296
|
+
traces: ReadonlyArray<string> = []
|
|
297
|
+
) {
|
|
333
298
|
super("Fail", error, traces)
|
|
334
299
|
}
|
|
335
300
|
}
|
|
@@ -339,10 +304,16 @@ class FailImpl<E> extends MicroCauseImpl<"Fail", E> implements MicroCause.Fail<E
|
|
|
339
304
|
* @experimental
|
|
340
305
|
* @category MicroCause
|
|
341
306
|
*/
|
|
342
|
-
export const causeFail = <E>(
|
|
307
|
+
export const causeFail = <E>(
|
|
308
|
+
error: E,
|
|
309
|
+
traces: ReadonlyArray<string> = []
|
|
310
|
+
): MicroCause<E> => new FailImpl(error, traces)
|
|
343
311
|
|
|
344
312
|
class DieImpl extends MicroCauseImpl<"Die", never> implements MicroCause.Die {
|
|
345
|
-
constructor(
|
|
313
|
+
constructor(
|
|
314
|
+
readonly defect: unknown,
|
|
315
|
+
traces: ReadonlyArray<string> = []
|
|
316
|
+
) {
|
|
346
317
|
super("Die", defect, traces)
|
|
347
318
|
}
|
|
348
319
|
}
|
|
@@ -352,8 +323,10 @@ class DieImpl extends MicroCauseImpl<"Die", never> implements MicroCause.Die {
|
|
|
352
323
|
* @experimental
|
|
353
324
|
* @category MicroCause
|
|
354
325
|
*/
|
|
355
|
-
export const causeDie = (
|
|
356
|
-
|
|
326
|
+
export const causeDie = (
|
|
327
|
+
defect: unknown,
|
|
328
|
+
traces: ReadonlyArray<string> = []
|
|
329
|
+
): MicroCause<never> => new DieImpl(defect, traces)
|
|
357
330
|
|
|
358
331
|
class InterruptImpl extends MicroCauseImpl<"Interrupt", never> implements MicroCause.Interrupt {
|
|
359
332
|
constructor(traces: ReadonlyArray<string> = []) {
|
|
@@ -366,14 +339,18 @@ class InterruptImpl extends MicroCauseImpl<"Interrupt", never> implements MicroC
|
|
|
366
339
|
* @experimental
|
|
367
340
|
* @category MicroCause
|
|
368
341
|
*/
|
|
369
|
-
export const causeInterrupt = (
|
|
342
|
+
export const causeInterrupt = (
|
|
343
|
+
traces: ReadonlyArray<string> = []
|
|
344
|
+
): MicroCause<never> => new InterruptImpl(traces)
|
|
370
345
|
|
|
371
346
|
/**
|
|
372
347
|
* @since 3.4.6
|
|
373
348
|
* @experimental
|
|
374
349
|
* @category MicroCause
|
|
375
350
|
*/
|
|
376
|
-
export const causeIsFail = <E>(
|
|
351
|
+
export const causeIsFail = <E>(
|
|
352
|
+
self: MicroCause<E>
|
|
353
|
+
): self is MicroCause.Fail<E> => self._tag === "Fail"
|
|
377
354
|
|
|
378
355
|
/**
|
|
379
356
|
* @since 3.4.6
|
|
@@ -387,7 +364,9 @@ export const causeIsDie = <E>(self: MicroCause<E>): self is MicroCause.Die => se
|
|
|
387
364
|
* @experimental
|
|
388
365
|
* @category MicroCause
|
|
389
366
|
*/
|
|
390
|
-
export const causeIsInterrupt = <E>(
|
|
367
|
+
export const causeIsInterrupt = <E>(
|
|
368
|
+
self: MicroCause<E>
|
|
369
|
+
): self is MicroCause.Interrupt => self._tag === "Interrupt"
|
|
391
370
|
|
|
392
371
|
/**
|
|
393
372
|
* @since 3.4.6
|
|
@@ -428,1680 +407,1963 @@ export const causeWithTrace: {
|
|
|
428
407
|
})
|
|
429
408
|
|
|
430
409
|
// ----------------------------------------------------------------------------
|
|
431
|
-
//
|
|
410
|
+
// Fiber
|
|
432
411
|
// ----------------------------------------------------------------------------
|
|
433
412
|
|
|
434
413
|
/**
|
|
435
|
-
* @since 3.
|
|
414
|
+
* @since 3.11.0
|
|
436
415
|
* @experimental
|
|
437
|
-
* @category
|
|
416
|
+
* @category Fiber
|
|
438
417
|
*/
|
|
439
|
-
export
|
|
440
|
-
/**
|
|
441
|
-
* @since 3.4.6
|
|
442
|
-
* @experimental
|
|
443
|
-
* @category MicroExit
|
|
444
|
-
*/
|
|
445
|
-
export type Success<A, E = never> = Either.Right<MicroCause<E>, A>
|
|
446
|
-
|
|
447
|
-
/**
|
|
448
|
-
* @since 3.4.6
|
|
449
|
-
* @experimental
|
|
450
|
-
* @category MicroExit
|
|
451
|
-
*/
|
|
452
|
-
export type Failure<A, E = never> = Either.Left<MicroCause<E>, A>
|
|
453
|
-
}
|
|
418
|
+
export const FiberTypeId = Symbol.for("effect/Micro/Fiber")
|
|
454
419
|
|
|
455
420
|
/**
|
|
456
|
-
*
|
|
457
|
-
* computation.
|
|
458
|
-
*
|
|
459
|
-
* It uses the `Either` data type to represent the success and failure cases.
|
|
460
|
-
*
|
|
461
|
-
* @since 3.4.6
|
|
421
|
+
* @since 3.11.0
|
|
462
422
|
* @experimental
|
|
463
|
-
* @category
|
|
423
|
+
* @category Fiber
|
|
464
424
|
*/
|
|
465
|
-
export type
|
|
425
|
+
export type FiberTypeId = typeof FiberTypeId
|
|
466
426
|
|
|
467
427
|
/**
|
|
468
|
-
* @since 3.
|
|
428
|
+
* @since 3.11.0
|
|
469
429
|
* @experimental
|
|
470
|
-
* @category
|
|
430
|
+
* @category Fiber
|
|
471
431
|
*/
|
|
472
|
-
export
|
|
432
|
+
export interface Fiber<out A, out E = never> {
|
|
433
|
+
readonly [FiberTypeId]: Fiber.Variance<A, E>
|
|
473
434
|
|
|
474
|
-
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
435
|
+
readonly currentOpCount: number
|
|
436
|
+
readonly getRef: <I, A>(ref: Context.Reference<I, A>) => A
|
|
437
|
+
readonly context: Context.Context<never>
|
|
438
|
+
readonly addObserver: (cb: (exit: MicroExit<A, E>) => void) => () => void
|
|
439
|
+
readonly unsafeInterrupt: () => void
|
|
440
|
+
readonly unsafePoll: () => MicroExit<A, E> | undefined
|
|
441
|
+
}
|
|
480
442
|
|
|
481
443
|
/**
|
|
482
|
-
* @since 3.
|
|
444
|
+
* @since 3.11.0
|
|
483
445
|
* @experimental
|
|
484
|
-
* @category
|
|
446
|
+
* @category Fiber
|
|
485
447
|
*/
|
|
486
|
-
export
|
|
448
|
+
export declare namespace Fiber {
|
|
449
|
+
/**
|
|
450
|
+
* @since 3.11.0
|
|
451
|
+
* @experimental
|
|
452
|
+
* @category Fiber
|
|
453
|
+
*/
|
|
454
|
+
export interface Variance<out A, out E = never> {
|
|
455
|
+
readonly _A: Covariant<A>
|
|
456
|
+
readonly _E: Covariant<E>
|
|
457
|
+
}
|
|
458
|
+
}
|
|
459
|
+
|
|
460
|
+
const fiberVariance = {
|
|
461
|
+
_A: identity,
|
|
462
|
+
_E: identity
|
|
463
|
+
}
|
|
464
|
+
|
|
465
|
+
class FiberImpl<in out A = any, in out E = any> implements Fiber<A, E> {
|
|
466
|
+
readonly [FiberTypeId]: Fiber.Variance<A, E>
|
|
467
|
+
|
|
468
|
+
readonly _stack: Array<Primitive> = []
|
|
469
|
+
readonly _observers: Array<(exit: MicroExit<A, E>) => void> = []
|
|
470
|
+
_exit: MicroExit<A, E> | undefined
|
|
471
|
+
public _children: Set<FiberImpl<any, any>> | undefined
|
|
472
|
+
|
|
473
|
+
public currentOpCount = 0
|
|
474
|
+
|
|
475
|
+
constructor(
|
|
476
|
+
public context: Context.Context<never>,
|
|
477
|
+
public interruptible = true
|
|
478
|
+
) {
|
|
479
|
+
this[FiberTypeId] = fiberVariance
|
|
480
|
+
}
|
|
481
|
+
|
|
482
|
+
getRef<I, A>(ref: Context.Reference<I, A>): A {
|
|
483
|
+
return InternalContext.unsafeGetReference(this.context, ref)
|
|
484
|
+
}
|
|
485
|
+
|
|
486
|
+
addObserver(cb: (exit: MicroExit<A, E>) => void): () => void {
|
|
487
|
+
if (this._exit) {
|
|
488
|
+
cb(this._exit)
|
|
489
|
+
return constVoid
|
|
490
|
+
}
|
|
491
|
+
this._observers.push(cb)
|
|
492
|
+
return () => {
|
|
493
|
+
const index = this._observers.indexOf(cb)
|
|
494
|
+
if (index >= 0) {
|
|
495
|
+
this._observers.splice(index, 1)
|
|
496
|
+
}
|
|
497
|
+
}
|
|
498
|
+
}
|
|
499
|
+
|
|
500
|
+
_interrupted = false
|
|
501
|
+
unsafeInterrupt(): void {
|
|
502
|
+
if (this._exit) {
|
|
503
|
+
return
|
|
504
|
+
}
|
|
505
|
+
this._interrupted = true
|
|
506
|
+
if (this.interruptible) {
|
|
507
|
+
this.evaluate(exitInterrupt as any)
|
|
508
|
+
}
|
|
509
|
+
}
|
|
510
|
+
|
|
511
|
+
unsafePoll(): MicroExit<A, E> | undefined {
|
|
512
|
+
return this._exit
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
evaluate(effect: Primitive): void {
|
|
516
|
+
if (this._exit) {
|
|
517
|
+
return
|
|
518
|
+
} else if (this._yielded !== undefined) {
|
|
519
|
+
const yielded = this._yielded as () => void
|
|
520
|
+
this._yielded = undefined
|
|
521
|
+
yielded()
|
|
522
|
+
}
|
|
523
|
+
const exit = this.runLoop(effect)
|
|
524
|
+
if (exit === Yield) {
|
|
525
|
+
return
|
|
526
|
+
}
|
|
527
|
+
|
|
528
|
+
// the interruptChildren middlware is added in Micro.fork, so it can be
|
|
529
|
+
// tree-shaken if not used
|
|
530
|
+
const interruptChildren = fiberMiddleware.interruptChildren && fiberMiddleware.interruptChildren(this)
|
|
531
|
+
if (interruptChildren !== undefined) {
|
|
532
|
+
return this.evaluate(flatMap(interruptChildren, () => exit) as any)
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
this._exit = exit
|
|
536
|
+
for (let i = 0; i < this._observers.length; i++) {
|
|
537
|
+
this._observers[i](exit)
|
|
538
|
+
}
|
|
539
|
+
this._observers.length = 0
|
|
540
|
+
}
|
|
541
|
+
|
|
542
|
+
runLoop(effect: Primitive): MicroExit<A, E> | Yield {
|
|
543
|
+
let yielding = false
|
|
544
|
+
let current: Primitive | Yield = effect
|
|
545
|
+
this.currentOpCount = 0
|
|
546
|
+
try {
|
|
547
|
+
while (true) {
|
|
548
|
+
this.currentOpCount++
|
|
549
|
+
if (!yielding && this.getRef(CurrentScheduler).shouldYield(this as any)) {
|
|
550
|
+
yielding = true
|
|
551
|
+
const prev = current
|
|
552
|
+
current = flatMap(yieldNow, () => prev as any) as any
|
|
553
|
+
}
|
|
554
|
+
current = (current as any)[evaluate](this)
|
|
555
|
+
if (current === Yield) {
|
|
556
|
+
const yielded = this._yielded!
|
|
557
|
+
if (MicroExitTypeId in yielded) {
|
|
558
|
+
this._yielded = undefined
|
|
559
|
+
return yielded
|
|
560
|
+
}
|
|
561
|
+
return Yield
|
|
562
|
+
}
|
|
563
|
+
}
|
|
564
|
+
} catch (error) {
|
|
565
|
+
if (!hasProperty(current, evaluate)) {
|
|
566
|
+
return exitDie(`Micro/Fiber.runLoop: Not a valid effect: ${String(current)}`)
|
|
567
|
+
}
|
|
568
|
+
return exitDie(error)
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
getCont<S extends successCont | failureCont>(
|
|
573
|
+
symbol: S
|
|
574
|
+
): Primitive & Record<S, (value: any, fiber: FiberImpl) => Primitive> | undefined {
|
|
575
|
+
while (true) {
|
|
576
|
+
const op = this._stack.pop()
|
|
577
|
+
if (!op) return undefined
|
|
578
|
+
const cont = op[ensureCont] && op[ensureCont](this)
|
|
579
|
+
if (cont) return { [symbol]: cont } as any
|
|
580
|
+
if (op[symbol]) return op as any
|
|
581
|
+
}
|
|
582
|
+
}
|
|
583
|
+
|
|
584
|
+
// cancel the yielded operation, or for the yielded exit value
|
|
585
|
+
_yielded: MicroExit<any, any> | (() => void) | undefined = undefined
|
|
586
|
+
yieldWith(value: MicroExit<any, any> | (() => void)): Yield {
|
|
587
|
+
this._yielded = value
|
|
588
|
+
return Yield
|
|
589
|
+
}
|
|
590
|
+
|
|
591
|
+
children(): Set<Fiber<any, any>> {
|
|
592
|
+
return this._children ??= new Set()
|
|
593
|
+
}
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
const fiberMiddleware = globalValue("effect/Micro/fiberMiddleware", () => ({
|
|
597
|
+
interruptChildren: undefined as ((fiber: FiberImpl) => Micro<void> | undefined) | undefined
|
|
598
|
+
}))
|
|
599
|
+
|
|
600
|
+
const fiberInterruptChildren = (fiber: FiberImpl) => {
|
|
601
|
+
if (fiber._children === undefined || fiber._children.size === 0) {
|
|
602
|
+
return undefined
|
|
603
|
+
}
|
|
604
|
+
return fiberInterruptAll(fiber._children)
|
|
605
|
+
}
|
|
487
606
|
|
|
488
607
|
/**
|
|
489
|
-
* @since 3.
|
|
608
|
+
* @since 3.11.0
|
|
490
609
|
* @experimental
|
|
491
|
-
* @category
|
|
610
|
+
* @category Fiber
|
|
492
611
|
*/
|
|
493
|
-
export const
|
|
612
|
+
export const fiberAwait = <A, E>(self: Fiber<A, E>): Micro<MicroExit<A, E>> =>
|
|
613
|
+
async((resume) => sync(self.addObserver((exit) => resume(succeed(exit)))))
|
|
494
614
|
|
|
495
615
|
/**
|
|
496
|
-
* @since 3.
|
|
616
|
+
* @since 3.11.0
|
|
497
617
|
* @experimental
|
|
498
|
-
* @category
|
|
618
|
+
* @category Fiber
|
|
499
619
|
*/
|
|
500
|
-
export const
|
|
620
|
+
export const fiberInterrupt = <A, E>(self: Fiber<A, E>): Micro<void> =>
|
|
621
|
+
suspend(() => {
|
|
622
|
+
self.unsafeInterrupt()
|
|
623
|
+
return asVoid(fiberAwait(self))
|
|
624
|
+
})
|
|
501
625
|
|
|
502
626
|
/**
|
|
503
|
-
* @since 3.
|
|
627
|
+
* @since 3.11.0
|
|
504
628
|
* @experimental
|
|
505
|
-
* @category
|
|
629
|
+
* @category Fiber
|
|
506
630
|
*/
|
|
507
|
-
export const
|
|
631
|
+
export const fiberInterruptAll = <A extends Iterable<Fiber<any, any>>>(fibers: A): Micro<void> =>
|
|
632
|
+
suspend(() => {
|
|
633
|
+
for (const fiber of fibers) fiber.unsafeInterrupt()
|
|
634
|
+
const iter = fibers[Symbol.iterator]()
|
|
635
|
+
const wait: Micro<void> = suspend(() => {
|
|
636
|
+
let result = iter.next()
|
|
637
|
+
while (!result.done) {
|
|
638
|
+
if (result.value.unsafePoll()) {
|
|
639
|
+
result = iter.next()
|
|
640
|
+
continue
|
|
641
|
+
}
|
|
642
|
+
const fiber = result.value
|
|
643
|
+
return async((resume) => {
|
|
644
|
+
fiber.addObserver((_) => {
|
|
645
|
+
resume(wait)
|
|
646
|
+
})
|
|
647
|
+
})
|
|
648
|
+
}
|
|
649
|
+
return exitVoid
|
|
650
|
+
})
|
|
651
|
+
return wait
|
|
652
|
+
})
|
|
653
|
+
|
|
654
|
+
const identifier = Symbol.for("effect/Micro/identifier")
|
|
655
|
+
type identifier = typeof identifier
|
|
656
|
+
|
|
657
|
+
const args = Symbol.for("effect/Micro/args")
|
|
658
|
+
type args = typeof args
|
|
659
|
+
|
|
660
|
+
const evaluate = Symbol.for("effect/Micro/evaluate")
|
|
661
|
+
type evaluate = typeof evaluate
|
|
662
|
+
|
|
663
|
+
const successCont = Symbol.for("effect/Micro/successCont")
|
|
664
|
+
type successCont = typeof successCont
|
|
665
|
+
|
|
666
|
+
const failureCont = Symbol.for("effect/Micro/failureCont")
|
|
667
|
+
type failureCont = typeof failureCont
|
|
668
|
+
|
|
669
|
+
const ensureCont = Symbol.for("effect/Micro/ensureCont")
|
|
670
|
+
type ensureCont = typeof ensureCont
|
|
671
|
+
|
|
672
|
+
const Yield = Symbol.for("effect/Micro/Yield")
|
|
673
|
+
type Yield = typeof Yield
|
|
674
|
+
|
|
675
|
+
interface Primitive {
|
|
676
|
+
readonly [identifier]: string
|
|
677
|
+
readonly [successCont]: ((value: unknown, fiber: FiberImpl) => Primitive | Yield) | undefined
|
|
678
|
+
readonly [failureCont]:
|
|
679
|
+
| ((cause: MicroCause<unknown>, fiber: FiberImpl) => Primitive | Yield)
|
|
680
|
+
| undefined
|
|
681
|
+
readonly [ensureCont]:
|
|
682
|
+
| ((fiber: FiberImpl) =>
|
|
683
|
+
| ((value: unknown, fiber: FiberImpl) => Primitive | Yield)
|
|
684
|
+
| undefined)
|
|
685
|
+
| undefined
|
|
686
|
+
[evaluate](fiber: FiberImpl): Primitive | Yield
|
|
687
|
+
}
|
|
688
|
+
|
|
689
|
+
const microVariance = {
|
|
690
|
+
_A: identity,
|
|
691
|
+
_E: identity,
|
|
692
|
+
_R: identity
|
|
693
|
+
}
|
|
694
|
+
|
|
695
|
+
const MicroProto = {
|
|
696
|
+
...Effectable.EffectPrototype,
|
|
697
|
+
_op: "Micro",
|
|
698
|
+
[TypeId]: microVariance,
|
|
699
|
+
pipe() {
|
|
700
|
+
return pipeArguments(this, arguments)
|
|
701
|
+
},
|
|
702
|
+
[Symbol.iterator]() {
|
|
703
|
+
return new SingleShotGen(new YieldWrap(this)) as any
|
|
704
|
+
},
|
|
705
|
+
toJSON(this: Primitive) {
|
|
706
|
+
return {
|
|
707
|
+
_id: "effect/Micro",
|
|
708
|
+
op: this[identifier],
|
|
709
|
+
...(args in this ? { args: this[args] } : undefined)
|
|
710
|
+
}
|
|
711
|
+
},
|
|
712
|
+
toString() {
|
|
713
|
+
return format(this)
|
|
714
|
+
},
|
|
715
|
+
[NodeInspectSymbol]() {
|
|
716
|
+
return format(this)
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
|
|
720
|
+
function defaultEvaluate(_fiber: FiberImpl): Primitive | Yield {
|
|
721
|
+
return exitDie(`Micro.evaluate: Not implemented`) as any
|
|
722
|
+
}
|
|
723
|
+
|
|
724
|
+
const makePrimitiveProto = <Op extends string>(options: {
|
|
725
|
+
readonly op: Op
|
|
726
|
+
readonly eval?: (fiber: FiberImpl) => Primitive | Micro<any, any, any> | Yield
|
|
727
|
+
readonly contA?: (this: Primitive, value: any, fiber: FiberImpl) => Primitive | Micro<any, any, any> | Yield
|
|
728
|
+
readonly contE?: (
|
|
729
|
+
this: Primitive,
|
|
730
|
+
cause: MicroCause<any>,
|
|
731
|
+
fiber: FiberImpl
|
|
732
|
+
) => Primitive | Micro<any, any, any> | Yield
|
|
733
|
+
readonly ensure?: (this: Primitive, fiber: FiberImpl) => void | ((value: any, fiber: FiberImpl) => void)
|
|
734
|
+
}): Primitive => ({
|
|
735
|
+
...MicroProto,
|
|
736
|
+
[identifier]: options.op,
|
|
737
|
+
[evaluate]: options.eval ?? defaultEvaluate,
|
|
738
|
+
[successCont]: options.contA,
|
|
739
|
+
[failureCont]: options.contE,
|
|
740
|
+
[ensureCont]: options.ensure
|
|
741
|
+
} as any)
|
|
742
|
+
|
|
743
|
+
const makePrimitive = <Fn extends (...args: Array<any>) => any, Single extends boolean = true>(options: {
|
|
744
|
+
readonly op: string
|
|
745
|
+
readonly single?: Single
|
|
746
|
+
readonly eval?: (
|
|
747
|
+
this: Primitive & { readonly [args]: Single extends true ? Parameters<Fn>[0] : Parameters<Fn> },
|
|
748
|
+
fiber: FiberImpl
|
|
749
|
+
) => Primitive | Micro<any, any, any> | Yield
|
|
750
|
+
readonly contA?: (
|
|
751
|
+
this: Primitive & { readonly [args]: Single extends true ? Parameters<Fn>[0] : Parameters<Fn> },
|
|
752
|
+
value: any,
|
|
753
|
+
fiber: FiberImpl
|
|
754
|
+
) => Primitive | Micro<any, any, any> | Yield
|
|
755
|
+
readonly contE?: (
|
|
756
|
+
this: Primitive & { readonly [args]: Single extends true ? Parameters<Fn>[0] : Parameters<Fn> },
|
|
757
|
+
cause: MicroCause<any>,
|
|
758
|
+
fiber: FiberImpl
|
|
759
|
+
) => Primitive | Micro<any, any, any> | Yield
|
|
760
|
+
readonly ensure?: (
|
|
761
|
+
this: Primitive & { readonly [args]: Single extends true ? Parameters<Fn>[0] : Parameters<Fn> },
|
|
762
|
+
fiber: FiberImpl
|
|
763
|
+
) => void | ((value: any, fiber: FiberImpl) => void)
|
|
764
|
+
}): Fn => {
|
|
765
|
+
const Proto = makePrimitiveProto(options as any)
|
|
766
|
+
return function() {
|
|
767
|
+
const self = Object.create(Proto)
|
|
768
|
+
self[args] = options.single === false ? arguments : arguments[0]
|
|
769
|
+
return self
|
|
770
|
+
} as Fn
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
const makeExit = <Fn extends (...args: Array<any>) => any, Prop extends string>(options: {
|
|
774
|
+
readonly op: "Success" | "Failure"
|
|
775
|
+
readonly prop: Prop
|
|
776
|
+
readonly eval: (
|
|
777
|
+
this:
|
|
778
|
+
& MicroExit<unknown, unknown>
|
|
779
|
+
& { [args]: Parameters<Fn>[0] },
|
|
780
|
+
fiber: FiberImpl<unknown, unknown>
|
|
781
|
+
) => Primitive | Yield
|
|
782
|
+
}): Fn => {
|
|
783
|
+
const Proto = {
|
|
784
|
+
...makePrimitiveProto(options),
|
|
785
|
+
[MicroExitTypeId]: MicroExitTypeId,
|
|
786
|
+
_tag: options.op,
|
|
787
|
+
get [options.prop](): any {
|
|
788
|
+
return (this as any)[args]
|
|
789
|
+
},
|
|
790
|
+
toJSON(this: any) {
|
|
791
|
+
return {
|
|
792
|
+
_id: "effect/Micro/Exit",
|
|
793
|
+
_tag: options.op,
|
|
794
|
+
[options.prop]: this[args]
|
|
795
|
+
}
|
|
796
|
+
},
|
|
797
|
+
[Equal.symbol](this: any, that: any): boolean {
|
|
798
|
+
return isMicroExit(that) && that._tag === options.op &&
|
|
799
|
+
Equal.equals(this[args], (that as any)[args])
|
|
800
|
+
},
|
|
801
|
+
[Hash.symbol](this: any): number {
|
|
802
|
+
return Hash.cached(this, Hash.combine(Hash.string(options.op))(Hash.hash(this[args])))
|
|
803
|
+
}
|
|
804
|
+
}
|
|
805
|
+
return function(value: unknown) {
|
|
806
|
+
const self = Object.create(Proto)
|
|
807
|
+
self[args] = value
|
|
808
|
+
self[successCont] = undefined
|
|
809
|
+
self[failureCont] = undefined
|
|
810
|
+
self[ensureCont] = undefined
|
|
811
|
+
return self
|
|
812
|
+
} as Fn
|
|
813
|
+
}
|
|
508
814
|
|
|
509
815
|
/**
|
|
510
|
-
*
|
|
816
|
+
* Creates a `Micro` effect that will succeed with the specified constant value.
|
|
817
|
+
*
|
|
818
|
+
* @since 3.4.0
|
|
511
819
|
* @experimental
|
|
512
|
-
* @category
|
|
820
|
+
* @category constructors
|
|
513
821
|
*/
|
|
514
|
-
export const
|
|
822
|
+
export const succeed: <A>(value: A) => Micro<A> = makeExit({
|
|
823
|
+
op: "Success",
|
|
824
|
+
prop: "value",
|
|
825
|
+
eval(fiber) {
|
|
826
|
+
const cont = fiber.getCont(successCont)
|
|
827
|
+
return cont ? cont[successCont](this[args], fiber) : fiber.yieldWith(this)
|
|
828
|
+
}
|
|
829
|
+
})
|
|
515
830
|
|
|
516
831
|
/**
|
|
832
|
+
* Creates a `Micro` effect that will fail with the specified `MicroCause`.
|
|
833
|
+
*
|
|
517
834
|
* @since 3.4.6
|
|
518
835
|
* @experimental
|
|
519
|
-
* @category
|
|
836
|
+
* @category constructors
|
|
520
837
|
*/
|
|
521
|
-
export const
|
|
522
|
-
|
|
838
|
+
export const failCause: <E>(cause: MicroCause<E>) => Micro<never, E> = makeExit({
|
|
839
|
+
op: "Failure",
|
|
840
|
+
prop: "cause",
|
|
841
|
+
eval(fiber) {
|
|
842
|
+
let cont = fiber.getCont(failureCont)
|
|
843
|
+
while (causeIsInterrupt(this[args]) && cont && fiber.interruptible) {
|
|
844
|
+
cont = fiber.getCont(failureCont)
|
|
845
|
+
}
|
|
846
|
+
return cont ? cont[failureCont](this[args], fiber) : fiber.yieldWith(this)
|
|
847
|
+
}
|
|
848
|
+
})
|
|
523
849
|
|
|
524
850
|
/**
|
|
525
|
-
*
|
|
851
|
+
* Creates a `Micro` effect that will fail with the specified error.
|
|
852
|
+
*
|
|
853
|
+
* This will result in a `CauseFail`, where the error is tracked at the
|
|
854
|
+
* type level.
|
|
855
|
+
*
|
|
856
|
+
* @since 3.4.0
|
|
526
857
|
* @experimental
|
|
527
|
-
* @category
|
|
858
|
+
* @category constructors
|
|
528
859
|
*/
|
|
529
|
-
export const
|
|
530
|
-
exitIsFailure(self) && self.left._tag === "Fail"
|
|
860
|
+
export const fail = <E>(error: E): Micro<never, E> => failCause(causeFail(error))
|
|
531
861
|
|
|
532
862
|
/**
|
|
533
|
-
*
|
|
863
|
+
* Creates a `Micro` effect that will succeed with the lazily evaluated value.
|
|
864
|
+
*
|
|
865
|
+
* If the evaluation of the value throws an error, the effect will fail with
|
|
866
|
+
* `CauseDie`.
|
|
867
|
+
*
|
|
868
|
+
* @since 3.4.0
|
|
534
869
|
* @experimental
|
|
535
|
-
* @category
|
|
870
|
+
* @category constructors
|
|
536
871
|
*/
|
|
537
|
-
export const
|
|
538
|
-
|
|
872
|
+
export const sync: <A>(evaluate: LazyArg<A>) => Micro<A> = makePrimitive({
|
|
873
|
+
op: "Sync",
|
|
874
|
+
eval(fiber): Primitive | Yield {
|
|
875
|
+
const value = this[args]()
|
|
876
|
+
const cont = fiber.getCont(successCont)
|
|
877
|
+
return cont ? cont[successCont](value, fiber) : fiber.yieldWith(exitSucceed(value))
|
|
878
|
+
}
|
|
879
|
+
})
|
|
539
880
|
|
|
540
881
|
/**
|
|
541
|
-
*
|
|
882
|
+
* Lazily creates a `Micro` effect from the given side-effect.
|
|
883
|
+
*
|
|
884
|
+
* @since 3.4.0
|
|
542
885
|
* @experimental
|
|
543
|
-
* @category
|
|
886
|
+
* @category constructors
|
|
544
887
|
*/
|
|
545
|
-
export const
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
888
|
+
export const suspend: <A, E, R>(evaluate: LazyArg<Micro<A, E, R>>) => Micro<A, E, R> = makePrimitive({
|
|
889
|
+
op: "Suspend",
|
|
890
|
+
eval(_fiber) {
|
|
891
|
+
return this[args]()
|
|
892
|
+
}
|
|
893
|
+
})
|
|
550
894
|
|
|
551
895
|
/**
|
|
896
|
+
* Pause the execution of the current `Micro` effect, and resume it on the next
|
|
897
|
+
* scheduler tick.
|
|
898
|
+
*
|
|
552
899
|
* @since 3.4.0
|
|
553
900
|
* @experimental
|
|
554
|
-
* @category
|
|
901
|
+
* @category constructors
|
|
555
902
|
*/
|
|
556
|
-
export const
|
|
903
|
+
export const yieldNowWith: (priority?: number) => Micro<void> = makePrimitive({
|
|
904
|
+
op: "Yield",
|
|
905
|
+
eval(fiber) {
|
|
906
|
+
let resumed = false
|
|
907
|
+
fiber.getRef(CurrentScheduler).scheduleTask(() => {
|
|
908
|
+
if (resumed) return
|
|
909
|
+
fiber.evaluate(exitVoid as any)
|
|
910
|
+
}, this[args] ?? 0)
|
|
911
|
+
return fiber.yieldWith(() => {
|
|
912
|
+
resumed = true
|
|
913
|
+
})
|
|
914
|
+
}
|
|
915
|
+
})
|
|
557
916
|
|
|
558
917
|
/**
|
|
918
|
+
* Pause the execution of the current `Micro` effect, and resume it on the next
|
|
919
|
+
* scheduler tick.
|
|
920
|
+
*
|
|
559
921
|
* @since 3.4.0
|
|
560
922
|
* @experimental
|
|
561
|
-
* @category
|
|
923
|
+
* @category constructors
|
|
562
924
|
*/
|
|
563
|
-
export
|
|
925
|
+
export const yieldNow: Micro<void> = yieldNowWith(0)
|
|
564
926
|
|
|
565
927
|
/**
|
|
566
|
-
*
|
|
928
|
+
* Creates a `Micro` effect that will succeed with `Option.Some` of the value.
|
|
929
|
+
*
|
|
930
|
+
* @since 3.4.0
|
|
567
931
|
* @experimental
|
|
568
|
-
* @category
|
|
932
|
+
* @category constructors
|
|
569
933
|
*/
|
|
570
|
-
export
|
|
571
|
-
readonly [EnvTypeId]: {
|
|
572
|
-
_R: Covariant<R>
|
|
573
|
-
}
|
|
574
|
-
readonly refs: ReadonlyRecord<string, unknown>
|
|
575
|
-
}
|
|
576
|
-
|
|
577
|
-
const EnvProto = {
|
|
578
|
-
[EnvTypeId]: {
|
|
579
|
-
_R: identity
|
|
580
|
-
},
|
|
581
|
-
pipe() {
|
|
582
|
-
return pipeArguments(this, arguments)
|
|
583
|
-
}
|
|
584
|
-
}
|
|
934
|
+
export const succeedSome = <A>(a: A): Micro<Option.Option<A>> => succeed(Option.some(a))
|
|
585
935
|
|
|
586
936
|
/**
|
|
937
|
+
* Creates a `Micro` effect that will succeed with `Option.None`.
|
|
938
|
+
*
|
|
587
939
|
* @since 3.4.0
|
|
588
940
|
* @experimental
|
|
589
|
-
* @category
|
|
941
|
+
* @category constructors
|
|
590
942
|
*/
|
|
591
|
-
export const
|
|
592
|
-
refs: Record<string, unknown>
|
|
593
|
-
): Env<R> => {
|
|
594
|
-
const self = Object.create(EnvProto)
|
|
595
|
-
self.refs = refs
|
|
596
|
-
return self
|
|
597
|
-
}
|
|
943
|
+
export const succeedNone: Micro<Option.Option<never>> = succeed(Option.none())
|
|
598
944
|
|
|
599
945
|
/**
|
|
946
|
+
* Creates a `Micro` effect that will fail with the lazily evaluated `MicroCause`.
|
|
947
|
+
*
|
|
600
948
|
* @since 3.4.0
|
|
601
949
|
* @experimental
|
|
602
|
-
* @category
|
|
950
|
+
* @category constructors
|
|
603
951
|
*/
|
|
604
|
-
export const
|
|
605
|
-
|
|
606
|
-
const refs = Object.create(null)
|
|
607
|
-
refs[currentAbortController.key] = controller
|
|
608
|
-
refs[currentAbortSignal.key] = controller.signal
|
|
609
|
-
refs[currentScheduler.key] = new MicroSchedulerDefault()
|
|
610
|
-
return envMake(refs)
|
|
611
|
-
}
|
|
952
|
+
export const failCauseSync = <E>(evaluate: LazyArg<MicroCause<E>>): Micro<never, E> =>
|
|
953
|
+
suspend(() => failCause(evaluate()))
|
|
612
954
|
|
|
613
955
|
/**
|
|
956
|
+
* Creates a `Micro` effect that will die with the specified error.
|
|
957
|
+
*
|
|
958
|
+
* This will result in a `CauseDie`, where the error is not tracked at
|
|
959
|
+
* the type level.
|
|
960
|
+
*
|
|
614
961
|
* @since 3.4.0
|
|
615
962
|
* @experimental
|
|
616
|
-
* @category
|
|
963
|
+
* @category constructors
|
|
617
964
|
*/
|
|
618
|
-
export const
|
|
619
|
-
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
624
|
-
|
|
625
|
-
|
|
626
|
-
|
|
627
|
-
|
|
628
|
-
|
|
629
|
-
|
|
630
|
-
|
|
631
|
-
} = dual(2, <R, A>(self: Env<R>, ref: EnvRef<A>): A => ref.key in self.refs ? (self.refs[ref.key] as A) : ref.initial)
|
|
965
|
+
export const die = (defect: unknown): Micro<never> => exitDie(defect)
|
|
966
|
+
|
|
967
|
+
/**
|
|
968
|
+
* Creates a `Micro` effect that will fail with the lazily evaluated error.
|
|
969
|
+
*
|
|
970
|
+
* This will result in a `CauseFail`, where the error is tracked at the
|
|
971
|
+
* type level.
|
|
972
|
+
*
|
|
973
|
+
* @since 3.4.6
|
|
974
|
+
* @experimental
|
|
975
|
+
* @category constructors
|
|
976
|
+
*/
|
|
977
|
+
export const failSync = <E>(error: LazyArg<E>): Micro<never, E> => suspend(() => fail(error()))
|
|
632
978
|
|
|
633
979
|
/**
|
|
980
|
+
* Converts an `Option` into a `Micro` effect, that will fail with
|
|
981
|
+
* `NoSuchElementException` if the option is `None`. Otherwise, it will succeed with the
|
|
982
|
+
* value of the option.
|
|
983
|
+
*
|
|
634
984
|
* @since 3.4.0
|
|
635
985
|
* @experimental
|
|
636
|
-
* @category
|
|
986
|
+
* @category constructors
|
|
637
987
|
*/
|
|
638
|
-
export const
|
|
639
|
-
|
|
640
|
-
* @since 3.4.0
|
|
641
|
-
* @experimental
|
|
642
|
-
* @category environment
|
|
643
|
-
*/
|
|
644
|
-
<A>(ref: EnvRef<A>, value: A): <R>(self: Env<R>) => Env<R>
|
|
645
|
-
/**
|
|
646
|
-
* @since 3.4.0
|
|
647
|
-
* @experimental
|
|
648
|
-
* @category environment
|
|
649
|
-
*/
|
|
650
|
-
<A, R>(self: Env<R>, ref: EnvRef<A>, value: A): Env<R>
|
|
651
|
-
} = dual(3, <R, A>(self: Env<R>, ref: EnvRef<A>, value: A): Env<R> => {
|
|
652
|
-
const refs = Object.assign(Object.create(null), self.refs)
|
|
653
|
-
refs[ref.key] = value
|
|
654
|
-
return envMake(refs)
|
|
655
|
-
})
|
|
988
|
+
export const fromOption = <A>(option: Option.Option<A>): Micro<A, NoSuchElementException> =>
|
|
989
|
+
option._tag === "Some" ? succeed(option.value) : fail(new NoSuchElementException({}))
|
|
656
990
|
|
|
657
991
|
/**
|
|
992
|
+
* Converts an `Either` into a `Micro` effect, that will fail with the left side
|
|
993
|
+
* of the either if it is a `Left`. Otherwise, it will succeed with the right
|
|
994
|
+
* side of the either.
|
|
995
|
+
*
|
|
658
996
|
* @since 3.4.0
|
|
659
997
|
* @experimental
|
|
660
|
-
* @category
|
|
998
|
+
* @category constructors
|
|
661
999
|
*/
|
|
662
|
-
export const
|
|
1000
|
+
export const fromEither = <R, L>(either: Either.Either<R, L>): Micro<R, L> =>
|
|
1001
|
+
either._tag === "Right" ? succeed(either.right) : fail(either.left)
|
|
1002
|
+
|
|
1003
|
+
const void_: Micro<void> = succeed(void 0)
|
|
1004
|
+
export {
|
|
663
1005
|
/**
|
|
1006
|
+
* A `Micro` effect that will succeed with `void` (`undefined`).
|
|
1007
|
+
*
|
|
664
1008
|
* @since 3.4.0
|
|
665
1009
|
* @experimental
|
|
666
|
-
* @category
|
|
1010
|
+
* @category constructors
|
|
667
1011
|
*/
|
|
668
|
-
|
|
1012
|
+
void_ as void
|
|
1013
|
+
}
|
|
1014
|
+
|
|
1015
|
+
const try_ = <A, E>(options: {
|
|
1016
|
+
try: LazyArg<A>
|
|
1017
|
+
catch: (error: unknown) => E
|
|
1018
|
+
}): Micro<A, E> =>
|
|
1019
|
+
suspend(() => {
|
|
1020
|
+
try {
|
|
1021
|
+
return succeed(options.try())
|
|
1022
|
+
} catch (err) {
|
|
1023
|
+
return fail(options.catch(err))
|
|
1024
|
+
}
|
|
1025
|
+
})
|
|
1026
|
+
export {
|
|
669
1027
|
/**
|
|
1028
|
+
* The `Micro` equivalent of a try / catch block, which allows you to map
|
|
1029
|
+
* thrown errors to a specific error type.
|
|
1030
|
+
*
|
|
670
1031
|
* @since 3.4.0
|
|
671
1032
|
* @experimental
|
|
672
|
-
* @category
|
|
1033
|
+
* @category constructors
|
|
1034
|
+
* @example
|
|
1035
|
+
* ```ts
|
|
1036
|
+
* import { Micro } from "effect"
|
|
1037
|
+
*
|
|
1038
|
+
* Micro.try({
|
|
1039
|
+
* try: () => throw new Error("boom"),
|
|
1040
|
+
* catch: (cause) => new Error("caught", { cause })
|
|
1041
|
+
* })
|
|
1042
|
+
* ```
|
|
673
1043
|
*/
|
|
674
|
-
|
|
675
|
-
}
|
|
676
|
-
2,
|
|
677
|
-
<R>(self: Env<R>, f: (map: Record<string, unknown>) => ReadonlyRecord<string, unknown>): Env<R> =>
|
|
678
|
-
envMake(f(Object.assign(Object.create(null), self.refs)))
|
|
679
|
-
)
|
|
1044
|
+
try_ as try
|
|
1045
|
+
}
|
|
680
1046
|
|
|
681
1047
|
/**
|
|
682
|
-
*
|
|
1048
|
+
* Wrap a `Promise` into a `Micro` effect. Any errors will result in a
|
|
1049
|
+
* `CauseDie`.
|
|
683
1050
|
*
|
|
684
1051
|
* @since 3.4.0
|
|
685
1052
|
* @experimental
|
|
686
|
-
* @category
|
|
1053
|
+
* @category constructors
|
|
687
1054
|
*/
|
|
688
|
-
export const
|
|
689
|
-
|
|
690
|
-
|
|
691
|
-
|
|
1055
|
+
export const promise = <A>(evaluate: (signal: AbortSignal) => PromiseLike<A>): Micro<A> =>
|
|
1056
|
+
asyncOptions<A>(function(resume, signal) {
|
|
1057
|
+
evaluate(signal!).then(
|
|
1058
|
+
(a) => resume(succeed(a)),
|
|
1059
|
+
(e) => resume(die(e))
|
|
1060
|
+
)
|
|
1061
|
+
}, evaluate.length !== 0)
|
|
692
1062
|
|
|
693
1063
|
/**
|
|
694
|
-
*
|
|
695
|
-
*
|
|
1064
|
+
* Wrap a `Promise` into a `Micro` effect. Any errors will be caught and
|
|
1065
|
+
* converted into a specific error type.
|
|
696
1066
|
*
|
|
697
|
-
*
|
|
698
|
-
*
|
|
1067
|
+
* @since 3.4.0
|
|
1068
|
+
* @experimental
|
|
1069
|
+
* @category constructors
|
|
1070
|
+
* @example
|
|
1071
|
+
* ```ts
|
|
1072
|
+
* import { Micro } from "effect"
|
|
1073
|
+
*
|
|
1074
|
+
* Micro.tryPromise({
|
|
1075
|
+
* try: () => Promise.resolve("success"),
|
|
1076
|
+
* catch: (cause) => new Error("caught", { cause })
|
|
1077
|
+
* })
|
|
1078
|
+
* ```
|
|
1079
|
+
*/
|
|
1080
|
+
export const tryPromise = <A, E>(options: {
|
|
1081
|
+
readonly try: (signal: AbortSignal) => PromiseLike<A>
|
|
1082
|
+
readonly catch: (error: unknown) => E
|
|
1083
|
+
}): Micro<A, E> =>
|
|
1084
|
+
asyncOptions<A, E>(function(resume, signal) {
|
|
1085
|
+
try {
|
|
1086
|
+
options.try(signal!).then(
|
|
1087
|
+
(a) => resume(succeed(a)),
|
|
1088
|
+
(e) => resume(fail(options.catch(e)))
|
|
1089
|
+
)
|
|
1090
|
+
} catch (err) {
|
|
1091
|
+
resume(fail(options.catch(err)))
|
|
1092
|
+
}
|
|
1093
|
+
}, options.try.length !== 0)
|
|
1094
|
+
|
|
1095
|
+
/**
|
|
1096
|
+
* Create a `Micro` effect using the current `Fiber`.
|
|
699
1097
|
*
|
|
700
1098
|
* @since 3.4.0
|
|
701
1099
|
* @experimental
|
|
702
|
-
* @category
|
|
1100
|
+
* @category constructors
|
|
703
1101
|
*/
|
|
704
|
-
export const
|
|
705
|
-
|
|
706
|
-
|
|
707
|
-
|
|
1102
|
+
export const withFiber: <A, E = never, R = never>(
|
|
1103
|
+
evaluate: (fiber: FiberImpl<A, E>) => Micro<A, E, R>
|
|
1104
|
+
) => Micro<A, E, R> = makePrimitive({
|
|
1105
|
+
op: "WithFiber",
|
|
1106
|
+
eval(fiber) {
|
|
1107
|
+
return this[args](fiber)
|
|
1108
|
+
}
|
|
1109
|
+
})
|
|
708
1110
|
|
|
709
1111
|
/**
|
|
710
|
-
*
|
|
1112
|
+
* Flush any yielded effects that are waiting to be executed.
|
|
711
1113
|
*
|
|
712
1114
|
* @since 3.4.0
|
|
713
1115
|
* @experimental
|
|
714
|
-
* @category
|
|
1116
|
+
* @category constructors
|
|
715
1117
|
*/
|
|
716
|
-
export const
|
|
717
|
-
|
|
1118
|
+
export const yieldFlush: Micro<void> = withFiber((fiber) => {
|
|
1119
|
+
fiber.getRef(CurrentScheduler).flush()
|
|
1120
|
+
return exitVoid
|
|
1121
|
+
})
|
|
1122
|
+
|
|
1123
|
+
const asyncOptions: <A, E = never, R = never>(
|
|
1124
|
+
register: (
|
|
1125
|
+
resume: (effect: Micro<A, E, R>) => void,
|
|
1126
|
+
signal?: AbortSignal
|
|
1127
|
+
) => void | Micro<void, never, R>,
|
|
1128
|
+
withSignal: boolean
|
|
1129
|
+
) => Micro<A, E, R> = makePrimitive({
|
|
1130
|
+
op: "Async",
|
|
1131
|
+
single: false,
|
|
1132
|
+
eval(fiber) {
|
|
1133
|
+
const register = this[args][0]
|
|
1134
|
+
let resumed = false
|
|
1135
|
+
let yielded: boolean | Primitive = false
|
|
1136
|
+
const controller = this[args][1] ? new AbortController() : undefined
|
|
1137
|
+
const onCancel = register((effect) => {
|
|
1138
|
+
if (resumed) return
|
|
1139
|
+
resumed = true
|
|
1140
|
+
if (yielded) {
|
|
1141
|
+
fiber.evaluate(effect as any)
|
|
1142
|
+
} else {
|
|
1143
|
+
yielded = effect as any
|
|
1144
|
+
}
|
|
1145
|
+
}, controller?.signal)
|
|
1146
|
+
if (yielded !== false) return yielded
|
|
1147
|
+
yielded = true
|
|
1148
|
+
fiber._yielded = () => {
|
|
1149
|
+
resumed = true
|
|
1150
|
+
}
|
|
1151
|
+
if (controller === undefined && onCancel === undefined) {
|
|
1152
|
+
return Yield
|
|
1153
|
+
}
|
|
1154
|
+
fiber._stack.push(asyncFinalizer(() => {
|
|
1155
|
+
resumed = true
|
|
1156
|
+
controller?.abort()
|
|
1157
|
+
return onCancel ?? exitVoid
|
|
1158
|
+
}))
|
|
1159
|
+
return Yield
|
|
1160
|
+
}
|
|
1161
|
+
})
|
|
1162
|
+
const asyncFinalizer: (onInterrupt: () => Micro<void, any, any>) => Primitive = makePrimitive({
|
|
1163
|
+
op: "AsyncFinalizer",
|
|
1164
|
+
ensure(fiber) {
|
|
1165
|
+
if (fiber.interruptible) {
|
|
1166
|
+
fiber.interruptible = false
|
|
1167
|
+
fiber._stack.push(setInterruptible(true))
|
|
1168
|
+
}
|
|
1169
|
+
},
|
|
1170
|
+
contE(cause, _fiber) {
|
|
1171
|
+
return causeIsInterrupt(cause)
|
|
1172
|
+
? flatMap(this[args](), () => failCause(cause))
|
|
1173
|
+
: failCause(cause)
|
|
1174
|
+
}
|
|
1175
|
+
})
|
|
718
1176
|
|
|
719
1177
|
/**
|
|
720
|
-
*
|
|
1178
|
+
* Create a `Micro` effect from an asynchronous computation.
|
|
1179
|
+
*
|
|
1180
|
+
* You can return a cleanup effect that will be run when the effect is aborted.
|
|
1181
|
+
* It is also passed an `AbortSignal` that is triggered when the effect is
|
|
1182
|
+
* aborted.
|
|
721
1183
|
*
|
|
722
1184
|
* @since 3.4.0
|
|
723
1185
|
* @experimental
|
|
724
|
-
* @category
|
|
1186
|
+
* @category constructors
|
|
725
1187
|
*/
|
|
726
|
-
export const
|
|
727
|
-
|
|
728
|
-
|
|
729
|
-
|
|
730
|
-
|
|
731
|
-
|
|
732
|
-
* @category environment
|
|
733
|
-
*/
|
|
734
|
-
<A>(fiberRef: EnvRef<A>, value: A): <XA, E, R>(self: Micro<XA, E, R>) => Micro<XA, E, R>
|
|
735
|
-
/**
|
|
736
|
-
* Set the value of the given `EnvRef` for the duration of the effect.
|
|
737
|
-
*
|
|
738
|
-
* @since 3.4.0
|
|
739
|
-
* @experimental
|
|
740
|
-
* @category environment
|
|
741
|
-
*/
|
|
742
|
-
<XA, E, R, A>(self: Micro<XA, E, R>, fiberRef: EnvRef<A>, value: A): Micro<XA, E, R>
|
|
743
|
-
} = dual(
|
|
744
|
-
3,
|
|
745
|
-
<XA, E, R, A>(self: Micro<XA, E, R>, fiberRef: EnvRef<A>, value: A): Micro<XA, E, R> =>
|
|
746
|
-
make((env, onExit) => self[runSymbol](envSet(env, fiberRef, value), onExit))
|
|
747
|
-
)
|
|
1188
|
+
export const async = <A, E = never, R = never>(
|
|
1189
|
+
register: (
|
|
1190
|
+
resume: (effect: Micro<A, E, R>) => void,
|
|
1191
|
+
signal: AbortSignal
|
|
1192
|
+
) => void | Micro<void, never, R>
|
|
1193
|
+
): Micro<A, E, R> => asyncOptions(register as any, register.length >= 2)
|
|
748
1194
|
|
|
749
1195
|
/**
|
|
750
|
-
*
|
|
1196
|
+
* A `Micro` that will never succeed or fail. It wraps `setInterval` to prevent
|
|
1197
|
+
* the Javascript runtime from exiting.
|
|
751
1198
|
*
|
|
752
1199
|
* @since 3.4.0
|
|
753
1200
|
* @experimental
|
|
754
|
-
* @category
|
|
1201
|
+
* @category constructors
|
|
755
1202
|
*/
|
|
756
|
-
export const
|
|
1203
|
+
export const never: Micro<never> = async<never>(function() {
|
|
1204
|
+
const interval = setInterval(constVoid, 2147483646)
|
|
1205
|
+
return sync(() => clearInterval(interval))
|
|
1206
|
+
})
|
|
757
1207
|
|
|
758
1208
|
/**
|
|
759
|
-
*
|
|
1209
|
+
* @since 3.4.0
|
|
1210
|
+
* @experimental
|
|
1211
|
+
* @category constructors
|
|
1212
|
+
*/
|
|
1213
|
+
export const gen = <Self, Eff extends YieldWrap<Micro<any, any, any>>, AEff>(
|
|
1214
|
+
...args:
|
|
1215
|
+
| [self: Self, body: (this: Self) => Generator<Eff, AEff, never>]
|
|
1216
|
+
| [body: () => Generator<Eff, AEff, never>]
|
|
1217
|
+
): Micro<
|
|
1218
|
+
AEff,
|
|
1219
|
+
[Eff] extends [never] ? never : [Eff] extends [YieldWrap<Micro<infer _A, infer E, infer _R>>] ? E : never,
|
|
1220
|
+
[Eff] extends [never] ? never : [Eff] extends [YieldWrap<Micro<infer _A, infer _E, infer R>>] ? R : never
|
|
1221
|
+
> => suspend(() => fromIterator(args.length === 1 ? args[0]() : args[1].call(args[0]) as any))
|
|
1222
|
+
|
|
1223
|
+
const fromIterator: (
|
|
1224
|
+
iterator: Iterator<any, YieldWrap<Micro<any, any, any>>>
|
|
1225
|
+
) => Micro<any, any, any> = makePrimitive({
|
|
1226
|
+
op: "Iterator",
|
|
1227
|
+
contA(value, fiber) {
|
|
1228
|
+
const state = this[args].next(value)
|
|
1229
|
+
if (state.done) return succeed(state.value)
|
|
1230
|
+
fiber._stack.push(this)
|
|
1231
|
+
return yieldWrapGet(state.value)
|
|
1232
|
+
},
|
|
1233
|
+
eval(this: any, fiber: FiberImpl) {
|
|
1234
|
+
return this[successCont](undefined, fiber)
|
|
1235
|
+
}
|
|
1236
|
+
})
|
|
1237
|
+
|
|
1238
|
+
// ----------------------------------------------------------------------------
|
|
1239
|
+
// mapping & sequencing
|
|
1240
|
+
// ----------------------------------------------------------------------------
|
|
1241
|
+
|
|
1242
|
+
/**
|
|
1243
|
+
* Create a `Micro` effect that will replace the success value of the given
|
|
1244
|
+
* effect.
|
|
760
1245
|
*
|
|
761
1246
|
* @since 3.4.0
|
|
762
1247
|
* @experimental
|
|
763
|
-
* @category
|
|
1248
|
+
* @category mapping & sequencing
|
|
764
1249
|
*/
|
|
765
|
-
export const
|
|
1250
|
+
export const as: {
|
|
1251
|
+
// ----------------------------------------------------------------------------
|
|
1252
|
+
// mapping & sequencing
|
|
1253
|
+
// ----------------------------------------------------------------------------
|
|
1254
|
+
|
|
766
1255
|
/**
|
|
767
|
-
*
|
|
1256
|
+
* Create a `Micro` effect that will replace the success value of the given
|
|
1257
|
+
* effect.
|
|
768
1258
|
*
|
|
769
1259
|
* @since 3.4.0
|
|
770
1260
|
* @experimental
|
|
771
|
-
* @category
|
|
1261
|
+
* @category mapping & sequencing
|
|
772
1262
|
*/
|
|
773
|
-
<
|
|
1263
|
+
<A, B>(value: B): <E, R>(self: Micro<A, E, R>) => Micro<B, E, R>
|
|
1264
|
+
// ----------------------------------------------------------------------------
|
|
1265
|
+
// mapping & sequencing
|
|
1266
|
+
// ----------------------------------------------------------------------------
|
|
1267
|
+
|
|
774
1268
|
/**
|
|
775
|
-
*
|
|
1269
|
+
* Create a `Micro` effect that will replace the success value of the given
|
|
1270
|
+
* effect.
|
|
776
1271
|
*
|
|
777
1272
|
* @since 3.4.0
|
|
778
1273
|
* @experimental
|
|
779
|
-
* @category
|
|
1274
|
+
* @category mapping & sequencing
|
|
780
1275
|
*/
|
|
781
|
-
<A, E, R,
|
|
782
|
-
} = dual(
|
|
783
|
-
2,
|
|
784
|
-
<A, E, R, XR>(self: Micro<A, E, R>, provided: Context.Context<XR>): Micro<A, E, Exclude<R, XR>> =>
|
|
785
|
-
make(function(env, onExit) {
|
|
786
|
-
const context = envGet(env, currentContext)
|
|
787
|
-
const nextEnv = envSet(env, currentContext, Context.merge(context, provided))
|
|
788
|
-
self[runSymbol](nextEnv, onExit)
|
|
789
|
-
})
|
|
790
|
-
)
|
|
1276
|
+
<A, E, R, B>(self: Micro<A, E, R>, value: B): Micro<B, E, R>
|
|
1277
|
+
} = dual(2, <A, E, R, B>(self: Micro<A, E, R>, value: B): Micro<B, E, R> => map(self, (_) => value))
|
|
791
1278
|
|
|
792
1279
|
/**
|
|
793
|
-
*
|
|
1280
|
+
* Wrap the success value of this `Micro` effect in an `Option.Some`.
|
|
794
1281
|
*
|
|
795
1282
|
* @since 3.4.0
|
|
796
1283
|
* @experimental
|
|
797
|
-
* @category
|
|
1284
|
+
* @category mapping & sequencing
|
|
798
1285
|
*/
|
|
799
|
-
export const
|
|
1286
|
+
export const asSome = <A, E, R>(self: Micro<A, E, R>): Micro<Option.Option<A>, E, R> => map(self, Option.some)
|
|
1287
|
+
|
|
1288
|
+
/**
|
|
1289
|
+
* Swap the error and success types of the `Micro` effect.
|
|
1290
|
+
*
|
|
1291
|
+
* @since 3.4.0
|
|
1292
|
+
* @experimental
|
|
1293
|
+
* @category mapping & sequencing
|
|
1294
|
+
*/
|
|
1295
|
+
export const flip = <A, E, R>(self: Micro<A, E, R>): Micro<E, A, R> =>
|
|
1296
|
+
matchEffect(self, {
|
|
1297
|
+
onFailure: succeed,
|
|
1298
|
+
onSuccess: fail
|
|
1299
|
+
})
|
|
1300
|
+
|
|
1301
|
+
/**
|
|
1302
|
+
* A more flexible version of `flatMap`, that combines `map` and `flatMap` into
|
|
1303
|
+
* a single api.
|
|
1304
|
+
*
|
|
1305
|
+
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1306
|
+
* executed after the current effect.
|
|
1307
|
+
*
|
|
1308
|
+
* @since 3.4.0
|
|
1309
|
+
* @experimental
|
|
1310
|
+
* @category mapping & sequencing
|
|
1311
|
+
*/
|
|
1312
|
+
export const andThen: {
|
|
800
1313
|
/**
|
|
801
|
-
*
|
|
1314
|
+
* A more flexible version of `flatMap`, that combines `map` and `flatMap` into
|
|
1315
|
+
* a single api.
|
|
1316
|
+
*
|
|
1317
|
+
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1318
|
+
* executed after the current effect.
|
|
802
1319
|
*
|
|
803
1320
|
* @since 3.4.0
|
|
804
1321
|
* @experimental
|
|
805
|
-
* @category
|
|
1322
|
+
* @category mapping & sequencing
|
|
806
1323
|
*/
|
|
807
|
-
<
|
|
1324
|
+
<A, X>(f: (a: A) => X): <E, R>(
|
|
1325
|
+
self: Micro<A, E, R>
|
|
1326
|
+
) => [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
|
|
1327
|
+
: Micro<X, E, R>
|
|
808
1328
|
/**
|
|
809
|
-
*
|
|
1329
|
+
* A more flexible version of `flatMap`, that combines `map` and `flatMap` into
|
|
1330
|
+
* a single api.
|
|
1331
|
+
*
|
|
1332
|
+
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1333
|
+
* executed after the current effect.
|
|
810
1334
|
*
|
|
811
1335
|
* @since 3.4.0
|
|
812
1336
|
* @experimental
|
|
813
|
-
* @category
|
|
1337
|
+
* @category mapping & sequencing
|
|
814
1338
|
*/
|
|
815
|
-
<
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
make(function(env, onExit) {
|
|
820
|
-
const context = envGet(env, currentContext)
|
|
821
|
-
const nextEnv = envSet(env, currentContext, Context.add(context, tag, service))
|
|
822
|
-
self[runSymbol](nextEnv, onExit)
|
|
823
|
-
})
|
|
824
|
-
)
|
|
825
|
-
|
|
826
|
-
/**
|
|
827
|
-
* Create a service using the provided `Micro` effect, and add it to the
|
|
828
|
-
* current context.
|
|
829
|
-
*
|
|
830
|
-
* @since 3.4.6
|
|
831
|
-
* @experimental
|
|
832
|
-
* @category environment
|
|
833
|
-
*/
|
|
834
|
-
export const provideServiceEffect: {
|
|
1339
|
+
<X>(f: NotFunction<X>): <A, E, R>(
|
|
1340
|
+
self: Micro<A, E, R>
|
|
1341
|
+
) => [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
|
|
1342
|
+
: Micro<X, E, R>
|
|
835
1343
|
/**
|
|
836
|
-
*
|
|
837
|
-
*
|
|
1344
|
+
* A more flexible version of `flatMap`, that combines `map` and `flatMap` into
|
|
1345
|
+
* a single api.
|
|
838
1346
|
*
|
|
839
|
-
*
|
|
1347
|
+
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1348
|
+
* executed after the current effect.
|
|
1349
|
+
*
|
|
1350
|
+
* @since 3.4.0
|
|
840
1351
|
* @experimental
|
|
841
|
-
* @category
|
|
1352
|
+
* @category mapping & sequencing
|
|
842
1353
|
*/
|
|
843
|
-
<
|
|
844
|
-
|
|
845
|
-
|
|
846
|
-
):
|
|
1354
|
+
<A, E, R, X>(
|
|
1355
|
+
self: Micro<A, E, R>,
|
|
1356
|
+
f: (a: A) => X
|
|
1357
|
+
): [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
|
|
1358
|
+
: Micro<X, E, R>
|
|
847
1359
|
/**
|
|
848
|
-
*
|
|
849
|
-
*
|
|
1360
|
+
* A more flexible version of `flatMap`, that combines `map` and `flatMap` into
|
|
1361
|
+
* a single api.
|
|
850
1362
|
*
|
|
851
|
-
*
|
|
1363
|
+
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1364
|
+
* executed after the current effect.
|
|
1365
|
+
*
|
|
1366
|
+
* @since 3.4.0
|
|
852
1367
|
* @experimental
|
|
853
|
-
* @category
|
|
1368
|
+
* @category mapping & sequencing
|
|
854
1369
|
*/
|
|
855
|
-
<A, E, R,
|
|
1370
|
+
<A, E, R, X>(
|
|
856
1371
|
self: Micro<A, E, R>,
|
|
857
|
-
|
|
858
|
-
|
|
859
|
-
|
|
1372
|
+
f: NotFunction<X>
|
|
1373
|
+
): [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
|
|
1374
|
+
: Micro<X, E, R>
|
|
860
1375
|
} = dual(
|
|
861
|
-
|
|
862
|
-
<A, E, R,
|
|
863
|
-
self
|
|
864
|
-
|
|
865
|
-
|
|
866
|
-
|
|
1376
|
+
2,
|
|
1377
|
+
<A, E, R, B, E2, R2>(self: Micro<A, E, R>, f: any): Micro<B, E | E2, R | R2> =>
|
|
1378
|
+
flatMap(self, (a) => {
|
|
1379
|
+
const value = isMicro(f) ? f : typeof f === "function" ? f(a) : f
|
|
1380
|
+
return isMicro(value) ? value : succeed(value)
|
|
1381
|
+
})
|
|
867
1382
|
)
|
|
868
1383
|
|
|
869
|
-
// ----------------------------------------------------------------------------
|
|
870
|
-
// scheduler
|
|
871
|
-
// ----------------------------------------------------------------------------
|
|
872
|
-
|
|
873
|
-
/**
|
|
874
|
-
* @since 3.5.9
|
|
875
|
-
* @experimental
|
|
876
|
-
* @category scheduler
|
|
877
|
-
*/
|
|
878
|
-
export interface MicroScheduler {
|
|
879
|
-
readonly scheduleTask: (task: () => void, priority: number) => void
|
|
880
|
-
readonly shouldYield: (env: Env<unknown>) => boolean
|
|
881
|
-
readonly flush: () => void
|
|
882
|
-
}
|
|
883
|
-
|
|
884
|
-
const setImmediate = "setImmediate" in globalThis ? globalThis.setImmediate : (f: () => void) => setTimeout(f, 0)
|
|
885
|
-
|
|
886
1384
|
/**
|
|
887
|
-
*
|
|
1385
|
+
* Execute a side effect from the success value of the `Micro` effect.
|
|
1386
|
+
*
|
|
1387
|
+
* It is similar to the `andThen` api, but the success value is ignored.
|
|
1388
|
+
*
|
|
1389
|
+
* @since 3.4.0
|
|
888
1390
|
* @experimental
|
|
889
|
-
* @category
|
|
1391
|
+
* @category mapping & sequencing
|
|
890
1392
|
*/
|
|
891
|
-
export
|
|
892
|
-
private tasks: Array<() => void> = []
|
|
893
|
-
private running = false
|
|
894
|
-
|
|
895
|
-
/**
|
|
896
|
-
* @since 3.5.9
|
|
897
|
-
*/
|
|
898
|
-
scheduleTask(task: () => void, _priority: number) {
|
|
899
|
-
this.tasks.push(task)
|
|
900
|
-
if (!this.running) {
|
|
901
|
-
this.running = true
|
|
902
|
-
setImmediate(this.afterScheduled)
|
|
903
|
-
}
|
|
904
|
-
}
|
|
905
|
-
|
|
906
|
-
/**
|
|
907
|
-
* @since 3.5.9
|
|
908
|
-
*/
|
|
909
|
-
afterScheduled = () => {
|
|
910
|
-
this.running = false
|
|
911
|
-
this.runTasks()
|
|
912
|
-
}
|
|
913
|
-
|
|
914
|
-
/**
|
|
915
|
-
* @since 3.5.9
|
|
916
|
-
*/
|
|
917
|
-
runTasks() {
|
|
918
|
-
const tasks = this.tasks
|
|
919
|
-
this.tasks = []
|
|
920
|
-
for (let i = 0, len = tasks.length; i < len; i++) {
|
|
921
|
-
tasks[i]()
|
|
922
|
-
}
|
|
923
|
-
}
|
|
924
|
-
|
|
1393
|
+
export const tap: {
|
|
925
1394
|
/**
|
|
926
|
-
*
|
|
1395
|
+
* Execute a side effect from the success value of the `Micro` effect.
|
|
1396
|
+
*
|
|
1397
|
+
* It is similar to the `andThen` api, but the success value is ignored.
|
|
1398
|
+
*
|
|
1399
|
+
* @since 3.4.0
|
|
1400
|
+
* @experimental
|
|
1401
|
+
* @category mapping & sequencing
|
|
927
1402
|
*/
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
1403
|
+
<A, X>(f: (a: NoInfer<A>) => X): <E, R>(
|
|
1404
|
+
self: Micro<A, E, R>
|
|
1405
|
+
) => [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
|
|
1406
|
+
: Micro<A, E, R>
|
|
932
1407
|
/**
|
|
933
|
-
*
|
|
1408
|
+
* Execute a side effect from the success value of the `Micro` effect.
|
|
1409
|
+
*
|
|
1410
|
+
* It is similar to the `andThen` api, but the success value is ignored.
|
|
1411
|
+
*
|
|
1412
|
+
* @since 3.4.0
|
|
1413
|
+
* @experimental
|
|
1414
|
+
* @category mapping & sequencing
|
|
934
1415
|
*/
|
|
935
|
-
|
|
936
|
-
|
|
937
|
-
|
|
938
|
-
|
|
939
|
-
}
|
|
940
|
-
}
|
|
941
|
-
|
|
942
|
-
// ========================================================================
|
|
943
|
-
// Env refs
|
|
944
|
-
// ========================================================================
|
|
945
|
-
|
|
946
|
-
/**
|
|
947
|
-
* @since 3.4.0
|
|
948
|
-
* @experimental
|
|
949
|
-
* @category environment
|
|
950
|
-
*/
|
|
951
|
-
export const EnvRefTypeId: unique symbol = Symbol.for("effect/Micro/EnvRef")
|
|
952
|
-
|
|
953
|
-
/**
|
|
954
|
-
* @since 3.4.0
|
|
955
|
-
* @experimental
|
|
956
|
-
* @category environment
|
|
957
|
-
*/
|
|
958
|
-
export type EnvRefTypeId = typeof EnvRefTypeId
|
|
959
|
-
|
|
960
|
-
/**
|
|
961
|
-
* @since 3.4.0
|
|
962
|
-
* @experimental
|
|
963
|
-
* @category environment
|
|
964
|
-
*/
|
|
965
|
-
export interface EnvRef<A> extends Micro<A> {
|
|
966
|
-
readonly [EnvRefTypeId]: EnvRefTypeId
|
|
967
|
-
readonly key: string
|
|
968
|
-
readonly initial: A
|
|
969
|
-
|
|
970
|
-
[Unify.typeSymbol]?: unknown
|
|
971
|
-
[Unify.unifySymbol]?: EnvRefUnify<this>
|
|
972
|
-
[Unify.ignoreSymbol]?: EnvRefUnifyIgnore
|
|
973
|
-
}
|
|
974
|
-
|
|
975
|
-
/**
|
|
976
|
-
* @category models
|
|
977
|
-
* @since 3.8.4
|
|
978
|
-
* @experimental
|
|
979
|
-
*/
|
|
980
|
-
export interface EnvRefUnify<A extends { [Unify.typeSymbol]?: any }> extends MicroUnify<A> {
|
|
981
|
-
EnvRef?: () => A[Unify.typeSymbol] extends EnvRef<infer A0> | infer _ ? EnvRef<A0> : never
|
|
982
|
-
}
|
|
983
|
-
|
|
984
|
-
/**
|
|
985
|
-
* @category models
|
|
986
|
-
* @since 3.8.4
|
|
987
|
-
* @experimental
|
|
988
|
-
*/
|
|
989
|
-
export interface EnvRefUnifyIgnore extends MicroUnifyIgnore {
|
|
990
|
-
Micro?: true
|
|
991
|
-
}
|
|
992
|
-
|
|
993
|
-
const EnvRefProto: ThisType<EnvRef<any>> = {
|
|
994
|
-
...MicroProto,
|
|
995
|
-
[EnvRefTypeId]: EnvRefTypeId,
|
|
996
|
-
[runSymbol](env: Env<any>, onExit: (exit: MicroExit<any, any>) => void) {
|
|
997
|
-
getEnvRef(this)[runSymbol](env, onExit)
|
|
998
|
-
}
|
|
999
|
-
}
|
|
1000
|
-
|
|
1001
|
-
/**
|
|
1002
|
-
* @since 3.4.0
|
|
1003
|
-
* @experimental
|
|
1004
|
-
* @category environment refs
|
|
1005
|
-
*/
|
|
1006
|
-
export const envRefMake = <A>(key: string, initial: LazyArg<A>): EnvRef<A> =>
|
|
1007
|
-
globalValue(key, () => {
|
|
1008
|
-
const self = Object.create(EnvRefProto)
|
|
1009
|
-
self.key = key
|
|
1010
|
-
self.initial = initial()
|
|
1011
|
-
return self
|
|
1012
|
-
})
|
|
1013
|
-
|
|
1014
|
-
/**
|
|
1015
|
-
* @since 3.4.0
|
|
1016
|
-
* @experimental
|
|
1017
|
-
* @category environment refs
|
|
1018
|
-
*/
|
|
1019
|
-
export const currentAbortController: EnvRef<AbortController> = envRefMake(
|
|
1020
|
-
"effect/Micro/currentAbortController",
|
|
1021
|
-
() => undefined as any
|
|
1022
|
-
)
|
|
1023
|
-
|
|
1024
|
-
/**
|
|
1025
|
-
* @since 3.4.0
|
|
1026
|
-
* @experimental
|
|
1027
|
-
* @category environment refs
|
|
1028
|
-
*/
|
|
1029
|
-
export const currentAbortSignal: EnvRef<AbortSignal> = envRefMake(
|
|
1030
|
-
"effect/Micro/currentAbortSignal",
|
|
1031
|
-
() => undefined as any
|
|
1032
|
-
)
|
|
1033
|
-
|
|
1034
|
-
/**
|
|
1035
|
-
* @since 3.4.0
|
|
1036
|
-
* @experimental
|
|
1037
|
-
* @category environment refs
|
|
1038
|
-
*/
|
|
1039
|
-
export const currentContext: EnvRef<Context.Context<never>> = envRefMake(
|
|
1040
|
-
"effect/Micro/currentContext",
|
|
1041
|
-
() => Context.empty()
|
|
1042
|
-
)
|
|
1043
|
-
|
|
1044
|
-
/**
|
|
1045
|
-
* @since 3.4.0
|
|
1046
|
-
* @experimental
|
|
1047
|
-
* @category environment refs
|
|
1048
|
-
*/
|
|
1049
|
-
export const currentConcurrency: EnvRef<"unbounded" | number> = envRefMake(
|
|
1050
|
-
"effect/Micro/currentConcurrency",
|
|
1051
|
-
() => "unbounded"
|
|
1052
|
-
)
|
|
1053
|
-
|
|
1054
|
-
/**
|
|
1055
|
-
* @since 3.4.0
|
|
1056
|
-
* @experimental
|
|
1057
|
-
* @category environment refs
|
|
1058
|
-
*/
|
|
1059
|
-
export const currentMaxDepthBeforeYield: EnvRef<number> = envRefMake(
|
|
1060
|
-
"effect/Micro/currentMaxDepthBeforeYield",
|
|
1061
|
-
() => 2048
|
|
1062
|
-
)
|
|
1063
|
-
|
|
1064
|
-
const currentInterruptible: EnvRef<boolean> = envRefMake(
|
|
1065
|
-
"effect/Micro/currentInterruptible",
|
|
1066
|
-
() => true
|
|
1067
|
-
)
|
|
1068
|
-
|
|
1069
|
-
/**
|
|
1070
|
-
* @since 3.4.0
|
|
1071
|
-
* @experimental
|
|
1072
|
-
* @category environment refs
|
|
1073
|
-
*/
|
|
1074
|
-
export const currentScheduler: EnvRef<MicroScheduler> = envRefMake(
|
|
1075
|
-
"effect/Micro/currentScheduler",
|
|
1076
|
-
() => new MicroSchedulerDefault()
|
|
1077
|
-
)
|
|
1078
|
-
|
|
1079
|
-
/**
|
|
1080
|
-
* If you have a `Micro` that uses `concurrency: "inherit"`, you can use this
|
|
1081
|
-
* api to control the concurrency of that `Micro` when it is run.
|
|
1082
|
-
*
|
|
1083
|
-
* @since 3.4.0
|
|
1084
|
-
* @experimental
|
|
1085
|
-
* @category environment refs
|
|
1086
|
-
* @example
|
|
1087
|
-
* import * as Micro from "effect/Micro"
|
|
1088
|
-
*
|
|
1089
|
-
* Micro.forEach([1, 2, 3], (n) => Micro.succeed(n), {
|
|
1090
|
-
* concurrency: "inherit"
|
|
1091
|
-
* }).pipe(
|
|
1092
|
-
* Micro.withConcurrency(2) // use a concurrency of 2
|
|
1093
|
-
* )
|
|
1094
|
-
*/
|
|
1095
|
-
export const withConcurrency: {
|
|
1416
|
+
<X>(f: NotFunction<X>): <A, E, R>(
|
|
1417
|
+
self: Micro<A, E, R>
|
|
1418
|
+
) => [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
|
|
1419
|
+
: Micro<A, E, R>
|
|
1096
1420
|
/**
|
|
1097
|
-
*
|
|
1098
|
-
*
|
|
1421
|
+
* Execute a side effect from the success value of the `Micro` effect.
|
|
1422
|
+
*
|
|
1423
|
+
* It is similar to the `andThen` api, but the success value is ignored.
|
|
1099
1424
|
*
|
|
1100
1425
|
* @since 3.4.0
|
|
1101
1426
|
* @experimental
|
|
1102
|
-
* @category
|
|
1103
|
-
* @example
|
|
1104
|
-
* import * as Micro from "effect/Micro"
|
|
1105
|
-
*
|
|
1106
|
-
* Micro.forEach([1, 2, 3], (n) => Micro.succeed(n), {
|
|
1107
|
-
* concurrency: "inherit"
|
|
1108
|
-
* }).pipe(
|
|
1109
|
-
* Micro.withConcurrency(2) // use a concurrency of 2
|
|
1110
|
-
* )
|
|
1427
|
+
* @category mapping & sequencing
|
|
1111
1428
|
*/
|
|
1112
|
-
|
|
1429
|
+
<A, E, R, X>(
|
|
1430
|
+
self: Micro<A, E, R>,
|
|
1431
|
+
f: (a: NoInfer<A>) => X
|
|
1432
|
+
): [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
|
|
1433
|
+
: Micro<A, E, R>
|
|
1113
1434
|
/**
|
|
1114
|
-
*
|
|
1115
|
-
*
|
|
1435
|
+
* Execute a side effect from the success value of the `Micro` effect.
|
|
1436
|
+
*
|
|
1437
|
+
* It is similar to the `andThen` api, but the success value is ignored.
|
|
1116
1438
|
*
|
|
1117
1439
|
* @since 3.4.0
|
|
1118
1440
|
* @experimental
|
|
1119
|
-
* @category
|
|
1120
|
-
* @example
|
|
1121
|
-
* import * as Micro from "effect/Micro"
|
|
1122
|
-
*
|
|
1123
|
-
* Micro.forEach([1, 2, 3], (n) => Micro.succeed(n), {
|
|
1124
|
-
* concurrency: "inherit"
|
|
1125
|
-
* }).pipe(
|
|
1126
|
-
* Micro.withConcurrency(2) // use a concurrency of 2
|
|
1127
|
-
* )
|
|
1441
|
+
* @category mapping & sequencing
|
|
1128
1442
|
*/
|
|
1129
|
-
<A, E, R
|
|
1443
|
+
<A, E, R, X>(
|
|
1444
|
+
self: Micro<A, E, R>,
|
|
1445
|
+
f: NotFunction<X>
|
|
1446
|
+
): [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
|
|
1447
|
+
: Micro<A, E, R>
|
|
1130
1448
|
} = dual(
|
|
1131
1449
|
2,
|
|
1132
|
-
<A, E, R>(self: Micro<A, E, R>,
|
|
1133
|
-
|
|
1450
|
+
<A, E, R, B, E2, R2>(self: Micro<A, E, R>, f: (a: A) => Micro<B, E2, R2>): Micro<A, E | E2, R | R2> =>
|
|
1451
|
+
flatMap(self, (a) => {
|
|
1452
|
+
const value = isMicro(f) ? f : typeof f === "function" ? f(a) : f
|
|
1453
|
+
return isMicro(value) ? as(value, a) : succeed(a)
|
|
1454
|
+
})
|
|
1134
1455
|
)
|
|
1135
1456
|
|
|
1136
|
-
// ----------------------------------------------------------------------------
|
|
1137
|
-
// constructors
|
|
1138
|
-
// ----------------------------------------------------------------------------
|
|
1139
|
-
|
|
1140
|
-
const microDepthState = globalValue("effect/Micro/microDepthState", () => ({
|
|
1141
|
-
depth: 0,
|
|
1142
|
-
maxDepthBeforeYield: currentMaxDepthBeforeYield.initial
|
|
1143
|
-
}))
|
|
1144
|
-
|
|
1145
|
-
const unsafeMake = <R, A, E>(
|
|
1146
|
-
run: (env: Env<R>, onExit: (exit: MicroExit<A, E>) => void) => void
|
|
1147
|
-
): Micro<A, E, R> => {
|
|
1148
|
-
const self = Object.create(MicroProto)
|
|
1149
|
-
self[runSymbol] = run
|
|
1150
|
-
return self
|
|
1151
|
-
}
|
|
1152
|
-
|
|
1153
|
-
const unsafeMakeOptions = <R, A, E>(
|
|
1154
|
-
run: (env: Env<R>, onExit: (exit: MicroExit<A, E>) => void) => void,
|
|
1155
|
-
checkAbort: boolean
|
|
1156
|
-
): Micro<A, E, R> =>
|
|
1157
|
-
unsafeMake(function execute(env, onExit) {
|
|
1158
|
-
if (
|
|
1159
|
-
checkAbort && env.refs[currentInterruptible.key] !== false &&
|
|
1160
|
-
(env.refs[currentAbortSignal.key] as AbortSignal).aborted
|
|
1161
|
-
) {
|
|
1162
|
-
return onExit(exitInterrupt)
|
|
1163
|
-
}
|
|
1164
|
-
microDepthState.depth++
|
|
1165
|
-
if (microDepthState.depth === 1) {
|
|
1166
|
-
microDepthState.maxDepthBeforeYield = envGet(env, currentMaxDepthBeforeYield)
|
|
1167
|
-
}
|
|
1168
|
-
const scheduler = env.refs[currentScheduler.key] as MicroScheduler
|
|
1169
|
-
if (microDepthState.depth >= microDepthState.maxDepthBeforeYield || scheduler.shouldYield(env)) {
|
|
1170
|
-
scheduler.scheduleTask(() => execute(env, onExit), 0)
|
|
1171
|
-
} else {
|
|
1172
|
-
try {
|
|
1173
|
-
run(env, onExit)
|
|
1174
|
-
} catch (err) {
|
|
1175
|
-
onExit(exitDie(err))
|
|
1176
|
-
}
|
|
1177
|
-
}
|
|
1178
|
-
microDepthState.depth--
|
|
1179
|
-
})
|
|
1180
|
-
|
|
1181
1457
|
/**
|
|
1182
|
-
*
|
|
1183
|
-
* that receives an environment and a callback which should be called with the
|
|
1184
|
-
* result of the effect.
|
|
1458
|
+
* Replace the success value of the `Micro` effect with `void`.
|
|
1185
1459
|
*
|
|
1186
1460
|
* @since 3.4.0
|
|
1187
1461
|
* @experimental
|
|
1188
|
-
* @category
|
|
1462
|
+
* @category mapping & sequencing
|
|
1189
1463
|
*/
|
|
1190
|
-
export const
|
|
1191
|
-
run: (env: Env<R>, onExit: (exit: MicroExit<A, E>) => void) => void
|
|
1192
|
-
): Micro<A, E, R> => unsafeMakeOptions(run, true)
|
|
1464
|
+
export const asVoid = <A, E, R>(self: Micro<A, E, R>): Micro<void, E, R> => flatMap(self, (_) => exitVoid)
|
|
1193
1465
|
|
|
1194
1466
|
/**
|
|
1195
|
-
*
|
|
1467
|
+
* Access the `MicroExit` of the given `Micro` effect.
|
|
1196
1468
|
*
|
|
1197
1469
|
* @since 3.4.6
|
|
1198
1470
|
* @experimental
|
|
1199
|
-
* @category
|
|
1471
|
+
* @category mapping & sequencing
|
|
1200
1472
|
*/
|
|
1201
|
-
export const
|
|
1202
|
-
|
|
1203
|
-
|
|
1473
|
+
export const exit = <A, E, R>(self: Micro<A, E, R>): Micro<MicroExit<A, E>, never, R> =>
|
|
1474
|
+
matchCause(self, {
|
|
1475
|
+
onFailure: exitFailCause,
|
|
1476
|
+
onSuccess: exitSucceed
|
|
1204
1477
|
})
|
|
1205
1478
|
|
|
1206
1479
|
/**
|
|
1207
|
-
*
|
|
1480
|
+
* Replace the error type of the given `Micro` with the full `MicroCause` object.
|
|
1208
1481
|
*
|
|
1209
|
-
* @since 3.4.
|
|
1482
|
+
* @since 3.4.0
|
|
1210
1483
|
* @experimental
|
|
1211
|
-
* @category
|
|
1484
|
+
* @category mapping & sequencing
|
|
1212
1485
|
*/
|
|
1213
|
-
export const
|
|
1214
|
-
make(function(_env, onExit) {
|
|
1215
|
-
onExit(self())
|
|
1216
|
-
})
|
|
1486
|
+
export const sandbox = <A, E, R>(self: Micro<A, E, R>): Micro<A, MicroCause<E>, R> => catchAllCause(self, fail)
|
|
1217
1487
|
|
|
1218
1488
|
/**
|
|
1219
|
-
*
|
|
1489
|
+
* Returns an effect that races all the specified effects,
|
|
1490
|
+
* yielding the value of the first effect to succeed with a value. Losers of
|
|
1491
|
+
* the race will be interrupted immediately
|
|
1220
1492
|
*
|
|
1221
1493
|
* @since 3.4.0
|
|
1222
1494
|
* @experimental
|
|
1223
|
-
* @category
|
|
1495
|
+
* @category sequencing
|
|
1224
1496
|
*/
|
|
1225
|
-
export const
|
|
1497
|
+
export const raceAll = <Eff extends Micro<any, any, any>>(
|
|
1498
|
+
all: Iterable<Eff>
|
|
1499
|
+
): Micro<Micro.Success<Eff>, Micro.Error<Eff>, Micro.Context<Eff>> =>
|
|
1500
|
+
withFiber((parent) =>
|
|
1501
|
+
async((resume) => {
|
|
1502
|
+
const effects = Arr.fromIterable(all)
|
|
1503
|
+
const len = effects.length
|
|
1504
|
+
let doneCount = 0
|
|
1505
|
+
let done = false
|
|
1506
|
+
const fibers = new Set<Fiber<any, any>>()
|
|
1507
|
+
const causes: Array<MicroCause<any>> = []
|
|
1508
|
+
const onExit = (exit: MicroExit<any, any>) => {
|
|
1509
|
+
doneCount++
|
|
1510
|
+
if (exit._tag === "Failure") {
|
|
1511
|
+
causes.push(exit.cause)
|
|
1512
|
+
if (doneCount >= len) {
|
|
1513
|
+
resume(failCause(causes[0]))
|
|
1514
|
+
}
|
|
1515
|
+
return
|
|
1516
|
+
}
|
|
1517
|
+
done = true
|
|
1518
|
+
resume(fibers.size === 0 ? exit : flatMap(uninterruptible(fiberInterruptAll(fibers)), () => exit))
|
|
1519
|
+
}
|
|
1520
|
+
|
|
1521
|
+
for (let i = 0; i < len; i++) {
|
|
1522
|
+
if (done) break
|
|
1523
|
+
const fiber = unsafeFork(parent, interruptible(effects[i]), true, true)
|
|
1524
|
+
fibers.add(fiber)
|
|
1525
|
+
fiber.addObserver((exit) => {
|
|
1526
|
+
fibers.delete(fiber)
|
|
1527
|
+
onExit(exit)
|
|
1528
|
+
})
|
|
1529
|
+
}
|
|
1530
|
+
|
|
1531
|
+
return fiberInterruptAll(fibers)
|
|
1532
|
+
})
|
|
1533
|
+
)
|
|
1226
1534
|
|
|
1227
1535
|
/**
|
|
1228
|
-
*
|
|
1536
|
+
* Returns an effect that races all the specified effects,
|
|
1537
|
+
* yielding the value of the first effect to succeed or fail. Losers of
|
|
1538
|
+
* the race will be interrupted immediately
|
|
1229
1539
|
*
|
|
1230
1540
|
* @since 3.4.0
|
|
1231
1541
|
* @experimental
|
|
1232
|
-
* @category
|
|
1542
|
+
* @category sequencing
|
|
1233
1543
|
*/
|
|
1234
|
-
export const
|
|
1544
|
+
export const raceAllFirst = <Eff extends Micro<any, any, any>>(
|
|
1545
|
+
all: Iterable<Eff>
|
|
1546
|
+
): Micro<Micro.Success<Eff>, Micro.Error<Eff>, Micro.Context<Eff>> =>
|
|
1547
|
+
withFiber((parent) =>
|
|
1548
|
+
async((resume) => {
|
|
1549
|
+
let done = false
|
|
1550
|
+
const fibers = new Set<Fiber<any, any>>()
|
|
1551
|
+
const onExit = (exit: MicroExit<any, any>) => {
|
|
1552
|
+
done = true
|
|
1553
|
+
resume(fibers.size === 0 ? exit : flatMap(fiberInterruptAll(fibers), () => exit))
|
|
1554
|
+
}
|
|
1555
|
+
|
|
1556
|
+
for (const effect of all) {
|
|
1557
|
+
if (done) break
|
|
1558
|
+
const fiber = unsafeFork(parent, interruptible(effect), true, true)
|
|
1559
|
+
fibers.add(fiber)
|
|
1560
|
+
fiber.addObserver((exit) => {
|
|
1561
|
+
fibers.delete(fiber)
|
|
1562
|
+
onExit(exit)
|
|
1563
|
+
})
|
|
1564
|
+
}
|
|
1565
|
+
|
|
1566
|
+
return fiberInterruptAll(fibers)
|
|
1567
|
+
})
|
|
1568
|
+
)
|
|
1235
1569
|
|
|
1236
1570
|
/**
|
|
1237
|
-
*
|
|
1571
|
+
* Returns an effect that races two effects, yielding the value of the first
|
|
1572
|
+
* effect to succeed. Losers of the race will be interrupted immediately
|
|
1238
1573
|
*
|
|
1239
1574
|
* @since 3.4.0
|
|
1240
1575
|
* @experimental
|
|
1241
|
-
* @category
|
|
1576
|
+
* @category sequencing
|
|
1242
1577
|
*/
|
|
1243
|
-
export const
|
|
1578
|
+
export const race: {
|
|
1579
|
+
/**
|
|
1580
|
+
* Returns an effect that races two effects, yielding the value of the first
|
|
1581
|
+
* effect to succeed. Losers of the race will be interrupted immediately
|
|
1582
|
+
*
|
|
1583
|
+
* @since 3.4.0
|
|
1584
|
+
* @experimental
|
|
1585
|
+
* @category sequencing
|
|
1586
|
+
*/
|
|
1587
|
+
<A2, E2, R2>(that: Micro<A2, E2, R2>): <A, E, R>(self: Micro<A, E, R>) => Micro<A | A2, E | E2, R | R2>
|
|
1588
|
+
/**
|
|
1589
|
+
* Returns an effect that races two effects, yielding the value of the first
|
|
1590
|
+
* effect to succeed. Losers of the race will be interrupted immediately
|
|
1591
|
+
*
|
|
1592
|
+
* @since 3.4.0
|
|
1593
|
+
* @experimental
|
|
1594
|
+
* @category sequencing
|
|
1595
|
+
*/
|
|
1596
|
+
<A, E, R, A2, E2, R2>(self: Micro<A, E, R>, that: Micro<A2, E2, R2>): Micro<A | A2, E | E2, R | R2>
|
|
1597
|
+
} = dual(
|
|
1598
|
+
2,
|
|
1599
|
+
<A, E, R, A2, E2, R2>(self: Micro<A, E, R>, that: Micro<A2, E2, R2>): Micro<A | A2, E | E2, R | R2> =>
|
|
1600
|
+
raceAll([self, that])
|
|
1601
|
+
)
|
|
1244
1602
|
|
|
1245
1603
|
/**
|
|
1246
|
-
*
|
|
1604
|
+
* Returns an effect that races two effects, yielding the value of the first
|
|
1605
|
+
* effect to succeed *or* fail. Losers of the race will be interrupted immediately
|
|
1247
1606
|
*
|
|
1248
|
-
*
|
|
1249
|
-
*
|
|
1607
|
+
* @since 3.4.0
|
|
1608
|
+
* @experimental
|
|
1609
|
+
* @category sequencing
|
|
1610
|
+
*/
|
|
1611
|
+
export const raceFirst: {
|
|
1612
|
+
/**
|
|
1613
|
+
* Returns an effect that races two effects, yielding the value of the first
|
|
1614
|
+
* effect to succeed *or* fail. Losers of the race will be interrupted immediately
|
|
1615
|
+
*
|
|
1616
|
+
* @since 3.4.0
|
|
1617
|
+
* @experimental
|
|
1618
|
+
* @category sequencing
|
|
1619
|
+
*/
|
|
1620
|
+
<A2, E2, R2>(that: Micro<A2, E2, R2>): <A, E, R>(self: Micro<A, E, R>) => Micro<A | A2, E | E2, R | R2>
|
|
1621
|
+
/**
|
|
1622
|
+
* Returns an effect that races two effects, yielding the value of the first
|
|
1623
|
+
* effect to succeed *or* fail. Losers of the race will be interrupted immediately
|
|
1624
|
+
*
|
|
1625
|
+
* @since 3.4.0
|
|
1626
|
+
* @experimental
|
|
1627
|
+
* @category sequencing
|
|
1628
|
+
*/
|
|
1629
|
+
<A, E, R, A2, E2, R2>(self: Micro<A, E, R>, that: Micro<A2, E2, R2>): Micro<A | A2, E | E2, R | R2>
|
|
1630
|
+
} = dual(
|
|
1631
|
+
2,
|
|
1632
|
+
<A, E, R, A2, E2, R2>(self: Micro<A, E, R>, that: Micro<A2, E2, R2>): Micro<A | A2, E | E2, R | R2> =>
|
|
1633
|
+
raceAllFirst([self, that])
|
|
1634
|
+
)
|
|
1635
|
+
|
|
1636
|
+
/**
|
|
1637
|
+
* Map the success value of this `Micro` effect to another `Micro` effect, then
|
|
1638
|
+
* flatten the result.
|
|
1250
1639
|
*
|
|
1251
1640
|
* @since 3.4.0
|
|
1252
1641
|
* @experimental
|
|
1253
|
-
* @category
|
|
1642
|
+
* @category mapping & sequencing
|
|
1254
1643
|
*/
|
|
1255
|
-
export const
|
|
1644
|
+
export const flatMap: {
|
|
1645
|
+
/**
|
|
1646
|
+
* Map the success value of this `Micro` effect to another `Micro` effect, then
|
|
1647
|
+
* flatten the result.
|
|
1648
|
+
*
|
|
1649
|
+
* @since 3.4.0
|
|
1650
|
+
* @experimental
|
|
1651
|
+
* @category mapping & sequencing
|
|
1652
|
+
*/
|
|
1653
|
+
<A, B, E2, R2>(f: (a: A) => Micro<B, E2, R2>): <E, R>(self: Micro<A, E, R>) => Micro<B, E | E2, R | R2>
|
|
1654
|
+
/**
|
|
1655
|
+
* Map the success value of this `Micro` effect to another `Micro` effect, then
|
|
1656
|
+
* flatten the result.
|
|
1657
|
+
*
|
|
1658
|
+
* @since 3.4.0
|
|
1659
|
+
* @experimental
|
|
1660
|
+
* @category mapping & sequencing
|
|
1661
|
+
*/
|
|
1662
|
+
<A, E, R, B, E2, R2>(self: Micro<A, E, R>, f: (a: A) => Micro<B, E2, R2>): Micro<B, E | E2, R | R2>
|
|
1663
|
+
} = dual(
|
|
1664
|
+
2,
|
|
1665
|
+
<A, E, R, B, E2, R2>(
|
|
1666
|
+
self: Micro<A, E, R>,
|
|
1667
|
+
f: (a: A) => Micro<B, E2, R2>
|
|
1668
|
+
): Micro<B, E | E2, R | R2> => {
|
|
1669
|
+
const onSuccess = Object.create(OnSuccessProto)
|
|
1670
|
+
onSuccess[args] = self
|
|
1671
|
+
onSuccess[successCont] = f
|
|
1672
|
+
return onSuccess
|
|
1673
|
+
}
|
|
1674
|
+
)
|
|
1675
|
+
const OnSuccessProto = makePrimitiveProto({
|
|
1676
|
+
op: "OnSuccess",
|
|
1677
|
+
eval(this: any, fiber: FiberImpl): Primitive {
|
|
1678
|
+
fiber._stack.push(this)
|
|
1679
|
+
return this[args]
|
|
1680
|
+
}
|
|
1681
|
+
})
|
|
1682
|
+
|
|
1683
|
+
// ----------------------------------------------------------------------------
|
|
1684
|
+
// mapping & sequencing
|
|
1685
|
+
// ----------------------------------------------------------------------------
|
|
1256
1686
|
|
|
1257
1687
|
/**
|
|
1258
|
-
*
|
|
1688
|
+
* Flattens any nested `Micro` effects, merging the error and requirement types.
|
|
1259
1689
|
*
|
|
1260
|
-
*
|
|
1261
|
-
*
|
|
1690
|
+
* @since 3.4.0
|
|
1691
|
+
* @experimental
|
|
1692
|
+
* @category mapping & sequencing
|
|
1693
|
+
*/
|
|
1694
|
+
export const flatten = <A, E, R, E2, R2>(
|
|
1695
|
+
self: Micro<Micro<A, E, R>, E2, R2>
|
|
1696
|
+
): Micro<A, E | E2, R | R2> => flatMap(self, identity)
|
|
1697
|
+
|
|
1698
|
+
/**
|
|
1699
|
+
* Transforms the success value of the `Micro` effect with the specified
|
|
1700
|
+
* function.
|
|
1262
1701
|
*
|
|
1263
1702
|
* @since 3.4.0
|
|
1264
1703
|
* @experimental
|
|
1265
|
-
* @category
|
|
1704
|
+
* @category mapping & sequencing
|
|
1266
1705
|
*/
|
|
1267
|
-
export const
|
|
1268
|
-
|
|
1269
|
-
|
|
1270
|
-
|
|
1706
|
+
export const map: {
|
|
1707
|
+
/**
|
|
1708
|
+
* Transforms the success value of the `Micro` effect with the specified
|
|
1709
|
+
* function.
|
|
1710
|
+
*
|
|
1711
|
+
* @since 3.4.0
|
|
1712
|
+
* @experimental
|
|
1713
|
+
* @category mapping & sequencing
|
|
1714
|
+
*/
|
|
1715
|
+
<A, B>(f: (a: A) => B): <E, R>(self: Micro<A, E, R>) => Micro<B, E, R>
|
|
1716
|
+
/**
|
|
1717
|
+
* Transforms the success value of the `Micro` effect with the specified
|
|
1718
|
+
* function.
|
|
1719
|
+
*
|
|
1720
|
+
* @since 3.4.0
|
|
1721
|
+
* @experimental
|
|
1722
|
+
* @category mapping & sequencing
|
|
1723
|
+
*/
|
|
1724
|
+
<A, E, R, B>(self: Micro<A, E, R>, f: (a: A) => B): Micro<B, E, R>
|
|
1725
|
+
} = dual(
|
|
1726
|
+
2,
|
|
1727
|
+
<A, E, R, B>(self: Micro<A, E, R>, f: (a: A) => B): Micro<B, E, R> => flatMap(self, (a) => succeed(f(a)))
|
|
1728
|
+
)
|
|
1729
|
+
|
|
1730
|
+
// ----------------------------------------------------------------------------
|
|
1731
|
+
// MicroExit
|
|
1732
|
+
// ----------------------------------------------------------------------------
|
|
1271
1733
|
|
|
1272
1734
|
/**
|
|
1273
|
-
*
|
|
1735
|
+
* The MicroExit type is a data type that represents the result of a Micro
|
|
1736
|
+
* computation.
|
|
1274
1737
|
*
|
|
1275
|
-
*
|
|
1276
|
-
* the type level.
|
|
1738
|
+
* It uses the `Either` data type to represent the success and failure cases.
|
|
1277
1739
|
*
|
|
1278
|
-
* @since 3.4.
|
|
1740
|
+
* @since 3.4.6
|
|
1279
1741
|
* @experimental
|
|
1280
|
-
* @category
|
|
1742
|
+
* @category MicroExit
|
|
1743
|
+
*/
|
|
1744
|
+
export type MicroExit<A, E = never> =
|
|
1745
|
+
| MicroExit.Success<A, E>
|
|
1746
|
+
| MicroExit.Failure<A, E>
|
|
1747
|
+
|
|
1748
|
+
/**
|
|
1749
|
+
* @since 3.4.6
|
|
1750
|
+
* @experimental
|
|
1751
|
+
* @category MicroExit
|
|
1281
1752
|
*/
|
|
1282
|
-
export
|
|
1753
|
+
export declare namespace MicroExit {
|
|
1754
|
+
/**
|
|
1755
|
+
* @since 3.4.6
|
|
1756
|
+
* @experimental
|
|
1757
|
+
* @category MicroExit
|
|
1758
|
+
*/
|
|
1759
|
+
export interface Proto<out A, out E = never> extends Micro<A, E> {
|
|
1760
|
+
readonly [MicroExitTypeId]: MicroExitTypeId
|
|
1761
|
+
}
|
|
1762
|
+
|
|
1763
|
+
/**
|
|
1764
|
+
* @since 3.4.6
|
|
1765
|
+
* @experimental
|
|
1766
|
+
* @category MicroExit
|
|
1767
|
+
*/
|
|
1768
|
+
export interface Success<out A, out E> extends Proto<A, E> {
|
|
1769
|
+
readonly _tag: "Success"
|
|
1770
|
+
readonly value: A
|
|
1771
|
+
}
|
|
1283
1772
|
|
|
1284
|
-
/**
|
|
1285
|
-
|
|
1286
|
-
|
|
1287
|
-
|
|
1288
|
-
|
|
1289
|
-
|
|
1290
|
-
|
|
1291
|
-
|
|
1773
|
+
/**
|
|
1774
|
+
* @since 3.4.6
|
|
1775
|
+
* @experimental
|
|
1776
|
+
* @category MicroExit
|
|
1777
|
+
*/
|
|
1778
|
+
export interface Failure<out A, out E> extends Proto<A, E> {
|
|
1779
|
+
readonly _tag: "Failure"
|
|
1780
|
+
readonly cause: MicroCause<E>
|
|
1781
|
+
}
|
|
1782
|
+
}
|
|
1292
1783
|
|
|
1293
1784
|
/**
|
|
1294
|
-
* Creates a `Micro` effect that will fail with the lazily evaluated `MicroCause`.
|
|
1295
|
-
*
|
|
1296
1785
|
* @since 3.4.6
|
|
1297
1786
|
* @experimental
|
|
1298
|
-
* @category
|
|
1787
|
+
* @category MicroExit
|
|
1299
1788
|
*/
|
|
1300
|
-
export const
|
|
1301
|
-
fromExitSync(() => exitFailCause(cause()))
|
|
1789
|
+
export const isMicroExit = (u: unknown): u is MicroExit<unknown, unknown> => hasProperty(u, MicroExitTypeId)
|
|
1302
1790
|
|
|
1303
1791
|
/**
|
|
1304
|
-
*
|
|
1305
|
-
*
|
|
1306
|
-
* If the evaluation of the value throws an error, the effect will fail with
|
|
1307
|
-
* `CauseDie`.
|
|
1308
|
-
*
|
|
1309
|
-
* @since 3.4.0
|
|
1792
|
+
* @since 3.4.6
|
|
1310
1793
|
* @experimental
|
|
1311
|
-
* @category
|
|
1794
|
+
* @category MicroExit
|
|
1312
1795
|
*/
|
|
1313
|
-
export const
|
|
1314
|
-
make(function(_env, onExit) {
|
|
1315
|
-
onExit(exitSucceed(evaluate()))
|
|
1316
|
-
})
|
|
1796
|
+
export const exitSucceed: <A>(a: A) => MicroExit<A, never> = succeed as any
|
|
1317
1797
|
|
|
1318
1798
|
/**
|
|
1319
|
-
*
|
|
1320
|
-
* `NoSuchElementException` if the option is `None`. Otherwise, it will succeed with the
|
|
1321
|
-
* value of the option.
|
|
1322
|
-
*
|
|
1323
|
-
* @since 3.4.0
|
|
1799
|
+
* @since 3.4.6
|
|
1324
1800
|
* @experimental
|
|
1325
|
-
* @category
|
|
1801
|
+
* @category MicroExit
|
|
1326
1802
|
*/
|
|
1327
|
-
export const
|
|
1328
|
-
make(function(_env, onExit) {
|
|
1329
|
-
onExit(option._tag === "Some" ? exitSucceed(option.value) : exitFail(new NoSuchElementException({})))
|
|
1330
|
-
})
|
|
1803
|
+
export const exitFailCause: <E>(cause: MicroCause<E>) => MicroExit<never, E> = failCause as any
|
|
1331
1804
|
|
|
1332
1805
|
/**
|
|
1333
|
-
*
|
|
1334
|
-
* of the either if it is a `Left`. Otherwise, it will succeed with the right
|
|
1335
|
-
* side of the either.
|
|
1336
|
-
*
|
|
1337
|
-
* @since 3.4.0
|
|
1806
|
+
* @since 3.4.6
|
|
1338
1807
|
* @experimental
|
|
1339
|
-
* @category
|
|
1808
|
+
* @category MicroExit
|
|
1340
1809
|
*/
|
|
1341
|
-
export const
|
|
1342
|
-
make(function(_env, onExit) {
|
|
1343
|
-
onExit(either._tag === "Right" ? either as MicroExit<R, never> : exitFail(either.left))
|
|
1344
|
-
})
|
|
1810
|
+
export const exitInterrupt: MicroExit<never> = exitFailCause(causeInterrupt())
|
|
1345
1811
|
|
|
1346
1812
|
/**
|
|
1347
|
-
*
|
|
1348
|
-
*
|
|
1349
|
-
* @since 3.4.0
|
|
1813
|
+
* @since 3.4.6
|
|
1350
1814
|
* @experimental
|
|
1351
|
-
* @category
|
|
1815
|
+
* @category MicroExit
|
|
1352
1816
|
*/
|
|
1353
|
-
export const
|
|
1354
|
-
make(function(env, onExit) {
|
|
1355
|
-
evaluate()[runSymbol](env, onExit)
|
|
1356
|
-
})
|
|
1357
|
-
|
|
1358
|
-
const void_: Micro<void> = succeed(void 0)
|
|
1359
|
-
export {
|
|
1360
|
-
/**
|
|
1361
|
-
* A `Micro` effect that will succeed with `void` (`undefined`).
|
|
1362
|
-
*
|
|
1363
|
-
* @since 3.4.0
|
|
1364
|
-
* @experimental
|
|
1365
|
-
* @category constructors
|
|
1366
|
-
*/
|
|
1367
|
-
void_ as void
|
|
1368
|
-
}
|
|
1817
|
+
export const exitFail = <E>(e: E): MicroExit<never, E> => exitFailCause(causeFail(e))
|
|
1369
1818
|
|
|
1370
1819
|
/**
|
|
1371
|
-
*
|
|
1372
|
-
*
|
|
1373
|
-
* You can return a cleanup effect that will be run when the effect is aborted.
|
|
1374
|
-
* It is also passed an `AbortSignal` that is triggered when the effect is
|
|
1375
|
-
* aborted.
|
|
1376
|
-
*
|
|
1377
|
-
* @since 3.4.0
|
|
1820
|
+
* @since 3.4.6
|
|
1378
1821
|
* @experimental
|
|
1379
|
-
* @category
|
|
1822
|
+
* @category MicroExit
|
|
1380
1823
|
*/
|
|
1381
|
-
export const
|
|
1382
|
-
register: (resume: (effect: Micro<A, E, R>) => void, signal: AbortSignal) => void | Micro<void, never, R>
|
|
1383
|
-
): Micro<A, E, R> =>
|
|
1384
|
-
make(function(env, onExit) {
|
|
1385
|
-
let resumed = false
|
|
1386
|
-
const controller = register.length > 1 ? new AbortController() : undefined
|
|
1387
|
-
const signal = envGet(env, currentAbortSignal)
|
|
1388
|
-
let cleanup: Micro<void, never, R> | void = undefined
|
|
1389
|
-
function onAbort() {
|
|
1390
|
-
if (cleanup) {
|
|
1391
|
-
resume(uninterruptible(andThen(cleanup, fromExit(exitInterrupt))))
|
|
1392
|
-
} else {
|
|
1393
|
-
resume(fromExit(exitInterrupt))
|
|
1394
|
-
}
|
|
1395
|
-
if (controller !== undefined) {
|
|
1396
|
-
controller.abort()
|
|
1397
|
-
}
|
|
1398
|
-
}
|
|
1399
|
-
function resume(effect: Micro<A, E, R>) {
|
|
1400
|
-
if (resumed) {
|
|
1401
|
-
return
|
|
1402
|
-
}
|
|
1403
|
-
resumed = true
|
|
1404
|
-
signal.removeEventListener("abort", onAbort)
|
|
1405
|
-
effect[runSymbol](env, onExit)
|
|
1406
|
-
}
|
|
1407
|
-
cleanup = controller === undefined
|
|
1408
|
-
? (register as any)(resume)
|
|
1409
|
-
: register(resume, controller.signal)
|
|
1410
|
-
if (resumed) return
|
|
1411
|
-
signal.addEventListener("abort", onAbort)
|
|
1412
|
-
})
|
|
1413
|
-
|
|
1414
|
-
const try_ = <A, E>(options: {
|
|
1415
|
-
try: LazyArg<A>
|
|
1416
|
-
catch: (error: unknown) => E
|
|
1417
|
-
}): Micro<A, E> =>
|
|
1418
|
-
make(function(_env, onExit) {
|
|
1419
|
-
try {
|
|
1420
|
-
onExit(exitSucceed(options.try()))
|
|
1421
|
-
} catch (err) {
|
|
1422
|
-
onExit(exitFail(options.catch(err)))
|
|
1423
|
-
}
|
|
1424
|
-
})
|
|
1425
|
-
export {
|
|
1426
|
-
/**
|
|
1427
|
-
* The `Micro` equivalent of a try / catch block, which allows you to map
|
|
1428
|
-
* thrown errors to a specific error type.
|
|
1429
|
-
*
|
|
1430
|
-
* @since 3.4.0
|
|
1431
|
-
* @experimental
|
|
1432
|
-
* @category constructors
|
|
1433
|
-
* @example
|
|
1434
|
-
* import { Micro } from "effect"
|
|
1435
|
-
*
|
|
1436
|
-
* Micro.try({
|
|
1437
|
-
* try: () => throw new Error("boom"),
|
|
1438
|
-
* catch: (cause) => new Error("caught", { cause })
|
|
1439
|
-
* })
|
|
1440
|
-
*/
|
|
1441
|
-
try_ as try
|
|
1442
|
-
}
|
|
1824
|
+
export const exitDie = (defect: unknown): MicroExit<never> => exitFailCause(causeDie(defect))
|
|
1443
1825
|
|
|
1444
1826
|
/**
|
|
1445
|
-
*
|
|
1446
|
-
* `CauseDie`.
|
|
1447
|
-
*
|
|
1448
|
-
* @since 3.4.0
|
|
1827
|
+
* @since 3.4.6
|
|
1449
1828
|
* @experimental
|
|
1450
|
-
* @category
|
|
1829
|
+
* @category MicroExit
|
|
1451
1830
|
*/
|
|
1452
|
-
export const
|
|
1453
|
-
|
|
1454
|
-
|
|
1455
|
-
(a) => resume(succeed(a)),
|
|
1456
|
-
(e) => resume(die(e))
|
|
1457
|
-
)
|
|
1458
|
-
})
|
|
1831
|
+
export const exitIsSuccess = <A, E>(
|
|
1832
|
+
self: MicroExit<A, E>
|
|
1833
|
+
): self is MicroExit.Success<A, E> => self._tag === "Success"
|
|
1459
1834
|
|
|
1460
1835
|
/**
|
|
1461
|
-
*
|
|
1462
|
-
* converted into a specific error type.
|
|
1463
|
-
*
|
|
1464
|
-
* @since 3.4.0
|
|
1836
|
+
* @since 3.4.6
|
|
1465
1837
|
* @experimental
|
|
1466
|
-
* @category
|
|
1467
|
-
* @example
|
|
1468
|
-
* import { Micro } from "effect"
|
|
1469
|
-
*
|
|
1470
|
-
* Micro.tryPromise({
|
|
1471
|
-
* try: () => Promise.resolve("success"),
|
|
1472
|
-
* catch: (cause) => new Error("caught", { cause })
|
|
1473
|
-
* })
|
|
1838
|
+
* @category MicroExit
|
|
1474
1839
|
*/
|
|
1475
|
-
export const
|
|
1476
|
-
|
|
1477
|
-
|
|
1478
|
-
}): Micro<A, E> =>
|
|
1479
|
-
async<A, E>(function(resume, signal) {
|
|
1480
|
-
try {
|
|
1481
|
-
options.try(signal).then(
|
|
1482
|
-
(a) => resume(succeed(a)),
|
|
1483
|
-
(e) => resume(fail(options.catch(e)))
|
|
1484
|
-
)
|
|
1485
|
-
} catch (err) {
|
|
1486
|
-
resume(fail(options.catch(err)))
|
|
1487
|
-
}
|
|
1488
|
-
})
|
|
1840
|
+
export const exitIsFailure = <A, E>(
|
|
1841
|
+
self: MicroExit<A, E>
|
|
1842
|
+
): self is MicroExit.Failure<A, E> => self._tag === "Failure"
|
|
1489
1843
|
|
|
1490
1844
|
/**
|
|
1491
|
-
*
|
|
1492
|
-
* iteration of the event loop.
|
|
1493
|
-
*
|
|
1494
|
-
* You can specify a priority for the task, which will determine when it is
|
|
1495
|
-
* executed relative to other tasks.
|
|
1496
|
-
*
|
|
1497
|
-
* @since 3.4.0
|
|
1845
|
+
* @since 3.4.6
|
|
1498
1846
|
* @experimental
|
|
1499
|
-
* @category
|
|
1847
|
+
* @category MicroExit
|
|
1500
1848
|
*/
|
|
1501
|
-
export const
|
|
1502
|
-
|
|
1503
|
-
|
|
1504
|
-
|
|
1849
|
+
export const exitIsInterrupt = <A, E>(
|
|
1850
|
+
self: MicroExit<A, E>
|
|
1851
|
+
): self is MicroExit.Failure<A, E> & {
|
|
1852
|
+
readonly cause: MicroCause.Interrupt
|
|
1853
|
+
} => exitIsFailure(self) && self.cause._tag === "Interrupt"
|
|
1505
1854
|
|
|
1506
1855
|
/**
|
|
1507
|
-
*
|
|
1508
|
-
* iteration of the event loop.
|
|
1509
|
-
*
|
|
1510
|
-
* @since 3.4.0
|
|
1856
|
+
* @since 3.4.6
|
|
1511
1857
|
* @experimental
|
|
1512
|
-
* @category
|
|
1858
|
+
* @category MicroExit
|
|
1513
1859
|
*/
|
|
1514
|
-
export const
|
|
1860
|
+
export const exitIsFail = <A, E>(
|
|
1861
|
+
self: MicroExit<A, E>
|
|
1862
|
+
): self is MicroExit.Failure<A, E> & {
|
|
1863
|
+
readonly cause: MicroCause.Fail<E>
|
|
1864
|
+
} => exitIsFailure(self) && self.cause._tag === "Fail"
|
|
1515
1865
|
|
|
1516
1866
|
/**
|
|
1517
|
-
*
|
|
1518
|
-
*
|
|
1519
|
-
* @since 3.4.0
|
|
1867
|
+
* @since 3.4.6
|
|
1520
1868
|
* @experimental
|
|
1521
|
-
* @category
|
|
1869
|
+
* @category MicroExit
|
|
1522
1870
|
*/
|
|
1523
|
-
export const
|
|
1524
|
-
|
|
1525
|
-
|
|
1526
|
-
|
|
1871
|
+
export const exitIsDie = <A, E>(
|
|
1872
|
+
self: MicroExit<A, E>
|
|
1873
|
+
): self is MicroExit.Failure<A, E> & {
|
|
1874
|
+
readonly cause: MicroCause.Die
|
|
1875
|
+
} => exitIsFailure(self) && self.cause._tag === "Die"
|
|
1527
1876
|
|
|
1528
1877
|
/**
|
|
1529
|
-
*
|
|
1530
|
-
* the Javascript runtime from exiting.
|
|
1531
|
-
*
|
|
1532
|
-
* @since 3.4.0
|
|
1878
|
+
* @since 3.4.6
|
|
1533
1879
|
* @experimental
|
|
1534
|
-
* @category
|
|
1880
|
+
* @category MicroExit
|
|
1535
1881
|
*/
|
|
1536
|
-
export const
|
|
1537
|
-
const interval = setInterval(constVoid, 2147483646)
|
|
1538
|
-
return sync(() => clearInterval(interval))
|
|
1539
|
-
})
|
|
1882
|
+
export const exitVoid: MicroExit<void> = exitSucceed(void 0)
|
|
1540
1883
|
|
|
1541
1884
|
/**
|
|
1542
|
-
* @since 3.
|
|
1885
|
+
* @since 3.11.0
|
|
1543
1886
|
* @experimental
|
|
1544
|
-
* @category
|
|
1887
|
+
* @category MicroExit
|
|
1545
1888
|
*/
|
|
1546
|
-
export const
|
|
1547
|
-
|
|
1548
|
-
|
|
1549
|
-
|
|
1550
|
-
)
|
|
1551
|
-
|
|
1552
|
-
[Eff] extends [never] ? never : [Eff] extends [YieldWrap<Micro<infer _A, infer E, infer _R>>] ? E : never,
|
|
1553
|
-
[Eff] extends [never] ? never : [Eff] extends [YieldWrap<Micro<infer _A, infer _E, infer R>>] ? R : never
|
|
1554
|
-
> =>
|
|
1555
|
-
make(function(env, onExit) {
|
|
1556
|
-
const iterator: Generator<Eff, AEff, any> = args.length === 1 ? args[0]() : args[1].call(args[0])
|
|
1557
|
-
let running = false
|
|
1558
|
-
let value: any = undefined
|
|
1559
|
-
function run() {
|
|
1560
|
-
running = true
|
|
1561
|
-
try {
|
|
1562
|
-
let shouldContinue = true
|
|
1563
|
-
while (shouldContinue) {
|
|
1564
|
-
const result = iterator.next(value)
|
|
1565
|
-
if (result.done) {
|
|
1566
|
-
return onExit(exitSucceed(result.value))
|
|
1567
|
-
}
|
|
1568
|
-
shouldContinue = false
|
|
1569
|
-
yieldWrapGet(result.value)[runSymbol](env, function(exit) {
|
|
1570
|
-
if (exit._tag === "Left") {
|
|
1571
|
-
onExit(exit)
|
|
1572
|
-
} else {
|
|
1573
|
-
shouldContinue = true
|
|
1574
|
-
value = exit.right
|
|
1575
|
-
if (!running) run()
|
|
1576
|
-
}
|
|
1577
|
-
})
|
|
1578
|
-
}
|
|
1579
|
-
} catch (err) {
|
|
1580
|
-
onExit(exitDie(err))
|
|
1581
|
-
}
|
|
1582
|
-
running = false
|
|
1889
|
+
export const exitVoidAll = <I extends Iterable<MicroExit<any, any>>>(
|
|
1890
|
+
exits: I
|
|
1891
|
+
): MicroExit<void, I extends Iterable<MicroExit<infer _A, infer _E>> ? _E : never> => {
|
|
1892
|
+
for (const exit of exits) {
|
|
1893
|
+
if (exit._tag === "Failure") {
|
|
1894
|
+
return exit
|
|
1583
1895
|
}
|
|
1584
|
-
|
|
1585
|
-
|
|
1896
|
+
}
|
|
1897
|
+
return exitVoid
|
|
1898
|
+
}
|
|
1586
1899
|
|
|
1587
1900
|
// ----------------------------------------------------------------------------
|
|
1588
|
-
//
|
|
1901
|
+
// scheduler
|
|
1589
1902
|
// ----------------------------------------------------------------------------
|
|
1590
1903
|
|
|
1591
1904
|
/**
|
|
1592
|
-
*
|
|
1593
|
-
*
|
|
1594
|
-
* @since 3.4.0
|
|
1905
|
+
* @since 3.5.9
|
|
1595
1906
|
* @experimental
|
|
1596
|
-
* @category
|
|
1907
|
+
* @category scheduler
|
|
1597
1908
|
*/
|
|
1598
|
-
export
|
|
1599
|
-
|
|
1600
|
-
|
|
1601
|
-
|
|
1602
|
-
|
|
1603
|
-
|
|
1604
|
-
|
|
1909
|
+
export interface MicroScheduler {
|
|
1910
|
+
readonly scheduleTask: (task: () => void, priority: number) => void
|
|
1911
|
+
readonly shouldYield: (fiber: Fiber<unknown, unknown>) => boolean
|
|
1912
|
+
readonly flush: () => void
|
|
1913
|
+
}
|
|
1914
|
+
|
|
1915
|
+
const setImmediate = "setImmediate" in globalThis
|
|
1916
|
+
? globalThis.setImmediate
|
|
1917
|
+
: (f: () => void) => setTimeout(f, 0)
|
|
1605
1918
|
|
|
1606
1919
|
/**
|
|
1607
|
-
*
|
|
1608
|
-
* function.
|
|
1609
|
-
*
|
|
1610
|
-
* @since 3.4.0
|
|
1920
|
+
* @since 3.5.9
|
|
1611
1921
|
* @experimental
|
|
1612
|
-
* @category
|
|
1922
|
+
* @category scheduler
|
|
1613
1923
|
*/
|
|
1614
|
-
export
|
|
1924
|
+
export class MicroSchedulerDefault implements MicroScheduler {
|
|
1925
|
+
private tasks: Array<() => void> = []
|
|
1926
|
+
private running = false
|
|
1927
|
+
|
|
1615
1928
|
/**
|
|
1616
|
-
*
|
|
1617
|
-
* function.
|
|
1618
|
-
*
|
|
1619
|
-
* @since 3.4.0
|
|
1620
|
-
* @experimental
|
|
1621
|
-
* @category mapping & sequencing
|
|
1929
|
+
* @since 3.5.9
|
|
1622
1930
|
*/
|
|
1623
|
-
|
|
1931
|
+
scheduleTask(task: () => void, _priority: number) {
|
|
1932
|
+
this.tasks.push(task)
|
|
1933
|
+
if (!this.running) {
|
|
1934
|
+
this.running = true
|
|
1935
|
+
setImmediate(this.afterScheduled)
|
|
1936
|
+
}
|
|
1937
|
+
}
|
|
1938
|
+
|
|
1624
1939
|
/**
|
|
1625
|
-
*
|
|
1626
|
-
* function.
|
|
1627
|
-
*
|
|
1628
|
-
* @since 3.4.0
|
|
1629
|
-
* @experimental
|
|
1630
|
-
* @category mapping & sequencing
|
|
1940
|
+
* @since 3.5.9
|
|
1631
1941
|
*/
|
|
1632
|
-
|
|
1633
|
-
|
|
1634
|
-
|
|
1635
|
-
|
|
1636
|
-
onExit(exit._tag === "Left" ? exit as MicroExit<never, E> : exitSucceed(f(exit.right)))
|
|
1637
|
-
})
|
|
1638
|
-
}))
|
|
1942
|
+
afterScheduled = () => {
|
|
1943
|
+
this.running = false
|
|
1944
|
+
this.runTasks()
|
|
1945
|
+
}
|
|
1639
1946
|
|
|
1640
|
-
/**
|
|
1641
|
-
* Create a `Micro` effect that will replace the success value of the given
|
|
1642
|
-
* effect.
|
|
1643
|
-
*
|
|
1644
|
-
* @since 3.4.0
|
|
1645
|
-
* @experimental
|
|
1646
|
-
* @category mapping & sequencing
|
|
1647
|
-
*/
|
|
1648
|
-
export const as: {
|
|
1649
1947
|
/**
|
|
1650
|
-
*
|
|
1651
|
-
* effect.
|
|
1652
|
-
*
|
|
1653
|
-
* @since 3.4.0
|
|
1654
|
-
* @experimental
|
|
1655
|
-
* @category mapping & sequencing
|
|
1948
|
+
* @since 3.5.9
|
|
1656
1949
|
*/
|
|
1657
|
-
|
|
1950
|
+
runTasks() {
|
|
1951
|
+
const tasks = this.tasks
|
|
1952
|
+
this.tasks = []
|
|
1953
|
+
for (let i = 0, len = tasks.length; i < len; i++) {
|
|
1954
|
+
tasks[i]()
|
|
1955
|
+
}
|
|
1956
|
+
}
|
|
1957
|
+
|
|
1658
1958
|
/**
|
|
1659
|
-
*
|
|
1660
|
-
* effect.
|
|
1661
|
-
*
|
|
1662
|
-
* @since 3.4.0
|
|
1663
|
-
* @experimental
|
|
1664
|
-
* @category mapping & sequencing
|
|
1959
|
+
* @since 3.5.9
|
|
1665
1960
|
*/
|
|
1666
|
-
|
|
1667
|
-
|
|
1961
|
+
shouldYield(fiber: Fiber<unknown, unknown>) {
|
|
1962
|
+
return fiber.currentOpCount >= fiber.getRef(MaxOpsBeforeYield)
|
|
1963
|
+
}
|
|
1668
1964
|
|
|
1669
|
-
/**
|
|
1670
|
-
|
|
1671
|
-
|
|
1672
|
-
|
|
1673
|
-
|
|
1674
|
-
|
|
1675
|
-
|
|
1676
|
-
|
|
1965
|
+
/**
|
|
1966
|
+
* @since 3.5.9
|
|
1967
|
+
*/
|
|
1968
|
+
flush() {
|
|
1969
|
+
while (this.tasks.length > 0) {
|
|
1970
|
+
this.runTasks()
|
|
1971
|
+
}
|
|
1972
|
+
}
|
|
1973
|
+
}
|
|
1677
1974
|
|
|
1678
1975
|
/**
|
|
1679
|
-
*
|
|
1680
|
-
* flatten the result.
|
|
1976
|
+
* Access the given `Context.Tag` from the environment.
|
|
1681
1977
|
*
|
|
1682
1978
|
* @since 3.4.0
|
|
1683
1979
|
* @experimental
|
|
1684
|
-
* @category
|
|
1980
|
+
* @category environment
|
|
1685
1981
|
*/
|
|
1686
|
-
export const
|
|
1982
|
+
export const service: {
|
|
1687
1983
|
/**
|
|
1688
|
-
*
|
|
1689
|
-
* flatten the result.
|
|
1984
|
+
* Access the given `Context.Tag` from the environment.
|
|
1690
1985
|
*
|
|
1691
1986
|
* @since 3.4.0
|
|
1692
1987
|
* @experimental
|
|
1693
|
-
* @category
|
|
1988
|
+
* @category environment
|
|
1694
1989
|
*/
|
|
1695
|
-
<
|
|
1990
|
+
<I, S>(tag: Context.Reference<I, S>): Micro<S>
|
|
1696
1991
|
/**
|
|
1697
|
-
*
|
|
1698
|
-
* flatten the result.
|
|
1992
|
+
* Access the given `Context.Tag` from the environment.
|
|
1699
1993
|
*
|
|
1700
1994
|
* @since 3.4.0
|
|
1701
1995
|
* @experimental
|
|
1702
|
-
* @category
|
|
1996
|
+
* @category environment
|
|
1703
1997
|
*/
|
|
1704
|
-
<
|
|
1705
|
-
} =
|
|
1706
|
-
|
|
1707
|
-
|
|
1708
|
-
make(function(env, onExit) {
|
|
1709
|
-
self[runSymbol](env, function(exit) {
|
|
1710
|
-
if (exit._tag === "Left") {
|
|
1711
|
-
return onExit(exit as MicroExit<never, E>)
|
|
1712
|
-
}
|
|
1713
|
-
f(exit.right)[runSymbol](env, onExit)
|
|
1714
|
-
})
|
|
1715
|
-
})
|
|
1716
|
-
)
|
|
1998
|
+
<I, S>(tag: Context.Tag<I, S>): Micro<S, never, I>
|
|
1999
|
+
} =
|
|
2000
|
+
(<I, S>(tag: Context.Tag<I, S>): Micro<S, never, I> =>
|
|
2001
|
+
withFiber((fiber) => succeed(Context.unsafeGet(fiber.context, tag)))) as any
|
|
1717
2002
|
|
|
1718
2003
|
/**
|
|
1719
|
-
*
|
|
2004
|
+
* Access the given `Context.Tag` from the environment, without tracking the
|
|
2005
|
+
* dependency at the type level.
|
|
2006
|
+
*
|
|
2007
|
+
* It will return an `Option` of the service, depending on whether it is
|
|
2008
|
+
* available in the environment or not.
|
|
1720
2009
|
*
|
|
1721
2010
|
* @since 3.4.0
|
|
1722
2011
|
* @experimental
|
|
1723
|
-
* @category
|
|
2012
|
+
* @category environment
|
|
1724
2013
|
*/
|
|
1725
|
-
export const
|
|
1726
|
-
|
|
1727
|
-
|
|
1728
|
-
onSuccess: fail
|
|
1729
|
-
})
|
|
2014
|
+
export const serviceOption = <I, S>(
|
|
2015
|
+
tag: Context.Tag<I, S>
|
|
2016
|
+
): Micro<Option.Option<S>> => withFiber((fiber) => succeed(Context.getOption(fiber.context, tag)))
|
|
1730
2017
|
|
|
1731
2018
|
/**
|
|
1732
|
-
*
|
|
1733
|
-
* a single api.
|
|
1734
|
-
*
|
|
1735
|
-
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1736
|
-
* executed after the current effect.
|
|
2019
|
+
* Update the Context with the given mapping function.
|
|
1737
2020
|
*
|
|
1738
|
-
* @since 3.
|
|
2021
|
+
* @since 3.11.0
|
|
1739
2022
|
* @experimental
|
|
1740
|
-
* @category
|
|
2023
|
+
* @category environment
|
|
1741
2024
|
*/
|
|
1742
|
-
export const
|
|
1743
|
-
/**
|
|
1744
|
-
* A more flexible version of `flatMap`, that combines `map` and `flatMap` into
|
|
1745
|
-
* a single api.
|
|
1746
|
-
*
|
|
1747
|
-
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1748
|
-
* executed after the current effect.
|
|
1749
|
-
*
|
|
1750
|
-
* @since 3.4.0
|
|
1751
|
-
* @experimental
|
|
1752
|
-
* @category mapping & sequencing
|
|
1753
|
-
*/
|
|
1754
|
-
<A, X>(f: (a: A) => X): <E, R>(
|
|
1755
|
-
self: Micro<A, E, R>
|
|
1756
|
-
) => [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
|
|
1757
|
-
: Micro<X, E, R>
|
|
1758
|
-
/**
|
|
1759
|
-
* A more flexible version of `flatMap`, that combines `map` and `flatMap` into
|
|
1760
|
-
* a single api.
|
|
1761
|
-
*
|
|
1762
|
-
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1763
|
-
* executed after the current effect.
|
|
1764
|
-
*
|
|
1765
|
-
* @since 3.4.0
|
|
1766
|
-
* @experimental
|
|
1767
|
-
* @category mapping & sequencing
|
|
1768
|
-
*/
|
|
1769
|
-
<X>(f: NotFunction<X>): <A, E, R>(
|
|
1770
|
-
self: Micro<A, E, R>
|
|
1771
|
-
) => [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
|
|
1772
|
-
: Micro<X, E, R>
|
|
2025
|
+
export const updateContext: {
|
|
1773
2026
|
/**
|
|
1774
|
-
*
|
|
1775
|
-
* a single api.
|
|
2027
|
+
* Update the Context with the given mapping function.
|
|
1776
2028
|
*
|
|
1777
|
-
*
|
|
1778
|
-
* executed after the current effect.
|
|
1779
|
-
*
|
|
1780
|
-
* @since 3.4.0
|
|
2029
|
+
* @since 3.11.0
|
|
1781
2030
|
* @experimental
|
|
1782
|
-
* @category
|
|
2031
|
+
* @category environment
|
|
1783
2032
|
*/
|
|
1784
|
-
<
|
|
1785
|
-
|
|
1786
|
-
|
|
1787
|
-
): [X] extends [Micro<infer A1, infer E1, infer R1>] ? Micro<A1, E | E1, R | R1>
|
|
1788
|
-
: Micro<X, E, R>
|
|
2033
|
+
<R2, R>(
|
|
2034
|
+
f: (context: Context.Context<R2>) => Context.Context<NoInfer<R>>
|
|
2035
|
+
): <A, E>(self: Micro<A, E, R>) => Micro<A, E, R2>
|
|
1789
2036
|
/**
|
|
1790
|
-
*
|
|
1791
|
-
* a single api.
|
|
1792
|
-
*
|
|
1793
|
-
* It also allows you to pass in a `Micro` effect directly, which will be
|
|
1794
|
-
* executed after the current effect.
|
|
2037
|
+
* Update the Context with the given mapping function.
|
|
1795
2038
|
*
|
|
1796
|
-
* @since 3.
|
|
2039
|
+
* @since 3.11.0
|
|
1797
2040
|
* @experimental
|
|
1798
|
-
* @category
|
|
2041
|
+
* @category environment
|
|
1799
2042
|
*/
|
|
1800
|
-
<A, E, R,
|
|
2043
|
+
<A, E, R, R2>(
|
|
1801
2044
|
self: Micro<A, E, R>,
|
|
1802
|
-
f:
|
|
1803
|
-
):
|
|
1804
|
-
: Micro<X, E, R>
|
|
2045
|
+
f: (context: Context.Context<R2>) => Context.Context<NoInfer<R>>
|
|
2046
|
+
): Micro<A, E, R2>
|
|
1805
2047
|
} = dual(
|
|
1806
2048
|
2,
|
|
1807
|
-
<A, E, R,
|
|
1808
|
-
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
2049
|
+
<A, E, R, R2>(
|
|
2050
|
+
self: Micro<A, E, R>,
|
|
2051
|
+
f: (context: Context.Context<R2>) => Context.Context<NoInfer<R>>
|
|
2052
|
+
): Micro<A, E, R2> =>
|
|
2053
|
+
withFiber<
|
|
2054
|
+
/**
|
|
2055
|
+
* Update the Context with the given mapping function.
|
|
2056
|
+
*
|
|
2057
|
+
* @since 3.11.0
|
|
2058
|
+
* @experimental
|
|
2059
|
+
* @category environment
|
|
2060
|
+
*/
|
|
2061
|
+
A, /**
|
|
2062
|
+
* Update the Context with the given mapping function.
|
|
2063
|
+
*
|
|
2064
|
+
* @since 3.11.0
|
|
2065
|
+
* @experimental
|
|
2066
|
+
* @category environment
|
|
2067
|
+
*/
|
|
2068
|
+
E, /**
|
|
2069
|
+
* Update the Context with the given mapping function.
|
|
2070
|
+
*
|
|
2071
|
+
* @since 3.11.0
|
|
2072
|
+
* @experimental
|
|
2073
|
+
* @category environment
|
|
2074
|
+
*/
|
|
2075
|
+
R2
|
|
2076
|
+
>((fiber) => {
|
|
2077
|
+
const prev = fiber.context as Context.Context<R2>
|
|
2078
|
+
fiber.context = f(prev)
|
|
2079
|
+
return onExit(
|
|
2080
|
+
self as any,
|
|
2081
|
+
() => {
|
|
2082
|
+
fiber.context = prev
|
|
2083
|
+
return void_
|
|
1820
2084
|
}
|
|
1821
|
-
|
|
2085
|
+
)
|
|
1822
2086
|
})
|
|
1823
2087
|
)
|
|
1824
2088
|
|
|
1825
2089
|
/**
|
|
1826
|
-
*
|
|
1827
|
-
*
|
|
1828
|
-
* It is similar to the `andThen` api, but the success value is ignored.
|
|
2090
|
+
* Update the service for the given `Context.Tag` in the environment.
|
|
1829
2091
|
*
|
|
1830
|
-
* @since 3.
|
|
2092
|
+
* @since 3.11.0
|
|
1831
2093
|
* @experimental
|
|
1832
|
-
* @category
|
|
2094
|
+
* @category environment
|
|
1833
2095
|
*/
|
|
1834
|
-
export const
|
|
2096
|
+
export const updateService: {
|
|
1835
2097
|
/**
|
|
1836
|
-
*
|
|
2098
|
+
* Update the service for the given `Context.Tag` in the environment.
|
|
1837
2099
|
*
|
|
1838
|
-
*
|
|
1839
|
-
*
|
|
1840
|
-
* @since 3.4.0
|
|
2100
|
+
* @since 3.11.0
|
|
1841
2101
|
* @experimental
|
|
1842
|
-
* @category
|
|
2102
|
+
* @category environment
|
|
1843
2103
|
*/
|
|
1844
|
-
<
|
|
1845
|
-
self: Micro<A, E, R>
|
|
1846
|
-
) => [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
|
|
1847
|
-
: Micro<A, E, R>
|
|
2104
|
+
<I, A>(tag: Context.Reference<I, A>, f: (value: A) => A): <XA, E, R>(self: Micro<XA, E, R>) => Micro<XA, E, R>
|
|
1848
2105
|
/**
|
|
1849
|
-
*
|
|
1850
|
-
*
|
|
1851
|
-
* It is similar to the `andThen` api, but the success value is ignored.
|
|
2106
|
+
* Update the service for the given `Context.Tag` in the environment.
|
|
1852
2107
|
*
|
|
1853
|
-
* @since 3.
|
|
2108
|
+
* @since 3.11.0
|
|
1854
2109
|
* @experimental
|
|
1855
|
-
* @category
|
|
2110
|
+
* @category environment
|
|
1856
2111
|
*/
|
|
1857
|
-
<
|
|
1858
|
-
self: Micro<A, E, R>
|
|
1859
|
-
) => [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
|
|
1860
|
-
: Micro<A, E, R>
|
|
2112
|
+
<I, A>(tag: Context.Tag<I, A>, f: (value: A) => A): <XA, E, R>(self: Micro<XA, E, R>) => Micro<XA, E, R | I>
|
|
1861
2113
|
/**
|
|
1862
|
-
*
|
|
2114
|
+
* Update the service for the given `Context.Tag` in the environment.
|
|
1863
2115
|
*
|
|
1864
|
-
*
|
|
1865
|
-
*
|
|
1866
|
-
* @since 3.4.0
|
|
2116
|
+
* @since 3.11.0
|
|
1867
2117
|
* @experimental
|
|
1868
|
-
* @category
|
|
2118
|
+
* @category environment
|
|
1869
2119
|
*/
|
|
1870
|
-
<A, E, R,
|
|
1871
|
-
self: Micro<A, E, R>,
|
|
1872
|
-
f: (a: NoInfer<A>) => X
|
|
1873
|
-
): [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
|
|
1874
|
-
: Micro<A, E, R>
|
|
2120
|
+
<XA, E, R, I, A>(self: Micro<XA, E, R>, tag: Context.Reference<I, A>, f: (value: A) => A): Micro<XA, E, R>
|
|
1875
2121
|
/**
|
|
1876
|
-
*
|
|
1877
|
-
*
|
|
1878
|
-
* It is similar to the `andThen` api, but the success value is ignored.
|
|
2122
|
+
* Update the service for the given `Context.Tag` in the environment.
|
|
1879
2123
|
*
|
|
1880
|
-
* @since 3.
|
|
2124
|
+
* @since 3.11.0
|
|
1881
2125
|
* @experimental
|
|
1882
|
-
* @category
|
|
2126
|
+
* @category environment
|
|
1883
2127
|
*/
|
|
1884
|
-
<A, E, R,
|
|
1885
|
-
self: Micro<A, E, R>,
|
|
1886
|
-
f: NotFunction<X>
|
|
1887
|
-
): [X] extends [Micro<infer _A1, infer E1, infer R1>] ? Micro<A, E | E1, R | R1>
|
|
1888
|
-
: Micro<A, E, R>
|
|
2128
|
+
<XA, E, R, I, A>(self: Micro<XA, E, R>, tag: Context.Tag<I, A>, f: (value: A) => A): Micro<XA, E, R | I>
|
|
1889
2129
|
} = dual(
|
|
1890
|
-
|
|
1891
|
-
<
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
|
|
1897
|
-
|
|
1898
|
-
|
|
1899
|
-
|
|
1900
|
-
|
|
1901
|
-
|
|
1902
|
-
|
|
1903
|
-
|
|
1904
|
-
}
|
|
1905
|
-
onExit(selfExit)
|
|
1906
|
-
})
|
|
1907
|
-
} else {
|
|
1908
|
-
onExit(selfExit)
|
|
2130
|
+
3,
|
|
2131
|
+
<XA, E, R, I, A>(
|
|
2132
|
+
self: Micro<XA, E, R>,
|
|
2133
|
+
tag: Context.Reference<I, A>,
|
|
2134
|
+
f: (value: A) => A
|
|
2135
|
+
): Micro<XA, E, R> =>
|
|
2136
|
+
withFiber((fiber) => {
|
|
2137
|
+
const prev = Context.unsafeGet(fiber.context, tag)
|
|
2138
|
+
fiber.context = Context.add(fiber.context, tag, f(prev))
|
|
2139
|
+
return onExit(
|
|
2140
|
+
self,
|
|
2141
|
+
() => {
|
|
2142
|
+
fiber.context = Context.add(fiber.context, tag, prev)
|
|
2143
|
+
return void_
|
|
1909
2144
|
}
|
|
1910
|
-
|
|
2145
|
+
)
|
|
1911
2146
|
})
|
|
1912
2147
|
)
|
|
1913
|
-
|
|
1914
|
-
/**
|
|
1915
|
-
*
|
|
1916
|
-
*
|
|
1917
|
-
* @since 3.4.0
|
|
1918
|
-
* @experimental
|
|
1919
|
-
* @category mapping & sequencing
|
|
1920
|
-
*/
|
|
1921
|
-
export const asVoid = <A, E, R>(self: Micro<A, E, R>): Micro<void, E, R> => map(self, (_) => void 0)
|
|
1922
|
-
|
|
1923
|
-
/**
|
|
1924
|
-
* Access the `MicroExit` of the given `Micro` effect.
|
|
1925
|
-
*
|
|
1926
|
-
* @since 3.4.6
|
|
1927
|
-
* @experimental
|
|
1928
|
-
* @category mapping & sequencing
|
|
1929
|
-
*/
|
|
1930
|
-
export const exit = <A, E, R>(self: Micro<A, E, R>): Micro<MicroExit<A, E>, never, R> =>
|
|
1931
|
-
make(function(env, onExit) {
|
|
1932
|
-
self[runSymbol](env, function(exit) {
|
|
1933
|
-
onExit(exitSucceed(exit))
|
|
1934
|
-
})
|
|
1935
|
-
})
|
|
1936
|
-
|
|
1937
|
-
/**
|
|
1938
|
-
* Replace the error type of the given `Micro` with the full `MicroCause` object.
|
|
1939
|
-
*
|
|
1940
|
-
* @since 3.4.0
|
|
1941
|
-
* @experimental
|
|
1942
|
-
* @category mapping & sequencing
|
|
1943
|
-
*/
|
|
1944
|
-
export const sandbox = <A, E, R>(self: Micro<A, E, R>): Micro<A, MicroCause<E>, R> =>
|
|
1945
|
-
catchAllCause(self, (cause) => fail(cause))
|
|
1946
|
-
|
|
1947
|
-
function forkSignal(env: Env<any>) {
|
|
1948
|
-
const controller = new AbortController()
|
|
1949
|
-
const parentSignal = envGet(env, currentAbortSignal)
|
|
1950
|
-
function onAbort() {
|
|
1951
|
-
controller.abort()
|
|
1952
|
-
parentSignal.removeEventListener("abort", onAbort)
|
|
1953
|
-
}
|
|
1954
|
-
parentSignal.addEventListener("abort", onAbort)
|
|
1955
|
-
const envWithSignal = envMutate(env, function(refs) {
|
|
1956
|
-
refs[currentAbortController.key] = controller
|
|
1957
|
-
refs[currentAbortSignal.key] = controller.signal
|
|
1958
|
-
return refs
|
|
1959
|
-
})
|
|
1960
|
-
return [envWithSignal, onAbort] as const
|
|
1961
|
-
}
|
|
1962
|
-
|
|
1963
|
-
/**
|
|
1964
|
-
* Returns an effect that races all the specified effects,
|
|
1965
|
-
* yielding the value of the first effect to succeed with a value. Losers of
|
|
1966
|
-
* the race will be interrupted immediately
|
|
2148
|
+
|
|
2149
|
+
/**
|
|
2150
|
+
* Access the current `Context` from the environment.
|
|
1967
2151
|
*
|
|
1968
2152
|
* @since 3.4.0
|
|
1969
2153
|
* @experimental
|
|
1970
|
-
* @category
|
|
2154
|
+
* @category environment
|
|
1971
2155
|
*/
|
|
1972
|
-
export const
|
|
1973
|
-
|
|
1974
|
-
): Micro<Micro.Success<Eff>, Micro.Error<Eff>, Micro.Context<Eff>> =>
|
|
1975
|
-
make(function(env, onExit) {
|
|
1976
|
-
const [envWithSignal, onAbort] = forkSignal(env)
|
|
1977
|
-
|
|
1978
|
-
const effects = Array.from(all)
|
|
1979
|
-
let len = effects.length
|
|
1980
|
-
let index = 0
|
|
1981
|
-
let done = 0
|
|
1982
|
-
let exit: MicroExit<any, any> | undefined = undefined
|
|
1983
|
-
const causes: Array<MicroCause<any>> = []
|
|
1984
|
-
function onDone(exit_: MicroExit<any, any>) {
|
|
1985
|
-
done++
|
|
1986
|
-
if (exit_._tag === "Right" && exit === undefined) {
|
|
1987
|
-
len = index
|
|
1988
|
-
exit = exit_
|
|
1989
|
-
onAbort()
|
|
1990
|
-
} else if (exit_._tag === "Left") {
|
|
1991
|
-
causes.push(exit_.left)
|
|
1992
|
-
}
|
|
1993
|
-
if (done >= len) {
|
|
1994
|
-
onExit(exit ?? Either.left(causes[0]))
|
|
1995
|
-
}
|
|
1996
|
-
}
|
|
1997
|
-
|
|
1998
|
-
for (; index < len; index++) {
|
|
1999
|
-
effects[index][runSymbol](envWithSignal, onDone)
|
|
2000
|
-
}
|
|
2001
|
-
})
|
|
2156
|
+
export const context = <R>(): Micro<Context.Context<R>> => getContext as any
|
|
2157
|
+
const getContext = withFiber((fiber) => succeed(fiber.context))
|
|
2002
2158
|
|
|
2003
2159
|
/**
|
|
2004
|
-
*
|
|
2005
|
-
* yielding the value of the first effect to succeed or fail. Losers of
|
|
2006
|
-
* the race will be interrupted immediately
|
|
2160
|
+
* Merge the given `Context` with the current context.
|
|
2007
2161
|
*
|
|
2008
2162
|
* @since 3.4.0
|
|
2009
2163
|
* @experimental
|
|
2010
|
-
* @category
|
|
2164
|
+
* @category environment
|
|
2011
2165
|
*/
|
|
2012
|
-
export const
|
|
2013
|
-
|
|
2014
|
-
|
|
2015
|
-
|
|
2016
|
-
|
|
2017
|
-
|
|
2018
|
-
|
|
2019
|
-
|
|
2020
|
-
|
|
2021
|
-
|
|
2022
|
-
|
|
2023
|
-
|
|
2024
|
-
|
|
2025
|
-
|
|
2026
|
-
|
|
2027
|
-
|
|
2028
|
-
|
|
2029
|
-
|
|
2030
|
-
|
|
2031
|
-
|
|
2032
|
-
|
|
2033
|
-
|
|
2034
|
-
|
|
2035
|
-
|
|
2036
|
-
for (; index < len; index++) {
|
|
2037
|
-
effects[index][runSymbol](envWithSignal, onDone)
|
|
2038
|
-
}
|
|
2039
|
-
})
|
|
2166
|
+
export const provideContext: {
|
|
2167
|
+
/**
|
|
2168
|
+
* Merge the given `Context` with the current context.
|
|
2169
|
+
*
|
|
2170
|
+
* @since 3.4.0
|
|
2171
|
+
* @experimental
|
|
2172
|
+
* @category environment
|
|
2173
|
+
*/
|
|
2174
|
+
<XR>(context: Context.Context<XR>): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E, Exclude<R, XR>>
|
|
2175
|
+
/**
|
|
2176
|
+
* Merge the given `Context` with the current context.
|
|
2177
|
+
*
|
|
2178
|
+
* @since 3.4.0
|
|
2179
|
+
* @experimental
|
|
2180
|
+
* @category environment
|
|
2181
|
+
*/
|
|
2182
|
+
<A, E, R, XR>(self: Micro<A, E, R>, context: Context.Context<XR>): Micro<A, E, Exclude<R, XR>>
|
|
2183
|
+
} = dual(
|
|
2184
|
+
2,
|
|
2185
|
+
<A, E, R, XR>(
|
|
2186
|
+
self: Micro<A, E, R>,
|
|
2187
|
+
provided: Context.Context<XR>
|
|
2188
|
+
): Micro<A, E, Exclude<R, XR>> => updateContext(self, Context.merge(provided)) as any
|
|
2189
|
+
)
|
|
2040
2190
|
|
|
2041
2191
|
/**
|
|
2042
|
-
*
|
|
2043
|
-
* effect to succeed. Losers of the race will be interrupted immediately
|
|
2192
|
+
* Add the provided service to the current context.
|
|
2044
2193
|
*
|
|
2045
2194
|
* @since 3.4.0
|
|
2046
2195
|
* @experimental
|
|
2047
|
-
* @category
|
|
2196
|
+
* @category environment
|
|
2048
2197
|
*/
|
|
2049
|
-
export const
|
|
2198
|
+
export const provideService: {
|
|
2050
2199
|
/**
|
|
2051
|
-
*
|
|
2052
|
-
* effect to succeed. Losers of the race will be interrupted immediately
|
|
2200
|
+
* Add the provided service to the current context.
|
|
2053
2201
|
*
|
|
2054
2202
|
* @since 3.4.0
|
|
2055
2203
|
* @experimental
|
|
2056
|
-
* @category
|
|
2204
|
+
* @category environment
|
|
2057
2205
|
*/
|
|
2058
|
-
<
|
|
2206
|
+
<I, S>(tag: Context.Tag<I, S>, service: S): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E, Exclude<R, I>>
|
|
2059
2207
|
/**
|
|
2060
|
-
*
|
|
2061
|
-
* effect to succeed. Losers of the race will be interrupted immediately
|
|
2208
|
+
* Add the provided service to the current context.
|
|
2062
2209
|
*
|
|
2063
2210
|
* @since 3.4.0
|
|
2064
2211
|
* @experimental
|
|
2065
|
-
* @category
|
|
2212
|
+
* @category environment
|
|
2066
2213
|
*/
|
|
2067
|
-
<A, E, R,
|
|
2214
|
+
<A, E, R, I, S>(self: Micro<A, E, R>, tag: Context.Tag<I, S>, service: S): Micro<A, E, Exclude<R, I>>
|
|
2068
2215
|
} = dual(
|
|
2069
|
-
|
|
2070
|
-
<A, E, R,
|
|
2071
|
-
|
|
2216
|
+
3,
|
|
2217
|
+
<A, E, R, I, S>(
|
|
2218
|
+
self: Micro<A, E, R>,
|
|
2219
|
+
tag: Context.Tag<I, S>,
|
|
2220
|
+
service: S
|
|
2221
|
+
): Micro<A, E, Exclude<R, I>> => updateContext(self, Context.add(tag, service)) as any
|
|
2072
2222
|
)
|
|
2073
2223
|
|
|
2074
2224
|
/**
|
|
2075
|
-
*
|
|
2076
|
-
*
|
|
2225
|
+
* Create a service using the provided `Micro` effect, and add it to the
|
|
2226
|
+
* current context.
|
|
2227
|
+
*
|
|
2228
|
+
* @since 3.4.6
|
|
2229
|
+
* @experimental
|
|
2230
|
+
* @category environment
|
|
2231
|
+
*/
|
|
2232
|
+
export const provideServiceEffect: {
|
|
2233
|
+
/**
|
|
2234
|
+
* Create a service using the provided `Micro` effect, and add it to the
|
|
2235
|
+
* current context.
|
|
2236
|
+
*
|
|
2237
|
+
* @since 3.4.6
|
|
2238
|
+
* @experimental
|
|
2239
|
+
* @category environment
|
|
2240
|
+
*/
|
|
2241
|
+
<I, S, E2, R2>(
|
|
2242
|
+
tag: Context.Tag<I, S>,
|
|
2243
|
+
acquire: Micro<S, E2, R2>
|
|
2244
|
+
): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E | E2, Exclude<R, I> | R2>
|
|
2245
|
+
/**
|
|
2246
|
+
* Create a service using the provided `Micro` effect, and add it to the
|
|
2247
|
+
* current context.
|
|
2248
|
+
*
|
|
2249
|
+
* @since 3.4.6
|
|
2250
|
+
* @experimental
|
|
2251
|
+
* @category environment
|
|
2252
|
+
*/
|
|
2253
|
+
<A, E, R, I, S, E2, R2>(
|
|
2254
|
+
self: Micro<A, E, R>,
|
|
2255
|
+
tag: Context.Tag<I, S>,
|
|
2256
|
+
acquire: Micro<S, E2, R2>
|
|
2257
|
+
): Micro<A, E | E2, Exclude<R, I> | R2>
|
|
2258
|
+
} = dual(
|
|
2259
|
+
3,
|
|
2260
|
+
<A, E, R, I, S, E2, R2>(
|
|
2261
|
+
self: Micro<A, E, R>,
|
|
2262
|
+
tag: Context.Tag<I, S>,
|
|
2263
|
+
acquire: Micro<S, E2, R2>
|
|
2264
|
+
): Micro<A, E | E2, Exclude<R, I> | R2> => flatMap(acquire, (service) => provideService(self, tag, service))
|
|
2265
|
+
)
|
|
2266
|
+
|
|
2267
|
+
// ========================================================================
|
|
2268
|
+
// References
|
|
2269
|
+
// ========================================================================
|
|
2270
|
+
|
|
2271
|
+
/**
|
|
2272
|
+
* @since 3.11.0
|
|
2273
|
+
* @experimental
|
|
2274
|
+
* @category references
|
|
2275
|
+
*/
|
|
2276
|
+
export class MaxOpsBeforeYield extends Context.Reference<MaxOpsBeforeYield>()<
|
|
2277
|
+
"effect/Micro/currentMaxOpsBeforeYield",
|
|
2278
|
+
number
|
|
2279
|
+
>(
|
|
2280
|
+
"effect/Micro/currentMaxOpsBeforeYield",
|
|
2281
|
+
{ defaultValue: () => 2048 }
|
|
2282
|
+
) {}
|
|
2283
|
+
|
|
2284
|
+
/**
|
|
2285
|
+
* @since 3.11.0
|
|
2286
|
+
* @experimental
|
|
2287
|
+
* @category environment refs
|
|
2288
|
+
*/
|
|
2289
|
+
export class CurrentConcurrency extends Context.Reference<CurrentConcurrency>()<
|
|
2290
|
+
"effect/Micro/currentConcurrency",
|
|
2291
|
+
"unbounded" | number
|
|
2292
|
+
>(
|
|
2293
|
+
"effect/Micro/currentConcurrency",
|
|
2294
|
+
{ defaultValue: () => "unbounded" }
|
|
2295
|
+
) {}
|
|
2296
|
+
|
|
2297
|
+
/**
|
|
2298
|
+
* @since 3.11.0
|
|
2299
|
+
* @experimental
|
|
2300
|
+
* @category environment refs
|
|
2301
|
+
*/
|
|
2302
|
+
export class CurrentScheduler extends Context.Reference<CurrentScheduler>()<
|
|
2303
|
+
"effect/Micro/currentScheduler",
|
|
2304
|
+
MicroScheduler
|
|
2305
|
+
>(
|
|
2306
|
+
"effect/Micro/currentScheduler",
|
|
2307
|
+
{ defaultValue: () => new MicroSchedulerDefault() }
|
|
2308
|
+
) {}
|
|
2309
|
+
|
|
2310
|
+
/**
|
|
2311
|
+
* If you have a `Micro` that uses `concurrency: "inherit"`, you can use this
|
|
2312
|
+
* api to control the concurrency of that `Micro` when it is run.
|
|
2077
2313
|
*
|
|
2078
2314
|
* @since 3.4.0
|
|
2079
2315
|
* @experimental
|
|
2080
|
-
* @category
|
|
2316
|
+
* @category environment refs
|
|
2317
|
+
* @example
|
|
2318
|
+
* import * as Micro from "effect/Micro"
|
|
2319
|
+
*
|
|
2320
|
+
* Micro.forEach([1, 2, 3], (n) => Micro.succeed(n), {
|
|
2321
|
+
* concurrency: "inherit"
|
|
2322
|
+
* }).pipe(
|
|
2323
|
+
* Micro.withConcurrency(2) // use a concurrency of 2
|
|
2324
|
+
* )
|
|
2081
2325
|
*/
|
|
2082
|
-
export const
|
|
2326
|
+
export const withConcurrency: {
|
|
2083
2327
|
/**
|
|
2084
|
-
*
|
|
2085
|
-
*
|
|
2328
|
+
* If you have a `Micro` that uses `concurrency: "inherit"`, you can use this
|
|
2329
|
+
* api to control the concurrency of that `Micro` when it is run.
|
|
2086
2330
|
*
|
|
2087
2331
|
* @since 3.4.0
|
|
2088
2332
|
* @experimental
|
|
2089
|
-
* @category
|
|
2333
|
+
* @category environment refs
|
|
2334
|
+
* @example
|
|
2335
|
+
* import * as Micro from "effect/Micro"
|
|
2336
|
+
*
|
|
2337
|
+
* Micro.forEach([1, 2, 3], (n) => Micro.succeed(n), {
|
|
2338
|
+
* concurrency: "inherit"
|
|
2339
|
+
* }).pipe(
|
|
2340
|
+
* Micro.withConcurrency(2) // use a concurrency of 2
|
|
2341
|
+
* )
|
|
2090
2342
|
*/
|
|
2091
|
-
|
|
2343
|
+
(concurrency: "unbounded" | number): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E, R>
|
|
2092
2344
|
/**
|
|
2093
|
-
*
|
|
2094
|
-
*
|
|
2345
|
+
* If you have a `Micro` that uses `concurrency: "inherit"`, you can use this
|
|
2346
|
+
* api to control the concurrency of that `Micro` when it is run.
|
|
2095
2347
|
*
|
|
2096
2348
|
* @since 3.4.0
|
|
2097
2349
|
* @experimental
|
|
2098
|
-
* @category
|
|
2350
|
+
* @category environment refs
|
|
2351
|
+
* @example
|
|
2352
|
+
* import * as Micro from "effect/Micro"
|
|
2353
|
+
*
|
|
2354
|
+
* Micro.forEach([1, 2, 3], (n) => Micro.succeed(n), {
|
|
2355
|
+
* concurrency: "inherit"
|
|
2356
|
+
* }).pipe(
|
|
2357
|
+
* Micro.withConcurrency(2) // use a concurrency of 2
|
|
2358
|
+
* )
|
|
2099
2359
|
*/
|
|
2100
|
-
<A, E, R
|
|
2360
|
+
<A, E, R>(self: Micro<A, E, R>, concurrency: "unbounded" | number): Micro<A, E, R>
|
|
2101
2361
|
} = dual(
|
|
2102
2362
|
2,
|
|
2103
|
-
<A, E, R
|
|
2104
|
-
|
|
2363
|
+
<A, E, R>(
|
|
2364
|
+
self: Micro<A, E, R>,
|
|
2365
|
+
concurrency: "unbounded" | number
|
|
2366
|
+
): Micro<A, E, R> => provideService(self, CurrentConcurrency, concurrency)
|
|
2105
2367
|
)
|
|
2106
2368
|
|
|
2107
2369
|
// ----------------------------------------------------------------------------
|
|
@@ -2202,13 +2464,11 @@ export const zipWith: {
|
|
|
2202
2464
|
that: Micro<A2, E2, R2>,
|
|
2203
2465
|
f: (a: A, b: A2) => B,
|
|
2204
2466
|
options?: { readonly concurrent?: boolean | undefined }
|
|
2205
|
-
): Micro<B, E2 | E, R2 | R> =>
|
|
2206
|
-
|
|
2467
|
+
): Micro<B, E2 | E, R2 | R> =>
|
|
2468
|
+
options?.concurrent
|
|
2207
2469
|
// Use `all` exclusively for concurrent cases, as it introduces additional overhead due to the management of concurrency
|
|
2208
|
-
|
|
2209
|
-
|
|
2210
|
-
return flatMap(self, (a) => map(that, (a2) => f(a, a2)))
|
|
2211
|
-
})
|
|
2470
|
+
? map(all([self, that], { concurrency: 2 }), ([a, a2]) => f(a, a2))
|
|
2471
|
+
: flatMap(self, (a) => map(that, (a2) => f(a, a2))))
|
|
2212
2472
|
|
|
2213
2473
|
// ----------------------------------------------------------------------------
|
|
2214
2474
|
// filtering & conditionals
|
|
@@ -2421,7 +2681,7 @@ export const when: {
|
|
|
2421
2681
|
self: Micro<A, E, R>,
|
|
2422
2682
|
condition: LazyArg<boolean> | Micro<boolean, E2, R2>
|
|
2423
2683
|
): Micro<Option.Option<A>, E | E2, R | R2> =>
|
|
2424
|
-
flatMap(isMicro(condition) ? condition : sync(condition), (pass) => pass ? asSome(self) :
|
|
2684
|
+
flatMap(isMicro(condition) ? condition : sync(condition), (pass) => pass ? asSome(self) : succeedNone)
|
|
2425
2685
|
)
|
|
2426
2686
|
|
|
2427
2687
|
// ----------------------------------------------------------------------------
|
|
@@ -2487,14 +2747,15 @@ export const repeatExit: {
|
|
|
2487
2747
|
times?: number | undefined
|
|
2488
2748
|
schedule?: MicroSchedule | undefined
|
|
2489
2749
|
}): Micro<A, E, R> =>
|
|
2490
|
-
|
|
2750
|
+
suspend(() => {
|
|
2491
2751
|
const startedAt = options.schedule ? Date.now() : 0
|
|
2492
2752
|
let attempt = 0
|
|
2493
|
-
|
|
2753
|
+
|
|
2754
|
+
const loop: Micro<A, E, R> = flatMap(exit(self), (exit) => {
|
|
2494
2755
|
if (options.while !== undefined && !options.while(exit)) {
|
|
2495
|
-
return
|
|
2756
|
+
return exit
|
|
2496
2757
|
} else if (options.times !== undefined && attempt >= options.times) {
|
|
2497
|
-
return
|
|
2758
|
+
return exit
|
|
2498
2759
|
}
|
|
2499
2760
|
attempt++
|
|
2500
2761
|
let delayEffect = yieldNow
|
|
@@ -2502,17 +2763,14 @@ export const repeatExit: {
|
|
|
2502
2763
|
const elapsed = Date.now() - startedAt
|
|
2503
2764
|
const duration = options.schedule(attempt, elapsed)
|
|
2504
2765
|
if (Option.isNone(duration)) {
|
|
2505
|
-
return
|
|
2766
|
+
return exit
|
|
2506
2767
|
}
|
|
2507
2768
|
delayEffect = sleep(duration.value)
|
|
2508
2769
|
}
|
|
2509
|
-
delayEffect
|
|
2510
|
-
if (exit._tag === "Left") {
|
|
2511
|
-
return onExit(exit as MicroExit<never, never>)
|
|
2512
|
-
}
|
|
2513
|
-
self[runSymbol](env, loop)
|
|
2514
|
-
})
|
|
2770
|
+
return flatMap(delayEffect, () => loop)
|
|
2515
2771
|
})
|
|
2772
|
+
|
|
2773
|
+
return loop
|
|
2516
2774
|
}))
|
|
2517
2775
|
|
|
2518
2776
|
/**
|
|
@@ -2565,9 +2823,116 @@ export const repeat: {
|
|
|
2565
2823
|
): Micro<A, E, R> =>
|
|
2566
2824
|
repeatExit(self, {
|
|
2567
2825
|
...options,
|
|
2568
|
-
while: (exit) => exit._tag === "
|
|
2826
|
+
while: (exit) => exit._tag === "Success" && (options?.while === undefined || options.while(exit.value))
|
|
2569
2827
|
}))
|
|
2570
2828
|
|
|
2829
|
+
/**
|
|
2830
|
+
* Replicates the given effect `n` times.
|
|
2831
|
+
*
|
|
2832
|
+
* @since 3.11.0
|
|
2833
|
+
* @experimental
|
|
2834
|
+
* @category repetition
|
|
2835
|
+
*/
|
|
2836
|
+
export const replicate: {
|
|
2837
|
+
/**
|
|
2838
|
+
* Replicates the given effect `n` times.
|
|
2839
|
+
*
|
|
2840
|
+
* @since 3.11.0
|
|
2841
|
+
* @experimental
|
|
2842
|
+
* @category repetition
|
|
2843
|
+
*/
|
|
2844
|
+
(n: number): <A, E, R>(self: Micro<A, E, R>) => Array<Micro<A, E, R>>
|
|
2845
|
+
/**
|
|
2846
|
+
* Replicates the given effect `n` times.
|
|
2847
|
+
*
|
|
2848
|
+
* @since 3.11.0
|
|
2849
|
+
* @experimental
|
|
2850
|
+
* @category repetition
|
|
2851
|
+
*/
|
|
2852
|
+
<A, E, R>(self: Micro<A, E, R>, n: number): Array<Micro<A, E, R>>
|
|
2853
|
+
} = dual(
|
|
2854
|
+
2,
|
|
2855
|
+
<A, E, R>(self: Micro<A, E, R>, n: number): Array<Micro<A, E, R>> => Array.from({ length: n }, () => self)
|
|
2856
|
+
)
|
|
2857
|
+
|
|
2858
|
+
/**
|
|
2859
|
+
* Performs this effect the specified number of times and collects the
|
|
2860
|
+
* results.
|
|
2861
|
+
*
|
|
2862
|
+
* @since 3.11.0
|
|
2863
|
+
* @category repetition
|
|
2864
|
+
*/
|
|
2865
|
+
export const replicateEffect: {
|
|
2866
|
+
/**
|
|
2867
|
+
* Performs this effect the specified number of times and collects the
|
|
2868
|
+
* results.
|
|
2869
|
+
*
|
|
2870
|
+
* @since 3.11.0
|
|
2871
|
+
* @category repetition
|
|
2872
|
+
*/
|
|
2873
|
+
(
|
|
2874
|
+
n: number,
|
|
2875
|
+
options?: {
|
|
2876
|
+
readonly concurrency?: Concurrency | undefined
|
|
2877
|
+
readonly discard?: false | undefined
|
|
2878
|
+
}
|
|
2879
|
+
): <A, E, R>(self: Micro<A, E, R>) => Micro<Array<A>, E, R>
|
|
2880
|
+
/**
|
|
2881
|
+
* Performs this effect the specified number of times and collects the
|
|
2882
|
+
* results.
|
|
2883
|
+
*
|
|
2884
|
+
* @since 3.11.0
|
|
2885
|
+
* @category repetition
|
|
2886
|
+
*/
|
|
2887
|
+
(
|
|
2888
|
+
n: number,
|
|
2889
|
+
options: {
|
|
2890
|
+
readonly concurrency?: Concurrency | undefined
|
|
2891
|
+
readonly discard: true
|
|
2892
|
+
}
|
|
2893
|
+
): <A, E, R>(self: Micro<A, E, R>) => Micro<void, E, R>
|
|
2894
|
+
/**
|
|
2895
|
+
* Performs this effect the specified number of times and collects the
|
|
2896
|
+
* results.
|
|
2897
|
+
*
|
|
2898
|
+
* @since 3.11.0
|
|
2899
|
+
* @category repetition
|
|
2900
|
+
*/
|
|
2901
|
+
<A, E, R>(
|
|
2902
|
+
self: Micro<A, E, R>,
|
|
2903
|
+
n: number,
|
|
2904
|
+
options?: {
|
|
2905
|
+
readonly concurrency?: Concurrency | undefined
|
|
2906
|
+
readonly discard?: false | undefined
|
|
2907
|
+
}
|
|
2908
|
+
): Micro<Array<A>, E, R>
|
|
2909
|
+
/**
|
|
2910
|
+
* Performs this effect the specified number of times and collects the
|
|
2911
|
+
* results.
|
|
2912
|
+
*
|
|
2913
|
+
* @since 3.11.0
|
|
2914
|
+
* @category repetition
|
|
2915
|
+
*/
|
|
2916
|
+
<A, E, R>(
|
|
2917
|
+
self: Micro<A, E, R>,
|
|
2918
|
+
n: number,
|
|
2919
|
+
options: {
|
|
2920
|
+
readonly concurrency?: Concurrency | undefined
|
|
2921
|
+
readonly discard: true
|
|
2922
|
+
}
|
|
2923
|
+
): Micro<void, E, R>
|
|
2924
|
+
} = dual(
|
|
2925
|
+
(args) => isMicro(args[0]),
|
|
2926
|
+
<A, E, R>(
|
|
2927
|
+
self: Micro<A, E, R>,
|
|
2928
|
+
n: number,
|
|
2929
|
+
options: {
|
|
2930
|
+
readonly concurrency?: Concurrency | undefined
|
|
2931
|
+
readonly discard: true
|
|
2932
|
+
}
|
|
2933
|
+
): Micro<void, E, R> => all(replicate(self, n), options)
|
|
2934
|
+
)
|
|
2935
|
+
|
|
2571
2936
|
/**
|
|
2572
2937
|
* Repeat the given `Micro` effect forever, only stopping if the effect fails.
|
|
2573
2938
|
*
|
|
@@ -2838,8 +3203,20 @@ export const catchAllCause: {
|
|
|
2838
3203
|
<A, E, R, B, E2, R2>(
|
|
2839
3204
|
self: Micro<A, E, R>,
|
|
2840
3205
|
f: (cause: NoInfer<MicroCause<E>>) => Micro<B, E2, R2>
|
|
2841
|
-
): Micro<A | B, E2, R | R2> =>
|
|
3206
|
+
): Micro<A | B, E2, R | R2> => {
|
|
3207
|
+
const onFailure = Object.create(OnFailureProto)
|
|
3208
|
+
onFailure[args] = self
|
|
3209
|
+
onFailure[failureCont] = f
|
|
3210
|
+
return onFailure
|
|
3211
|
+
}
|
|
2842
3212
|
)
|
|
3213
|
+
const OnFailureProto = makePrimitiveProto({
|
|
3214
|
+
op: "OnFailure",
|
|
3215
|
+
eval(this: any, fiber: FiberImpl): Primitive {
|
|
3216
|
+
fiber._stack.push(this as any)
|
|
3217
|
+
return this[args]
|
|
3218
|
+
}
|
|
3219
|
+
})
|
|
2843
3220
|
|
|
2844
3221
|
/**
|
|
2845
3222
|
* Selectively catch a `MicroCause` object of the given `Micro` effect,
|
|
@@ -2861,7 +3238,9 @@ export const catchCauseIf: {
|
|
|
2861
3238
|
<E, B, E2, R2, EB extends MicroCause<E>>(
|
|
2862
3239
|
refinement: Refinement<MicroCause<E>, EB>,
|
|
2863
3240
|
f: (cause: EB) => Micro<B, E2, R2>
|
|
2864
|
-
): <A, R>(
|
|
3241
|
+
): <A, R>(
|
|
3242
|
+
self: Micro<A, E, R>
|
|
3243
|
+
) => Micro<A | B, Exclude<E, MicroCause.Error<EB>> | E2, R | R2>
|
|
2865
3244
|
/**
|
|
2866
3245
|
* Selectively catch a `MicroCause` object of the given `Micro` effect,
|
|
2867
3246
|
* using the provided predicate to determine if the failure should be caught.
|
|
@@ -2900,20 +3279,15 @@ export const catchCauseIf: {
|
|
|
2900
3279
|
predicate: Predicate<MicroCause<NoInfer<E>>>,
|
|
2901
3280
|
f: (cause: NoInfer<MicroCause<E>>) => Micro<B, E2, R2>
|
|
2902
3281
|
): Micro<A | B, E | E2, R | R2>
|
|
2903
|
-
} = dual(
|
|
2904
|
-
|
|
2905
|
-
|
|
2906
|
-
|
|
2907
|
-
|
|
2908
|
-
|
|
2909
|
-
|
|
2910
|
-
|
|
2911
|
-
|
|
2912
|
-
} else {
|
|
2913
|
-
f(exit.left)[runSymbol](env, onExit)
|
|
2914
|
-
}
|
|
2915
|
-
})
|
|
2916
|
-
}))
|
|
3282
|
+
} = dual(
|
|
3283
|
+
3,
|
|
3284
|
+
<A, E, R, B, E2, R2>(
|
|
3285
|
+
self: Micro<A, E, R>,
|
|
3286
|
+
predicate: Predicate<MicroCause<E>>,
|
|
3287
|
+
f: (cause: MicroCause<E>) => Micro<B, E2, R2>
|
|
3288
|
+
): Micro<A | B, E | E2, R | R2> =>
|
|
3289
|
+
catchAllCause(self, (cause) => predicate(cause) ? f(cause) : failCause(cause) as any)
|
|
3290
|
+
)
|
|
2917
3291
|
|
|
2918
3292
|
/**
|
|
2919
3293
|
* Catch the error of the given `Micro` effect, allowing you to recover from it.
|
|
@@ -2950,7 +3324,7 @@ export const catchAll: {
|
|
|
2950
3324
|
<A, E, R, B, E2, R2>(
|
|
2951
3325
|
self: Micro<A, E, R>,
|
|
2952
3326
|
f: (a: NoInfer<E>) => Micro<B, E2, R2>
|
|
2953
|
-
): Micro<A | B, E2, R | R2> =>
|
|
3327
|
+
): Micro<A | B, E2, R | R2> => catchCauseIf(self, causeIsFail, (cause) => f(cause.error))
|
|
2954
3328
|
)
|
|
2955
3329
|
|
|
2956
3330
|
/**
|
|
@@ -3386,7 +3760,7 @@ export const ignoreLogged = <A, E, R>(self: Micro<A, E, R>): Micro<void, never,
|
|
|
3386
3760
|
* @category error handling
|
|
3387
3761
|
*/
|
|
3388
3762
|
export const option = <A, E, R>(self: Micro<A, E, R>): Micro<Option.Option<A>, never, R> =>
|
|
3389
|
-
match(self, { onFailure:
|
|
3763
|
+
match(self, { onFailure: Option.none, onSuccess: Option.some })
|
|
3390
3764
|
|
|
3391
3765
|
/**
|
|
3392
3766
|
* Replace the success value of the given `Micro` effect with an `Either`,
|
|
@@ -3448,8 +3822,8 @@ export const retry: {
|
|
|
3448
3822
|
repeatExit(self, {
|
|
3449
3823
|
...options,
|
|
3450
3824
|
while: (exit) =>
|
|
3451
|
-
exit._tag === "
|
|
3452
|
-
(options?.while === undefined || options.while(exit.
|
|
3825
|
+
exit._tag === "Failure" && exit.cause._tag === "Fail" &&
|
|
3826
|
+
(options?.while === undefined || options.while(exit.cause.error))
|
|
3453
3827
|
}))
|
|
3454
3828
|
|
|
3455
3829
|
/**
|
|
@@ -3496,12 +3870,7 @@ export const withTrace: {
|
|
|
3496
3870
|
const lineMatch = line.match(/\((.*)\)$/)
|
|
3497
3871
|
return causeWithTrace(cause, `at ${name} (${lineMatch ? lineMatch[1] : line})`)
|
|
3498
3872
|
}
|
|
3499
|
-
const f = (name: string) => (self: Micro<any, any, any>) =>
|
|
3500
|
-
unsafeMakeOptions(function(env, onExit) {
|
|
3501
|
-
self[runSymbol](env, function(exit) {
|
|
3502
|
-
onExit(exit._tag === "Left" ? Either.left(generate(name, exit.left)) : exit)
|
|
3503
|
-
})
|
|
3504
|
-
}, false)
|
|
3873
|
+
const f = (name: string) => (self: Micro<any, any, any>) => onError(self, (cause) => failCause(generate(name, cause)))
|
|
3505
3874
|
if (arguments.length === 2) {
|
|
3506
3875
|
return f(arguments[1])(arguments[0])
|
|
3507
3876
|
}
|
|
@@ -3557,18 +3926,21 @@ export const matchCauseEffect: {
|
|
|
3557
3926
|
readonly onFailure: (cause: MicroCause<E>) => Micro<A2, E2, R2>
|
|
3558
3927
|
readonly onSuccess: (a: A) => Micro<A3, E3, R3>
|
|
3559
3928
|
}
|
|
3560
|
-
): Micro<A2 | A3, E2 | E3, R2 | R3 | R> =>
|
|
3561
|
-
|
|
3562
|
-
|
|
3563
|
-
|
|
3564
|
-
|
|
3565
|
-
|
|
3566
|
-
|
|
3567
|
-
onExit(exitDie(err))
|
|
3568
|
-
}
|
|
3569
|
-
})
|
|
3570
|
-
})
|
|
3929
|
+
): Micro<A2 | A3, E2 | E3, R2 | R3 | R> => {
|
|
3930
|
+
const primitive = Object.create(OnSuccessAndFailureProto)
|
|
3931
|
+
primitive[args] = self
|
|
3932
|
+
primitive[successCont] = options.onSuccess
|
|
3933
|
+
primitive[failureCont] = options.onFailure
|
|
3934
|
+
return primitive
|
|
3935
|
+
}
|
|
3571
3936
|
)
|
|
3937
|
+
const OnSuccessAndFailureProto = makePrimitiveProto({
|
|
3938
|
+
op: "OnSuccessAndFailure",
|
|
3939
|
+
eval(this: any, fiber: FiberImpl): Primitive {
|
|
3940
|
+
fiber._stack.push(this)
|
|
3941
|
+
return this[args]
|
|
3942
|
+
}
|
|
3943
|
+
})
|
|
3572
3944
|
|
|
3573
3945
|
/**
|
|
3574
3946
|
* @since 3.4.6
|
|
@@ -3714,12 +4086,12 @@ export const match: {
|
|
|
3714
4086
|
* @category delays & timeouts
|
|
3715
4087
|
*/
|
|
3716
4088
|
export const sleep = (millis: number): Micro<void> =>
|
|
3717
|
-
async(
|
|
3718
|
-
const timeout = setTimeout(
|
|
4089
|
+
async((resume) => {
|
|
4090
|
+
const timeout = setTimeout(() => {
|
|
3719
4091
|
resume(void_)
|
|
3720
4092
|
}, millis)
|
|
3721
4093
|
return sync(() => {
|
|
3722
|
-
|
|
4094
|
+
clearTimeout(timeout)
|
|
3723
4095
|
})
|
|
3724
4096
|
})
|
|
3725
4097
|
|
|
@@ -3987,7 +4359,7 @@ class MicroScopeImpl implements MicroScope.Closeable {
|
|
|
3987
4359
|
this.state = { _tag: "Closed", exit: microExit }
|
|
3988
4360
|
return flatMap(
|
|
3989
4361
|
forEach(finalizers, (finalizer) => exit(finalizer(microExit))),
|
|
3990
|
-
|
|
4362
|
+
exitVoidAll
|
|
3991
4363
|
)
|
|
3992
4364
|
}
|
|
3993
4365
|
return void_
|
|
@@ -4072,7 +4444,7 @@ export const provideScope: {
|
|
|
4072
4444
|
* @category resources & finalization
|
|
4073
4445
|
*/
|
|
4074
4446
|
export const scoped = <A, E, R>(self: Micro<A, E, R>): Micro<A, E, Exclude<R, MicroScope>> =>
|
|
4075
|
-
suspend(
|
|
4447
|
+
suspend(() => {
|
|
4076
4448
|
const scope = new MicroScopeImpl()
|
|
4077
4449
|
return onExit(provideService(self, MicroScope, scope), (exit) => scope.close(exit))
|
|
4078
4450
|
})
|
|
@@ -4139,7 +4511,45 @@ export const onExit: {
|
|
|
4139
4511
|
<A, E, R, XE, XR>(
|
|
4140
4512
|
self: Micro<A, E, R>,
|
|
4141
4513
|
f: (exit: MicroExit<A, E>) => Micro<void, XE, XR>
|
|
4142
|
-
): Micro<A, E | XE, R | XR> =>
|
|
4514
|
+
): Micro<A, E | XE, R | XR> =>
|
|
4515
|
+
uninterruptibleMask((restore) =>
|
|
4516
|
+
matchCauseEffect(restore(self), {
|
|
4517
|
+
onFailure: (cause) => flatMap(f(exitFailCause(cause)), () => failCause(cause)),
|
|
4518
|
+
onSuccess: (a) => flatMap(f(exitSucceed(a)), () => succeed(a))
|
|
4519
|
+
})
|
|
4520
|
+
)
|
|
4521
|
+
)
|
|
4522
|
+
|
|
4523
|
+
/**
|
|
4524
|
+
* Regardless of the result of the this `Micro` effect, run the finalizer effect.
|
|
4525
|
+
*
|
|
4526
|
+
* @since 3.4.0
|
|
4527
|
+
* @experimental
|
|
4528
|
+
* @category resources & finalization
|
|
4529
|
+
*/
|
|
4530
|
+
export const ensuring: {
|
|
4531
|
+
/**
|
|
4532
|
+
* Regardless of the result of the this `Micro` effect, run the finalizer effect.
|
|
4533
|
+
*
|
|
4534
|
+
* @since 3.4.0
|
|
4535
|
+
* @experimental
|
|
4536
|
+
* @category resources & finalization
|
|
4537
|
+
*/
|
|
4538
|
+
<XE, XR>(finalizer: Micro<void, XE, XR>): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E | XE, R | XR>
|
|
4539
|
+
/**
|
|
4540
|
+
* Regardless of the result of the this `Micro` effect, run the finalizer effect.
|
|
4541
|
+
*
|
|
4542
|
+
* @since 3.4.0
|
|
4543
|
+
* @experimental
|
|
4544
|
+
* @category resources & finalization
|
|
4545
|
+
*/
|
|
4546
|
+
<A, E, R, XE, XR>(self: Micro<A, E, R>, finalizer: Micro<void, XE, XR>): Micro<A, E | XE, R | XR>
|
|
4547
|
+
} = dual(
|
|
4548
|
+
2,
|
|
4549
|
+
<A, E, R, XE, XR>(
|
|
4550
|
+
self: Micro<A, E, R>,
|
|
4551
|
+
finalizer: Micro<void, XE, XR>
|
|
4552
|
+
): Micro<A, E | XE, R | XR> => onExit(self, (_) => finalizer)
|
|
4143
4553
|
)
|
|
4144
4554
|
|
|
4145
4555
|
/**
|
|
@@ -4207,52 +4617,7 @@ export const onExitIf: {
|
|
|
4207
4617
|
self: Micro<A, E, R>,
|
|
4208
4618
|
refinement: Refinement<MicroExit<A, E>, B>,
|
|
4209
4619
|
f: (exit: B) => Micro<void, XE, XR>
|
|
4210
|
-
): Micro<A, E | XE, R | XR> =>
|
|
4211
|
-
uninterruptibleMask((restore) =>
|
|
4212
|
-
make(function(env, onExit) {
|
|
4213
|
-
restore(self)[runSymbol](env, function(exit) {
|
|
4214
|
-
if (!refinement(exit)) {
|
|
4215
|
-
return onExit(exit)
|
|
4216
|
-
}
|
|
4217
|
-
f(exit)[runSymbol](env, function(finalizerExit) {
|
|
4218
|
-
if (finalizerExit._tag === "Left") {
|
|
4219
|
-
return onExit(finalizerExit as MicroExit<never, XE>)
|
|
4220
|
-
}
|
|
4221
|
-
onExit(exit)
|
|
4222
|
-
})
|
|
4223
|
-
})
|
|
4224
|
-
})
|
|
4225
|
-
)
|
|
4226
|
-
)
|
|
4227
|
-
|
|
4228
|
-
/**
|
|
4229
|
-
* Regardless of the result of the this `Micro` effect, run the finalizer effect.
|
|
4230
|
-
*
|
|
4231
|
-
* @since 3.4.0
|
|
4232
|
-
* @experimental
|
|
4233
|
-
* @category resources & finalization
|
|
4234
|
-
*/
|
|
4235
|
-
export const ensuring: {
|
|
4236
|
-
/**
|
|
4237
|
-
* Regardless of the result of the this `Micro` effect, run the finalizer effect.
|
|
4238
|
-
*
|
|
4239
|
-
* @since 3.4.0
|
|
4240
|
-
* @experimental
|
|
4241
|
-
* @category resources & finalization
|
|
4242
|
-
*/
|
|
4243
|
-
<XE, XR>(finalizer: Micro<void, XE, XR>): <A, E, R>(self: Micro<A, E, R>) => Micro<A, E | XE, R | XR>
|
|
4244
|
-
/**
|
|
4245
|
-
* Regardless of the result of the this `Micro` effect, run the finalizer effect.
|
|
4246
|
-
*
|
|
4247
|
-
* @since 3.4.0
|
|
4248
|
-
* @experimental
|
|
4249
|
-
* @category resources & finalization
|
|
4250
|
-
*/
|
|
4251
|
-
<A, E, R, XE, XR>(self: Micro<A, E, R>, finalizer: Micro<void, XE, XR>): Micro<A, E | XE, R | XR>
|
|
4252
|
-
} = dual(
|
|
4253
|
-
2,
|
|
4254
|
-
<A, E, R, XE, XR>(self: Micro<A, E, R>, finalizer: Micro<void, XE, XR>): Micro<A, E | XE, R | XR> =>
|
|
4255
|
-
onExit(self, (_) => finalizer)
|
|
4620
|
+
): Micro<A, E | XE, R | XR> => onExit(self, (exit) => (refinement(exit) ? f(exit) : exitVoid))
|
|
4256
4621
|
)
|
|
4257
4622
|
|
|
4258
4623
|
/**
|
|
@@ -4292,7 +4657,7 @@ export const onError: {
|
|
|
4292
4657
|
<A, E, R, XE, XR>(
|
|
4293
4658
|
self: Micro<A, E, R>,
|
|
4294
4659
|
f: (cause: MicroCause<NoInfer<E>>) => Micro<void, XE, XR>
|
|
4295
|
-
): Micro<A, E | XE, R | XR> => onExitIf(self, exitIsFailure, (exit) => f(exit.
|
|
4660
|
+
): Micro<A, E | XE, R | XR> => onExitIf(self, exitIsFailure, (exit) => f(exit.cause))
|
|
4296
4661
|
)
|
|
4297
4662
|
|
|
4298
4663
|
/**
|
|
@@ -4344,7 +4709,7 @@ export const acquireUseRelease = <Resource, E, R, A, E2, R2, E3, R3>(
|
|
|
4344
4709
|
(a) =>
|
|
4345
4710
|
flatMap(
|
|
4346
4711
|
exit(restore(use(a))),
|
|
4347
|
-
(exit) => andThen(release(a, exit),
|
|
4712
|
+
(exit) => andThen(release(a, exit), exit)
|
|
4348
4713
|
)
|
|
4349
4714
|
)
|
|
4350
4715
|
)
|
|
@@ -4360,29 +4725,54 @@ export const acquireUseRelease = <Resource, E, R, A, E2, R2, E3, R3>(
|
|
|
4360
4725
|
* @experimental
|
|
4361
4726
|
* @category interruption
|
|
4362
4727
|
*/
|
|
4363
|
-
export const interrupt: Micro<never> =
|
|
4364
|
-
|
|
4365
|
-
|
|
4366
|
-
|
|
4728
|
+
export const interrupt: Micro<never> = failCause(causeInterrupt())
|
|
4729
|
+
|
|
4730
|
+
/**
|
|
4731
|
+
* Flag the effect as uninterruptible, which means that when the effect is
|
|
4732
|
+
* interrupted, it will be allowed to continue running until completion.
|
|
4733
|
+
*
|
|
4734
|
+
* @since 3.4.0
|
|
4735
|
+
* @experimental
|
|
4736
|
+
* @category flags
|
|
4737
|
+
*/
|
|
4738
|
+
export const uninterruptible = <A, E, R>(
|
|
4739
|
+
self: Micro<A, E, R>
|
|
4740
|
+
): Micro<A, E, R> =>
|
|
4741
|
+
withFiber((fiber) => {
|
|
4742
|
+
if (!fiber.interruptible) return self
|
|
4743
|
+
fiber.interruptible = false
|
|
4744
|
+
fiber._stack.push(setInterruptible(true))
|
|
4745
|
+
return self
|
|
4746
|
+
})
|
|
4747
|
+
|
|
4748
|
+
const setInterruptible: (interruptible: boolean) => Primitive = makePrimitive({
|
|
4749
|
+
op: "SetInterruptible",
|
|
4750
|
+
ensure(fiber) {
|
|
4751
|
+
fiber.interruptible = this[args]
|
|
4752
|
+
if (fiber._interrupted && fiber.interruptible) {
|
|
4753
|
+
return () => exitInterrupt
|
|
4754
|
+
}
|
|
4755
|
+
}
|
|
4367
4756
|
})
|
|
4368
4757
|
|
|
4369
4758
|
/**
|
|
4370
|
-
*
|
|
4371
|
-
*
|
|
4759
|
+
* Flag the effect as interruptible, which means that when the effect is
|
|
4760
|
+
* interrupted, it will be interrupted immediately.
|
|
4372
4761
|
*
|
|
4373
4762
|
* @since 3.4.0
|
|
4374
4763
|
* @experimental
|
|
4375
|
-
* @category
|
|
4764
|
+
* @category flags
|
|
4376
4765
|
*/
|
|
4377
|
-
export const
|
|
4378
|
-
|
|
4379
|
-
|
|
4380
|
-
|
|
4381
|
-
|
|
4382
|
-
|
|
4383
|
-
|
|
4384
|
-
|
|
4385
|
-
|
|
4766
|
+
export const interruptible = <A, E, R>(
|
|
4767
|
+
self: Micro<A, E, R>
|
|
4768
|
+
): Micro<A, E, R> =>
|
|
4769
|
+
withFiber((fiber) => {
|
|
4770
|
+
if (fiber.interruptible) return self
|
|
4771
|
+
fiber.interruptible = true
|
|
4772
|
+
fiber._stack.push(setInterruptible(false))
|
|
4773
|
+
if (fiber._interrupted) return exitInterrupt
|
|
4774
|
+
return self
|
|
4775
|
+
})
|
|
4386
4776
|
|
|
4387
4777
|
/**
|
|
4388
4778
|
* Wrap the given `Micro` effect in an uninterruptible region, preventing the
|
|
@@ -4395,6 +4785,7 @@ export const uninterruptible = <A, E, R>(self: Micro<A, E, R>): Micro<A, E, R> =
|
|
|
4395
4785
|
* @experimental
|
|
4396
4786
|
* @category interruption
|
|
4397
4787
|
* @example
|
|
4788
|
+
* ```ts
|
|
4398
4789
|
* import * as Micro from "effect/Micro"
|
|
4399
4790
|
*
|
|
4400
4791
|
* Micro.uninterruptibleMask((restore) =>
|
|
@@ -4402,44 +4793,18 @@ export const uninterruptible = <A, E, R>(self: Micro<A, E, R>): Micro<A, E, R> =
|
|
|
4402
4793
|
* Micro.andThen(restore(Micro.sleep(1000))) // interruptible
|
|
4403
4794
|
* )
|
|
4404
4795
|
* )
|
|
4796
|
+
* ```
|
|
4405
4797
|
*/
|
|
4406
4798
|
export const uninterruptibleMask = <A, E, R>(
|
|
4407
|
-
f: (
|
|
4799
|
+
f: (
|
|
4800
|
+
restore: <A, E, R>(effect: Micro<A, E, R>) => Micro<A, E, R>
|
|
4801
|
+
) => Micro<A, E, R>
|
|
4408
4802
|
): Micro<A, E, R> =>
|
|
4409
|
-
|
|
4410
|
-
|
|
4411
|
-
|
|
4412
|
-
|
|
4413
|
-
|
|
4414
|
-
env[currentInterruptible.key] = false
|
|
4415
|
-
env[currentAbortSignal.key] = new AbortController().signal
|
|
4416
|
-
return env
|
|
4417
|
-
}) :
|
|
4418
|
-
env
|
|
4419
|
-
effect[runSymbol](nextEnv, onExit)
|
|
4420
|
-
}, false)
|
|
4421
|
-
|
|
4422
|
-
/**
|
|
4423
|
-
* Wrap the given `Micro` effect in an interruptible region, allowing the effect
|
|
4424
|
-
* to be aborted.
|
|
4425
|
-
*
|
|
4426
|
-
* @since 3.4.0
|
|
4427
|
-
* @experimental
|
|
4428
|
-
* @category interruption
|
|
4429
|
-
*/
|
|
4430
|
-
export const interruptible = <A, E, R>(self: Micro<A, E, R>): Micro<A, E, R> =>
|
|
4431
|
-
make((env, onExit) => {
|
|
4432
|
-
const isInterruptible = envGet(env, currentInterruptible)
|
|
4433
|
-
let newEnv = env
|
|
4434
|
-
if (!isInterruptible) {
|
|
4435
|
-
const controller = envGet(env, currentAbortController)
|
|
4436
|
-
newEnv = envMutate(env, function(env) {
|
|
4437
|
-
env[currentInterruptible.key] = true
|
|
4438
|
-
env[currentAbortSignal.key] = controller.signal
|
|
4439
|
-
return env
|
|
4440
|
-
})
|
|
4441
|
-
}
|
|
4442
|
-
self[runSymbol](newEnv, onExit)
|
|
4803
|
+
withFiber((fiber) => {
|
|
4804
|
+
if (!fiber.interruptible) return f(identity)
|
|
4805
|
+
fiber.interruptible = false
|
|
4806
|
+
fiber._stack.push(setInterruptible(true))
|
|
4807
|
+
return f(interruptible)
|
|
4443
4808
|
})
|
|
4444
4809
|
|
|
4445
4810
|
// ========================================================================
|
|
@@ -4559,6 +4924,34 @@ export const all = <
|
|
|
4559
4924
|
}) as any
|
|
4560
4925
|
}
|
|
4561
4926
|
|
|
4927
|
+
/**
|
|
4928
|
+
* @since 3.11.0
|
|
4929
|
+
* @experimental
|
|
4930
|
+
* @category collecting & elements
|
|
4931
|
+
*/
|
|
4932
|
+
export const whileLoop: <A, E, R>(options: {
|
|
4933
|
+
readonly while: LazyArg<boolean>
|
|
4934
|
+
readonly body: LazyArg<Micro<A, E, R>>
|
|
4935
|
+
readonly step: (a: A) => void
|
|
4936
|
+
}) => Micro<void, E, R> = makePrimitive({
|
|
4937
|
+
op: "While",
|
|
4938
|
+
contA(value, fiber) {
|
|
4939
|
+
this[args].step(value)
|
|
4940
|
+
if (this[args].while()) {
|
|
4941
|
+
fiber._stack.push(this)
|
|
4942
|
+
return this[args].body()
|
|
4943
|
+
}
|
|
4944
|
+
return exitVoid
|
|
4945
|
+
},
|
|
4946
|
+
eval(fiber) {
|
|
4947
|
+
if (this[args].while()) {
|
|
4948
|
+
fiber._stack.push(this)
|
|
4949
|
+
return this[args].body()
|
|
4950
|
+
}
|
|
4951
|
+
return exitVoid
|
|
4952
|
+
}
|
|
4953
|
+
})
|
|
4954
|
+
|
|
4562
4955
|
/**
|
|
4563
4956
|
* For each element of the provided iterable, run the effect and collect the results.
|
|
4564
4957
|
*
|
|
@@ -4624,64 +5017,89 @@ export const forEach: {
|
|
|
4624
5017
|
readonly concurrency?: Concurrency | undefined
|
|
4625
5018
|
readonly discard?: boolean | undefined
|
|
4626
5019
|
}): Micro<any, E, R> =>
|
|
4627
|
-
|
|
5020
|
+
withFiber((parent) => {
|
|
4628
5021
|
const concurrencyOption = options?.concurrency === "inherit"
|
|
4629
|
-
?
|
|
5022
|
+
? parent.getRef(CurrentConcurrency)
|
|
4630
5023
|
: options?.concurrency ?? 1
|
|
4631
5024
|
const concurrency = concurrencyOption === "unbounded"
|
|
4632
5025
|
? Number.POSITIVE_INFINITY
|
|
4633
5026
|
: Math.max(1, concurrencyOption)
|
|
4634
5027
|
|
|
4635
|
-
|
|
4636
|
-
const [envWithSignal, onAbort] = forkSignal(env)
|
|
4637
|
-
|
|
4638
|
-
// iterate
|
|
4639
|
-
let result: MicroExit<any, any> | undefined = undefined
|
|
4640
|
-
const items = Array.from(iterable)
|
|
5028
|
+
const items = Arr.fromIterable(iterable)
|
|
4641
5029
|
let length = items.length
|
|
4642
5030
|
if (length === 0) {
|
|
4643
|
-
return
|
|
5031
|
+
return options?.discard ? void_ : succeed([])
|
|
4644
5032
|
}
|
|
5033
|
+
|
|
4645
5034
|
const out: Array<B> | undefined = options?.discard ? undefined : new Array(length)
|
|
4646
5035
|
let index = 0
|
|
4647
|
-
|
|
4648
|
-
|
|
4649
|
-
|
|
4650
|
-
|
|
4651
|
-
|
|
4652
|
-
|
|
4653
|
-
|
|
4654
|
-
|
|
4655
|
-
|
|
4656
|
-
|
|
4657
|
-
|
|
4658
|
-
|
|
4659
|
-
|
|
4660
|
-
|
|
4661
|
-
|
|
4662
|
-
|
|
4663
|
-
|
|
5036
|
+
|
|
5037
|
+
if (concurrency === 1) {
|
|
5038
|
+
return as(
|
|
5039
|
+
whileLoop({
|
|
5040
|
+
while: () => index < items.length,
|
|
5041
|
+
body: () => f(items[index], index),
|
|
5042
|
+
step: out ?
|
|
5043
|
+
(b) => out[index++] = b :
|
|
5044
|
+
(_) => index++
|
|
5045
|
+
}),
|
|
5046
|
+
out as any
|
|
5047
|
+
)
|
|
5048
|
+
}
|
|
5049
|
+
return async((resume) => {
|
|
5050
|
+
const fibers = new Set<Fiber<unknown, unknown>>()
|
|
5051
|
+
let result: MicroExit<any, any> | undefined = undefined
|
|
5052
|
+
let inProgress = 0
|
|
5053
|
+
let doneCount = 0
|
|
5054
|
+
let pumping = false
|
|
5055
|
+
let interrupted = false
|
|
5056
|
+
function pump() {
|
|
5057
|
+
pumping = true
|
|
5058
|
+
while (inProgress < concurrency && index < length) {
|
|
5059
|
+
const currentIndex = index
|
|
5060
|
+
const item = items[currentIndex]
|
|
5061
|
+
index++
|
|
5062
|
+
inProgress++
|
|
5063
|
+
try {
|
|
5064
|
+
const child = unsafeFork(parent, f(item, currentIndex), true, true)
|
|
5065
|
+
fibers.add(child)
|
|
5066
|
+
child.addObserver((exit) => {
|
|
5067
|
+
fibers.delete(child)
|
|
5068
|
+
if (interrupted) {
|
|
5069
|
+
return
|
|
5070
|
+
} else if (exit._tag === "Failure") {
|
|
5071
|
+
if (result === undefined) {
|
|
5072
|
+
result = exit
|
|
5073
|
+
length = index
|
|
5074
|
+
fibers.forEach((fiber) => fiber.unsafeInterrupt())
|
|
5075
|
+
}
|
|
5076
|
+
} else if (out !== undefined) {
|
|
5077
|
+
out[currentIndex] = exit.value
|
|
4664
5078
|
}
|
|
4665
|
-
|
|
4666
|
-
|
|
4667
|
-
|
|
4668
|
-
|
|
4669
|
-
|
|
4670
|
-
|
|
4671
|
-
|
|
4672
|
-
}
|
|
4673
|
-
|
|
4674
|
-
|
|
4675
|
-
|
|
4676
|
-
|
|
4677
|
-
|
|
4678
|
-
length = index
|
|
4679
|
-
onAbort()
|
|
5079
|
+
doneCount++
|
|
5080
|
+
inProgress--
|
|
5081
|
+
if (doneCount === length) {
|
|
5082
|
+
resume(result ?? succeed(out))
|
|
5083
|
+
} else if (!pumping && inProgress < concurrency) {
|
|
5084
|
+
pump()
|
|
5085
|
+
}
|
|
5086
|
+
})
|
|
5087
|
+
} catch (err) {
|
|
5088
|
+
result = exitDie(err)
|
|
5089
|
+
length = index
|
|
5090
|
+
fibers.forEach((fiber) => fiber.unsafeInterrupt())
|
|
5091
|
+
}
|
|
4680
5092
|
}
|
|
5093
|
+
pumping = false
|
|
4681
5094
|
}
|
|
4682
|
-
|
|
4683
|
-
|
|
4684
|
-
|
|
5095
|
+
pump()
|
|
5096
|
+
|
|
5097
|
+
return suspend(() => {
|
|
5098
|
+
interrupted = true
|
|
5099
|
+
index = length
|
|
5100
|
+
return fiberInterruptAll(fibers)
|
|
5101
|
+
})
|
|
5102
|
+
})
|
|
4685
5103
|
})
|
|
4686
5104
|
|
|
4687
5105
|
/**
|
|
@@ -4831,151 +5249,9 @@ export {
|
|
|
4831
5249
|
}
|
|
4832
5250
|
|
|
4833
5251
|
// ----------------------------------------------------------------------------
|
|
4834
|
-
//
|
|
5252
|
+
// fibers & forking
|
|
4835
5253
|
// ----------------------------------------------------------------------------
|
|
4836
5254
|
|
|
4837
|
-
/**
|
|
4838
|
-
* @since 3.4.0
|
|
4839
|
-
* @experimental
|
|
4840
|
-
* @category handle & forking
|
|
4841
|
-
*/
|
|
4842
|
-
export const HandleTypeId: unique symbol = Symbol.for("effect/Micro/Handle")
|
|
4843
|
-
|
|
4844
|
-
/**
|
|
4845
|
-
* @since 3.4.0
|
|
4846
|
-
* @experimental
|
|
4847
|
-
* @category handle & forking
|
|
4848
|
-
*/
|
|
4849
|
-
export type HandleTypeId = typeof HandleTypeId
|
|
4850
|
-
|
|
4851
|
-
/**
|
|
4852
|
-
* @since 3.4.0
|
|
4853
|
-
* @experimental
|
|
4854
|
-
* @category handle & forking
|
|
4855
|
-
*/
|
|
4856
|
-
export interface Handle<A, E = never> extends Micro<A, E> {
|
|
4857
|
-
readonly [HandleTypeId]: HandleTypeId
|
|
4858
|
-
readonly await: Micro<MicroExit<A, E>>
|
|
4859
|
-
readonly join: Micro<A, E>
|
|
4860
|
-
readonly interrupt: Micro<MicroExit<A, E>>
|
|
4861
|
-
readonly unsafeInterrupt: () => void
|
|
4862
|
-
readonly addObserver: (observer: (exit: MicroExit<A, E>) => void) => void
|
|
4863
|
-
readonly removeObserver: (observer: (exit: MicroExit<A, E>) => void) => void
|
|
4864
|
-
readonly unsafePoll: () => MicroExit<A, E> | null
|
|
4865
|
-
|
|
4866
|
-
[Unify.typeSymbol]?: unknown
|
|
4867
|
-
[Unify.unifySymbol]?: HandleUnify<this>
|
|
4868
|
-
[Unify.ignoreSymbol]?: HandleUnifyIgnore
|
|
4869
|
-
}
|
|
4870
|
-
|
|
4871
|
-
/**
|
|
4872
|
-
* @category models
|
|
4873
|
-
* @since 3.8.4
|
|
4874
|
-
* @experimental
|
|
4875
|
-
*/
|
|
4876
|
-
export interface HandleUnify<A extends { [Unify.typeSymbol]?: any }> extends MicroUnify<A> {
|
|
4877
|
-
Handle?: () => A[Unify.typeSymbol] extends Handle<infer A0, infer E0> | infer _ ? Handle<A0, E0> : never
|
|
4878
|
-
}
|
|
4879
|
-
|
|
4880
|
-
/**
|
|
4881
|
-
* @category models
|
|
4882
|
-
* @since 3.8.4
|
|
4883
|
-
* @experimental
|
|
4884
|
-
*/
|
|
4885
|
-
export interface HandleUnifyIgnore extends MicroUnifyIgnore {
|
|
4886
|
-
Micro?: true
|
|
4887
|
-
}
|
|
4888
|
-
|
|
4889
|
-
/**
|
|
4890
|
-
* @since 3.4.0
|
|
4891
|
-
* @experimental
|
|
4892
|
-
* @category handle & forking
|
|
4893
|
-
*/
|
|
4894
|
-
export const isHandle = (u: unknown): u is Handle<unknown, unknown> =>
|
|
4895
|
-
typeof u === "object" && u !== null && HandleTypeId in u
|
|
4896
|
-
|
|
4897
|
-
class HandleImpl<A, E> extends Class<A, E> implements Handle<A, E> {
|
|
4898
|
-
readonly [HandleTypeId]: HandleTypeId
|
|
4899
|
-
|
|
4900
|
-
readonly observers: Set<(exit: MicroExit<A, E>) => void> = new Set()
|
|
4901
|
-
private _exit: MicroExit<A, E> | undefined = undefined
|
|
4902
|
-
_controller: AbortController
|
|
4903
|
-
readonly isRoot: boolean
|
|
4904
|
-
|
|
4905
|
-
constructor(readonly parentSignal: AbortSignal, controller?: AbortController) {
|
|
4906
|
-
super()
|
|
4907
|
-
this[HandleTypeId] = HandleTypeId
|
|
4908
|
-
this.isRoot = controller !== undefined
|
|
4909
|
-
this._controller = controller ?? new AbortController()
|
|
4910
|
-
if (!this.isRoot) {
|
|
4911
|
-
parentSignal.addEventListener("abort", this.unsafeInterrupt)
|
|
4912
|
-
}
|
|
4913
|
-
}
|
|
4914
|
-
|
|
4915
|
-
unsafePoll(): MicroExit<A, E> | null {
|
|
4916
|
-
return this._exit ?? null
|
|
4917
|
-
}
|
|
4918
|
-
|
|
4919
|
-
unsafeInterrupt = () => {
|
|
4920
|
-
this._controller.abort()
|
|
4921
|
-
}
|
|
4922
|
-
|
|
4923
|
-
emit(exit: MicroExit<A, E>): void {
|
|
4924
|
-
if (this._exit) {
|
|
4925
|
-
return
|
|
4926
|
-
}
|
|
4927
|
-
this._exit = exit
|
|
4928
|
-
if (!this.isRoot) {
|
|
4929
|
-
this.parentSignal.removeEventListener("abort", this.unsafeInterrupt)
|
|
4930
|
-
}
|
|
4931
|
-
this.observers.forEach((observer) => observer(exit))
|
|
4932
|
-
this.observers.clear()
|
|
4933
|
-
}
|
|
4934
|
-
|
|
4935
|
-
addObserver(observer: (exit: MicroExit<A, E>) => void): void {
|
|
4936
|
-
if (this._exit) {
|
|
4937
|
-
return observer(this._exit)
|
|
4938
|
-
}
|
|
4939
|
-
this.observers.add(observer)
|
|
4940
|
-
}
|
|
4941
|
-
|
|
4942
|
-
removeObserver(observer: (exit: MicroExit<A, E>) => void): void {
|
|
4943
|
-
this.observers.delete(observer)
|
|
4944
|
-
}
|
|
4945
|
-
|
|
4946
|
-
get await(): Micro<MicroExit<A, E>> {
|
|
4947
|
-
return suspend(() => {
|
|
4948
|
-
if (this._exit) {
|
|
4949
|
-
return succeed(this._exit)
|
|
4950
|
-
}
|
|
4951
|
-
return async((resume) => {
|
|
4952
|
-
function observer(exit: MicroExit<A, E>) {
|
|
4953
|
-
resume(succeed(exit))
|
|
4954
|
-
}
|
|
4955
|
-
this.addObserver(observer)
|
|
4956
|
-
return sync(() => {
|
|
4957
|
-
this.removeObserver(observer)
|
|
4958
|
-
})
|
|
4959
|
-
})
|
|
4960
|
-
})
|
|
4961
|
-
}
|
|
4962
|
-
|
|
4963
|
-
get join(): Micro<A, E> {
|
|
4964
|
-
return flatMap(this.await, fromExit)
|
|
4965
|
-
}
|
|
4966
|
-
|
|
4967
|
-
get interrupt(): Micro<MicroExit<A, E>> {
|
|
4968
|
-
return suspend(() => {
|
|
4969
|
-
this.unsafeInterrupt()
|
|
4970
|
-
return this.await
|
|
4971
|
-
})
|
|
4972
|
-
}
|
|
4973
|
-
|
|
4974
|
-
asMicro(): Micro<A, E> {
|
|
4975
|
-
return this.join
|
|
4976
|
-
}
|
|
4977
|
-
}
|
|
4978
|
-
|
|
4979
5255
|
/**
|
|
4980
5256
|
* Run the `Micro` effect in a new `Handle` that can be awaited, joined, or
|
|
4981
5257
|
* aborted.
|
|
@@ -4986,23 +5262,33 @@ class HandleImpl<A, E> extends Class<A, E> implements Handle<A, E> {
|
|
|
4986
5262
|
* @experimental
|
|
4987
5263
|
* @category handle & forking
|
|
4988
5264
|
*/
|
|
4989
|
-
export const fork = <A, E, R>(
|
|
4990
|
-
|
|
4991
|
-
|
|
4992
|
-
|
|
4993
|
-
|
|
4994
|
-
|
|
4995
|
-
map[currentAbortSignal.key] = handle._controller.signal
|
|
4996
|
-
return map
|
|
4997
|
-
})
|
|
4998
|
-
envGet(env, currentScheduler).scheduleTask(() => {
|
|
4999
|
-
self[runSymbol](nextEnv, (exit) => {
|
|
5000
|
-
handle.emit(exit)
|
|
5001
|
-
})
|
|
5002
|
-
}, 0)
|
|
5003
|
-
onExit(Either.right(handle))
|
|
5265
|
+
export const fork = <A, E, R>(
|
|
5266
|
+
self: Micro<A, E, R>
|
|
5267
|
+
): Micro<Fiber<A, E>, never, R> =>
|
|
5268
|
+
withFiber((fiber) => {
|
|
5269
|
+
fiberMiddleware.interruptChildren ??= fiberInterruptChildren
|
|
5270
|
+
return succeed(unsafeFork(fiber, self))
|
|
5004
5271
|
})
|
|
5005
5272
|
|
|
5273
|
+
const unsafeFork = <FA, FE, A, E, R>(
|
|
5274
|
+
parent: FiberImpl<FA, FE>,
|
|
5275
|
+
effect: Micro<A, E, R>,
|
|
5276
|
+
immediate = false,
|
|
5277
|
+
daemon = false
|
|
5278
|
+
): Fiber<A, E> => {
|
|
5279
|
+
const child = new FiberImpl<A, E>(parent.context, parent.interruptible)
|
|
5280
|
+
if (!daemon) {
|
|
5281
|
+
parent.children().add(child)
|
|
5282
|
+
child.addObserver(() => parent.children().delete(child))
|
|
5283
|
+
}
|
|
5284
|
+
if (immediate) {
|
|
5285
|
+
child.evaluate(effect as any)
|
|
5286
|
+
} else {
|
|
5287
|
+
parent.getRef(CurrentScheduler).scheduleTask(() => child.evaluate(effect as any), 0)
|
|
5288
|
+
}
|
|
5289
|
+
return child
|
|
5290
|
+
}
|
|
5291
|
+
|
|
5006
5292
|
/**
|
|
5007
5293
|
* Run the `Micro` effect in a new `Handle` that can be awaited, joined, or
|
|
5008
5294
|
* aborted.
|
|
@@ -5013,22 +5299,9 @@ export const fork = <A, E, R>(self: Micro<A, E, R>): Micro<Handle<A, E>, never,
|
|
|
5013
5299
|
* @experimental
|
|
5014
5300
|
* @category handle & forking
|
|
5015
5301
|
*/
|
|
5016
|
-
export const forkDaemon = <A, E, R>(
|
|
5017
|
-
|
|
5018
|
-
|
|
5019
|
-
const handle = new HandleImpl<A, E>(controller.signal, controller)
|
|
5020
|
-
const nextEnv = envMutate(env, (map) => {
|
|
5021
|
-
map[currentAbortController.key] = controller
|
|
5022
|
-
map[currentAbortSignal.key] = controller.signal
|
|
5023
|
-
return map
|
|
5024
|
-
})
|
|
5025
|
-
envGet(env, currentScheduler).scheduleTask(() => {
|
|
5026
|
-
self[runSymbol](nextEnv, (exit) => {
|
|
5027
|
-
handle.emit(exit)
|
|
5028
|
-
})
|
|
5029
|
-
}, 0)
|
|
5030
|
-
onExit(Either.right(handle))
|
|
5031
|
-
})
|
|
5302
|
+
export const forkDaemon = <A, E, R>(
|
|
5303
|
+
self: Micro<A, E, R>
|
|
5304
|
+
): Micro<Fiber<A, E>, never, R> => withFiber((fiber) => succeed(unsafeFork(fiber, self, false, true)))
|
|
5032
5305
|
|
|
5033
5306
|
/**
|
|
5034
5307
|
* Run the `Micro` effect in a new `Handle` that can be awaited, joined, or
|
|
@@ -5051,7 +5324,7 @@ export const forkIn: {
|
|
|
5051
5324
|
* @experimental
|
|
5052
5325
|
* @category handle & forking
|
|
5053
5326
|
*/
|
|
5054
|
-
(scope: MicroScope): <A, E, R>(self: Micro<A, E, R>) => Micro<
|
|
5327
|
+
(scope: MicroScope): <A, E, R>(self: Micro<A, E, R>) => Micro<Fiber<A, E>, never, R>
|
|
5055
5328
|
/**
|
|
5056
5329
|
* Run the `Micro` effect in a new `Handle` that can be awaited, joined, or
|
|
5057
5330
|
* aborted.
|
|
@@ -5062,15 +5335,15 @@ export const forkIn: {
|
|
|
5062
5335
|
* @experimental
|
|
5063
5336
|
* @category handle & forking
|
|
5064
5337
|
*/
|
|
5065
|
-
<A, E, R>(self: Micro<A, E, R>, scope: MicroScope): Micro<
|
|
5338
|
+
<A, E, R>(self: Micro<A, E, R>, scope: MicroScope): Micro<Fiber<A, E>, never, R>
|
|
5066
5339
|
} = dual(
|
|
5067
5340
|
2,
|
|
5068
|
-
<A, E, R>(self: Micro<A, E, R>, scope: MicroScope): Micro<
|
|
5341
|
+
<A, E, R>(self: Micro<A, E, R>, scope: MicroScope): Micro<Fiber<A, E>, never, R> =>
|
|
5069
5342
|
uninterruptibleMask((restore) =>
|
|
5070
5343
|
flatMap(scope.fork, (scope) =>
|
|
5071
5344
|
tap(
|
|
5072
5345
|
restore(forkDaemon(onExit(self, (exit) => scope.close(exit)))),
|
|
5073
|
-
(fiber) => scope.addFinalizer((_) =>
|
|
5346
|
+
(fiber) => scope.addFinalizer((_) => fiberInterrupt(fiber))
|
|
5074
5347
|
))
|
|
5075
5348
|
)
|
|
5076
5349
|
)
|
|
@@ -5085,7 +5358,7 @@ export const forkIn: {
|
|
|
5085
5358
|
* @experimental
|
|
5086
5359
|
* @category handle & forking
|
|
5087
5360
|
*/
|
|
5088
|
-
export const forkScoped = <A, E, R>(self: Micro<A, E, R>): Micro<
|
|
5361
|
+
export const forkScoped = <A, E, R>(self: Micro<A, E, R>): Micro<Fiber<A, E>, never, R | MicroScope> =>
|
|
5089
5362
|
flatMap(scope, (scope) => forkIn(self, scope))
|
|
5090
5363
|
|
|
5091
5364
|
// ----------------------------------------------------------------------------
|
|
@@ -5103,6 +5376,7 @@ export const forkScoped = <A, E, R>(self: Micro<A, E, R>): Micro<Handle<A, E>, n
|
|
|
5103
5376
|
* @experimental
|
|
5104
5377
|
* @category execution
|
|
5105
5378
|
* @example
|
|
5379
|
+
* ```ts
|
|
5106
5380
|
* import * as Micro from "effect/Micro"
|
|
5107
5381
|
*
|
|
5108
5382
|
* const handle = Micro.succeed(42).pipe(
|
|
@@ -5113,6 +5387,7 @@ export const forkScoped = <A, E, R>(self: Micro<A, E, R>): Micro<Handle<A, E>, n
|
|
|
5113
5387
|
* handle.addObserver((exit) => {
|
|
5114
5388
|
* console.log(exit)
|
|
5115
5389
|
* })
|
|
5390
|
+
* ```
|
|
5116
5391
|
*/
|
|
5117
5392
|
export const runFork = <A, E>(
|
|
5118
5393
|
effect: Micro<A, E>,
|
|
@@ -5120,28 +5395,21 @@ export const runFork = <A, E>(
|
|
|
5120
5395
|
readonly signal?: AbortSignal | undefined
|
|
5121
5396
|
readonly scheduler?: MicroScheduler | undefined
|
|
5122
5397
|
} | undefined
|
|
5123
|
-
):
|
|
5124
|
-
const
|
|
5125
|
-
|
|
5126
|
-
|
|
5127
|
-
|
|
5128
|
-
refs[currentScheduler.key] = options?.scheduler ?? new MicroSchedulerDefault()
|
|
5129
|
-
const env = envMake(refs)
|
|
5130
|
-
const handle = new HandleImpl<A, E>(controller.signal, controller)
|
|
5131
|
-
effect[runSymbol](envSet(env, currentAbortSignal, handle._controller.signal), (exit) => {
|
|
5132
|
-
handle.emit(exit)
|
|
5133
|
-
if (options?.signal) {
|
|
5134
|
-
options.signal.removeEventListener("abort", handle.unsafeInterrupt)
|
|
5135
|
-
}
|
|
5136
|
-
})
|
|
5398
|
+
): FiberImpl<A, E> => {
|
|
5399
|
+
const fiber = new FiberImpl<A, E>(CurrentScheduler.context(
|
|
5400
|
+
options?.scheduler ?? new MicroSchedulerDefault()
|
|
5401
|
+
))
|
|
5402
|
+
fiber.evaluate(effect as any)
|
|
5137
5403
|
if (options?.signal) {
|
|
5138
5404
|
if (options.signal.aborted) {
|
|
5139
|
-
|
|
5405
|
+
fiber.unsafeInterrupt()
|
|
5140
5406
|
} else {
|
|
5141
|
-
|
|
5407
|
+
const abort = () => fiber.unsafeInterrupt()
|
|
5408
|
+
options.signal.addEventListener("abort", abort, { once: true })
|
|
5409
|
+
fiber.addObserver(() => options.signal!.removeEventListener("abort", abort))
|
|
5142
5410
|
}
|
|
5143
5411
|
}
|
|
5144
|
-
return
|
|
5412
|
+
return fiber
|
|
5145
5413
|
}
|
|
5146
5414
|
|
|
5147
5415
|
/**
|
|
@@ -5180,10 +5448,10 @@ export const runPromise = <A, E>(
|
|
|
5180
5448
|
} | undefined
|
|
5181
5449
|
): Promise<A> =>
|
|
5182
5450
|
runPromiseExit(effect, options).then((exit) => {
|
|
5183
|
-
if (exit._tag === "
|
|
5184
|
-
throw exit.
|
|
5451
|
+
if (exit._tag === "Failure") {
|
|
5452
|
+
throw exit.cause
|
|
5185
5453
|
}
|
|
5186
|
-
return exit.
|
|
5454
|
+
return exit.value
|
|
5187
5455
|
})
|
|
5188
5456
|
|
|
5189
5457
|
/**
|
|
@@ -5198,13 +5466,9 @@ export const runPromise = <A, E>(
|
|
|
5198
5466
|
*/
|
|
5199
5467
|
export const runSyncExit = <A, E>(effect: Micro<A, E>): MicroExit<A, E> => {
|
|
5200
5468
|
const scheduler = new MicroSchedulerDefault()
|
|
5201
|
-
const
|
|
5469
|
+
const fiber = runFork(effect, { scheduler })
|
|
5202
5470
|
scheduler.flush()
|
|
5203
|
-
|
|
5204
|
-
if (exit === null) {
|
|
5205
|
-
return exitDie(handle)
|
|
5206
|
-
}
|
|
5207
|
-
return exit
|
|
5471
|
+
return fiber._exit ?? exitDie(fiber)
|
|
5208
5472
|
}
|
|
5209
5473
|
|
|
5210
5474
|
/**
|
|
@@ -5217,10 +5481,8 @@ export const runSyncExit = <A, E>(effect: Micro<A, E>): MicroExit<A, E> => {
|
|
|
5217
5481
|
*/
|
|
5218
5482
|
export const runSync = <A, E>(effect: Micro<A, E>): A => {
|
|
5219
5483
|
const exit = runSyncExit(effect)
|
|
5220
|
-
if (exit._tag === "
|
|
5221
|
-
|
|
5222
|
-
}
|
|
5223
|
-
return exit.right
|
|
5484
|
+
if (exit._tag === "Failure") throw exit.cause
|
|
5485
|
+
return exit.value
|
|
5224
5486
|
}
|
|
5225
5487
|
|
|
5226
5488
|
// ----------------------------------------------------------------------------
|
|
@@ -5233,35 +5495,35 @@ export const runSync = <A, E>(effect: Micro<A, E>): A => {
|
|
|
5233
5495
|
* @category errors
|
|
5234
5496
|
*/
|
|
5235
5497
|
export interface YieldableError extends Pipeable, Inspectable, Readonly<Error> {
|
|
5236
|
-
readonly [EffectTypeId]: Effect.VarianceStruct<never, this, never>
|
|
5237
|
-
readonly [StreamTypeId]: Stream.VarianceStruct<never, this, never>
|
|
5238
|
-
readonly [SinkTypeId]: Sink.VarianceStruct<never, unknown, never, this, never>
|
|
5239
|
-
readonly [ChannelTypeId]: Channel.VarianceStruct<never, unknown, this, unknown, never, unknown, never>
|
|
5498
|
+
readonly [Effectable.EffectTypeId]: Effect.VarianceStruct<never, this, never>
|
|
5499
|
+
readonly [Effectable.StreamTypeId]: Stream.VarianceStruct<never, this, never>
|
|
5500
|
+
readonly [Effectable.SinkTypeId]: Sink.VarianceStruct<never, unknown, never, this, never>
|
|
5501
|
+
readonly [Effectable.ChannelTypeId]: Channel.VarianceStruct<never, unknown, this, unknown, never, unknown, never>
|
|
5240
5502
|
readonly [TypeId]: Micro.Variance<never, this, never>
|
|
5241
|
-
readonly [runSymbol]: (env: Env<any>, onExit: (exit: MicroExit<never, this>) => void) => void
|
|
5242
5503
|
[Symbol.iterator](): MicroIterator<Micro<never, this, never>>
|
|
5243
5504
|
}
|
|
5244
5505
|
|
|
5245
5506
|
const YieldableError: new(message?: string) => YieldableError = (function() {
|
|
5246
|
-
class YieldableError extends globalThis.Error {
|
|
5247
|
-
|
|
5248
|
-
|
|
5249
|
-
|
|
5250
|
-
|
|
5507
|
+
class YieldableError extends globalThis.Error {}
|
|
5508
|
+
Object.assign(YieldableError.prototype, MicroProto, StructuralPrototype, {
|
|
5509
|
+
[identifier]: "Failure",
|
|
5510
|
+
[evaluate]() {
|
|
5511
|
+
return fail(this)
|
|
5512
|
+
},
|
|
5513
|
+
toString(this: Error) {
|
|
5251
5514
|
return this.message ? `${this.name}: ${this.message}` : this.name
|
|
5252
|
-
}
|
|
5515
|
+
},
|
|
5253
5516
|
toJSON() {
|
|
5254
5517
|
return { ...this }
|
|
5255
|
-
}
|
|
5256
|
-
[NodeInspectSymbol](): string {
|
|
5518
|
+
},
|
|
5519
|
+
[NodeInspectSymbol](this: Error): string {
|
|
5257
5520
|
const stack = this.stack
|
|
5258
5521
|
if (stack) {
|
|
5259
5522
|
return `${this.toString()}\n${stack.split("\n").slice(1).join("\n")}`
|
|
5260
5523
|
}
|
|
5261
5524
|
return this.toString()
|
|
5262
5525
|
}
|
|
5263
|
-
}
|
|
5264
|
-
Object.assign(YieldableError.prototype, MicroProto, StructuralPrototype)
|
|
5526
|
+
})
|
|
5265
5527
|
return YieldableError as any
|
|
5266
5528
|
})()
|
|
5267
5529
|
|