@effect-app/infra 1.38.0 → 1.40.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/CHANGELOG.md +13 -0
- package/_cjs/api/routing.cjs +0 -1
- package/_cjs/api/routing.cjs.map +1 -1
- package/_cjs/api/routing2.cjs +67 -2
- package/_cjs/api/routing2.cjs.map +1 -1
- package/_cjs/services/Operations.cjs +20 -16
- package/_cjs/services/Operations.cjs.map +1 -1
- package/dist/api/routing.d.ts +3 -3
- package/dist/api/routing.d.ts.map +1 -1
- package/dist/api/routing.js +1 -3
- package/dist/api/routing2.d.ts +16 -8
- package/dist/api/routing2.d.ts.map +1 -1
- package/dist/api/routing2.js +93 -4
- package/dist/services/Operations.d.ts +26 -11
- package/dist/services/Operations.d.ts.map +1 -1
- package/dist/services/Operations.js +20 -15
- package/dist/services/Repository/ext.d.ts +11 -11
- package/dist/services/RepositoryBase.d.ts +6 -6
- package/dist/services/query/new-kid-interpreter.d.ts +1 -1
- package/package.json +3 -3
- package/src/api/routing.ts +6 -4
- package/src/api/routing2.ts +178 -19
- package/src/services/Operations.ts +81 -78
package/src/api/routing2.ts
CHANGED
|
@@ -177,21 +177,32 @@ export interface ExtendedMiddleware<Context, CTXMap extends Record<string, RPCCo
|
|
|
177
177
|
}
|
|
178
178
|
|
|
179
179
|
export const RouterSymbol = Symbol()
|
|
180
|
-
export interface
|
|
180
|
+
export interface RouterShape<Rsc> {
|
|
181
181
|
[RouterSymbol]: Rsc
|
|
182
182
|
}
|
|
183
183
|
|
|
184
|
+
type RPCRouteR<T extends Rpc.Rpc<any, any>> = [T] extends [
|
|
185
|
+
Rpc.Rpc<any, infer R>
|
|
186
|
+
] ? R
|
|
187
|
+
: never
|
|
188
|
+
|
|
189
|
+
type RPCRouteReq<T extends Rpc.Rpc<any, any>> = [T] extends [
|
|
190
|
+
Rpc.Rpc<infer Req, any>
|
|
191
|
+
] ? Req
|
|
192
|
+
: never
|
|
193
|
+
|
|
184
194
|
export const makeRouter = <Context, CTXMap extends Record<string, RPCContextMap.Any>>(
|
|
185
195
|
middleware: ExtendedMiddleware<Context, CTXMap>,
|
|
186
196
|
devMode: boolean
|
|
187
197
|
) => {
|
|
188
198
|
const rpc = makeRpc(middleware)
|
|
189
|
-
function matchFor<
|
|
190
|
-
|
|
199
|
+
function matchFor<
|
|
200
|
+
const ModuleName extends string,
|
|
201
|
+
const Rsc extends Record<string, any>
|
|
202
|
+
>(
|
|
203
|
+
rsc: Rsc & { meta: { moduleName: ModuleName } }
|
|
191
204
|
) {
|
|
192
|
-
const meta =
|
|
193
|
-
if (!meta) throw new Error("Resource has no meta specified") // TODO: do something with moduleName+cur etc.
|
|
194
|
-
|
|
205
|
+
const meta = rsc.meta
|
|
195
206
|
type Filtered = Filter<Rsc>
|
|
196
207
|
const filtered = typedKeysOf(rsc).reduce((acc, cur) => {
|
|
197
208
|
if (Predicate.isObject(rsc[cur]) && rsc[cur]["success"]) {
|
|
@@ -388,25 +399,15 @@ export const makeRouter = <Context, CTXMap extends Record<string, RPCContextMap.
|
|
|
388
399
|
>
|
|
389
400
|
}
|
|
390
401
|
|
|
391
|
-
type RPCRouteR<T extends Rpc.Rpc<any, any>> = [T] extends [
|
|
392
|
-
Rpc.Rpc<any, infer R>
|
|
393
|
-
] ? R
|
|
394
|
-
: never
|
|
395
|
-
|
|
396
|
-
type RPCRouteReq<T extends Rpc.Rpc<any, any>> = [T] extends [
|
|
397
|
-
Rpc.Rpc<infer Req, any>
|
|
398
|
-
] ? Req
|
|
399
|
-
: never
|
|
400
|
-
|
|
401
402
|
const rpcRouter = RpcRouter.make(...Object.values(mapped) as any) as RpcRouter.RpcRouter<
|
|
402
403
|
RPCRouteReq<typeof mapped[keyof typeof mapped]>,
|
|
403
404
|
RPCRouteR<typeof mapped[keyof typeof mapped]>
|
|
404
405
|
>
|
|
405
406
|
|
|
406
|
-
type Router =
|
|
407
|
+
type Router = RouterShape<Rsc>
|
|
407
408
|
const r: HttpRouter.HttpRouter.TagClass<
|
|
408
409
|
Router,
|
|
409
|
-
|
|
410
|
+
`${typeof meta.moduleName}Router`,
|
|
410
411
|
never,
|
|
411
412
|
Exclude<
|
|
412
413
|
RPCRouteR<
|
|
@@ -414,7 +415,7 @@ export const makeRouter = <Context, CTXMap extends Record<string, RPCContextMap.
|
|
|
414
415
|
>,
|
|
415
416
|
{ [k in keyof TLayers]: Layer.Layer.Success<TLayers[k]> }[number]
|
|
416
417
|
>
|
|
417
|
-
> = (class Router extends HttpRouter.Tag(meta.moduleName
|
|
418
|
+
> = (class Router extends HttpRouter.Tag(`${meta.moduleName}Router`)<Router>() {}) as any
|
|
418
419
|
|
|
419
420
|
const layer = r.use((router) =>
|
|
420
421
|
Effect.gen(function*() {
|
|
@@ -456,7 +457,165 @@ export const makeRouter = <Context, CTXMap extends Record<string, RPCContextMap.
|
|
|
456
457
|
}
|
|
457
458
|
}
|
|
458
459
|
|
|
460
|
+
const effect = <
|
|
461
|
+
E,
|
|
462
|
+
R,
|
|
463
|
+
THandlers extends {
|
|
464
|
+
// import to keep them separate via | for type checking!!
|
|
465
|
+
[K in Keys]: AHandler<Rsc[K]>
|
|
466
|
+
},
|
|
467
|
+
TLayers extends NonEmptyArray<Layer.Layer.Any>
|
|
468
|
+
>(
|
|
469
|
+
layers: TLayers,
|
|
470
|
+
make: Effect<THandlers, E, R>
|
|
471
|
+
) => {
|
|
472
|
+
type Router = RouterShape<Rsc>
|
|
473
|
+
const r: HttpRouter.HttpRouter.TagClass<
|
|
474
|
+
Router,
|
|
475
|
+
`${typeof meta.moduleName}Router`,
|
|
476
|
+
never,
|
|
477
|
+
Exclude<
|
|
478
|
+
RPCRouteR<
|
|
479
|
+
{ [K in keyof Filter<Rsc>]: Rpc.Rpc<Rsc[K], _R<ReturnType<THandlers[K]["handler"]>>> }[keyof Filter<Rsc>]
|
|
480
|
+
>,
|
|
481
|
+
{ [k in keyof TLayers]: Layer.Layer.Success<TLayers[k]> }[number]
|
|
482
|
+
>
|
|
483
|
+
> = (class Router extends HttpRouter.Tag(`${meta.moduleName}Router`)<Router>() {}) as any
|
|
484
|
+
|
|
485
|
+
const layer = r.use((router) =>
|
|
486
|
+
Effect.gen(function*() {
|
|
487
|
+
const controllers = yield* make
|
|
488
|
+
// return make.pipe(Effect.map((c) => controllers(c, layers)))
|
|
489
|
+
const mapped = typedKeysOf(filtered).reduce((acc, cur) => {
|
|
490
|
+
const handler = controllers[cur as keyof typeof controllers]
|
|
491
|
+
const req = rsc[cur]
|
|
492
|
+
|
|
493
|
+
acc[cur] = rpc.effect(
|
|
494
|
+
handler._tag === "raw"
|
|
495
|
+
? class extends (req as any) {
|
|
496
|
+
static success = S.encodedSchema(req.success)
|
|
497
|
+
get [Serializable.symbol]() {
|
|
498
|
+
return this.constructor
|
|
499
|
+
}
|
|
500
|
+
get [Serializable.symbolResult]() {
|
|
501
|
+
return {
|
|
502
|
+
failure: req.failure,
|
|
503
|
+
success: S.encodedSchema(req.success)
|
|
504
|
+
}
|
|
505
|
+
}
|
|
506
|
+
} as any
|
|
507
|
+
: req,
|
|
508
|
+
(req) =>
|
|
509
|
+
Effect
|
|
510
|
+
.annotateCurrentSpan(
|
|
511
|
+
"requestInput",
|
|
512
|
+
Object.entries(req).reduce((prev, [key, value]: [string, unknown]) => {
|
|
513
|
+
prev[key] = key === "password"
|
|
514
|
+
? "<redacted>"
|
|
515
|
+
: typeof value === "string" || typeof value === "number" || typeof value === "boolean"
|
|
516
|
+
? typeof value === "string" && value.length > 256
|
|
517
|
+
? (value.substring(0, 253) + "...")
|
|
518
|
+
: value
|
|
519
|
+
: Array.isArray(value)
|
|
520
|
+
? `Array[${value.length}]`
|
|
521
|
+
: value === null || value === undefined
|
|
522
|
+
? `${value}`
|
|
523
|
+
: typeof value === "object" && value
|
|
524
|
+
? `Object[${Object.keys(value).length}]`
|
|
525
|
+
: typeof value
|
|
526
|
+
return prev
|
|
527
|
+
}, {} as Record<string, string | number | boolean>)
|
|
528
|
+
)
|
|
529
|
+
.pipe(
|
|
530
|
+
// can't use andThen due to some being a function and effect
|
|
531
|
+
Effect.zipRight(handler.handler(req as any) as any),
|
|
532
|
+
Effect.tapErrorCause((cause) => Cause.isFailure(cause) ? logRequestError(cause) : Effect.void),
|
|
533
|
+
Effect.tapDefect((cause) =>
|
|
534
|
+
Effect
|
|
535
|
+
.all([
|
|
536
|
+
reportRequestError(cause, {
|
|
537
|
+
action: `${meta.moduleName}.${req._tag}`
|
|
538
|
+
}),
|
|
539
|
+
Rpc.currentHeaders.pipe(Effect.andThen((headers) => {
|
|
540
|
+
return InfraLogger
|
|
541
|
+
.logError("Finished request", cause)
|
|
542
|
+
.pipe(Effect.annotateLogs({
|
|
543
|
+
action: `${meta.moduleName}.${req._tag}`,
|
|
544
|
+
req: pretty(req),
|
|
545
|
+
headers: pretty(headers)
|
|
546
|
+
// resHeaders: pretty(
|
|
547
|
+
// Object
|
|
548
|
+
// .entries(headers)
|
|
549
|
+
// .reduce((prev, [key, value]) => {
|
|
550
|
+
// prev[key] = value && typeof value === "string" ? snipString(value) : value
|
|
551
|
+
// return prev
|
|
552
|
+
// }, {} as Record<string, any>)
|
|
553
|
+
// )
|
|
554
|
+
}))
|
|
555
|
+
}))
|
|
556
|
+
])
|
|
557
|
+
),
|
|
558
|
+
devMode ? (_) => _ : Effect.catchAllDefect(() => Effect.die("Internal Server Error")),
|
|
559
|
+
Effect.withSpan("Request." + meta.moduleName + "." + req._tag, {
|
|
560
|
+
captureStackTrace: () => handler.stack
|
|
561
|
+
})
|
|
562
|
+
),
|
|
563
|
+
meta.moduleName
|
|
564
|
+
) // TODO
|
|
565
|
+
return acc
|
|
566
|
+
}, {} as any) as {
|
|
567
|
+
[K in Keys]: Rpc.Rpc<
|
|
568
|
+
Rsc[K],
|
|
569
|
+
_R<ReturnType<THandlers[K]["handler"]>>
|
|
570
|
+
>
|
|
571
|
+
}
|
|
572
|
+
|
|
573
|
+
const rpcRouter = RpcRouter.make(...Object.values(mapped) as any) as RpcRouter.RpcRouter<
|
|
574
|
+
RPCRouteReq<typeof mapped[keyof typeof mapped]>,
|
|
575
|
+
RPCRouteR<typeof mapped[keyof typeof mapped]>
|
|
576
|
+
>
|
|
577
|
+
const httpApp = toHttpApp(rpcRouter, {
|
|
578
|
+
spanPrefix: rsc
|
|
579
|
+
.meta
|
|
580
|
+
.moduleName + "."
|
|
581
|
+
})
|
|
582
|
+
const services = (yield* Effect.context<never>()).pipe(
|
|
583
|
+
Context.omit(Scope.Scope as never),
|
|
584
|
+
Context.omit(Tracer.ParentSpan as never)
|
|
585
|
+
)
|
|
586
|
+
yield* router
|
|
587
|
+
.all(
|
|
588
|
+
"/",
|
|
589
|
+
(httpApp
|
|
590
|
+
.pipe(HttpMiddleware.make(Effect.provide(services)))) as any,
|
|
591
|
+
// TODO: not queries.
|
|
592
|
+
{ uninterruptible: true }
|
|
593
|
+
)
|
|
594
|
+
})
|
|
595
|
+
)
|
|
596
|
+
|
|
597
|
+
// eslint-disable-next-line @typescript-eslint/no-unnecessary-type-assertion
|
|
598
|
+
const routes = layer.pipe(
|
|
599
|
+
Layer.provideMerge(r.Live),
|
|
600
|
+
layers ? Layer.provide(layers) as any : (_) => _
|
|
601
|
+
) as Layer.Layer<
|
|
602
|
+
Router,
|
|
603
|
+
{ [k in keyof TLayers]: Layer.Layer.Error<TLayers[k]> }[number] | E,
|
|
604
|
+
| { [k in keyof TLayers]: Layer.Layer.Context<TLayers[k]> }[number]
|
|
605
|
+
| Exclude<R, { [k in keyof TLayers]: Layer.Layer.Success<TLayers[k]> }[number]>
|
|
606
|
+
>
|
|
607
|
+
|
|
608
|
+
// Effect.Effect<HttpRouter.HttpRouter<unknown, HttpRouter.HttpRouter.DefaultServices>, never, UserRouter>
|
|
609
|
+
|
|
610
|
+
return {
|
|
611
|
+
moduleName: meta.moduleName,
|
|
612
|
+
Router: r,
|
|
613
|
+
routes
|
|
614
|
+
}
|
|
615
|
+
}
|
|
616
|
+
|
|
459
617
|
const r = {
|
|
618
|
+
effect,
|
|
460
619
|
controllers,
|
|
461
620
|
...typedKeysOf(filtered).reduce(
|
|
462
621
|
(prev, cur) => {
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { annotateLogscoped
|
|
1
|
+
import { annotateLogscoped } from "@effect-app/core/Effect"
|
|
2
2
|
import { dual, pipe } from "@effect-app/core/Function"
|
|
3
|
-
import
|
|
3
|
+
import { RequestFiberSet } from "@effect-app/infra-adapters/RequestFiberSet"
|
|
4
4
|
import { reportError } from "@effect-app/infra/errorReporter"
|
|
5
5
|
import { NonEmptyString2k } from "@effect-app/schema"
|
|
6
6
|
import { subHours } from "date-fns"
|
|
@@ -19,8 +19,19 @@ const reportAppError = reportError("Operations.Cleanup")
|
|
|
19
19
|
|
|
20
20
|
const make = Effect.gen(function*() {
|
|
21
21
|
const repo = yield* OperationsRepo
|
|
22
|
+
const reqFiberSet = yield* RequestFiberSet
|
|
22
23
|
const makeOp = Effect.sync(() => OperationId.make())
|
|
23
24
|
|
|
25
|
+
const register = (title: NonEmptyString2k) =>
|
|
26
|
+
Effect.tap(
|
|
27
|
+
makeOp,
|
|
28
|
+
(id) =>
|
|
29
|
+
Effect.andThen(
|
|
30
|
+
annotateLogscoped("operationId", id),
|
|
31
|
+
Effect.acquireRelease(addOp(id, title), (_, exit) => finishOp(id, exit))
|
|
32
|
+
)
|
|
33
|
+
)
|
|
34
|
+
|
|
24
35
|
const cleanup = Effect.sync(() => subHours(new Date(), 1)).pipe(
|
|
25
36
|
Effect.andThen((before) => repo.query(where("updatedAt", "lt", before.toISOString()))),
|
|
26
37
|
Effect.andThen((ops) => pipe(ops, batch(100, Effect.succeed, (items) => repo.removeAndPublish(items)))),
|
|
@@ -68,18 +79,75 @@ const make = Effect.gen(function*() {
|
|
|
68
79
|
(_) => repo.save(copy(_, { updatedAt: new Date(), progress })).pipe(Effect.orDie)
|
|
69
80
|
)
|
|
70
81
|
}
|
|
82
|
+
|
|
83
|
+
function fork<R, R2, E, E2, A, A2>(
|
|
84
|
+
self: (id: OperationId) => Effect<A, E, R>,
|
|
85
|
+
fnc: (id: OperationId) => Effect<A2, E2, R2>,
|
|
86
|
+
title: NonEmptyString2k
|
|
87
|
+
): Effect<
|
|
88
|
+
RunningOperation<A, E>,
|
|
89
|
+
never,
|
|
90
|
+
Exclude<R, Scope.Scope> | Exclude<R2, Scope.Scope>
|
|
91
|
+
> {
|
|
92
|
+
return Effect
|
|
93
|
+
.flatMap(
|
|
94
|
+
Scope.make(),
|
|
95
|
+
(scope) =>
|
|
96
|
+
register(title)
|
|
97
|
+
.pipe(
|
|
98
|
+
Scope.extend(scope),
|
|
99
|
+
Effect.flatMap((id) =>
|
|
100
|
+
forkDaemonReportRequestUnexpected(Scope.use(
|
|
101
|
+
self(id).pipe(Effect.withSpan(title)),
|
|
102
|
+
scope
|
|
103
|
+
))
|
|
104
|
+
.pipe(Effect.map((fiber): RunningOperation<A, E> => ({ fiber, id })))
|
|
105
|
+
),
|
|
106
|
+
Effect.tap(({ id }) =>
|
|
107
|
+
Effect.interruptible(fnc(id)).pipe(
|
|
108
|
+
Effect.forkScoped,
|
|
109
|
+
Scope.extend(scope)
|
|
110
|
+
)
|
|
111
|
+
)
|
|
112
|
+
)
|
|
113
|
+
)
|
|
114
|
+
.pipe(Effect.provideService(RequestFiberSet, reqFiberSet))
|
|
115
|
+
}
|
|
116
|
+
|
|
117
|
+
const fork2: {
|
|
118
|
+
(title: NonEmptyString2k): <R, E, A>(
|
|
119
|
+
self: (opId: OperationId) => Effect<A, E, R>
|
|
120
|
+
) => Effect<RunningOperation<A, E>, never, Exclude<R, Scope.Scope>>
|
|
121
|
+
<R, E, A>(
|
|
122
|
+
self: (opId: OperationId) => Effect<A, E, R>,
|
|
123
|
+
title: NonEmptyString2k
|
|
124
|
+
): Effect<RunningOperation<A, E>, never, Exclude<R, Scope.Scope>>
|
|
125
|
+
} = dual(
|
|
126
|
+
2,
|
|
127
|
+
<R, E, A>(self: (opId: OperationId) => Effect<A, E, R>, title: NonEmptyString2k) =>
|
|
128
|
+
Effect.flatMap(
|
|
129
|
+
Scope.make(),
|
|
130
|
+
(scope) =>
|
|
131
|
+
register(title)
|
|
132
|
+
.pipe(
|
|
133
|
+
Scope.extend(scope),
|
|
134
|
+
Effect
|
|
135
|
+
.flatMap((id) =>
|
|
136
|
+
forkDaemonReportRequestUnexpected(Scope.use(
|
|
137
|
+
self(id).pipe(Effect.withSpan(title)),
|
|
138
|
+
scope
|
|
139
|
+
))
|
|
140
|
+
.pipe(Effect.map((fiber): RunningOperation<A, E> => ({ fiber, id })))
|
|
141
|
+
)
|
|
142
|
+
)
|
|
143
|
+
)
|
|
144
|
+
)
|
|
145
|
+
|
|
71
146
|
return {
|
|
72
147
|
cleanup,
|
|
73
|
-
register
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
(id) =>
|
|
77
|
-
Effect.andThen(
|
|
78
|
-
annotateLogscoped("operationId", id),
|
|
79
|
-
Effect.acquireRelease(addOp(id, title), (_, exit) => finishOp(id, exit))
|
|
80
|
-
)
|
|
81
|
-
),
|
|
82
|
-
|
|
148
|
+
register,
|
|
149
|
+
fork,
|
|
150
|
+
fork2,
|
|
83
151
|
all: repo.all,
|
|
84
152
|
find: findOp,
|
|
85
153
|
update
|
|
@@ -106,7 +174,7 @@ export class Operations extends Context.TagMakeId("effect-app/Operations", make)
|
|
|
106
174
|
)
|
|
107
175
|
.pipe(Layer.effectDiscard, Layer.provide(MainFiberSet.Live))
|
|
108
176
|
|
|
109
|
-
static readonly Live = this.CleanupLive.pipe(Layer.provideMerge(this.toLayer()))
|
|
177
|
+
static readonly Live = this.CleanupLive.pipe(Layer.provideMerge(this.toLayer()), Layer.provide(RequestFiberSet.Live))
|
|
110
178
|
}
|
|
111
179
|
|
|
112
180
|
export interface RunningOperation<A, E> {
|
|
@@ -147,68 +215,3 @@ export const forkOperation: {
|
|
|
147
215
|
export function forkOperationFunction<R, E, A, Inp>(fnc: (inp: Inp) => Effect<A, E, R>, title: NonEmptyString2k) {
|
|
148
216
|
return (inp: Inp) => fnc(inp).pipe((_) => forkOperation(_, title))
|
|
149
217
|
}
|
|
150
|
-
|
|
151
|
-
export const forkOperation2: {
|
|
152
|
-
(title: NonEmptyString2k): <R, E, A>(
|
|
153
|
-
self: (opId: OperationId) => Effect<A, E, R>
|
|
154
|
-
) => Effect<RunningOperation<A, E>, never, Operations | Exclude<R, Scope.Scope>>
|
|
155
|
-
<R, E, A>(
|
|
156
|
-
self: (opId: OperationId) => Effect<A, E, R>,
|
|
157
|
-
title: NonEmptyString2k
|
|
158
|
-
): Effect<RunningOperation<A, E>, never, Operations | Exclude<R, Scope.Scope>>
|
|
159
|
-
} = dual(
|
|
160
|
-
2,
|
|
161
|
-
<R, E, A>(self: (opId: OperationId) => Effect<A, E, R>, title: NonEmptyString2k) =>
|
|
162
|
-
flatMap(Operations, (Operations) =>
|
|
163
|
-
Effect.flatMap(
|
|
164
|
-
Scope.make(),
|
|
165
|
-
(scope) =>
|
|
166
|
-
Operations
|
|
167
|
-
.register(title)
|
|
168
|
-
.pipe(
|
|
169
|
-
Scope.extend(scope),
|
|
170
|
-
Effect
|
|
171
|
-
.flatMap((id) =>
|
|
172
|
-
forkDaemonReportRequestUnexpected(Scope.use(
|
|
173
|
-
self(id).pipe(Effect.withSpan(title)),
|
|
174
|
-
scope
|
|
175
|
-
))
|
|
176
|
-
.pipe(Effect.map((fiber): RunningOperation<A, E> => ({ fiber, id })))
|
|
177
|
-
)
|
|
178
|
-
)
|
|
179
|
-
))
|
|
180
|
-
)
|
|
181
|
-
|
|
182
|
-
export function forkOperationWithEffect<R, R2, E, E2, A, A2>(
|
|
183
|
-
self: (id: OperationId) => Effect<A, E, R>,
|
|
184
|
-
fnc: (id: OperationId) => Effect<A2, E2, R2>,
|
|
185
|
-
title: NonEmptyString2k
|
|
186
|
-
): Effect<
|
|
187
|
-
RunningOperation<A, E>,
|
|
188
|
-
never,
|
|
189
|
-
Operations | RequestFiberSet | Exclude<R, Scope.Scope> | Exclude<R2, Scope.Scope>
|
|
190
|
-
> {
|
|
191
|
-
return Effect.flatMap(Operations, (Operations) =>
|
|
192
|
-
Effect.flatMap(
|
|
193
|
-
Scope.make(),
|
|
194
|
-
(scope) =>
|
|
195
|
-
Operations
|
|
196
|
-
.register(title)
|
|
197
|
-
.pipe(
|
|
198
|
-
Scope.extend(scope),
|
|
199
|
-
Effect.flatMap((id) =>
|
|
200
|
-
forkDaemonReportRequestUnexpected(Scope.use(
|
|
201
|
-
self(id).pipe(Effect.withSpan(title)),
|
|
202
|
-
scope
|
|
203
|
-
))
|
|
204
|
-
.pipe(Effect.map((fiber): RunningOperation<A, E> => ({ fiber, id })))
|
|
205
|
-
),
|
|
206
|
-
Effect.tap(({ id }) =>
|
|
207
|
-
Effect.interruptible(fnc(id)).pipe(
|
|
208
|
-
Effect.forkScoped,
|
|
209
|
-
Scope.extend(scope)
|
|
210
|
-
)
|
|
211
|
-
)
|
|
212
|
-
)
|
|
213
|
-
))
|
|
214
|
-
}
|