@demlik/tea 0.17.0 → 0.19.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 +4 -3
- package/dist/agent/index.d.ts +182 -35
- package/dist/agent/index.js +11 -11
- package/dist/{chunk-KWNCM6XM.js → chunk-AHW2CLPT.js} +65 -18
- package/dist/chunk-AHW2CLPT.js.map +1 -0
- package/dist/{chunk-K4ETBNKS.js → chunk-AIIXV4XB.js} +38 -9
- package/dist/chunk-AIIXV4XB.js.map +1 -0
- package/dist/{chunk-LYVOGOBC.js → chunk-BRX3243I.js} +3 -3
- package/dist/{chunk-LYVOGOBC.js.map → chunk-BRX3243I.js.map} +1 -1
- package/dist/{chunk-GWWCCSDH.js → chunk-C3G2QFEZ.js} +4 -4
- package/dist/{chunk-GWWCCSDH.js.map → chunk-C3G2QFEZ.js.map} +1 -1
- package/dist/{chunk-C4U5D5HP.js → chunk-FNGZMVIT.js} +3 -3
- package/dist/chunk-FNGZMVIT.js.map +1 -0
- package/dist/{chunk-QWIPH4YH.js → chunk-H2ELKHI6.js} +16 -6
- package/dist/chunk-H2ELKHI6.js.map +1 -0
- package/dist/chunk-H3MWNH7A.js +119 -0
- package/dist/chunk-H3MWNH7A.js.map +1 -0
- package/dist/chunk-I7E7AD2S.js +213 -0
- package/dist/chunk-I7E7AD2S.js.map +1 -0
- package/dist/{chunk-OYR7ENKU.js → chunk-IHUNKHDX.js} +3 -3
- package/dist/{chunk-OYR7ENKU.js.map → chunk-IHUNKHDX.js.map} +1 -1
- package/dist/chunk-JVE2LBFJ.js +21 -0
- package/dist/chunk-JVE2LBFJ.js.map +1 -0
- package/dist/chunk-JVKU2UQC.js +34 -0
- package/dist/chunk-JVKU2UQC.js.map +1 -0
- package/dist/{chunk-OPH6Y4UT.js → chunk-JYNYG5SF.js} +4 -4
- package/dist/{chunk-OPH6Y4UT.js.map → chunk-JYNYG5SF.js.map} +1 -1
- package/dist/{chunk-XBZQT2TD.js → chunk-PCJA2HTZ.js} +437 -162
- package/dist/chunk-PCJA2HTZ.js.map +1 -0
- package/dist/{chunk-DFUEAA6L.js → chunk-PQSDUX6B.js} +3 -3
- package/dist/{chunk-DFUEAA6L.js.map → chunk-PQSDUX6B.js.map} +1 -1
- package/dist/{chunk-6XBEYZME.js → chunk-WTSOW2MD.js} +5 -5
- package/dist/{chunk-6XBEYZME.js.map → chunk-WTSOW2MD.js.map} +1 -1
- package/dist/{chunk-4PXNZ5UY.js → chunk-XVIKSRCK.js} +4 -4
- package/dist/{chunk-4PXNZ5UY.js.map → chunk-XVIKSRCK.js.map} +1 -1
- package/dist/{chunk-4NTCPTNQ.js → chunk-YIMOFXST.js} +3 -3
- package/dist/{chunk-4NTCPTNQ.js.map → chunk-YIMOFXST.js.map} +1 -1
- package/dist/{core-rDbOaJTN.d.ts → core-Ce9ncpuv.d.ts} +5 -4
- package/dist/do/index.d.ts +140 -64
- package/dist/do/index.js +17 -18
- package/dist/do/index.js.map +1 -1
- package/dist/drive-loop-CsUsW3Wo.d.ts +127 -0
- package/dist/{durable-effects-CNaw97Be.d.ts → durable-effects-BmUrRA-h.d.ts} +1 -1
- package/dist/effect/index.d.ts +6 -150
- package/dist/effect/index.js +4 -96
- package/dist/effect/index.js.map +1 -1
- package/dist/extension/index.d.ts +7 -5
- package/dist/extension/index.js +2 -3
- package/dist/extension/index.js.map +1 -1
- package/dist/flow/index.d.ts +13 -13
- package/dist/flow/index.js +13 -12
- package/dist/flow/index.js.map +1 -1
- package/dist/idempotency/index.d.ts +3 -3
- package/dist/idempotency/index.js +4 -4
- package/dist/{index-q1PoukOZ.d.ts → index-2kNxy6az.d.ts} +2 -2
- package/dist/{index-B_BxplWi.d.ts → index-B1Wzarkl.d.ts} +1 -1
- package/dist/{index-Cberb5Rr.d.ts → index-Bf9_bNql.d.ts} +2 -2
- package/dist/index-BnsAqn0-.d.ts +286 -0
- package/dist/{index-Cx0F2M34.d.ts → index-Ce5GYAuI.d.ts} +2 -2
- package/dist/{index-CWmsXNdX.d.ts → index-D8sYVzCI.d.ts} +1 -1
- package/dist/{index-CcrKLtse.d.ts → index-DWdg7R1l.d.ts} +1 -1
- package/dist/{index-BOrsbdAf.d.ts → index-Dy3379ve.d.ts} +5 -5
- package/dist/{index-DaX_P35Q.d.ts → index-e36uEyl4.d.ts} +3 -3
- package/dist/index.d.ts +109 -36
- package/dist/index.js +2 -2
- package/dist/jev/index.d.ts +8 -8
- package/dist/jev/index.js +6 -7
- package/dist/jev/index.js.map +1 -1
- package/dist/{machine-BcfCFMYF.d.ts → machine-CuojfZup.d.ts} +353 -57
- package/dist/machine-viz/index.d.ts +1 -1
- package/dist/machine-viz/index.js +2 -2
- package/dist/mem/index.d.ts +6 -6
- package/dist/mem/index.js +6 -2
- package/dist/mem/index.js.map +1 -1
- package/dist/node/index.d.ts +16 -10
- package/dist/node/index.js +22 -3
- package/dist/node/index.js.map +1 -1
- package/dist/otel/index.d.ts +161 -0
- package/dist/otel/index.js +403 -0
- package/dist/otel/index.js.map +1 -0
- package/dist/paginate/index.d.ts +4 -4
- package/dist/paginate/index.js +5 -5
- package/dist/parity/index.d.ts +3 -3
- package/dist/parity/index.js +3 -3
- package/dist/pbt/index.d.ts +166 -53
- package/dist/pbt/index.js +2 -2
- package/dist/pbt/index.js.map +1 -1
- package/dist/persistence/index.d.ts +5 -5
- package/dist/persistence/index.js +5 -5
- package/dist/promise/index.d.ts +2 -2
- package/dist/promise/index.js +4 -3
- package/dist/react/index.d.ts +2 -2
- package/dist/resilience/index.d.ts +13 -9
- package/dist/resilience/index.js +5 -5
- package/dist/resilience/index.js.map +1 -1
- package/dist/{runtime-types-B62Ucnxr.d.ts → runtime-types-BKg2CGMx.d.ts} +88 -14
- package/dist/testing/effect/index.d.ts +65 -0
- package/dist/testing/effect/index.js +148 -0
- package/dist/testing/effect/index.js.map +1 -0
- package/dist/testing/index.d.ts +12 -158
- package/dist/testing/index.js +4 -130
- package/dist/testing/index.js.map +1 -1
- package/dist/testing/promise/index.d.ts +41 -0
- package/dist/testing/promise/index.js +37 -0
- package/dist/testing/promise/index.js.map +1 -0
- package/dist/timing/index.d.ts +4 -4
- package/dist/timing/index.js +4 -4
- package/dist/{types-DPm5YCDQ.d.ts → types-SzNSHKlV.d.ts} +1 -1
- package/dist/work-queue/index.d.ts +4 -4
- package/dist/work-queue/index.js +4 -3
- package/dist/work-queue/index.js.map +1 -1
- package/package.json +26 -14
- package/dist/chunk-C4U5D5HP.js.map +0 -1
- package/dist/chunk-G5E74IJB.js +0 -8
- package/dist/chunk-G5E74IJB.js.map +0 -1
- package/dist/chunk-K4ETBNKS.js.map +0 -1
- package/dist/chunk-KWNCM6XM.js.map +0 -1
- package/dist/chunk-QWIPH4YH.js.map +0 -1
- package/dist/chunk-XBZQT2TD.js.map +0 -1
|
@@ -0,0 +1,127 @@
|
|
|
1
|
+
import { C as CtxArg } from './runtime-types-BKg2CGMx.js';
|
|
2
|
+
|
|
3
|
+
/**
|
|
4
|
+
* The default round bound when `opts.maxRounds` is omitted: **100**.
|
|
5
|
+
*
|
|
6
|
+
* A round is one drain of the pending Msgs plus one drain of the Cmds those
|
|
7
|
+
* folds emitted, so a settling machine costs a handful; 100 is loose enough
|
|
8
|
+
* that a legitimate retry ladder finishes inside it and tight enough that a
|
|
9
|
+
* genuine cycle stops rather than hangs.
|
|
10
|
+
*/
|
|
11
|
+
declare const DEFAULT_MAX_ROUNDS = 100;
|
|
12
|
+
/**
|
|
13
|
+
* One entry of a driven run's history, in dispatch order.
|
|
14
|
+
*
|
|
15
|
+
* - `msg` — a Msg folded through the machine's reducer. The seed Msg is the
|
|
16
|
+
* first entry of every trace; every later one is a settle Msg a handler
|
|
17
|
+
* returned (or fired through its injected `dispatch`), or a Msg a running
|
|
18
|
+
* Sub emitted.
|
|
19
|
+
* - `cmd` — a Cmd handed to an interpret handler. It is recorded BEFORE the
|
|
20
|
+
* handler runs, so a trace recovered from a failed handler names the Cmd
|
|
21
|
+
* that failed as its last entry.
|
|
22
|
+
*/
|
|
23
|
+
type DriveTraceEntry<M, C> = {
|
|
24
|
+
readonly kind: "msg";
|
|
25
|
+
readonly msg: M;
|
|
26
|
+
} | {
|
|
27
|
+
readonly kind: "cmd";
|
|
28
|
+
readonly cmd: C;
|
|
29
|
+
};
|
|
30
|
+
/** What a settled `drive` hands back. */
|
|
31
|
+
interface DriveResult<S, M, C> {
|
|
32
|
+
/** The state after the machine went quiet — no Msg pending, no Cmd unperformed. */
|
|
33
|
+
readonly state: S;
|
|
34
|
+
/**
|
|
35
|
+
* Every Msg folded and every Cmd dispatched, in order. Filtering it to its
|
|
36
|
+
* `msg` entries and replaying those through `replay` from the same initial
|
|
37
|
+
* state reproduces {@link DriveResult.state}.
|
|
38
|
+
*/
|
|
39
|
+
readonly trace: readonly DriveTraceEntry<M, C>[];
|
|
40
|
+
}
|
|
41
|
+
/**
|
|
42
|
+
* `drive`'s `ctx` field. `CtxArg` widened by exactly one case: a machine
|
|
43
|
+
* declaring `ctx: undefined` in its `types` block — the pure shape every
|
|
44
|
+
* how-to on this package writes — may omit it too. `CtxArg` alone keeps `ctx`
|
|
45
|
+
* REQUIRED there, because `{}` is not assignable to `undefined`, which would
|
|
46
|
+
* make the common pure call site spell `{ ctx: undefined }` to say nothing.
|
|
47
|
+
* A machine whose `Ctx` carries a field a handler reads still requires it.
|
|
48
|
+
*/
|
|
49
|
+
type DriveCtxArg<Ctx> = [undefined] extends [Ctx] ? {
|
|
50
|
+
readonly ctx?: Ctx;
|
|
51
|
+
} : CtxArg<Ctx>;
|
|
52
|
+
/**
|
|
53
|
+
* The options both `drive`s take. `ctx` is conditionally optional (see
|
|
54
|
+
* {@link DriveCtxArg}).
|
|
55
|
+
*/
|
|
56
|
+
type DriveOptions<Ctx> = DriveCtxArg<Ctx> & {
|
|
57
|
+
/**
|
|
58
|
+
* The round bound. Exceeding it fails the drive with
|
|
59
|
+
* {@link DriveRoundsExceededError}; `drive` never returns a half-driven
|
|
60
|
+
* state. Defaults to {@link DEFAULT_MAX_ROUNDS} (100).
|
|
61
|
+
*/
|
|
62
|
+
readonly maxRounds?: number;
|
|
63
|
+
/**
|
|
64
|
+
* The clock that stamps `at` on a `Cmd.define`d Cmd's minted `_ok` / `_err`
|
|
65
|
+
* Msg — the one `run` takes. Defaults to `Date.now`; pin it for a test that
|
|
66
|
+
* asserts on `at`.
|
|
67
|
+
*/
|
|
68
|
+
readonly clock?: () => number;
|
|
69
|
+
};
|
|
70
|
+
/**
|
|
71
|
+
* Raised when a driven machine is still emitting work after `maxRounds` rounds.
|
|
72
|
+
* Follows the tea error dialect (`override readonly name`) and carries a `_tag`
|
|
73
|
+
* discriminant, so a test branches on it by `instanceof` or on the tag.
|
|
74
|
+
*
|
|
75
|
+
* It carries the round count it stopped at and the PARTIAL trace up to that
|
|
76
|
+
* point, which is what a test needs to see the cycle — the bound alone says
|
|
77
|
+
* only that one exists.
|
|
78
|
+
*/
|
|
79
|
+
declare class DriveRoundsExceededError<M, C> extends Error {
|
|
80
|
+
/** The bound that was exceeded. */
|
|
81
|
+
readonly maxRounds: number;
|
|
82
|
+
/** The round the driver stopped at — always `maxRounds + 1`. */
|
|
83
|
+
readonly rounds: number;
|
|
84
|
+
/** Every Msg folded and Cmd dispatched before the driver gave up. */
|
|
85
|
+
readonly trace: readonly DriveTraceEntry<M, C>[];
|
|
86
|
+
readonly name = "DriveRoundsExceededError";
|
|
87
|
+
readonly _tag: "DriveRoundsExceededError";
|
|
88
|
+
constructor(
|
|
89
|
+
/** The bound that was exceeded. */
|
|
90
|
+
maxRounds: number,
|
|
91
|
+
/** The round the driver stopped at — always `maxRounds + 1`. */
|
|
92
|
+
rounds: number,
|
|
93
|
+
/** Every Msg folded and Cmd dispatched before the driver gave up. */
|
|
94
|
+
trace: readonly DriveTraceEntry<M, C>[]);
|
|
95
|
+
}
|
|
96
|
+
/**
|
|
97
|
+
* Raised when a Cmd reaches `drive` with no handler for its `type` in the
|
|
98
|
+
* handler record. The record's mapped type makes that a compile error at a
|
|
99
|
+
* well-typed call site; this is the runtime arm for a handler record assembled
|
|
100
|
+
* dynamically or cast.
|
|
101
|
+
*/
|
|
102
|
+
declare class DriveNoHandlerError<M, C> extends Error {
|
|
103
|
+
/** The Cmd `type` nothing in the handler record answered. */
|
|
104
|
+
readonly cmdType: string;
|
|
105
|
+
/** Every Msg folded and Cmd dispatched before the miss. */
|
|
106
|
+
readonly trace: readonly DriveTraceEntry<M, C>[];
|
|
107
|
+
readonly name = "DriveNoHandlerError";
|
|
108
|
+
readonly _tag: "DriveNoHandlerError";
|
|
109
|
+
constructor(
|
|
110
|
+
/** The Cmd `type` nothing in the handler record answered. */
|
|
111
|
+
cmdType: string,
|
|
112
|
+
/** Every Msg folded and Cmd dispatched before the miss. */
|
|
113
|
+
trace: readonly DriveTraceEntry<M, C>[]);
|
|
114
|
+
}
|
|
115
|
+
/**
|
|
116
|
+
* Read back the partial trace `drive` attached to an error a handler failed
|
|
117
|
+
* with. Returns `undefined` for anything `drive` did not annotate.
|
|
118
|
+
*
|
|
119
|
+
* A failing handler's error leaves `drive` UNSWALLOWED — same value, same
|
|
120
|
+
* `instanceof`, same `_tag` — so a test that already branches on the handler's
|
|
121
|
+
* own error type keeps doing so. The trace rides along on a non-enumerable
|
|
122
|
+
* property so it is recoverable without changing how the error prints or
|
|
123
|
+
* serializes.
|
|
124
|
+
*/
|
|
125
|
+
declare function driveTraceOf<M, C>(err: unknown): readonly DriveTraceEntry<M, C>[] | undefined;
|
|
126
|
+
|
|
127
|
+
export { DriveRoundsExceededError as D, DriveNoHandlerError as a, type DriveOptions as b, type DriveResult as c, DEFAULT_MAX_ROUNDS as d, type DriveCtxArg as e, type DriveTraceEntry as f, driveTraceOf as g };
|
package/dist/effect/index.d.ts
CHANGED
|
@@ -1,151 +1,7 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
1
|
+
export { C as CellErrors, c as EffectBootingRuntime, E as EffectInterpret, d as EffectInterpretCell, e as EffectRunOptions, f as EffectRunner, g as EffectRuntime, a as EffectSubscribe, I as InterpretServices, h as Stopped, i as StoreFailed, b as SubscribeServices, r as run } from '../index-BnsAqn0-.js';
|
|
2
|
+
import 'effect/Cause';
|
|
3
|
+
import 'effect/Types';
|
|
4
|
+
import 'effect';
|
|
5
|
+
import '../core-Ce9ncpuv.js';
|
|
4
6
|
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 };
|
|
7
|
+
import '../runtime-types-BKg2CGMx.js';
|
package/dist/effect/index.js
CHANGED
|
@@ -1,98 +1,6 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
3
|
-
import
|
|
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 };
|
|
1
|
+
export { Stopped, StoreFailed, run } from '../chunk-I7E7AD2S.js';
|
|
2
|
+
import '../chunk-AHW2CLPT.js';
|
|
3
|
+
import '../chunk-JVE2LBFJ.js';
|
|
4
|
+
import '../chunk-AIIXV4XB.js';
|
|
97
5
|
//# sourceMappingURL=index.js.map
|
|
98
6
|
//# sourceMappingURL=index.js.map
|
package/dist/effect/index.js.map
CHANGED
|
@@ -1 +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
|
+
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { R as Runtime, S as Store } from '../runtime-types-
|
|
1
|
+
import { R as Runtime, M as Migrated, S as Store } from '../runtime-types-BKg2CGMx.js';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
import { S as SubscribeHandler } from '../types-
|
|
3
|
+
import { c as Sub } from '../core-Ce9ncpuv.js';
|
|
4
|
+
import { S as SubscribeHandler } from '../types-SzNSHKlV.js';
|
|
5
5
|
import '@standard-schema/spec';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -516,7 +516,9 @@ declare function fakeChrome(): FakeChrome;
|
|
|
516
516
|
* at the key, or unparseable JSON) — matches @demlik/tea/do's "throw at boot via
|
|
517
517
|
* store.load" contract so tea's `run()` surfaces it predictably. The
|
|
518
518
|
* `parse` callback handles the semantic layer (shape mismatch → return
|
|
519
|
-
* `null`); it must NOT throw, per the
|
|
519
|
+
* `refuse(reason)`, nothing saved → `null`); it must NOT throw, per the
|
|
520
|
+
* `Store<S>.migrate` contract. A throw or a refusal makes `ready` reject
|
|
521
|
+
* with `StoreRefusedError`, and nothing is saved.
|
|
520
522
|
*
|
|
521
523
|
* `parse` is REQUIRED because chrome.storage is a real serialization boundary
|
|
522
524
|
* — JSON to disk, then back — and the structural type of what comes back is
|
|
@@ -536,6 +538,6 @@ declare function fakeChrome(): FakeChrome;
|
|
|
536
538
|
* single writer, and that is a precondition to keep, not one this store can
|
|
537
539
|
* enforce. See `docs/explanation/durability-model.md`.
|
|
538
540
|
*/
|
|
539
|
-
declare function chromeStorageStore<S>(key: string, parse: (raw: unknown) => S
|
|
541
|
+
declare function chromeStorageStore<S>(key: string, parse: (raw: unknown) => Migrated<S>, area?: chrome.storage.StorageArea): Store<S>;
|
|
540
542
|
|
|
541
543
|
export { type BackgroundRuntimeContext, type BridgeClient, type BridgeClientOpts, type BridgeRuntimeOpts, type BridgeTabClientOpts, type ChromeMessageOpts, type ChromeStorageChangeOpts, type ChromeTabsEventOpts, type FakeChrome, type TabsEventName, type UseBackgroundRuntimeOpts, type UseBackgroundRuntimeResult, bridgeClient, bridgeRuntime, bridgeTabClient, chromeStorageStore, createBackgroundRuntimeContext, fakeChrome, fromChromeAlarm, fromChromeMessage, fromChromeStorageChange, fromChromeTabsEvent, passThroughMsg, useBackgroundRuntime };
|
package/dist/extension/index.js
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import '../chunk-K4ETBNKS.js';
|
|
1
|
+
import { historyTracker, dispatchIfPresent } from '../chunk-FNGZMVIT.js';
|
|
2
|
+
import { describeError } from '../chunk-AIIXV4XB.js';
|
|
4
3
|
import { useRef, useSyncExternalStore, useEffect, useCallback, createContext, useMemo, useContext } from 'react';
|
|
5
4
|
import { jsx } from 'react/jsx-runtime';
|
|
6
5
|
|