effect-app 4.0.0 → 4.0.2
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/CHANGELOG.md +21 -0
- package/dist/Array.d.ts +0 -17
- package/dist/Array.d.ts.map +1 -1
- package/dist/Array.js +2 -26
- package/dist/Chunk.d.ts +3 -27
- package/dist/Chunk.d.ts.map +1 -1
- package/dist/Chunk.js +4 -39
- package/dist/DateTime.d.ts +33 -0
- package/dist/DateTime.d.ts.map +1 -0
- package/dist/DateTime.js +18 -0
- package/dist/Effect.d.ts +0 -11
- package/dist/Effect.d.ts.map +1 -1
- package/dist/Effect.js +3 -18
- package/dist/Function.d.ts +0 -4
- package/dist/Function.d.ts.map +1 -1
- package/dist/Function.js +1 -7
- package/dist/Model/Repository/internal/internal.d.ts.map +1 -1
- package/dist/Model/Repository/internal/internal.js +4 -5
- package/dist/Model/dsl.d.ts +4 -3
- package/dist/Model/dsl.d.ts.map +1 -1
- package/dist/Model/dsl.js +6 -4
- package/dist/Model/query/new-kid-interpreter.d.ts.map +1 -1
- package/dist/Model/query/new-kid-interpreter.js +5 -6
- package/dist/Option.d.ts +0 -2
- package/dist/Option.d.ts.map +1 -1
- package/dist/Option.js +1 -7
- package/dist/Pure.d.ts +4 -4
- package/dist/Pure.d.ts.map +1 -1
- package/dist/Pure.js +16 -16
- package/dist/Schema/ext.d.ts +0 -21
- package/dist/Schema/ext.d.ts.map +1 -1
- package/dist/Schema/ext.js +4 -10
- package/dist/Schema.d.ts +1 -1
- package/dist/Schema.d.ts.map +1 -1
- package/dist/Schema.js +2 -2
- package/dist/Set.d.ts.map +1 -1
- package/dist/Set.js +6 -5
- package/dist/client/apiClientFactory.d.ts.map +1 -1
- package/dist/client/apiClientFactory.js +7 -6
- package/dist/migration/nativeEffect.d.ts +21 -0
- package/dist/migration/nativeEffect.d.ts.map +1 -0
- package/dist/migration/nativeEffect.js +598 -0
- package/dist/utils.d.ts +0 -6
- package/dist/utils.d.ts.map +1 -1
- package/dist/utils.js +1 -13
- package/dist/waitingGate.d.ts +38 -0
- package/dist/waitingGate.d.ts.map +1 -0
- package/dist/waitingGate.js +63 -0
- package/dist/withToast.d.ts.map +1 -1
- package/dist/withToast.js +42 -3
- package/package.json +2 -3
- package/src/Array.ts +4 -36
- package/src/Chunk.ts +4 -53
- package/src/DateTime.ts +473 -0
- package/src/Effect.ts +3 -22
- package/src/Function.ts +0 -7
- package/src/Model/Repository/internal/internal.ts +3 -4
- package/src/Model/dsl.ts +5 -4
- package/src/Model/query/new-kid-interpreter.ts +4 -5
- package/src/Option.ts +1 -8
- package/src/Pure.ts +15 -15
- package/src/Schema/ext.ts +3 -10
- package/src/Schema.ts +1 -1
- package/src/Set.ts +5 -4
- package/src/client/apiClientFactory.ts +8 -7
- package/src/migration/nativeEffect.ts +645 -0
- package/src/utils.ts +0 -17
- package/src/waitingGate.ts +82 -0
- package/src/withToast.ts +51 -5
- package/test/dateTimeLocal.test.ts +55 -0
- package/test/dist/dateTimeLocal.test.d.ts.map +1 -0
- package/test/dist/nativeEffectMigration.test.d.ts.map +1 -0
- package/test/dist/waitingGate.test.d.ts.map +1 -0
- package/test/nativeEffectMigration.test.ts +77 -0
- package/test/waitingGate.test.ts +64 -0
- package/dist/_ext/date.d.ts +0 -15
- package/dist/_ext/date.d.ts.map +0 -1
- package/dist/_ext/date.js +0 -16
- package/dist/_ext/misc.d.ts +0 -17
- package/dist/_ext/misc.d.ts.map +0 -1
- package/dist/_ext/misc.js +0 -19
- package/src/_ext/date.ts +0 -27
- package/src/_ext/misc.ts +0 -49
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
import * as Context from "./Context.ts"
|
|
2
|
+
import * as Effect from "./Effect.ts"
|
|
3
|
+
|
|
4
|
+
/**
|
|
5
|
+
* Notified with the suspension depth after each change. `0` means the command
|
|
6
|
+
* is doing work. A positive depth means it is parked on a caller.
|
|
7
|
+
*/
|
|
8
|
+
export type WaitingGateController = (depth: number) => Effect.Effect<void>
|
|
9
|
+
|
|
10
|
+
export interface WaitingGateShape {
|
|
11
|
+
/** `false` for the default gate. Suspension then changes nothing. */
|
|
12
|
+
readonly active: boolean
|
|
13
|
+
readonly depth: number
|
|
14
|
+
readonly add: (delta: number) => Effect.Effect<void>
|
|
15
|
+
/** Stack a controller. The returned function restores the previous one. */
|
|
16
|
+
readonly bind: (controller: WaitingGateController) => () => void
|
|
17
|
+
}
|
|
18
|
+
|
|
19
|
+
const inactiveWaitingGate: WaitingGateShape = {
|
|
20
|
+
active: false,
|
|
21
|
+
depth: 0,
|
|
22
|
+
add: () => Effect.void,
|
|
23
|
+
bind: () => () => {}
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
/**
|
|
27
|
+
* Per-command gate for {@link suspendWaiting}. Commands provide an active gate.
|
|
28
|
+
* The default is inactive, so the helper is a no-op outside a command.
|
|
29
|
+
*/
|
|
30
|
+
export const WaitingGate = Context.Reference<WaitingGateShape>("effect-app/WaitingGate", {
|
|
31
|
+
defaultValue: () => inactiveWaitingGate
|
|
32
|
+
})
|
|
33
|
+
|
|
34
|
+
/** Build the gate one command owns. `onDepth` runs synchronously inside `add`. */
|
|
35
|
+
export const makeWaitingGate = (onDepth?: (depth: number) => void): WaitingGateShape => {
|
|
36
|
+
let depth = 0
|
|
37
|
+
let controller: WaitingGateController | undefined
|
|
38
|
+
return {
|
|
39
|
+
active: true,
|
|
40
|
+
get depth() {
|
|
41
|
+
return depth
|
|
42
|
+
},
|
|
43
|
+
add: (delta) =>
|
|
44
|
+
Effect.uninterruptible(Effect.gen(function*() {
|
|
45
|
+
depth += delta
|
|
46
|
+
if (depth < 0) depth = 0
|
|
47
|
+
const next = depth
|
|
48
|
+
onDepth?.(next)
|
|
49
|
+
if (controller) yield* controller(next)
|
|
50
|
+
})),
|
|
51
|
+
bind: (next) => {
|
|
52
|
+
const previous = controller
|
|
53
|
+
controller = next
|
|
54
|
+
return () => {
|
|
55
|
+
if (controller === next) controller = previous
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
|
|
61
|
+
/**
|
|
62
|
+
* Run `self` while command chrome is quiet.
|
|
63
|
+
*
|
|
64
|
+
* The spinner and the waiting toast pause for `self` and resume when it
|
|
65
|
+
* finishes, including when it is interrupted. The command stays blocked for
|
|
66
|
+
* the whole run, so the button cannot start again.
|
|
67
|
+
*
|
|
68
|
+
* Outside a command the default gate is inactive and `self` runs unchanged.
|
|
69
|
+
*
|
|
70
|
+
* ```ts
|
|
71
|
+
* const decision = yield* suspendWaiting(ask(pickupDate))
|
|
72
|
+
* yield* close(orderId)
|
|
73
|
+
* ```
|
|
74
|
+
*/
|
|
75
|
+
export const suspendWaiting = <A, E, R>(self: Effect.Effect<A, E, R>): Effect.Effect<A, E, R> =>
|
|
76
|
+
Effect.uninterruptibleMask((restore) =>
|
|
77
|
+
Effect.gen(function*() {
|
|
78
|
+
const gate = yield* WaitingGate
|
|
79
|
+
yield* gate.add(1)
|
|
80
|
+
return yield* Effect.ensuring(restore(self), gate.add(-1))
|
|
81
|
+
})
|
|
82
|
+
)
|
package/src/withToast.ts
CHANGED
|
@@ -7,6 +7,7 @@ import type * as Option from "./Option.ts"
|
|
|
7
7
|
import * as S from "./Schema.ts"
|
|
8
8
|
import { CurrentToastId, Toast, type ToastId } from "./toast.ts"
|
|
9
9
|
import { wrapEffect } from "./utils.ts"
|
|
10
|
+
import { WaitingGate } from "./waitingGate.ts"
|
|
10
11
|
|
|
11
12
|
export interface ToastOptions<A, E, Args extends ReadonlyArray<unknown>, WaiR, SucR, ErrR> {
|
|
12
13
|
stableToastId?: undefined | string | ((...args: Args) => string | undefined)
|
|
@@ -66,12 +67,57 @@ export class WithToast extends Context.Service<WithToast>()("WithToast", {
|
|
|
66
67
|
? stableToastId
|
|
67
68
|
: stableToastId ?? `wait-${Math.random().toString(36).slice(2)}`
|
|
68
69
|
|
|
69
|
-
const
|
|
70
|
-
|
|
71
|
-
|
|
70
|
+
const gate = yield* WaitingGate
|
|
71
|
+
let waitingFiber: Fiber.Fiber<void> | undefined
|
|
72
|
+
let toastShown = false
|
|
73
|
+
let unbind = () => {}
|
|
74
|
+
|
|
75
|
+
const armWaiting = () =>
|
|
76
|
+
Effect.gen(function*() {
|
|
77
|
+
if (waitingFiber !== undefined || t === null || toastId === undefined) return
|
|
78
|
+
waitingFiber = yield* Effect.forkChild(
|
|
79
|
+
Effect.sleep("1 seconds").pipe(
|
|
80
|
+
Effect.andThen(Effect.uninterruptible(Effect.gen(function*() {
|
|
81
|
+
toastShown = true
|
|
82
|
+
yield* toast.info(t, { id: toastId, timeout: Infinity, ...meta })
|
|
83
|
+
}))),
|
|
84
|
+
Effect.asVoid
|
|
85
|
+
)
|
|
86
|
+
)
|
|
87
|
+
})
|
|
88
|
+
|
|
89
|
+
const disarmWaiting = () =>
|
|
90
|
+
Effect.gen(function*() {
|
|
91
|
+
const fiber = waitingFiber
|
|
92
|
+
waitingFiber = undefined
|
|
93
|
+
if (fiber) yield* Fiber.interrupt(fiber)
|
|
94
|
+
if (toastShown && toastId !== undefined) {
|
|
95
|
+
toastShown = false
|
|
96
|
+
yield* toast.dismiss(toastId)
|
|
97
|
+
}
|
|
98
|
+
})
|
|
99
|
+
|
|
100
|
+
// An active gate pauses the toast while `suspendWaiting` is parked and
|
|
101
|
+
// starts a fresh one-second delay when work resumes. The inactive
|
|
102
|
+
// default keeps the original fork.
|
|
103
|
+
if (t !== null && gate.active) {
|
|
104
|
+
unbind = gate.bind((depth) => (depth === 0 ? armWaiting() : disarmWaiting()))
|
|
105
|
+
if (gate.depth === 0) yield* armWaiting()
|
|
106
|
+
} else if (t !== null) {
|
|
107
|
+
waitingFiber = yield* Effect.forkChild(
|
|
108
|
+
Effect.sleep("1 seconds").pipe(
|
|
109
|
+
Effect.andThen(toast.info(t, { id: toastId!, timeout: Infinity, ...meta })),
|
|
110
|
+
Effect.asVoid
|
|
111
|
+
)
|
|
72
112
|
)
|
|
73
|
-
|
|
74
|
-
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
const interruptWaiting = Effect.uninterruptible(Effect.gen(function*() {
|
|
116
|
+
unbind()
|
|
117
|
+
const fiber = waitingFiber
|
|
118
|
+
waitingFiber = undefined
|
|
119
|
+
if (fiber) yield* Fiber.interrupt(fiber)
|
|
120
|
+
}))
|
|
75
121
|
|
|
76
122
|
return yield* self.pipe(
|
|
77
123
|
Effect.tap(Effect.fnUntraced(function*(a) {
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
import { makeZonedLocal, pipeZonedLocal } from "effect-app/DateTime"
|
|
2
|
+
import * as DateTime from "effect/DateTime"
|
|
3
|
+
import { describe, expect, test } from "vitest"
|
|
4
|
+
|
|
5
|
+
describe("local Date helpers", () => {
|
|
6
|
+
const start = new Date("2024-03-09T17:00:00.000Z")
|
|
7
|
+
|
|
8
|
+
test("makeZonedLocal keeps the instant and uses the process zone", () => {
|
|
9
|
+
const zoned = makeZonedLocal(start)
|
|
10
|
+
expect(zoned.epochMilliseconds).toBe(start.getTime())
|
|
11
|
+
expect(DateTime.zoneToString(zoned.zone)).toBe(DateTime.zoneToString(DateTime.zoneMakeLocal()))
|
|
12
|
+
})
|
|
13
|
+
|
|
14
|
+
test("pipeZonedLocal adds a local calendar day and returns the instant", () => {
|
|
15
|
+
const expected = new Date(start.getTime())
|
|
16
|
+
expected.setDate(expected.getDate() + 1)
|
|
17
|
+
expect(pipeZonedLocal(start, DateTime.add({ days: 1 })).getTime()).toBe(expected.getTime())
|
|
18
|
+
})
|
|
19
|
+
|
|
20
|
+
test("pipeZonedLocal runs every step before toDateUtc", () => {
|
|
21
|
+
const expected = new Date(start.getTime())
|
|
22
|
+
expected.setDate(expected.getDate() + 1)
|
|
23
|
+
expected.setMonth(expected.getMonth() + 1)
|
|
24
|
+
const result = pipeZonedLocal(start, DateTime.add({ days: 1 }), DateTime.add({ months: 1 }))
|
|
25
|
+
expect(result.getTime()).toBe(expected.getTime())
|
|
26
|
+
})
|
|
27
|
+
|
|
28
|
+
test("pipeZonedLocal accepts as many functions as pipe", () => {
|
|
29
|
+
const keep = <A extends DateTime.DateTime>(self: A) => self
|
|
30
|
+
const expected = new Date(start.getTime())
|
|
31
|
+
expected.setDate(expected.getDate() + 1)
|
|
32
|
+
const result = pipeZonedLocal(
|
|
33
|
+
start,
|
|
34
|
+
keep,
|
|
35
|
+
keep,
|
|
36
|
+
keep,
|
|
37
|
+
keep,
|
|
38
|
+
keep,
|
|
39
|
+
keep,
|
|
40
|
+
keep,
|
|
41
|
+
keep,
|
|
42
|
+
keep,
|
|
43
|
+
keep,
|
|
44
|
+
keep,
|
|
45
|
+
keep,
|
|
46
|
+
keep,
|
|
47
|
+
keep,
|
|
48
|
+
keep,
|
|
49
|
+
keep,
|
|
50
|
+
keep,
|
|
51
|
+
DateTime.add({ days: 1 })
|
|
52
|
+
)
|
|
53
|
+
expect(result.getTime()).toBe(expected.getTime())
|
|
54
|
+
})
|
|
55
|
+
})
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"dateTimeLocal.test.d.ts","sourceRoot":"","sources":["../dateTimeLocal.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"nativeEffectMigration.test.d.ts","sourceRoot":"","sources":["../nativeEffectMigration.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"waitingGate.test.d.ts","sourceRoot":"","sources":["../waitingGate.test.ts"],"names":[],"mappings":""}
|
|
@@ -0,0 +1,77 @@
|
|
|
1
|
+
import { migrateEffectAppSource } from "effect-app/migration/nativeEffect"
|
|
2
|
+
import { describe, expect, test } from "vitest"
|
|
3
|
+
|
|
4
|
+
describe("migrateEffectAppSource", () => {
|
|
5
|
+
test("rewrites named helpers and keeps the other imports", () => {
|
|
6
|
+
const source = `
|
|
7
|
+
import { typedKeysOf, pretty } from "effect-app/utils"
|
|
8
|
+
import { tuple } from "effect-app/Function"
|
|
9
|
+
import { toBool, fromBool } from "effect-app/Option"
|
|
10
|
+
|
|
11
|
+
const keys = typedKeysOf(value)
|
|
12
|
+
const pair = tuple(keys, pretty(value))
|
|
13
|
+
const present = toBool(option)
|
|
14
|
+
const flag = fromBool(enabled)
|
|
15
|
+
`
|
|
16
|
+
const migrated = migrateEffectAppSource(source)
|
|
17
|
+
expect(migrated).toContain(`import { pretty } from "effect-app/utils"`)
|
|
18
|
+
expect(migrated).toContain(`import { fromBool } from "effect-app/Option"`)
|
|
19
|
+
expect(migrated).toContain(`import * as Struct from "effect/Struct"`)
|
|
20
|
+
expect(migrated).toContain(`import * as Tuple from "effect/Tuple"`)
|
|
21
|
+
expect(migrated).toContain(`import * as Option from "effect/Option"`)
|
|
22
|
+
expect(migrated).toContain("const keys = Struct.keys(value)")
|
|
23
|
+
expect(migrated).toContain("const pair = Tuple.make(keys, pretty(value))")
|
|
24
|
+
expect(migrated).toContain("const present = Option.isSome(option)")
|
|
25
|
+
expect(migrated).toContain("const flag = fromBool(enabled)")
|
|
26
|
+
expect(migrated).not.toContain("typedKeysOf")
|
|
27
|
+
expect(migrated).not.toContain("effect-app/Function")
|
|
28
|
+
})
|
|
29
|
+
|
|
30
|
+
test("rewrites aliases, namespaces, calls, and leaves strings and comments", () => {
|
|
31
|
+
const source = `
|
|
32
|
+
import { dropUndefined as compact, assertUnreachable as unreachable } from "effect-app/utils"
|
|
33
|
+
import * as Dates from "effect-app/_ext/date"
|
|
34
|
+
import { chunk_, toNonEmptyArray } from "effect-app/Array"
|
|
35
|
+
import { DateValid } from "effect-app/Schema"
|
|
36
|
+
|
|
37
|
+
// typedKeysOf stays in this comment
|
|
38
|
+
const label = "tuple(typedKeysOf)"
|
|
39
|
+
const fields = compact({ a: 1, b: undefined })
|
|
40
|
+
const next = Dates.DateAddDays(today, 2)
|
|
41
|
+
const parts = chunk_(items, 10)
|
|
42
|
+
const some = toNonEmptyArray(items)
|
|
43
|
+
const Day = DateValid
|
|
44
|
+
const missing = unreachable(value)
|
|
45
|
+
`
|
|
46
|
+
const migrated = migrateEffectAppSource(source)
|
|
47
|
+
expect(migrated).toContain("// typedKeysOf stays in this comment")
|
|
48
|
+
expect(migrated).toContain(`const label = "tuple(typedKeysOf)"`)
|
|
49
|
+
expect(migrated).toContain("const fields = compact({ a: 1, b: undefined })")
|
|
50
|
+
expect(migrated).toContain("dropUndefined as compact")
|
|
51
|
+
expect(migrated).toContain(
|
|
52
|
+
"const next = pipeZonedLocal(today, DateTime.add({ days: 2 }))"
|
|
53
|
+
)
|
|
54
|
+
expect(migrated).toContain("const parts = Chunk.fromIterable(Array.chunksOf(items, 10))")
|
|
55
|
+
expect(migrated).toContain("const some = Option.liftPredicate(Array.isReadonlyArrayNonEmpty)(items)")
|
|
56
|
+
expect(migrated).toContain(`import { Date } from "effect-app/Schema"`)
|
|
57
|
+
expect(migrated).toContain("const Day = Date")
|
|
58
|
+
expect(migrated).toContain("const missing = absurd(value)")
|
|
59
|
+
expect(migrated).toContain(`import { pipeZonedLocal } from "effect-app/DateTime"`)
|
|
60
|
+
expect(migrated).toContain(`import * as DateTime from "effect/DateTime"`)
|
|
61
|
+
expect(migrated).not.toContain("effect-app/_ext/date")
|
|
62
|
+
expect(migrated).not.toContain("DateValid")
|
|
63
|
+
})
|
|
64
|
+
|
|
65
|
+
test("rewrites a namespace member and keeps the namespace when it still has other members", () => {
|
|
66
|
+
const source = `
|
|
67
|
+
import * as Chunk from "effect-app/Chunk"
|
|
68
|
+
|
|
69
|
+
const first = Chunk.findFirstSimple(chunk, predicate)
|
|
70
|
+
const grouped = Chunk.groupByTChunk_(chunk, key)
|
|
71
|
+
`
|
|
72
|
+
const migrated = migrateEffectAppSource(source)
|
|
73
|
+
expect(migrated).toContain(`import * as Chunk from "effect-app/Chunk"`)
|
|
74
|
+
expect(migrated).toContain("const first = Chunk.findFirst(chunk, predicate)")
|
|
75
|
+
expect(migrated).toContain("const grouped = Chunk.groupByTChunk_(chunk, key)")
|
|
76
|
+
})
|
|
77
|
+
})
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import * as Deferred from "effect/Deferred"
|
|
2
|
+
import * as Effect from "effect/Effect"
|
|
3
|
+
import * as Fiber from "effect/Fiber"
|
|
4
|
+
import { describe, expect, test } from "vitest"
|
|
5
|
+
import { makeWaitingGate, suspendWaiting, WaitingGate } from "../src/waitingGate.js"
|
|
6
|
+
|
|
7
|
+
const run = <A, E>(self: Effect.Effect<A, E, never>) => Effect.runPromise(self)
|
|
8
|
+
|
|
9
|
+
describe("suspendWaiting", () => {
|
|
10
|
+
test("brackets depth and tells the controller", async () => {
|
|
11
|
+
const depths: Array<number> = []
|
|
12
|
+
const gate = makeWaitingGate((depth) => depths.push(depth))
|
|
13
|
+
gate.bind((depth) => Effect.sync(() => depths.push(depth)))
|
|
14
|
+
|
|
15
|
+
await run(
|
|
16
|
+
suspendWaiting(Effect.sync(() => {
|
|
17
|
+
expect(gate.depth).toBe(1)
|
|
18
|
+
}))
|
|
19
|
+
.pipe(Effect.provideService(WaitingGate, gate))
|
|
20
|
+
)
|
|
21
|
+
|
|
22
|
+
expect(gate.depth).toBe(0)
|
|
23
|
+
expect(depths).toEqual([1, 1, 0, 0])
|
|
24
|
+
})
|
|
25
|
+
|
|
26
|
+
test("nests", async () => {
|
|
27
|
+
const gate = makeWaitingGate()
|
|
28
|
+
await run(
|
|
29
|
+
suspendWaiting(suspendWaiting(Effect.sync(() => {
|
|
30
|
+
expect(gate.depth).toBe(2)
|
|
31
|
+
})))
|
|
32
|
+
.pipe(Effect.provideService(WaitingGate, gate))
|
|
33
|
+
)
|
|
34
|
+
expect(gate.depth).toBe(0)
|
|
35
|
+
})
|
|
36
|
+
|
|
37
|
+
test("restores depth when the effect is interrupted", async () => {
|
|
38
|
+
const gate = makeWaitingGate()
|
|
39
|
+
await run(Effect.gen(function*() {
|
|
40
|
+
const entered = yield* Deferred.make<void>()
|
|
41
|
+
const fiber = yield* suspendWaiting(Effect.gen(function*() {
|
|
42
|
+
yield* Deferred.succeed(entered, undefined)
|
|
43
|
+
return yield* Effect.never
|
|
44
|
+
}))
|
|
45
|
+
.pipe(
|
|
46
|
+
Effect.provideService(WaitingGate, gate),
|
|
47
|
+
Effect.forkChild
|
|
48
|
+
)
|
|
49
|
+
yield* Deferred.await(entered)
|
|
50
|
+
expect(gate.depth).toBe(1)
|
|
51
|
+
yield* Fiber.interrupt(fiber)
|
|
52
|
+
expect(gate.depth).toBe(0)
|
|
53
|
+
}))
|
|
54
|
+
})
|
|
55
|
+
|
|
56
|
+
test("does nothing on the default gate", async () => {
|
|
57
|
+
await run(Effect.gen(function*() {
|
|
58
|
+
const gate = yield* WaitingGate
|
|
59
|
+
expect(gate.active).toBe(false)
|
|
60
|
+
yield* suspendWaiting(Effect.void)
|
|
61
|
+
expect(gate.depth).toBe(0)
|
|
62
|
+
}))
|
|
63
|
+
})
|
|
64
|
+
})
|
package/dist/_ext/date.d.ts
DELETED
|
@@ -1,15 +0,0 @@
|
|
|
1
|
-
export declare const DateAddDays: (date: Date, amount: number) => Date;
|
|
2
|
-
export declare const DateSubDays: (date: Date, amount: number) => Date;
|
|
3
|
-
export declare const DateAddHours: (date: Date, amount: number) => Date;
|
|
4
|
-
export declare const DateSubHours: (date: Date, amount: number) => Date;
|
|
5
|
-
export declare const DateAddMinutes: (date: Date, amount: number) => Date;
|
|
6
|
-
export declare const DateSubMinutes: (date: Date, amount: number) => Date;
|
|
7
|
-
export declare const DateAddSeconds: (date: Date, amount: number) => Date;
|
|
8
|
-
export declare const DateSubSeconds: (date: Date, amount: number) => Date;
|
|
9
|
-
export declare const DateAddYears: (date: Date, amount: number) => Date;
|
|
10
|
-
export declare const DateSubYears: (date: Date, amount: number) => Date;
|
|
11
|
-
export declare const DateAddMonths: (date: Date, amount: number) => Date;
|
|
12
|
-
export declare const DateSubMonths: (date: Date, amount: number) => Date;
|
|
13
|
-
export declare const DateAddWeeks: (date: Date, amount: number) => Date;
|
|
14
|
-
export declare const DateSubWeeks: (date: Date, amount: number) => Date;
|
|
15
|
-
//# sourceMappingURL=date.d.ts.map
|
package/dist/_ext/date.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"date.d.ts","sourceRoot":"","sources":["../../src/_ext/date.ts"],"names":[],"mappings":"AAEA,eAAO,MAAM,WAAW,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,IAAc,CAAA;AACxE,eAAO,MAAM,WAAW,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,IAAc,CAAA;AAExE,eAAO,MAAM,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,IAAe,CAAA;AAC1E,eAAO,MAAM,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,IAAe,CAAA;AAE1E,eAAO,MAAM,cAAc,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,IAAiB,CAAA;AAE9E,eAAO,MAAM,cAAc,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,IAAiB,CAAA;AAE9E,eAAO,MAAM,cAAc,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,IAAiB,CAAA;AAE9E,eAAO,MAAM,cAAc,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,IAAiB,CAAA;AAE9E,eAAO,MAAM,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,IAAe,CAAA;AAE1E,eAAO,MAAM,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,IAAe,CAAA;AAE1E,eAAO,MAAM,aAAa,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,IAAgB,CAAA;AAE5E,eAAO,MAAM,aAAa,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,IAAgB,CAAA;AAE5E,eAAO,MAAM,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,IAAe,CAAA;AAE1E,eAAO,MAAM,YAAY,EAAE,CAAC,IAAI,EAAE,IAAI,EAAE,MAAM,EAAE,MAAM,KAAK,IAAe,CAAA"}
|
package/dist/_ext/date.js
DELETED
|
@@ -1,16 +0,0 @@
|
|
|
1
|
-
import { addDays, addHours, addMinutes, addMonths, addSeconds, addWeeks, addYears, subDays, subHours, subMinutes, subMonths, subSeconds, subWeeks, subYears } from "date-fns";
|
|
2
|
-
export const DateAddDays = addDays;
|
|
3
|
-
export const DateSubDays = subDays;
|
|
4
|
-
export const DateAddHours = addHours;
|
|
5
|
-
export const DateSubHours = subHours;
|
|
6
|
-
export const DateAddMinutes = addMinutes;
|
|
7
|
-
export const DateSubMinutes = subMinutes;
|
|
8
|
-
export const DateAddSeconds = addSeconds;
|
|
9
|
-
export const DateSubSeconds = subSeconds;
|
|
10
|
-
export const DateAddYears = addYears;
|
|
11
|
-
export const DateSubYears = subYears;
|
|
12
|
-
export const DateAddMonths = addMonths;
|
|
13
|
-
export const DateSubMonths = subMonths;
|
|
14
|
-
export const DateAddWeeks = addWeeks;
|
|
15
|
-
export const DateSubWeeks = subWeeks;
|
|
16
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiZGF0ZS5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9fZXh0L2RhdGUudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxFQUFFLE9BQU8sRUFBRSxRQUFRLEVBQUUsVUFBVSxFQUFFLFNBQVMsRUFBRSxVQUFVLEVBQUUsUUFBUSxFQUFFLFFBQVEsRUFBRSxPQUFPLEVBQUUsUUFBUSxFQUFFLFVBQVUsRUFBRSxTQUFTLEVBQUUsVUFBVSxFQUFFLFFBQVEsRUFBRSxRQUFRLEVBQUUsTUFBTSxVQUFVLENBQUE7QUFFN0ssTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUF5QyxPQUFPLENBQUE7QUFDeEUsTUFBTSxDQUFDLE1BQU0sV0FBVyxHQUF5QyxPQUFPLENBQUE7QUFFeEUsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUF5QyxRQUFRLENBQUE7QUFDMUUsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUF5QyxRQUFRLENBQUE7QUFFMUUsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUF5QyxVQUFVLENBQUE7QUFFOUUsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUF5QyxVQUFVLENBQUE7QUFFOUUsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUF5QyxVQUFVLENBQUE7QUFFOUUsTUFBTSxDQUFDLE1BQU0sY0FBYyxHQUF5QyxVQUFVLENBQUE7QUFFOUUsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUF5QyxRQUFRLENBQUE7QUFFMUUsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUF5QyxRQUFRLENBQUE7QUFFMUUsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUF5QyxTQUFTLENBQUE7QUFFNUUsTUFBTSxDQUFDLE1BQU0sYUFBYSxHQUF5QyxTQUFTLENBQUE7QUFFNUUsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUF5QyxRQUFRLENBQUE7QUFFMUUsTUFBTSxDQUFDLE1BQU0sWUFBWSxHQUF5QyxRQUFRLENBQUEifQ==
|
package/dist/_ext/misc.d.ts
DELETED
|
@@ -1,17 +0,0 @@
|
|
|
1
|
-
import type { LazyArg } from "effect-app/Function";
|
|
2
|
-
import * as Effect from "effect/Effect";
|
|
3
|
-
import * as Option from "effect/Option";
|
|
4
|
-
import * as Result from "effect/Result";
|
|
5
|
-
import type * as Scope from "effect/Scope";
|
|
6
|
-
export type _R<T extends Effect.Effect<any, any, any>> = [T] extends [
|
|
7
|
-
Effect.Effect<any, any, infer R>
|
|
8
|
-
] ? R : never;
|
|
9
|
-
export type _E<T extends Effect.Effect<any, any, any>> = [T] extends [
|
|
10
|
-
Effect.Effect<any, infer E, any>
|
|
11
|
-
] ? E : never;
|
|
12
|
-
export declare function encaseMaybeInEffect_<E, A>(o: Option.Option<A>, onError: LazyArg<E>): Effect.Effect<A, E>;
|
|
13
|
-
export declare function encaseMaybeEither_<E, A>(o: Option.Option<A>, onError: LazyArg<E>): Result.Result<A, E>;
|
|
14
|
-
export declare function toNullable<R, E, A>(self: Effect.Effect<Option.Option<A>, E, R>): Effect.Effect<A | null, E, R>;
|
|
15
|
-
export declare function scope<R, E, A, R2, E2, A2>(scopedEffect: Effect.Effect<A, E, R | Scope.Scope>, effect: Effect.Effect<A2, E2, R2>): Effect.Effect<A2, E | E2, Exclude<R | R2, Scope.Scope>>;
|
|
16
|
-
export declare function flatMapScoped<R, E, A, R2, E2, A2>(scopedEffect: Effect.Effect<A, E, R | Scope.Scope>, effect: (a: A) => Effect.Effect<A2, E2, R2>): Effect.Effect<A2, E | E2, Exclude<R | R2, Scope.Scope>>;
|
|
17
|
-
//# sourceMappingURL=misc.d.ts.map
|
package/dist/_ext/misc.d.ts.map
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"file":"misc.d.ts","sourceRoot":"","sources":["../../src/_ext/misc.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,qBAAqB,CAAA;AAClD,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAA;AACvC,OAAO,KAAK,KAAK,KAAK,MAAM,cAAc,CAAA;AAE1C,MAAM,MAAM,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;IACnE,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,MAAM,CAAC,CAAC;CACjC,GAAG,CAAC,GACD,KAAK,CAAA;AAET,MAAM,MAAM,EAAE,CAAC,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,GAAG,EAAE,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,SAAS;IACnE,MAAM,CAAC,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,EAAE,GAAG,CAAC;CACjC,GAAG,CAAC,GACD,KAAK,CAAA;AAET,wBAAgB,oBAAoB,CAAC,CAAC,EAAE,CAAC,EACvC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EACnB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAClB,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAErB;AAED,wBAAgB,kBAAkB,CAAC,CAAC,EAAE,CAAC,EACrC,CAAC,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EACnB,OAAO,EAAE,OAAO,CAAC,CAAC,CAAC,GAClB,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,CAAC,CAErB;AAED,wBAAgB,UAAU,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAChC,IAAI,EAAE,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,MAAM,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,CAAC,iCAG5C;AAED,wBAAgB,KAAK,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EACvC,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,EAClD,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAChC,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAEzD;AAED,wBAAgB,aAAa,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,EAAE,EAC/C,YAAY,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,CAAC,EAAE,CAAC,GAAG,KAAK,CAAC,KAAK,CAAC,EAClD,MAAM,EAAE,CAAC,CAAC,EAAE,CAAC,KAAK,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,EAAE,EAAE,EAAE,CAAC,GAC1C,MAAM,CAAC,MAAM,CAAC,EAAE,EAAE,CAAC,GAAG,EAAE,EAAE,OAAO,CAAC,CAAC,GAAG,EAAE,EAAE,KAAK,CAAC,KAAK,CAAC,CAAC,CAEzD"}
|
package/dist/_ext/misc.js
DELETED
|
@@ -1,19 +0,0 @@
|
|
|
1
|
-
import * as Effect from "effect/Effect";
|
|
2
|
-
import * as Option from "effect/Option";
|
|
3
|
-
import * as Result from "effect/Result";
|
|
4
|
-
export function encaseMaybeInEffect_(o, onError) {
|
|
5
|
-
return Option.match(o, { onNone: () => Effect.fail(onError()), onSome: Effect.succeed });
|
|
6
|
-
}
|
|
7
|
-
export function encaseMaybeEither_(o, onError) {
|
|
8
|
-
return Option.match(o, { onNone: () => Result.fail(onError()), onSome: Result.succeed });
|
|
9
|
-
}
|
|
10
|
-
export function toNullable(self) {
|
|
11
|
-
return Effect.map(self, (_) => Option.getOrNull(_));
|
|
12
|
-
}
|
|
13
|
-
export function scope(scopedEffect, effect) {
|
|
14
|
-
return Effect.andThen(scopedEffect, effect).pipe(Effect.scoped);
|
|
15
|
-
}
|
|
16
|
-
export function flatMapScoped(scopedEffect, effect) {
|
|
17
|
-
return scopedEffect.pipe(Effect.flatMap(effect), Effect.scoped);
|
|
18
|
-
}
|
|
19
|
-
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibWlzYy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uLy4uL3NyYy9fZXh0L21pc2MudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQ0EsT0FBTyxLQUFLLE1BQU0sTUFBTSxlQUFlLENBQUE7QUFDdkMsT0FBTyxLQUFLLE1BQU0sTUFBTSxlQUFlLENBQUE7QUFDdkMsT0FBTyxLQUFLLE1BQU0sTUFBTSxlQUFlLENBQUE7QUFhdkMsTUFBTSxVQUFVLG9CQUFvQixDQUNsQyxDQUFtQixFQUNuQixPQUFtQjtJQUVuQixPQUFPLE1BQU0sQ0FBQyxLQUFLLENBQUMsQ0FBQyxFQUFFLEVBQUUsTUFBTSxFQUFFLEdBQUcsRUFBRSxDQUFDLE1BQU0sQ0FBQyxJQUFJLENBQUMsT0FBTyxFQUFFLENBQUMsRUFBRSxNQUFNLEVBQUUsTUFBTSxDQUFDLE9BQU8sRUFBRSxDQUFDLENBQUE7QUFDMUYsQ0FBQztBQUVELE1BQU0sVUFBVSxrQkFBa0IsQ0FDaEMsQ0FBbUIsRUFDbkIsT0FBbUI7SUFFbkIsT0FBTyxNQUFNLENBQUMsS0FBSyxDQUFDLENBQUMsRUFBRSxFQUFFLE1BQU0sRUFBRSxHQUFHLEVBQUUsQ0FBQyxNQUFNLENBQUMsSUFBSSxDQUFDLE9BQU8sRUFBRSxDQUFDLEVBQUUsTUFBTSxFQUFFLE1BQU0sQ0FBQyxPQUFPLEVBQUUsQ0FBQyxDQUFBO0FBQzFGLENBQUM7QUFFRCxNQUFNLFVBQVUsVUFBVSxDQUN4QixJQUEyQztJQUUzQyxPQUFPLE1BQU0sQ0FBQyxHQUFHLENBQUMsSUFBSSxFQUFFLENBQUMsQ0FBQyxFQUFFLEVBQUUsQ0FBQyxNQUFNLENBQUMsU0FBUyxDQUFDLENBQUMsQ0FBQyxDQUFDLENBQUE7QUFDckQsQ0FBQztBQUVELE1BQU0sVUFBVSxLQUFLLENBQ25CLFlBQWtELEVBQ2xELE1BQWlDO0lBRWpDLE9BQU8sTUFBTSxDQUFDLE9BQU8sQ0FBQyxZQUFZLEVBQUUsTUFBTSxDQUFDLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxNQUFNLENBQUMsQ0FBQTtBQUNqRSxDQUFDO0FBRUQsTUFBTSxVQUFVLGFBQWEsQ0FDM0IsWUFBa0QsRUFDbEQsTUFBMkM7SUFFM0MsT0FBTyxZQUFZLENBQUMsSUFBSSxDQUFDLE1BQU0sQ0FBQyxPQUFPLENBQUMsTUFBTSxDQUFDLEVBQUUsTUFBTSxDQUFDLE1BQU0sQ0FBQyxDQUFBO0FBQ2pFLENBQUMifQ==
|
package/src/_ext/date.ts
DELETED
|
@@ -1,27 +0,0 @@
|
|
|
1
|
-
import { addDays, addHours, addMinutes, addMonths, addSeconds, addWeeks, addYears, subDays, subHours, subMinutes, subMonths, subSeconds, subWeeks, subYears } from "date-fns"
|
|
2
|
-
|
|
3
|
-
export const DateAddDays: (date: Date, amount: number) => Date = addDays
|
|
4
|
-
export const DateSubDays: (date: Date, amount: number) => Date = subDays
|
|
5
|
-
|
|
6
|
-
export const DateAddHours: (date: Date, amount: number) => Date = addHours
|
|
7
|
-
export const DateSubHours: (date: Date, amount: number) => Date = subHours
|
|
8
|
-
|
|
9
|
-
export const DateAddMinutes: (date: Date, amount: number) => Date = addMinutes
|
|
10
|
-
|
|
11
|
-
export const DateSubMinutes: (date: Date, amount: number) => Date = subMinutes
|
|
12
|
-
|
|
13
|
-
export const DateAddSeconds: (date: Date, amount: number) => Date = addSeconds
|
|
14
|
-
|
|
15
|
-
export const DateSubSeconds: (date: Date, amount: number) => Date = subSeconds
|
|
16
|
-
|
|
17
|
-
export const DateAddYears: (date: Date, amount: number) => Date = addYears
|
|
18
|
-
|
|
19
|
-
export const DateSubYears: (date: Date, amount: number) => Date = subYears
|
|
20
|
-
|
|
21
|
-
export const DateAddMonths: (date: Date, amount: number) => Date = addMonths
|
|
22
|
-
|
|
23
|
-
export const DateSubMonths: (date: Date, amount: number) => Date = subMonths
|
|
24
|
-
|
|
25
|
-
export const DateAddWeeks: (date: Date, amount: number) => Date = addWeeks
|
|
26
|
-
|
|
27
|
-
export const DateSubWeeks: (date: Date, amount: number) => Date = subWeeks
|
package/src/_ext/misc.ts
DELETED
|
@@ -1,49 +0,0 @@
|
|
|
1
|
-
import type { LazyArg } from "effect-app/Function"
|
|
2
|
-
import * as Effect from "effect/Effect"
|
|
3
|
-
import * as Option from "effect/Option"
|
|
4
|
-
import * as Result from "effect/Result"
|
|
5
|
-
import type * as Scope from "effect/Scope"
|
|
6
|
-
|
|
7
|
-
export type _R<T extends Effect.Effect<any, any, any>> = [T] extends [
|
|
8
|
-
Effect.Effect<any, any, infer R>
|
|
9
|
-
] ? R
|
|
10
|
-
: never
|
|
11
|
-
|
|
12
|
-
export type _E<T extends Effect.Effect<any, any, any>> = [T] extends [
|
|
13
|
-
Effect.Effect<any, infer E, any>
|
|
14
|
-
] ? E
|
|
15
|
-
: never
|
|
16
|
-
|
|
17
|
-
export function encaseMaybeInEffect_<E, A>(
|
|
18
|
-
o: Option.Option<A>,
|
|
19
|
-
onError: LazyArg<E>
|
|
20
|
-
): Effect.Effect<A, E> {
|
|
21
|
-
return Option.match(o, { onNone: () => Effect.fail(onError()), onSome: Effect.succeed })
|
|
22
|
-
}
|
|
23
|
-
|
|
24
|
-
export function encaseMaybeEither_<E, A>(
|
|
25
|
-
o: Option.Option<A>,
|
|
26
|
-
onError: LazyArg<E>
|
|
27
|
-
): Result.Result<A, E> {
|
|
28
|
-
return Option.match(o, { onNone: () => Result.fail(onError()), onSome: Result.succeed })
|
|
29
|
-
}
|
|
30
|
-
|
|
31
|
-
export function toNullable<R, E, A>(
|
|
32
|
-
self: Effect.Effect<Option.Option<A>, E, R>
|
|
33
|
-
) {
|
|
34
|
-
return Effect.map(self, (_) => Option.getOrNull(_))
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
export function scope<R, E, A, R2, E2, A2>(
|
|
38
|
-
scopedEffect: Effect.Effect<A, E, R | Scope.Scope>,
|
|
39
|
-
effect: Effect.Effect<A2, E2, R2>
|
|
40
|
-
): Effect.Effect<A2, E | E2, Exclude<R | R2, Scope.Scope>> {
|
|
41
|
-
return Effect.andThen(scopedEffect, effect).pipe(Effect.scoped)
|
|
42
|
-
}
|
|
43
|
-
|
|
44
|
-
export function flatMapScoped<R, E, A, R2, E2, A2>(
|
|
45
|
-
scopedEffect: Effect.Effect<A, E, R | Scope.Scope>,
|
|
46
|
-
effect: (a: A) => Effect.Effect<A2, E2, R2>
|
|
47
|
-
): Effect.Effect<A2, E | E2, Exclude<R | R2, Scope.Scope>> {
|
|
48
|
-
return scopedEffect.pipe(Effect.flatMap(effect), Effect.scoped)
|
|
49
|
-
}
|