@demlik/tea 0.14.0 → 0.16.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/README.md +30 -7
- package/dist/agent/index.d.ts +49 -36
- package/dist/agent/index.js +12 -8
- package/dist/chunk-4LPY67E4.js +18 -0
- package/dist/chunk-4LPY67E4.js.map +1 -0
- package/dist/chunk-5XU6ZJO2.js +533 -0
- package/dist/chunk-5XU6ZJO2.js.map +1 -0
- package/dist/{chunk-AQ6ZIMEA.js → chunk-6NG4V5SB.js} +89 -115
- package/dist/chunk-6NG4V5SB.js.map +1 -0
- package/dist/{chunk-HYDWG35Q.js → chunk-7MGXQZPW.js} +11 -9
- package/dist/chunk-7MGXQZPW.js.map +1 -0
- package/dist/{chunk-BLJ2JQSH.js → chunk-BCTEOVOU.js} +3 -3
- package/dist/{chunk-BLJ2JQSH.js.map → chunk-BCTEOVOU.js.map} +1 -1
- package/dist/chunk-CH5KTOEZ.js +710 -0
- package/dist/chunk-CH5KTOEZ.js.map +1 -0
- package/dist/chunk-CIHSHLQX.js +64 -0
- package/dist/chunk-CIHSHLQX.js.map +1 -0
- package/dist/{chunk-Z2L3LSNV.js → chunk-EHUDXAKC.js} +246 -210
- package/dist/chunk-EHUDXAKC.js.map +1 -0
- package/dist/chunk-GOX2CYIM.js +380 -0
- package/dist/chunk-GOX2CYIM.js.map +1 -0
- package/dist/chunk-IVJP3GKJ.js +104 -0
- package/dist/chunk-IVJP3GKJ.js.map +1 -0
- package/dist/{chunk-F7FMAWLA.js → chunk-MVZS5FDM.js} +13 -6
- package/dist/chunk-MVZS5FDM.js.map +1 -0
- package/dist/{chunk-LYLTKJWM.js → chunk-MYNLY3HP.js} +9 -8
- package/dist/chunk-MYNLY3HP.js.map +1 -0
- package/dist/{chunk-I5MQMJDW.js → chunk-NSIAORRY.js} +20 -30
- package/dist/chunk-NSIAORRY.js.map +1 -0
- package/dist/{chunk-MYXFNWAJ.js → chunk-QNGYQMZB.js} +4 -4
- package/dist/chunk-QNGYQMZB.js.map +1 -0
- package/dist/chunk-WT5PBPLB.js +98 -0
- package/dist/chunk-WT5PBPLB.js.map +1 -0
- package/dist/{core-CTzMJ82M.d.ts → core-BbgtiXdg.d.ts} +231 -139
- package/dist/do/index.d.ts +37 -32
- package/dist/do/index.js +21 -14
- package/dist/do/index.js.map +1 -1
- package/dist/{durable-effects-B0-qGQDy.d.ts → durable-effects-7MTK_jnj.d.ts} +1 -1
- package/dist/effect/index.d.ts +151 -0
- package/dist/effect/index.js +98 -0
- package/dist/effect/index.js.map +1 -0
- package/dist/extension/index.d.ts +6 -7
- package/dist/extension/index.js +3 -2
- package/dist/extension/index.js.map +1 -1
- package/dist/flow/index.d.ts +68 -70
- package/dist/flow/index.js +32 -27
- package/dist/flow/index.js.map +1 -1
- package/dist/idempotency/index.d.ts +6 -7
- package/dist/idempotency/index.js +4 -2
- package/dist/{index-DJWIER_3.d.ts → index-7vV8xmsD.d.ts} +1 -1
- package/dist/{index-NjrT3fL2.d.ts → index-Bz5Rh9Ga.d.ts} +19 -96
- package/dist/index-CjFDUBeq.d.ts +207 -0
- package/dist/{index-6A7dB8f6.d.ts → index-CkFYA9Y6.d.ts} +14 -16
- package/dist/{index-B5BZ-_cT.d.ts → index-Cou86-GX.d.ts} +189 -108
- package/dist/{index-TvRb1KVf.d.ts → index-DU6JpQ8G.d.ts} +1 -1
- package/dist/{index-q0hXFeZ0.d.ts → index-Xufl55W8.d.ts} +286 -215
- package/dist/{index-4vZzljCD.d.ts → index-_dOR3xqA.d.ts} +57 -45
- package/dist/index.d.ts +181 -385
- package/dist/index.js +2 -1
- package/dist/jev/index.d.ts +147 -99
- package/dist/jev/index.js +329 -233
- package/dist/jev/index.js.map +1 -1
- package/dist/{machine-CdIcN2Xm.d.ts → machine-BQzTV8On.d.ts} +171 -280
- package/dist/machine-viz/index.d.ts +5 -5
- package/dist/machine-viz/index.js +8 -4
- package/dist/machine-viz/index.js.map +1 -1
- package/dist/mem/index.d.ts +3 -4
- package/dist/mem/index.js +2 -1
- package/dist/mem/index.js.map +1 -1
- package/dist/node/index.d.ts +119 -78
- package/dist/node/index.js +52 -38
- package/dist/node/index.js.map +1 -1
- package/dist/paginate/index.d.ts +27 -33
- package/dist/paginate/index.js +6 -4
- package/dist/parity/index.d.ts +4 -5
- package/dist/parity/index.js +3 -2
- package/dist/parity/index.js.map +1 -1
- package/dist/pbt/index.d.ts +2 -2
- package/dist/pbt/index.js +2 -1
- package/dist/pbt/index.js.map +1 -1
- package/dist/persistence/index.d.ts +6 -7
- package/dist/persistence/index.js +5 -3
- package/dist/promise/index.d.ts +186 -0
- package/dist/promise/index.js +5 -0
- package/dist/promise/index.js.map +1 -0
- package/dist/protocol-ClRZBhHQ.d.ts +53 -0
- package/dist/react/index.d.ts +36 -17
- package/dist/react/index.js +27 -4
- package/dist/react/index.js.map +1 -1
- package/dist/resilience/index.d.ts +63 -455
- package/dist/resilience/index.js +37 -483
- package/dist/resilience/index.js.map +1 -1
- package/dist/{runtime-types-LWDoi943.d.ts → runtime-types-CiVpC0HN.d.ts} +131 -388
- package/dist/testing/index.d.ts +165 -15
- package/dist/testing/index.js +104 -3
- package/dist/testing/index.js.map +1 -1
- package/dist/timing/index.d.ts +25 -22
- package/dist/timing/index.js +4 -3
- package/dist/timing/index.js.map +1 -1
- package/dist/{types-DP3f5NIl.d.ts → types-LxZxGYda.d.ts} +2 -2
- package/dist/work-queue/index.d.ts +5 -6
- package/package.json +18 -5
- package/dist/chunk-AQ6ZIMEA.js.map +0 -1
- package/dist/chunk-F2US5BW6.js +0 -72
- package/dist/chunk-F2US5BW6.js.map +0 -1
- package/dist/chunk-F7FMAWLA.js.map +0 -1
- package/dist/chunk-HUKZQX6U.js +0 -97
- package/dist/chunk-HUKZQX6U.js.map +0 -1
- package/dist/chunk-HYDWG35Q.js.map +0 -1
- package/dist/chunk-I5MQMJDW.js.map +0 -1
- package/dist/chunk-LYLTKJWM.js.map +0 -1
- package/dist/chunk-MYXFNWAJ.js.map +0 -1
- package/dist/chunk-RQULHGYH.js +0 -1804
- package/dist/chunk-RQULHGYH.js.map +0 -1
- package/dist/chunk-Z2L3LSNV.js.map +0 -1
- package/dist/index-DMCeMPMJ.d.ts +0 -272
|
@@ -0,0 +1,151 @@
|
|
|
1
|
+
import { Effect, Stream, Scope } from 'effect';
|
|
2
|
+
import { C as Cmd, E as ErrorsOf, O as OkOfCmd, D as DeclaredErrorsOf, S as Sub, B as BuiltinSubType, a as BuiltinSub, M as Machine } from '../core-BbgtiXdg.js';
|
|
3
|
+
import { C as CtxArg, S as Store, O as OnError, a as Supervision, T as TelemetrySink, B as BootingRuntime } from '../runtime-types-CiVpC0HN.js';
|
|
4
|
+
import '@standard-schema/spec';
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* The Effect engine's `run` (#283): the same machine the Promise engine runs,
|
|
8
|
+
* with Effect handlers, Effect sub runners, the caller's Layers and
|
|
9
|
+
* interruption on stop.
|
|
10
|
+
*
|
|
11
|
+
* It runs the one core loop both engines share (`src/internal/engine/loop.ts`)
|
|
12
|
+
* with the same built-ins in the same order, so a machine folds the same way on
|
|
13
|
+
* either engine. What this file adds is the Effect edge:
|
|
14
|
+
*
|
|
15
|
+
* - an `interpret` cell returns `Effect<Ok, E, R>`, read with
|
|
16
|
+
* `Effect.result`: a success settles `_ok`, a declared failure settles
|
|
17
|
+
* `_err`, a defect goes to the error sink;
|
|
18
|
+
* - a `subscribe` runner returns a `Stream<Msg>`, drained on its own fiber;
|
|
19
|
+
* - every handler and runner fiber runs with the services the caller
|
|
20
|
+
* provided, so `R` reaches them from the caller's Layers;
|
|
21
|
+
* - stopping interrupts every handler fiber still in flight.
|
|
22
|
+
*/
|
|
23
|
+
|
|
24
|
+
/**
|
|
25
|
+
* One Effect `interpret` cell. For a `Cmd.define`d Cmd it succeeds with the
|
|
26
|
+
* Cmd's `Ok` and fails with one of its declared tags, and the engine mints
|
|
27
|
+
* `<name>_ok` / `<name>_err` from that (ADR 0021). For a hand-written Cmd it
|
|
28
|
+
* succeeds with a follow-up Msg or nothing, and a failure rejects the dispatch,
|
|
29
|
+
* as a throw does on the Promise engine. `R` is whatever services it reads.
|
|
30
|
+
*/
|
|
31
|
+
type EffectInterpretCell<M extends {
|
|
32
|
+
type: string;
|
|
33
|
+
}, C extends Cmd, R = unknown> = unknown extends ErrorsOf<C> ? (cmd: C) => Effect.Effect<M | void, unknown, R> : (cmd: C) => Effect.Effect<OkOfCmd<C>, DeclaredErrorsOf<C>, R>;
|
|
34
|
+
/**
|
|
35
|
+
* The Effect engine's `interpret` map: one cell per Cmd variant, each reading
|
|
36
|
+
* services within `R`.
|
|
37
|
+
*/
|
|
38
|
+
type EffectInterpret<M extends {
|
|
39
|
+
type: string;
|
|
40
|
+
}, C extends Cmd, R = unknown> = {
|
|
41
|
+
readonly [K in C["type"]]: EffectInterpretCell<M, Extract<C, {
|
|
42
|
+
type: K;
|
|
43
|
+
}>, R>;
|
|
44
|
+
};
|
|
45
|
+
/**
|
|
46
|
+
* One Effect sub runner: the Sub in, a `Stream` of Msgs out. The engine drains
|
|
47
|
+
* it on its own fiber and interrupts that fiber when the Sub stops. A stream
|
|
48
|
+
* that fails reaches the error sink under `"follow-up"`.
|
|
49
|
+
*/
|
|
50
|
+
type EffectRunner<M extends {
|
|
51
|
+
type: string;
|
|
52
|
+
}, U extends Sub, R = unknown> = (sub: U) => Stream.Stream<M, unknown, R>;
|
|
53
|
+
/**
|
|
54
|
+
* The Effect engine's `subscribe` map: a runner for every Sub type the machine
|
|
55
|
+
* declares beyond the built-ins, and optionally one for a built-in, which
|
|
56
|
+
* replaces the engine's own (#270 R2.1).
|
|
57
|
+
*/
|
|
58
|
+
type EffectSubscribe<M extends {
|
|
59
|
+
type: string;
|
|
60
|
+
}, U extends Sub, R = unknown> = {
|
|
61
|
+
readonly [K in Exclude<U["type"], BuiltinSubType>]: EffectRunner<M, Extract<U, {
|
|
62
|
+
type: K;
|
|
63
|
+
}>, R>;
|
|
64
|
+
} & {
|
|
65
|
+
readonly [K in BuiltinSubType]?: EffectRunner<M, Extract<BuiltinSub<M>, {
|
|
66
|
+
type: K;
|
|
67
|
+
}>, R>;
|
|
68
|
+
};
|
|
69
|
+
/** The services every cell of an `interpret` map reads. */
|
|
70
|
+
type InterpretServices<I> = {
|
|
71
|
+
[K in keyof I]: ServicesOfCell<I[K]>;
|
|
72
|
+
}[keyof I];
|
|
73
|
+
type ServicesOfCell<F> = F extends (cmd: never) => Effect.Effect<unknown, unknown, infer R> ? R : never;
|
|
74
|
+
/** The services every runner of a `subscribe` map reads. */
|
|
75
|
+
type SubscribeServices<B> = {
|
|
76
|
+
[K in keyof B]-?: ServicesOfRunner<NonNullable<B[K]>>;
|
|
77
|
+
}[keyof B];
|
|
78
|
+
type ServicesOfRunner<F> = F extends (sub: never) => Stream.Stream<unknown, unknown, infer R> ? R : never;
|
|
79
|
+
type InterpretOption<C extends Cmd, I> = [C] extends [Cmd<never>] ? {
|
|
80
|
+
readonly interpret?: I;
|
|
81
|
+
} : {
|
|
82
|
+
readonly interpret: I;
|
|
83
|
+
};
|
|
84
|
+
type SubscribeOption<U extends Sub, B> = [
|
|
85
|
+
Exclude<U["type"], BuiltinSubType>
|
|
86
|
+
] extends [never] ? {
|
|
87
|
+
readonly subscribe?: B;
|
|
88
|
+
} : {
|
|
89
|
+
readonly subscribe: B;
|
|
90
|
+
};
|
|
91
|
+
/**
|
|
92
|
+
* The options of the Effect engine's `run`. Beside `interpret` and
|
|
93
|
+
* `subscribe`, they are the Promise engine's, with the same meaning; see `run`
|
|
94
|
+
* in `@demlik/tea/promise` for each one's contract.
|
|
95
|
+
*/
|
|
96
|
+
type EffectRunOptions<S, M extends {
|
|
97
|
+
type: string;
|
|
98
|
+
}, C extends Cmd, U extends Sub, Ctx, E extends {
|
|
99
|
+
type: string;
|
|
100
|
+
}, I, B> = CtxArg<Ctx> & InterpretOption<C, I> & SubscribeOption<U, B> & {
|
|
101
|
+
readonly store?: Store<S>;
|
|
102
|
+
readonly onError?: OnError;
|
|
103
|
+
/** Stamps `at` on minted Msgs and telemetry. Defaults to `Date.now`. */
|
|
104
|
+
readonly clock?: () => number;
|
|
105
|
+
/** Projects each applied transition to the public events `on` serves. */
|
|
106
|
+
readonly events?: (msg: M, state: S) => readonly E[];
|
|
107
|
+
/** The policy for a reducer throw. Defaults to `"stop"`. */
|
|
108
|
+
readonly supervision?: Supervision<S, M>;
|
|
109
|
+
/** The terminal predicate `result()` and `done()` read. */
|
|
110
|
+
readonly terminal?: (state: S) => boolean;
|
|
111
|
+
/** A fire-and-forget sink for every applied transition. */
|
|
112
|
+
readonly telemetry?: TelemetrySink;
|
|
113
|
+
/** How long `stop()` waits for async teardown. Defaults to 5_000ms. */
|
|
114
|
+
readonly disposeTimeoutMs?: number;
|
|
115
|
+
};
|
|
116
|
+
/**
|
|
117
|
+
* Run `machine` on the Effect engine. The returned Effect needs a `Scope` and
|
|
118
|
+
* the services its handlers and runners read, and yields the run handle —
|
|
119
|
+
* the same handle the Promise engine returns, so a host adapter typed against
|
|
120
|
+
* `RunHandle` takes either.
|
|
121
|
+
*
|
|
122
|
+
* Closing the scope stops the run: every handler still in flight is
|
|
123
|
+
* interrupted (its finalizers run), its Msg is never dispatched, and no Msg is
|
|
124
|
+
* dispatched after stop. Calling `stop()` on the handle does the same.
|
|
125
|
+
*
|
|
126
|
+
* A fenced store is fenced here exactly as on the Promise engine: the check is
|
|
127
|
+
* one of the built-ins both engines run.
|
|
128
|
+
*
|
|
129
|
+
* ```ts
|
|
130
|
+
* const program = Effect.gen(function* () {
|
|
131
|
+
* const rt = yield* run(machine, {
|
|
132
|
+
* interpret: {
|
|
133
|
+
* fetch: (cmd) =>
|
|
134
|
+
* Effect.gen(function* () {
|
|
135
|
+
* const api = yield* Api;
|
|
136
|
+
* return yield* api.get(cmd.id);
|
|
137
|
+
* }),
|
|
138
|
+
* },
|
|
139
|
+
* });
|
|
140
|
+
* yield* Effect.promise(() => rt.dispatch({ type: "go", id: "7" }));
|
|
141
|
+
* });
|
|
142
|
+
* Effect.runPromise(program.pipe(Effect.scoped, Effect.provide(ApiLive)));
|
|
143
|
+
* ```
|
|
144
|
+
*/
|
|
145
|
+
declare function run<S, M extends {
|
|
146
|
+
type: string;
|
|
147
|
+
}, C extends Cmd, U extends Sub, Ctx, I extends EffectInterpret<M, C> = EffectInterpret<M, C, never>, B extends EffectSubscribe<M, U> = EffectSubscribe<M, U, never>, E extends {
|
|
148
|
+
type: string;
|
|
149
|
+
} = never>(machine: Machine<S, M, C, U, Ctx>, opts: EffectRunOptions<S, M, C, U, Ctx, E, I, B>): Effect.Effect<BootingRuntime<S, M, E>, never, Scope.Scope | InterpretServices<I> | SubscribeServices<B>>;
|
|
150
|
+
|
|
151
|
+
export { type EffectInterpret, type EffectInterpretCell, type EffectRunOptions, type EffectRunner, type EffectSubscribe, type InterpretServices, type SubscribeServices, run };
|
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
import { startLoop, builtinExtensions } from '../chunk-5XU6ZJO2.js';
|
|
2
|
+
import { subEntriesOf, applyCell, Outcome } from '../chunk-CH5KTOEZ.js';
|
|
3
|
+
import { Effect, Stream, Cause, Fiber, Exit, Result } from 'effect';
|
|
4
|
+
|
|
5
|
+
function timer(sub) {
|
|
6
|
+
return Stream.fromEffect(Effect.as(Effect.sleep(sub.deps.ms), sub.deps.msg));
|
|
7
|
+
}
|
|
8
|
+
var builtinRunners = { timer };
|
|
9
|
+
function run(machine, opts) {
|
|
10
|
+
return Effect.gen(function* () {
|
|
11
|
+
const services = yield* Effect.context();
|
|
12
|
+
return yield* Effect.acquireRelease(
|
|
13
|
+
Effect.sync(
|
|
14
|
+
() => start(
|
|
15
|
+
machine,
|
|
16
|
+
opts,
|
|
17
|
+
Effect.runPromiseExitWith(services),
|
|
18
|
+
Effect.runForkWith(services)
|
|
19
|
+
)
|
|
20
|
+
),
|
|
21
|
+
(runtime) => Effect.promise(() => runtime.stop())
|
|
22
|
+
);
|
|
23
|
+
});
|
|
24
|
+
}
|
|
25
|
+
function start(machine, opts, runEffect, fork) {
|
|
26
|
+
const interpret = opts.interpret ?? {};
|
|
27
|
+
const subscribe = opts.subscribe ?? {};
|
|
28
|
+
const builtins = builtinRunners;
|
|
29
|
+
const defined = new Set((machine.cmds ?? []).map((def) => def.cmdType));
|
|
30
|
+
const interruption = new AbortController();
|
|
31
|
+
let report = () => {
|
|
32
|
+
};
|
|
33
|
+
const edge = (loop) => {
|
|
34
|
+
report = loop.report;
|
|
35
|
+
return {};
|
|
36
|
+
};
|
|
37
|
+
async function settle(cell, cmd) {
|
|
38
|
+
const type = cmd.type;
|
|
39
|
+
const exit = await runEffect(Effect.result(cell(cmd)), {
|
|
40
|
+
signal: interruption.signal
|
|
41
|
+
});
|
|
42
|
+
if (Exit.isFailure(exit)) {
|
|
43
|
+
if (Cause.hasInterruptsOnly(exit.cause)) return void 0;
|
|
44
|
+
throw Cause.squash(exit.cause);
|
|
45
|
+
}
|
|
46
|
+
const result = exit.value;
|
|
47
|
+
if (defined.has(type)) {
|
|
48
|
+
return Result.isSuccess(result) ? Outcome.ok(result.success) : Outcome.err(result.failure);
|
|
49
|
+
}
|
|
50
|
+
if (Result.isFailure(result)) throw result.failure;
|
|
51
|
+
return result.success;
|
|
52
|
+
}
|
|
53
|
+
function handlerFor(type) {
|
|
54
|
+
const cell = interpret[type];
|
|
55
|
+
if (cell === void 0) return void 0;
|
|
56
|
+
return (cmd) => settle(cell, cmd);
|
|
57
|
+
}
|
|
58
|
+
function runnerFor(type) {
|
|
59
|
+
const make = subscribe[type] ?? builtins[type];
|
|
60
|
+
if (make === void 0) return void 0;
|
|
61
|
+
return (sub, _ctx, dispatch) => {
|
|
62
|
+
const drain = Stream.runForEach(
|
|
63
|
+
make(sub),
|
|
64
|
+
(msg) => Effect.sync(() => dispatch(msg))
|
|
65
|
+
).pipe(
|
|
66
|
+
Effect.catchCause(
|
|
67
|
+
(cause) => Cause.hasInterruptsOnly(cause) ? Effect.void : Effect.sync(() => report(Cause.squash(cause), "follow-up"))
|
|
68
|
+
)
|
|
69
|
+
);
|
|
70
|
+
const fiber = fork(drain);
|
|
71
|
+
return () => Effect.runPromise(Fiber.interrupt(fiber));
|
|
72
|
+
};
|
|
73
|
+
}
|
|
74
|
+
const handle = startLoop({
|
|
75
|
+
init: machine.init,
|
|
76
|
+
reduce: (state, msg) => applyCell(machine, state, msg),
|
|
77
|
+
subs: subEntriesOf(machine),
|
|
78
|
+
runnerFor,
|
|
79
|
+
handlerFor,
|
|
80
|
+
store: opts.store,
|
|
81
|
+
ctx: opts.ctx ?? {},
|
|
82
|
+
onError: opts.onError,
|
|
83
|
+
disposeTimeoutMs: opts.disposeTimeoutMs ?? 5e3,
|
|
84
|
+
idleCap: 1e5,
|
|
85
|
+
extensions: [...builtinExtensions(machine, opts), edge]
|
|
86
|
+
});
|
|
87
|
+
const stopLoop = handle.stop;
|
|
88
|
+
handle.stop = () => {
|
|
89
|
+
const stopped = stopLoop();
|
|
90
|
+
interruption.abort();
|
|
91
|
+
return stopped;
|
|
92
|
+
};
|
|
93
|
+
return handle;
|
|
94
|
+
}
|
|
95
|
+
|
|
96
|
+
export { run };
|
|
97
|
+
//# sourceMappingURL=index.js.map
|
|
98
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../../src/effect/run.ts"],"names":[],"mappings":"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","file":"index.js","sourcesContent":["/**\n * The Effect engine's `run` (#283): the same machine the Promise engine runs,\n * with Effect handlers, Effect sub runners, the caller's Layers and\n * interruption on stop.\n *\n * It runs the one core loop both engines share (`src/internal/engine/loop.ts`)\n * with the same built-ins in the same order, so a machine folds the same way on\n * either engine. What this file adds is the Effect edge:\n *\n * - an `interpret` cell returns `Effect<Ok, E, R>`, read with\n * `Effect.result`: a success settles `_ok`, a declared failure settles\n * `_err`, a defect goes to the error sink;\n * - a `subscribe` runner returns a `Stream<Msg>`, drained on its own fiber;\n * - every handler and runner fiber runs with the services the caller\n * provided, so `R` reaches them from the caller's Layers;\n * - stopping interrupts every handler fiber still in flight.\n */\n\nimport { Cause, Effect, Exit, Fiber, Result, type Scope, Stream } from \"effect\";\nimport { builtinExtensions } from \"../internal/engine/builtins\";\nimport {\n type ExtensionFactory,\n type LoopHandler,\n type LoopRunner,\n startLoop,\n} from \"../internal/engine/loop\";\nimport type {\n BuiltinSub,\n BuiltinSubType,\n Cmd,\n DeclaredErrorsOf,\n ErrorsOf,\n Machine,\n OkOfCmd,\n Sub,\n TimerSub,\n} from \"../pure/core\";\nimport { applyCell, Outcome, subEntriesOf } from \"../pure/core\";\nimport type {\n BootingRuntime,\n CtxArg,\n OnError,\n RuntimeErrorPhase,\n Store,\n Supervision,\n TelemetrySink,\n} from \"../runtime-types\";\n\n// === The handler and runner shapes ===\n\n/**\n * One Effect `interpret` cell. For a `Cmd.define`d Cmd it succeeds with the\n * Cmd's `Ok` and fails with one of its declared tags, and the engine mints\n * `<name>_ok` / `<name>_err` from that (ADR 0021). For a hand-written Cmd it\n * succeeds with a follow-up Msg or nothing, and a failure rejects the dispatch,\n * as a throw does on the Promise engine. `R` is whatever services it reads.\n */\nexport type EffectInterpretCell<\n M extends { type: string },\n C extends Cmd,\n R = unknown,\n> =\n unknown extends ErrorsOf<C>\n ? // biome-ignore lint/suspicious/noConfusingVoidType: a hand-written Cmd's handler may settle with nothing\n (cmd: C) => Effect.Effect<M | void, unknown, R>\n : (cmd: C) => Effect.Effect<OkOfCmd<C>, DeclaredErrorsOf<C>, R>;\n\n/**\n * The Effect engine's `interpret` map: one cell per Cmd variant, each reading\n * services within `R`.\n */\nexport type EffectInterpret<\n M extends { type: string },\n C extends Cmd,\n R = unknown,\n> = {\n readonly [K in C[\"type\"]]: EffectInterpretCell<M, Extract<C, { type: K }>, R>;\n};\n\n/**\n * One Effect sub runner: the Sub in, a `Stream` of Msgs out. The engine drains\n * it on its own fiber and interrupts that fiber when the Sub stops. A stream\n * that fails reaches the error sink under `\"follow-up\"`.\n */\nexport type EffectRunner<\n M extends { type: string },\n U extends Sub,\n R = unknown,\n> = (sub: U) => Stream.Stream<M, unknown, R>;\n\n/**\n * The Effect engine's `subscribe` map: a runner for every Sub type the machine\n * declares beyond the built-ins, and optionally one for a built-in, which\n * replaces the engine's own (#270 R2.1).\n */\nexport type EffectSubscribe<\n M extends { type: string },\n U extends Sub,\n R = unknown,\n> = {\n readonly [K in Exclude<U[\"type\"], BuiltinSubType>]: EffectRunner<\n M,\n Extract<U, { type: K }>,\n R\n >;\n} & {\n readonly [K in BuiltinSubType]?: EffectRunner<\n M,\n Extract<BuiltinSub<M>, { type: K }>,\n R\n >;\n};\n\n/** The services every cell of an `interpret` map reads. */\nexport type InterpretServices<I> = {\n [K in keyof I]: ServicesOfCell<I[K]>;\n}[keyof I];\n\ntype ServicesOfCell<F> = F extends (\n cmd: never,\n) => Effect.Effect<unknown, unknown, infer R>\n ? R\n : never;\n\n/** The services every runner of a `subscribe` map reads. */\nexport type SubscribeServices<B> = {\n [K in keyof B]-?: ServicesOfRunner<NonNullable<B[K]>>;\n}[keyof B];\n\ntype ServicesOfRunner<F> = F extends (\n sub: never,\n) => Stream.Stream<unknown, unknown, infer R>\n ? R\n : never;\n\n// `interpret` is optional for a machine that emits no Cmd, and `subscribe` for\n// one that declares only built-in Subs — the same requiredness the Promise\n// engine's `RunHandlers` carries.\ntype InterpretOption<C extends Cmd, I> = [C] extends [Cmd<never>]\n ? { readonly interpret?: I }\n : { readonly interpret: I };\n\ntype SubscribeOption<U extends Sub, B> = [\n Exclude<U[\"type\"], BuiltinSubType>,\n] extends [never]\n ? { readonly subscribe?: B }\n : { readonly subscribe: B };\n\n/**\n * The options of the Effect engine's `run`. Beside `interpret` and\n * `subscribe`, they are the Promise engine's, with the same meaning; see `run`\n * in `@demlik/tea/promise` for each one's contract.\n */\nexport type EffectRunOptions<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n E extends { type: string },\n I,\n B,\n> = CtxArg<Ctx> &\n InterpretOption<C, I> &\n SubscribeOption<U, B> & {\n readonly store?: Store<S>;\n readonly onError?: OnError;\n /** Stamps `at` on minted Msgs and telemetry. Defaults to `Date.now`. */\n readonly clock?: () => number;\n /** Projects each applied transition to the public events `on` serves. */\n readonly events?: (msg: M, state: S) => readonly E[];\n /** The policy for a reducer throw. Defaults to `\"stop\"`. */\n readonly supervision?: Supervision<S, M>;\n /** The terminal predicate `result()` and `done()` read. */\n readonly terminal?: (state: S) => boolean;\n /** A fire-and-forget sink for every applied transition. */\n readonly telemetry?: TelemetrySink;\n /** How long `stop()` waits for async teardown. Defaults to 5_000ms. */\n readonly disposeTimeoutMs?: number;\n };\n\n// === Built-in runners ===\n\n/** `timer`: emit `deps.msg` once, `deps.ms` after the Sub starts. */\nfunction timer<M>(sub: TimerSub<M>): Stream.Stream<M> {\n return Stream.fromEffect(Effect.as(Effect.sleep(sub.deps.ms), sub.deps.msg));\n}\n\n/** The Effect engine's built-in runners, keyed by the Sub type each runs. */\nconst builtinRunners = { timer } as const satisfies Record<\n BuiltinSubType,\n unknown\n>;\n\n// === run ===\n\n/**\n * Run `machine` on the Effect engine. The returned Effect needs a `Scope` and\n * the services its handlers and runners read, and yields the run handle —\n * the same handle the Promise engine returns, so a host adapter typed against\n * `RunHandle` takes either.\n *\n * Closing the scope stops the run: every handler still in flight is\n * interrupted (its finalizers run), its Msg is never dispatched, and no Msg is\n * dispatched after stop. Calling `stop()` on the handle does the same.\n *\n * A fenced store is fenced here exactly as on the Promise engine: the check is\n * one of the built-ins both engines run.\n *\n * ```ts\n * const program = Effect.gen(function* () {\n * const rt = yield* run(machine, {\n * interpret: {\n * fetch: (cmd) =>\n * Effect.gen(function* () {\n * const api = yield* Api;\n * return yield* api.get(cmd.id);\n * }),\n * },\n * });\n * yield* Effect.promise(() => rt.dispatch({ type: \"go\", id: \"7\" }));\n * });\n * Effect.runPromise(program.pipe(Effect.scoped, Effect.provide(ApiLive)));\n * ```\n */\nexport function run<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n // The defaults read no services, so an omitted map adds none to `R`.\n I extends EffectInterpret<M, C> = EffectInterpret<M, C, never>,\n B extends EffectSubscribe<M, U> = EffectSubscribe<M, U, never>,\n E extends { type: string } = never,\n>(\n machine: Machine<S, M, C, U, Ctx>,\n opts: EffectRunOptions<S, M, C, U, Ctx, E, I, B>,\n): Effect.Effect<\n BootingRuntime<S, M, E>,\n never,\n Scope.Scope | InterpretServices<I> | SubscribeServices<B>\n> {\n return Effect.gen(function* () {\n const services = yield* Effect.context<\n InterpretServices<I> | SubscribeServices<B>\n >();\n return yield* Effect.acquireRelease(\n Effect.sync(() =>\n start<S, M, C, U, Ctx, E>(\n machine,\n opts as EffectRunOptions<S, M, C, U, Ctx, E, unknown, unknown>,\n Effect.runPromiseExitWith(services) as RunEffect,\n Effect.runForkWith(services) as ForkEffect,\n ),\n ),\n (runtime) => Effect.promise(() => runtime.stop()),\n );\n });\n}\n\n/** Run an erased Effect to its Exit, interruptible through `signal`. */\ntype RunEffect = (\n effect: Effect.Effect<unknown, unknown>,\n options: { readonly signal: AbortSignal },\n) => Promise<Exit.Exit<unknown, unknown>>;\n\n/** Fork an erased Effect onto its own fiber. */\ntype ForkEffect = (\n effect: Effect.Effect<unknown, unknown>,\n) => Fiber.Fiber<unknown, unknown>;\n\ntype AnyCell = (cmd: unknown) => Effect.Effect<unknown, unknown>;\ntype AnyRunner = (sub: Sub) => Stream.Stream<unknown, unknown>;\n\nfunction start<\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n E extends { type: string },\n>(\n machine: Machine<S, M, C, U, Ctx>,\n opts: EffectRunOptions<S, M, C, U, Ctx, E, unknown, unknown>,\n runEffect: RunEffect,\n fork: ForkEffect,\n): BootingRuntime<S, M, E> {\n const interpret = ((opts as { interpret?: unknown }).interpret ??\n {}) as Readonly<Record<string, AnyCell | undefined>>;\n const subscribe = ((opts as { subscribe?: unknown }).subscribe ??\n {}) as Readonly<Record<string, AnyRunner | undefined>>;\n const builtins = builtinRunners as unknown as Readonly<\n Record<string, AnyRunner | undefined>\n >;\n const defined = new Set((machine.cmds ?? []).map((def) => def.cmdType));\n\n // Aborted on stop: every handler fiber runs under this signal, so aborting\n // it interrupts all of them at once.\n const interruption = new AbortController();\n\n // The loop's error sink, lent to the runners below: a stream that fails\n // after it started has no caller to reject at.\n let report: (error: unknown, phase: RuntimeErrorPhase) => void = () => {};\n const edge: ExtensionFactory<S, M, C> = (loop) => {\n report = loop.report;\n return {};\n };\n\n // Read the cell's Effect with `Effect.result`, so a declared failure is a\n // value and only a defect or an interruption is left in the Exit's cause.\n async function settle(cell: AnyCell, cmd: unknown): Promise<unknown> {\n const type = (cmd as { type: string }).type;\n const exit = await runEffect(Effect.result(cell(cmd)), {\n signal: interruption.signal,\n });\n if (Exit.isFailure(exit)) {\n // Interrupted by stop: nothing to dispatch.\n if (Cause.hasInterruptsOnly(exit.cause)) return undefined;\n // A defect. For a defined Cmd the `Cmd.define` edge routes this throw to\n // the error sink; for a hand-written one it rejects the dispatch.\n throw Cause.squash(exit.cause);\n }\n const result = exit.value as Result.Result<unknown, unknown>;\n if (defined.has(type)) {\n return Result.isSuccess(result)\n ? Outcome.ok(result.success)\n : Outcome.err(result.failure);\n }\n if (Result.isFailure(result)) throw result.failure;\n return result.success;\n }\n\n function handlerFor(type: string): LoopHandler<M> | undefined {\n const cell = interpret[type];\n if (cell === undefined) return undefined;\n return (cmd) => settle(cell, cmd);\n }\n\n // A runner's Msgs reach the loop through its `dispatch`, which queues each\n // one behind the step in progress — never a transition on the stream's own\n // fiber (spike #260).\n function runnerFor(type: string): LoopRunner<Ctx, M> | undefined {\n const make = subscribe[type] ?? builtins[type];\n if (make === undefined) return undefined;\n return (sub, _ctx, dispatch) => {\n const drain = Stream.runForEach(make(sub), (msg) =>\n Effect.sync(() => dispatch(msg as M)),\n ).pipe(\n Effect.catchCause((cause) =>\n Cause.hasInterruptsOnly(cause)\n ? Effect.void\n : Effect.sync(() => report(Cause.squash(cause), \"follow-up\")),\n ),\n );\n const fiber = fork(drain);\n return () => Effect.runPromise(Fiber.interrupt(fiber));\n };\n }\n\n const handle = startLoop<S, M, C, Ctx>({\n init: machine.init,\n reduce: (state, msg) => applyCell<S, M, C>(machine, state, msg),\n subs: subEntriesOf<S>(machine),\n runnerFor,\n handlerFor,\n store: opts.store,\n ctx: (opts.ctx ?? {}) as Ctx,\n onError: opts.onError,\n disposeTimeoutMs: opts.disposeTimeoutMs ?? 5_000,\n idleCap: 100_000,\n extensions: [...builtinExtensions<S, M, C, E>(machine, opts), edge],\n });\n\n // Stop closes the gate first, so nothing an interrupted handler leaves\n // behind is dispatched, then interrupts every handler still in flight so the\n // drain it waits on can finish.\n const stopLoop = handle.stop;\n handle.stop = () => {\n const stopped = stopLoop();\n interruption.abort();\n return stopped;\n };\n return handle as unknown as BootingRuntime<S, M, E>;\n}\n"]}
|
|
@@ -1,9 +1,8 @@
|
|
|
1
|
-
import { R as Runtime, S as Store } from '../runtime-types-
|
|
1
|
+
import { R as Runtime, S as Store } from '../runtime-types-CiVpC0HN.js';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { S as Sub } from '../core-
|
|
4
|
-
import { S as SubscribeHandler } from '../types-
|
|
5
|
-
import '
|
|
6
|
-
import 'zod';
|
|
3
|
+
import { S as Sub } from '../core-BbgtiXdg.js';
|
|
4
|
+
import { S as SubscribeHandler } from '../types-LxZxGYda.js';
|
|
5
|
+
import '@standard-schema/spec';
|
|
7
6
|
|
|
8
7
|
/**
|
|
9
8
|
* Runtime bridge — expose a `@demlik/tea` runtime running in one chrome context
|
|
@@ -327,9 +326,9 @@ declare function createBackgroundRuntimeContext<S, M extends {
|
|
|
327
326
|
}>(): BackgroundRuntimeContext<S, M>;
|
|
328
327
|
|
|
329
328
|
type AlarmSubData = {
|
|
330
|
-
alarmName: string;
|
|
329
|
+
readonly alarmName: string;
|
|
331
330
|
};
|
|
332
|
-
declare function fromChromeAlarm<S extends Sub
|
|
331
|
+
declare function fromChromeAlarm<S extends Sub<string, AlarmSubData>, M>(msgFn: (alarm: chrome.alarms.Alarm, sub: S) => M | null): SubscribeHandler<S, M, unknown>;
|
|
333
332
|
|
|
334
333
|
interface ChromeMessageOpts<S extends Sub, M> {
|
|
335
334
|
/**
|
package/dist/extension/index.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { describeError } from '../chunk-G5E74IJB.js';
|
|
2
|
-
import { historyTracker, dispatchIfPresent } from '../chunk-
|
|
2
|
+
import { historyTracker, dispatchIfPresent } from '../chunk-GOX2CYIM.js';
|
|
3
|
+
import '../chunk-CH5KTOEZ.js';
|
|
3
4
|
import { useRef, useSyncExternalStore, useEffect, useCallback, createContext, useMemo, useContext } from 'react';
|
|
4
5
|
import { jsx } from 'react/jsx-runtime';
|
|
5
6
|
|
|
@@ -249,7 +250,7 @@ function createBackgroundRuntimeContext() {
|
|
|
249
250
|
function fromChromeAlarm(msgFn) {
|
|
250
251
|
return (sub, _ctx, dispatch) => {
|
|
251
252
|
const listener = (alarm) => {
|
|
252
|
-
if (alarm.name !== sub.alarmName) return;
|
|
253
|
+
if (alarm.name !== sub.deps.alarmName) return;
|
|
253
254
|
dispatchIfPresent(dispatch, msgFn(alarm, sub));
|
|
254
255
|
};
|
|
255
256
|
chrome.alarms.onAlarm.addListener(listener);
|