@demlik/tea 0.19.0 → 0.20.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 +25 -18
- package/dist/agent/index.d.ts +44 -13
- package/dist/agent/index.js +10 -10
- package/dist/{chunk-PCJA2HTZ.js → chunk-2774I242.js} +7 -7
- package/dist/chunk-2774I242.js.map +1 -0
- package/dist/{chunk-YIMOFXST.js → chunk-2R62Q5UK.js} +3 -3
- package/dist/chunk-2R62Q5UK.js.map +1 -0
- package/dist/{chunk-PQSDUX6B.js → chunk-5HVKDHY6.js} +3 -3
- package/dist/{chunk-PQSDUX6B.js.map → chunk-5HVKDHY6.js.map} +1 -1
- package/dist/{chunk-WTSOW2MD.js → chunk-72CN3VPY.js} +5 -5
- package/dist/{chunk-WTSOW2MD.js.map → chunk-72CN3VPY.js.map} +1 -1
- package/dist/{chunk-JVE2LBFJ.js → chunk-A73IJ27X.js} +3 -3
- package/dist/{chunk-JVE2LBFJ.js.map → chunk-A73IJ27X.js.map} +1 -1
- package/dist/{chunk-I7E7AD2S.js → chunk-AIXC33SE.js} +4 -4
- package/dist/chunk-AIXC33SE.js.map +1 -0
- package/dist/{chunk-FNGZMVIT.js → chunk-DVNXEB7V.js} +3 -3
- package/dist/chunk-DVNXEB7V.js.map +1 -0
- package/dist/{chunk-XVIKSRCK.js → chunk-EA47MI5Q.js} +4 -4
- package/dist/{chunk-XVIKSRCK.js.map → chunk-EA47MI5Q.js.map} +1 -1
- package/dist/{chunk-IHUNKHDX.js → chunk-FTCYY2DO.js} +3 -3
- package/dist/{chunk-IHUNKHDX.js.map → chunk-FTCYY2DO.js.map} +1 -1
- package/dist/{chunk-JVKU2UQC.js → chunk-HX3C6LDK.js} +3 -3
- package/dist/{chunk-JVKU2UQC.js.map → chunk-HX3C6LDK.js.map} +1 -1
- package/dist/{chunk-H2ELKHI6.js → chunk-JAKM53JF.js} +4 -4
- package/dist/chunk-JAKM53JF.js.map +1 -0
- package/dist/{chunk-JYNYG5SF.js → chunk-NGYFBD5G.js} +3 -3
- package/dist/chunk-NGYFBD5G.js.map +1 -0
- package/dist/{chunk-AIIXV4XB.js → chunk-RKVUVALV.js} +2 -2
- package/dist/chunk-RKVUVALV.js.map +1 -0
- package/dist/{chunk-C3G2QFEZ.js → chunk-TAKPC6SD.js} +4 -4
- package/dist/{chunk-C3G2QFEZ.js.map → chunk-TAKPC6SD.js.map} +1 -1
- package/dist/{chunk-BRX3243I.js → chunk-TGJLXZAU.js} +3 -3
- package/dist/{chunk-BRX3243I.js.map → chunk-TGJLXZAU.js.map} +1 -1
- package/dist/{chunk-AHW2CLPT.js → chunk-UHAQ4PI6.js} +4 -4
- package/dist/{chunk-AHW2CLPT.js.map → chunk-UHAQ4PI6.js.map} +1 -1
- package/dist/{chunk-H3MWNH7A.js → chunk-XWIE5V7R.js} +4 -4
- package/dist/{chunk-H3MWNH7A.js.map → chunk-XWIE5V7R.js.map} +1 -1
- package/dist/{core-Ce9ncpuv.d.ts → core-CtvAyPpH.d.ts} +153 -1
- package/dist/devtools/index.d.ts +17 -0
- package/dist/devtools/index.js.map +1 -1
- package/dist/do/index.d.ts +12 -12
- package/dist/do/index.js +11 -11
- package/dist/{drive-loop-CsUsW3Wo.d.ts → drive-loop-Dw1sGSsW.d.ts} +1 -1
- package/dist/{durable-effects-BmUrRA-h.d.ts → durable-effects-Ump5lSdO.d.ts} +1 -1
- package/dist/effect/index.d.ts +124 -5
- package/dist/effect/index.js +33 -4
- package/dist/effect/index.js.map +1 -1
- package/dist/extension/index.d.ts +84 -3
- package/dist/extension/index.js +2 -2
- package/dist/extension/index.js.map +1 -1
- package/dist/flow/index.d.ts +29 -13
- package/dist/flow/index.js +11 -11
- package/dist/flow/index.js.map +1 -1
- package/dist/idempotency/index.d.ts +11 -3
- package/dist/idempotency/index.js +3 -3
- package/dist/{index-D8sYVzCI.d.ts → index-Bk2hBUdK.d.ts} +6 -1
- package/dist/{index-2kNxy6az.d.ts → index-CKtEKGyp.d.ts} +15 -3
- package/dist/{index-e36uEyl4.d.ts → index-CVU7SK3a.d.ts} +2 -2
- package/dist/{index-Dy3379ve.d.ts → index-CZZ3HI-Z.d.ts} +4 -4
- package/dist/{index-Ce5GYAuI.d.ts → index-CrcoVfd_.d.ts} +2 -2
- package/dist/{index-DWdg7R1l.d.ts → index-D3NY3VCN.d.ts} +5 -1
- package/dist/{index-B1Wzarkl.d.ts → index-Dl71V7kt.d.ts} +1 -1
- package/dist/{index-Bf9_bNql.d.ts → index-EIgfl83J.d.ts} +2 -2
- package/dist/index.d.ts +66 -5
- package/dist/index.js +2 -2
- package/dist/jev/index.d.ts +39 -27
- package/dist/jev/index.js +12 -8
- package/dist/jev/index.js.map +1 -1
- package/dist/{machine-CuojfZup.d.ts → machine-Dtre2TmN.d.ts} +9 -7
- package/dist/machine-viz/index.d.ts +2 -1
- package/dist/machine-viz/index.js +2 -2
- package/dist/machine-viz/index.js.map +1 -1
- package/dist/mem/index.d.ts +2 -2
- package/dist/mem/index.js +2 -2
- package/dist/node/index.d.ts +11 -2
- package/dist/node/index.js +2 -2
- package/dist/node/index.js.map +1 -1
- package/dist/otel/index.d.ts +10 -10
- package/dist/otel/index.js +10 -10
- package/dist/paginate/index.d.ts +5 -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 +1 -1
- package/dist/pbt/index.js +2 -2
- package/dist/persistence/index.d.ts +5 -5
- package/dist/persistence/index.js +4 -4
- package/dist/promise/index.d.ts +7 -2
- package/dist/promise/index.js +4 -4
- package/dist/react/index.d.ts +2 -2
- package/dist/resilience/index.d.ts +7 -6
- package/dist/resilience/index.js +5 -5
- package/dist/resilience/index.js.map +1 -1
- package/dist/{index-BnsAqn0-.d.ts → run-fiBe7pOG.d.ts} +8 -5
- package/dist/{runtime-types-BKg2CGMx.d.ts → runtime-types-DEluQgGO.d.ts} +74 -2
- package/dist/testing/effect/index.d.ts +5 -5
- package/dist/testing/effect/index.js +8 -8
- package/dist/testing/index.d.ts +2 -2
- package/dist/testing/index.js +3 -3
- package/dist/testing/promise/index.d.ts +4 -4
- package/dist/testing/promise/index.js +5 -5
- package/dist/timing/index.d.ts +4 -4
- package/dist/timing/index.js +4 -4
- package/dist/types-CXNzlbAg.d.ts +9 -0
- package/dist/work-queue/index.d.ts +4 -4
- package/dist/work-queue/index.js +2 -2
- package/dist/work-queue/index.js.map +1 -1
- package/package.json +3 -2
- package/dist/chunk-AIIXV4XB.js.map +0 -1
- package/dist/chunk-FNGZMVIT.js.map +0 -1
- package/dist/chunk-H2ELKHI6.js.map +0 -1
- package/dist/chunk-I7E7AD2S.js.map +0 -1
- package/dist/chunk-JYNYG5SF.js.map +0 -1
- package/dist/chunk-PCJA2HTZ.js.map +0 -1
- package/dist/chunk-YIMOFXST.js.map +0 -1
- package/dist/types-SzNSHKlV.d.ts +0 -5
package/dist/effect/index.d.ts
CHANGED
|
@@ -1,7 +1,126 @@
|
|
|
1
|
-
|
|
1
|
+
import { Scope, Effect } from 'effect';
|
|
2
|
+
import { C as Cmd, S as Sub, M as Machine } from '../core-CtvAyPpH.js';
|
|
3
|
+
import { E as EffectRuntime, S as StoreFailed } from '../run-fiBe7pOG.js';
|
|
4
|
+
export { C as CellErrors, a as EffectBootingRuntime, b as EffectInterpret, c as EffectInterpretCell, d as EffectRunOptions, e as EffectRunner, f as EffectSubscribe, I as InterpretServices, g as Stopped, h as SubscribeServices, r as run } from '../run-fiBe7pOG.js';
|
|
5
|
+
import '@standard-schema/spec';
|
|
6
|
+
import '../runtime-types-DEluQgGO.js';
|
|
2
7
|
import 'effect/Cause';
|
|
3
8
|
import 'effect/Types';
|
|
4
|
-
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
9
|
+
|
|
10
|
+
/**
|
|
11
|
+
* Helpers for running child machines under a parent on the Effect engine
|
|
12
|
+
* (#556, ruling R1.1 of #554).
|
|
13
|
+
*
|
|
14
|
+
* tea still runs one machine per `run` and keeps no table of runs (#312). A
|
|
15
|
+
* host that builds a tree of runs keeps its own table, ids and Msg names, and
|
|
16
|
+
* hands the steps that race to these functions: `spawn` starts a child and
|
|
17
|
+
* enrols it as one step, `stop` stops one child, and `tell` sends the parent a
|
|
18
|
+
* notice it may no longer take.
|
|
19
|
+
*/
|
|
20
|
+
|
|
21
|
+
/**
|
|
22
|
+
* Hand `msg` to a run only when its State has a cell for it, and drop it when
|
|
23
|
+
* the run no longer takes it.
|
|
24
|
+
*
|
|
25
|
+
* `machine` is the machine `runtime` runs. The dispatch lands a moment after
|
|
26
|
+
* the check, so a State that changed in between refuses the Msg with a
|
|
27
|
+
* `NoCellError`, and a run that stopped refuses it with `Stopped`. Both mean
|
|
28
|
+
* the run no longer takes the notice, so both are dropped and `tell` succeeds.
|
|
29
|
+
* A failed save stays a `StoreFailed`, and a hand-written cell's declared
|
|
30
|
+
* failure stays that failure.
|
|
31
|
+
*
|
|
32
|
+
* ```ts
|
|
33
|
+
* yield* tell(parent, parentRun, { type: "child_stopped", id });
|
|
34
|
+
* ```
|
|
35
|
+
*/
|
|
36
|
+
declare const tell: <S, M extends {
|
|
37
|
+
type: string;
|
|
38
|
+
}, C extends Cmd, U extends Sub, Ctx, E extends {
|
|
39
|
+
type: string;
|
|
40
|
+
} = never, Err = never>(machine: Machine<S, M, C, U, Ctx>, runtime: EffectRuntime<S, M, E, Err>, msg: NoInfer<M>) => Effect.Effect<void, Err | StoreFailed>;
|
|
41
|
+
/**
|
|
42
|
+
* The host's own steps of a {@link spawn}. The host owns the table of
|
|
43
|
+
* children, their ids and the parent's Msg names; `spawn` owns the order the
|
|
44
|
+
* steps run in and keeps an interrupt from landing between them.
|
|
45
|
+
*/
|
|
46
|
+
interface SpawnSteps<A, E = never, R = never> {
|
|
47
|
+
/**
|
|
48
|
+
* Start the child and return what the host keeps for it. It runs with the
|
|
49
|
+
* child's scope provided, so a `run(machine, opts)` in it belongs to that
|
|
50
|
+
* scope, and so does anything else it acquires. `scope` is the same scope,
|
|
51
|
+
* for a host that keeps it to stop the child with `stop`. A failure
|
|
52
|
+
* closes the child's scope, which runs `remove` and `notify`.
|
|
53
|
+
*/
|
|
54
|
+
readonly start: (scope: Scope.Closeable) => Effect.Effect<A, E, R>;
|
|
55
|
+
/** Add the started child to the host's table. */
|
|
56
|
+
readonly enrol: (child: A) => Effect.Effect<unknown>;
|
|
57
|
+
/**
|
|
58
|
+
* Take the child out of the host's table. It runs when the child's scope
|
|
59
|
+
* closes, after its run has stopped, whether or not `enrol` ran, so it must
|
|
60
|
+
* be safe on a child the table does not hold.
|
|
61
|
+
*/
|
|
62
|
+
readonly remove: Effect.Effect<unknown>;
|
|
63
|
+
/**
|
|
64
|
+
* Say the child stopped, usually a {@link tell} to the parent. It runs
|
|
65
|
+
* after `remove`, on a fiber of its own that the closing scope never waits
|
|
66
|
+
* for, so it may wait on the parent.
|
|
67
|
+
*
|
|
68
|
+
* It cannot fail: nothing reads that fiber, so the step itself handles what
|
|
69
|
+
* its notice can fail with, such as the `StoreFailed` of a `tell`. A defect
|
|
70
|
+
* in it is not observed by `spawn` and ends the fiber unseen.
|
|
71
|
+
*/
|
|
72
|
+
readonly notify: Effect.Effect<unknown>;
|
|
73
|
+
}
|
|
74
|
+
/**
|
|
75
|
+
* Start a child in a scope forked from `parentScope` and enrol it in the
|
|
76
|
+
* host's table, as one uninterruptible step. Stop a child with `stop`,
|
|
77
|
+
* or by closing its scope; closing `parentScope` stops every child spawned
|
|
78
|
+
* under it.
|
|
79
|
+
*
|
|
80
|
+
* What it guarantees, with no guard in host code:
|
|
81
|
+
*
|
|
82
|
+
* - the table never holds a child whose scope has closed. The fork, the
|
|
83
|
+
* removal finalizer, `start` and `enrol` all happen or none do, and a
|
|
84
|
+
* child whose scope closed before `enrol` is removed again;
|
|
85
|
+
* - closing a child never waits for the parent. `notify` runs on a detached
|
|
86
|
+
* fiber, so a parent Cmd handler can stop a child;
|
|
87
|
+
* - `remove` runs after the child's run has stopped.
|
|
88
|
+
*
|
|
89
|
+
* Nothing reads the fiber `notify` runs on, so `spawn` reports no failure of
|
|
90
|
+
* it and `notify` is typed to have none. The host handles what its notice can
|
|
91
|
+
* fail with inside the step, as the `Effect.catch` below does for a parent
|
|
92
|
+
* whose save failed. A defect in `notify` ends that fiber unseen.
|
|
93
|
+
*
|
|
94
|
+
* `child.run.stop()` is not one of the two ways to stop a child. It stops the
|
|
95
|
+
* run and leaves the scope open, so the entry stays in the table and the
|
|
96
|
+
* parent is not told.
|
|
97
|
+
*
|
|
98
|
+
* ```ts
|
|
99
|
+
* const child = yield* spawn(parentScope, {
|
|
100
|
+
* start: (scope) =>
|
|
101
|
+
* Effect.map(run(worker, {}), (run) => ({ run, scope })),
|
|
102
|
+
* enrol: (child) => Effect.sync(() => children.set(id, child)),
|
|
103
|
+
* remove: Effect.sync(() => children.delete(id)),
|
|
104
|
+
* notify: tell(parent, parentRun, { type: "child_stopped", id }).pipe(
|
|
105
|
+
* Effect.catch((failure) => Effect.logError("notice failed", failure)),
|
|
106
|
+
* ),
|
|
107
|
+
* });
|
|
108
|
+
* ```
|
|
109
|
+
*/
|
|
110
|
+
declare const spawn: <A, E = never, R = never>(parentScope: Scope.Scope, steps: SpawnSteps<A, E, R>) => Effect.Effect<A, E, Exclude<R, Scope.Scope>>;
|
|
111
|
+
/**
|
|
112
|
+
* Stop one child that `spawn` started. `scope` is the child's scope,
|
|
113
|
+
* the one its `start` was handed.
|
|
114
|
+
*
|
|
115
|
+
* It closes that scope, so the child's run stops, `remove` takes the entry
|
|
116
|
+
* out of the host's table and `notify` tells the parent. It does not wait for
|
|
117
|
+
* `notify`, so a parent Cmd handler can call it. Stopping a child that has
|
|
118
|
+
* already stopped succeeds and sends no second notice.
|
|
119
|
+
*
|
|
120
|
+
* ```ts
|
|
121
|
+
* yield* stop(child.scope);
|
|
122
|
+
* ```
|
|
123
|
+
*/
|
|
124
|
+
declare const stop: (scope: Scope.Closeable) => Effect.Effect<void>;
|
|
125
|
+
|
|
126
|
+
export { EffectRuntime, type SpawnSteps, StoreFailed, spawn, stop, tell };
|
package/dist/effect/index.js
CHANGED
|
@@ -1,6 +1,35 @@
|
|
|
1
|
-
export { Stopped, StoreFailed, run } from '../chunk-
|
|
2
|
-
import '../chunk-
|
|
3
|
-
import '../chunk-
|
|
4
|
-
import '../chunk-
|
|
1
|
+
export { Stopped, StoreFailed, run } from '../chunk-AIXC33SE.js';
|
|
2
|
+
import '../chunk-UHAQ4PI6.js';
|
|
3
|
+
import '../chunk-A73IJ27X.js';
|
|
4
|
+
import { acceptedTypes, NoCellError } from '../chunk-RKVUVALV.js';
|
|
5
|
+
import { Effect, Scope, Exit } from 'effect';
|
|
6
|
+
|
|
7
|
+
var tell = (machine, runtime, msg) => Effect.suspend(
|
|
8
|
+
() => acceptedTypes(machine, runtime.getState()).includes(msg.type) ? runtime.dispatch(msg) : Effect.void
|
|
9
|
+
).pipe(
|
|
10
|
+
Effect.catchTag("Stopped", () => Effect.void),
|
|
11
|
+
Effect.catchDefect(
|
|
12
|
+
(defect) => defect instanceof NoCellError ? Effect.void : Effect.die(defect)
|
|
13
|
+
)
|
|
14
|
+
);
|
|
15
|
+
var spawn = (parentScope, steps) => Effect.uninterruptible(
|
|
16
|
+
Effect.gen(function* () {
|
|
17
|
+
const scope = yield* Scope.fork(parentScope);
|
|
18
|
+
yield* Scope.addFinalizer(
|
|
19
|
+
scope,
|
|
20
|
+
Effect.andThen(steps.remove, Effect.forkDetach(steps.notify))
|
|
21
|
+
);
|
|
22
|
+
const child = yield* steps.start(scope).pipe(
|
|
23
|
+
Scope.provide(scope),
|
|
24
|
+
Effect.onError((cause) => Scope.close(scope, Exit.failCause(cause)))
|
|
25
|
+
);
|
|
26
|
+
yield* steps.enrol(child);
|
|
27
|
+
if (scope.state._tag === "Closed") yield* steps.remove;
|
|
28
|
+
return child;
|
|
29
|
+
})
|
|
30
|
+
);
|
|
31
|
+
var stop = (scope) => Scope.close(scope, Exit.void);
|
|
32
|
+
|
|
33
|
+
export { spawn, stop, tell };
|
|
5
34
|
//# sourceMappingURL=index.js.map
|
|
6
35
|
//# sourceMappingURL=index.js.map
|
package/dist/effect/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":[],"names":[],"mappings":"","file":"index.js"}
|
|
1
|
+
{"version":3,"sources":["../../src/effect/children.ts"],"names":[],"mappings":";;;;;;AAgCO,IAAM,IAAA,GAAO,CASlB,OAAA,EACA,OAAA,EACA,QAEA,MAAA,CAAO,OAAA;AAAA,EAAQ,MACb,aAAA,CAAc,OAAA,EAAS,OAAA,CAAQ,UAAU,CAAA,CAAE,QAAA,CAAS,GAAA,CAAI,IAAI,CAAA,GACxD,OAAA,CAAQ,QAAA,CAAS,GAAG,IACpB,MAAA,CAAO;AACb,CAAA,CAAE,IAAA;AAAA,EACA,MAAA,CAAO,QAAA,CAAS,SAAA,EAAW,MAAM,OAAO,IAAI,CAAA;AAAA,EAC5C,MAAA,CAAO,WAAA;AAAA,IAAY,CAAC,WAClB,MAAA,YAAkB,WAAA,GAAc,OAAO,IAAA,GAAO,MAAA,CAAO,IAAI,MAAM;AAAA;AAEnE;AAwEK,IAAM,KAAA,GAAQ,CACnB,WAAA,EACA,KAAA,KAEA,MAAA,CAAO,eAAA;AAAA,EACL,MAAA,CAAO,IAAI,aAAa;AACtB,IAAA,MAAM,KAAA,GAAQ,OAAO,KAAA,CAAM,IAAA,CAAK,WAAW,CAAA;AAG3C,IAAA,OAAO,KAAA,CAAM,YAAA;AAAA,MACX,KAAA;AAAA,MACA,MAAA,CAAO,QAAQ,KAAA,CAAM,MAAA,EAAQ,OAAO,UAAA,CAAW,KAAA,CAAM,MAAM,CAAC;AAAA,KAC9D;AACA,IAAA,MAAM,KAAA,GAAQ,OAAO,KAAA,CAAM,KAAA,CAAM,KAAK,CAAA,CAAE,IAAA;AAAA,MACtC,KAAA,CAAM,QAAQ,KAAK,CAAA;AAAA,MACnB,MAAA,CAAO,OAAA,CAAQ,CAAC,KAAA,KAAU,KAAA,CAAM,KAAA,CAAM,KAAA,EAAO,IAAA,CAAK,SAAA,CAAU,KAAK,CAAC,CAAC;AAAA,KACrE;AACA,IAAA,OAAO,KAAA,CAAM,MAAM,KAAK,CAAA;AAExB,IAAA,IAAI,KAAA,CAAM,KAAA,CAAM,IAAA,KAAS,QAAA,SAAiB,KAAA,CAAM,MAAA;AAChD,IAAA,OAAO,KAAA;AAAA,EACT,CAAC;AACH;AAeK,IAAM,OAAO,CAAC,KAAA,KACnB,MAAM,KAAA,CAAM,KAAA,EAAO,KAAK,IAAI","file":"index.js","sourcesContent":["/**\n * Helpers for running child machines under a parent on the Effect engine\n * (#556, ruling R1.1 of #554).\n *\n * tea still runs one machine per `run` and keeps no table of runs (#312). A\n * host that builds a tree of runs keeps its own table, ids and Msg names, and\n * hands the steps that race to these functions: `spawn` starts a child and\n * enrols it as one step, `stop` stops one child, and `tell` sends the parent a\n * notice it may no longer take.\n */\n\nimport { Effect, Exit, Scope } from \"effect\";\nimport type { Cmd, Machine, Sub } from \"../pure/core\";\nimport { acceptedTypes, NoCellError } from \"../pure/core\";\nimport type { StoreFailed } from \"./failures\";\nimport type { EffectRuntime } from \"./handle\";\n\n/**\n * Hand `msg` to a run only when its State has a cell for it, and drop it when\n * the run no longer takes it.\n *\n * `machine` is the machine `runtime` runs. The dispatch lands a moment after\n * the check, so a State that changed in between refuses the Msg with a\n * `NoCellError`, and a run that stopped refuses it with `Stopped`. Both mean\n * the run no longer takes the notice, so both are dropped and `tell` succeeds.\n * A failed save stays a `StoreFailed`, and a hand-written cell's declared\n * failure stays that failure.\n *\n * ```ts\n * yield* tell(parent, parentRun, { type: \"child_stopped\", id });\n * ```\n */\nexport const tell = <\n S,\n M extends { type: string },\n C extends Cmd,\n U extends Sub,\n Ctx,\n E extends { type: string } = never,\n Err = never,\n>(\n machine: Machine<S, M, C, U, Ctx>,\n runtime: EffectRuntime<S, M, E, Err>,\n msg: NoInfer<M>,\n): Effect.Effect<void, Err | StoreFailed> =>\n Effect.suspend(() =>\n acceptedTypes(machine, runtime.getState()).includes(msg.type)\n ? runtime.dispatch(msg)\n : Effect.void,\n ).pipe(\n Effect.catchTag(\"Stopped\", () => Effect.void),\n Effect.catchDefect((defect) =>\n defect instanceof NoCellError ? Effect.void : Effect.die(defect),\n ),\n ) as Effect.Effect<void, Err | StoreFailed>;\n\n/**\n * The host's own steps of a {@link spawn}. The host owns the table of\n * children, their ids and the parent's Msg names; `spawn` owns the order the\n * steps run in and keeps an interrupt from landing between them.\n */\nexport interface SpawnSteps<A, E = never, R = never> {\n /**\n * Start the child and return what the host keeps for it. It runs with the\n * child's scope provided, so a `run(machine, opts)` in it belongs to that\n * scope, and so does anything else it acquires. `scope` is the same scope,\n * for a host that keeps it to stop the child with `stop`. A failure\n * closes the child's scope, which runs `remove` and `notify`.\n */\n readonly start: (scope: Scope.Closeable) => Effect.Effect<A, E, R>;\n /** Add the started child to the host's table. */\n readonly enrol: (child: A) => Effect.Effect<unknown>;\n /**\n * Take the child out of the host's table. It runs when the child's scope\n * closes, after its run has stopped, whether or not `enrol` ran, so it must\n * be safe on a child the table does not hold.\n */\n readonly remove: Effect.Effect<unknown>;\n /**\n * Say the child stopped, usually a {@link tell} to the parent. It runs\n * after `remove`, on a fiber of its own that the closing scope never waits\n * for, so it may wait on the parent.\n *\n * It cannot fail: nothing reads that fiber, so the step itself handles what\n * its notice can fail with, such as the `StoreFailed` of a `tell`. A defect\n * in it is not observed by `spawn` and ends the fiber unseen.\n */\n readonly notify: Effect.Effect<unknown>;\n}\n\n/**\n * Start a child in a scope forked from `parentScope` and enrol it in the\n * host's table, as one uninterruptible step. Stop a child with `stop`,\n * or by closing its scope; closing `parentScope` stops every child spawned\n * under it.\n *\n * What it guarantees, with no guard in host code:\n *\n * - the table never holds a child whose scope has closed. The fork, the\n * removal finalizer, `start` and `enrol` all happen or none do, and a\n * child whose scope closed before `enrol` is removed again;\n * - closing a child never waits for the parent. `notify` runs on a detached\n * fiber, so a parent Cmd handler can stop a child;\n * - `remove` runs after the child's run has stopped.\n *\n * Nothing reads the fiber `notify` runs on, so `spawn` reports no failure of\n * it and `notify` is typed to have none. The host handles what its notice can\n * fail with inside the step, as the `Effect.catch` below does for a parent\n * whose save failed. A defect in `notify` ends that fiber unseen.\n *\n * `child.run.stop()` is not one of the two ways to stop a child. It stops the\n * run and leaves the scope open, so the entry stays in the table and the\n * parent is not told.\n *\n * ```ts\n * const child = yield* spawn(parentScope, {\n * start: (scope) =>\n * Effect.map(run(worker, {}), (run) => ({ run, scope })),\n * enrol: (child) => Effect.sync(() => children.set(id, child)),\n * remove: Effect.sync(() => children.delete(id)),\n * notify: tell(parent, parentRun, { type: \"child_stopped\", id }).pipe(\n * Effect.catch((failure) => Effect.logError(\"notice failed\", failure)),\n * ),\n * });\n * ```\n */\nexport const spawn = <A, E = never, R = never>(\n parentScope: Scope.Scope,\n steps: SpawnSteps<A, E, R>,\n): Effect.Effect<A, E, Exclude<R, Scope.Scope>> =>\n Effect.uninterruptible(\n Effect.gen(function* () {\n const scope = yield* Scope.fork(parentScope);\n // Added before `start`, so it runs after everything `start` put in the\n // scope has been released, the child's run included.\n yield* Scope.addFinalizer(\n scope,\n Effect.andThen(steps.remove, Effect.forkDetach(steps.notify)),\n );\n const child = yield* steps.start(scope).pipe(\n Scope.provide(scope),\n Effect.onError((cause) => Scope.close(scope, Exit.failCause(cause))),\n );\n yield* steps.enrol(child);\n // A scope that closed under `start` ran `remove` before `enrol`.\n if (scope.state._tag === \"Closed\") yield* steps.remove;\n return child;\n }),\n );\n\n/**\n * Stop one child that `spawn` started. `scope` is the child's scope,\n * the one its `start` was handed.\n *\n * It closes that scope, so the child's run stops, `remove` takes the entry\n * out of the host's table and `notify` tells the parent. It does not wait for\n * `notify`, so a parent Cmd handler can call it. Stopping a child that has\n * already stopped succeeds and sends no second notice.\n *\n * ```ts\n * yield* stop(child.scope);\n * ```\n */\nexport const stop = (scope: Scope.Closeable): Effect.Effect<void> =>\n Scope.close(scope, Exit.void);\n"]}
|
|
@@ -1,7 +1,7 @@
|
|
|
1
|
-
import { R as Runtime, M as Migrated, S as Store } from '../runtime-types-
|
|
1
|
+
import { R as Runtime, M as Migrated, S as Store } from '../runtime-types-DEluQgGO.js';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import {
|
|
4
|
-
import { S as SubscribeHandler } from '../types-
|
|
3
|
+
import { S as Sub } from '../core-CtvAyPpH.js';
|
|
4
|
+
import { S as SubscribeHandler } from '../types-CXNzlbAg.js';
|
|
5
5
|
import '@standard-schema/spec';
|
|
6
6
|
|
|
7
7
|
/**
|
|
@@ -35,6 +35,10 @@ import '@standard-schema/spec';
|
|
|
35
35
|
* delivery guarantees should layer their own retry, not bake it here.
|
|
36
36
|
*/
|
|
37
37
|
|
|
38
|
+
/**
|
|
39
|
+
* Options for `bridgeRuntime`: the `channel` name, the required `parseMsg` for
|
|
40
|
+
* inbound Msgs, and an optional `serialize` for the state sent to surfaces.
|
|
41
|
+
*/
|
|
38
42
|
interface BridgeRuntimeOpts<S, M, V = S> {
|
|
39
43
|
channel: string;
|
|
40
44
|
/**
|
|
@@ -125,6 +129,11 @@ declare function bridgeRuntime<S, M extends {
|
|
|
125
129
|
* the documented exception, chosen explicitly.)
|
|
126
130
|
*/
|
|
127
131
|
declare function passThroughMsg<M>(raw: unknown): M | null;
|
|
132
|
+
/**
|
|
133
|
+
* A surface's handle on the background runtime: hydrate the current state,
|
|
134
|
+
* dispatch Msgs, and subscribe to state broadcasts. `bridgeClient` and
|
|
135
|
+
* `bridgeTabClient` return one.
|
|
136
|
+
*/
|
|
128
137
|
interface BridgeClient<S, M> {
|
|
129
138
|
/** Send the hydrate request; resolves with the initial snapshot (or null
|
|
130
139
|
* if the host is still booting OR the response failed to parse). Also
|
|
@@ -144,6 +153,10 @@ interface BridgeClient<S, M> {
|
|
|
144
153
|
* underlying state hasn't changed since the prior call. */
|
|
145
154
|
getSnapshot(): S | null;
|
|
146
155
|
}
|
|
156
|
+
/**
|
|
157
|
+
* Options for `bridgeClient`: the `channel` name and the required parsers for
|
|
158
|
+
* inbound state and Msgs.
|
|
159
|
+
*/
|
|
147
160
|
interface BridgeClientOpts<S, M> {
|
|
148
161
|
channel: string;
|
|
149
162
|
/**
|
|
@@ -168,9 +181,17 @@ interface BridgeClientOpts<S, M> {
|
|
|
168
181
|
*/
|
|
169
182
|
parseMsg: (raw: unknown) => M | null;
|
|
170
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Create a `BridgeClient` for a popup, side panel or content script, which
|
|
186
|
+
* talks to the background runtime over `chrome.runtime` messages.
|
|
187
|
+
*/
|
|
171
188
|
declare function bridgeClient<S, M extends {
|
|
172
189
|
type: string;
|
|
173
190
|
}>({ channel, parseState, parseMsg, }: BridgeClientOpts<S, M>): BridgeClient<S, M>;
|
|
191
|
+
/**
|
|
192
|
+
* Options for `bridgeTabClient`: the target `tabId`, the `channel` name, and
|
|
193
|
+
* the required parsers.
|
|
194
|
+
*/
|
|
174
195
|
interface BridgeTabClientOpts<S, M> {
|
|
175
196
|
tabId: number;
|
|
176
197
|
channel: string;
|
|
@@ -256,6 +277,10 @@ declare function bridgeTabClient<S, M extends {
|
|
|
256
277
|
* adapter peer-depends on react (you must have it installed in the app).
|
|
257
278
|
*/
|
|
258
279
|
|
|
280
|
+
/**
|
|
281
|
+
* Options for `useBackgroundRuntime`: the `channel` name and the required
|
|
282
|
+
* `parseState`.
|
|
283
|
+
*/
|
|
259
284
|
interface UseBackgroundRuntimeOpts<S> {
|
|
260
285
|
channel: string;
|
|
261
286
|
/**
|
|
@@ -266,6 +291,10 @@ interface UseBackgroundRuntimeOpts<S> {
|
|
|
266
291
|
*/
|
|
267
292
|
parseState: (raw: unknown) => S | null;
|
|
268
293
|
}
|
|
294
|
+
/**
|
|
295
|
+
* What `useBackgroundRuntime` returns: the latest `state`, which is `null`
|
|
296
|
+
* until the first one arrives, and `dispatch`.
|
|
297
|
+
*/
|
|
269
298
|
interface UseBackgroundRuntimeResult<S, M> {
|
|
270
299
|
/** Latest snapshot from the host. `null` until the first hydrate response
|
|
271
300
|
* or the first broadcast arrives. Surfaces SHOULD render a placeholder
|
|
@@ -275,9 +304,18 @@ interface UseBackgroundRuntimeResult<S, M> {
|
|
|
275
304
|
* settles. */
|
|
276
305
|
dispatch(msg: M): Promise<void>;
|
|
277
306
|
}
|
|
307
|
+
/**
|
|
308
|
+
* React hook for an extension surface: it subscribes to the background
|
|
309
|
+
* runtime's state and returns it with a `dispatch`. Use it in a popup or side
|
|
310
|
+
* panel component.
|
|
311
|
+
*/
|
|
278
312
|
declare function useBackgroundRuntime<S, M extends {
|
|
279
313
|
type: string;
|
|
280
314
|
}>({ channel, parseState, }: UseBackgroundRuntimeOpts<S>): UseBackgroundRuntimeResult<S, M>;
|
|
315
|
+
/**
|
|
316
|
+
* What `createBackgroundRuntimeContext` returns: a `Provider`, plus the
|
|
317
|
+
* `useState`, `useDispatch` and `useRuntime` hooks that read from it.
|
|
318
|
+
*/
|
|
281
319
|
interface BackgroundRuntimeContext<S, M> {
|
|
282
320
|
/**
|
|
283
321
|
* Wrap a subtree to share a single background-runtime bridge client.
|
|
@@ -321,6 +359,11 @@ interface BackgroundRuntimeContext<S, M> {
|
|
|
321
359
|
*/
|
|
322
360
|
useRuntime: () => UseBackgroundRuntimeResult<S, M>;
|
|
323
361
|
}
|
|
362
|
+
/**
|
|
363
|
+
* Create a React context that shares one background-runtime connection across a
|
|
364
|
+
* component tree. Use it instead of calling `useBackgroundRuntime` in several
|
|
365
|
+
* components.
|
|
366
|
+
*/
|
|
324
367
|
declare function createBackgroundRuntimeContext<S, M extends {
|
|
325
368
|
type: string;
|
|
326
369
|
}>(): BackgroundRuntimeContext<S, M>;
|
|
@@ -328,8 +371,17 @@ declare function createBackgroundRuntimeContext<S, M extends {
|
|
|
328
371
|
type AlarmSubData = {
|
|
329
372
|
readonly alarmName: string;
|
|
330
373
|
};
|
|
374
|
+
/**
|
|
375
|
+
* Build a Sub runner that dispatches `msgFn(alarm, sub)` when the
|
|
376
|
+
* `chrome.alarms` alarm named `sub.deps.alarmName` fires. It only listens;
|
|
377
|
+
* create and clear the alarm with Cmds.
|
|
378
|
+
*/
|
|
331
379
|
declare function fromChromeAlarm<S extends Sub<string, AlarmSubData>, M>(msgFn: (alarm: chrome.alarms.Alarm, sub: S) => M | null): SubscribeHandler<S, M, unknown>;
|
|
332
380
|
|
|
381
|
+
/**
|
|
382
|
+
* Options for `fromChromeMessage`: an optional `filter`, and the `msgFn` that
|
|
383
|
+
* maps a runtime message to a Msg.
|
|
384
|
+
*/
|
|
333
385
|
interface ChromeMessageOpts<S extends Sub, M> {
|
|
334
386
|
/**
|
|
335
387
|
* Pre-filter — when provided, the factory only dispatches when this
|
|
@@ -338,8 +390,16 @@ interface ChromeMessageOpts<S extends Sub, M> {
|
|
|
338
390
|
filter?: (message: unknown) => boolean;
|
|
339
391
|
msgFn: (message: unknown, sender: chrome.runtime.MessageSender, sub: S) => M | null;
|
|
340
392
|
}
|
|
393
|
+
/**
|
|
394
|
+
* Build a Sub runner that dispatches a Msg for each `chrome.runtime.onMessage`
|
|
395
|
+
* message that passes the filter. It never sends a response.
|
|
396
|
+
*/
|
|
341
397
|
declare function fromChromeMessage<S extends Sub, M>(opts: ChromeMessageOpts<S, M>): SubscribeHandler<S, M, unknown>;
|
|
342
398
|
|
|
399
|
+
/**
|
|
400
|
+
* Options for `fromChromeStorageChange`: the storage `area`, an optional `keys`
|
|
401
|
+
* filter, and the `msgFn` that maps the changes to a Msg.
|
|
402
|
+
*/
|
|
343
403
|
interface ChromeStorageChangeOpts<S extends Sub, M> {
|
|
344
404
|
area: chrome.storage.AreaName;
|
|
345
405
|
/**
|
|
@@ -349,9 +409,18 @@ interface ChromeStorageChangeOpts<S extends Sub, M> {
|
|
|
349
409
|
keys?: readonly string[];
|
|
350
410
|
msgFn: (changes: Record<string, chrome.storage.StorageChange>, sub: S) => M | null;
|
|
351
411
|
}
|
|
412
|
+
/**
|
|
413
|
+
* Build a Sub runner that dispatches a Msg when keys change in a
|
|
414
|
+
* `chrome.storage` area.
|
|
415
|
+
*/
|
|
352
416
|
declare function fromChromeStorageChange<S extends Sub, M>(opts: ChromeStorageChangeOpts<S, M>): SubscribeHandler<S, M, unknown>;
|
|
353
417
|
|
|
418
|
+
/** The `chrome.tabs` events `fromChromeTabsEvent` can listen to. */
|
|
354
419
|
type TabsEventName = "onActivated" | "onUpdated" | "onRemoved";
|
|
420
|
+
/**
|
|
421
|
+
* Options for `fromChromeTabsEvent`: which tab `events` to listen to, whether
|
|
422
|
+
* to fire once on mount, and the `msgFn` that builds the Msg.
|
|
423
|
+
*/
|
|
355
424
|
interface ChromeTabsEventOpts<S extends Sub, M> {
|
|
356
425
|
events: readonly TabsEventName[];
|
|
357
426
|
/**
|
|
@@ -363,6 +432,10 @@ interface ChromeTabsEventOpts<S extends Sub, M> {
|
|
|
363
432
|
fireOnMount?: boolean;
|
|
364
433
|
msgFn: (sub: S) => M | null;
|
|
365
434
|
}
|
|
435
|
+
/**
|
|
436
|
+
* Build a Sub runner that dispatches `msgFn(sub)` whenever one of the chosen
|
|
437
|
+
* `chrome.tabs` events fires.
|
|
438
|
+
*/
|
|
366
439
|
declare function fromChromeTabsEvent<S extends Sub, M>(opts: ChromeTabsEventOpts<S, M>): SubscribeHandler<S, M, unknown>;
|
|
367
440
|
|
|
368
441
|
/**
|
|
@@ -384,6 +457,10 @@ type AlarmListener = (alarm: chrome.alarms.Alarm) => void;
|
|
|
384
457
|
type TabActivatedListener = (info: chrome.tabs.OnActivatedInfo) => void;
|
|
385
458
|
type TabUpdatedListener = (tabId: number, changeInfo: chrome.tabs.OnUpdatedInfo, tab: chrome.tabs.Tab) => void;
|
|
386
459
|
type TabRemovedListener = (tabId: number, removeInfo: chrome.tabs.OnRemovedInfo) => void;
|
|
460
|
+
/**
|
|
461
|
+
* The in-memory `chrome` stand-in `fakeChrome` returns, with `__test.fire*`
|
|
462
|
+
* helpers that drive its events from a test.
|
|
463
|
+
*/
|
|
387
464
|
interface FakeChrome {
|
|
388
465
|
storage: {
|
|
389
466
|
local: chrome.storage.StorageArea;
|
|
@@ -490,6 +567,10 @@ interface FakeChrome {
|
|
|
490
567
|
fireTabRemoved(tabId: number, removeInfo: chrome.tabs.OnRemovedInfo): void;
|
|
491
568
|
};
|
|
492
569
|
}
|
|
570
|
+
/**
|
|
571
|
+
* Create an in-memory fake of the `chrome` APIs this adapter uses. Use it to
|
|
572
|
+
* test extension machines without a browser.
|
|
573
|
+
*/
|
|
493
574
|
declare function fakeChrome(): FakeChrome;
|
|
494
575
|
|
|
495
576
|
/**
|
package/dist/extension/index.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { historyTracker, dispatchIfPresent } from '../chunk-
|
|
2
|
-
import { describeError } from '../chunk-
|
|
1
|
+
import { historyTracker, dispatchIfPresent } from '../chunk-DVNXEB7V.js';
|
|
2
|
+
import { describeError } from '../chunk-RKVUVALV.js';
|
|
3
3
|
import { useRef, useSyncExternalStore, useEffect, useCallback, createContext, useMemo, useContext } from 'react';
|
|
4
4
|
import { jsx } from 'react/jsx-runtime';
|
|
5
5
|
|