effect-browser 0.3.0-beta.6 → 0.3.0-beta.8

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.
Files changed (53) hide show
  1. package/README.md +124 -21
  2. package/dist/{Browser-B5AV7zPS.mjs → Browser-CNwK0r0q.mjs} +2 -2
  3. package/dist/{Browser-B5AV7zPS.mjs.map → Browser-CNwK0r0q.mjs.map} +1 -1
  4. package/dist/Browser.d.mts +2 -2
  5. package/dist/Browser.mjs +1 -1
  6. package/dist/{BrowserEvent-DzdNdvoh.d.mts → BrowserEvent-BRu2juEz.d.mts} +3 -1
  7. package/dist/BrowserEvent.d.mts +1 -1
  8. package/dist/BrowserEvent.mjs +2 -0
  9. package/dist/BrowserEvent.mjs.map +1 -1
  10. package/dist/Cdp.mjs +1 -1
  11. package/dist/{Change-DVP2IJWm.d.mts → Change-iMlcuzVD.d.mts} +2 -2
  12. package/dist/Change.d.mts +1 -1
  13. package/dist/Chromium.mjs +1 -1
  14. package/dist/Expect.d.mts +1 -1
  15. package/dist/Expect.mjs +1 -1
  16. package/dist/Moment.d.mts +1 -1
  17. package/dist/{Page-DYTdVhYa.d.mts → Page-C30aG2RQ.d.mts} +6 -4
  18. package/dist/Page-D4281dIi.mjs.map +1 -1
  19. package/dist/Page.d.mts +1 -1
  20. package/dist/Plan-BvCS9qAf.d.mts +209 -0
  21. package/dist/{Plan-5MdsRzE5.mjs → Plan-CyQNv49C.mjs} +232 -38
  22. package/dist/Plan-CyQNv49C.mjs.map +1 -0
  23. package/dist/Plan.d.mts +2 -2
  24. package/dist/Plan.mjs +2 -2
  25. package/dist/Policy.d.mts +1 -1
  26. package/dist/Presentation.d.mts +1 -1
  27. package/dist/Presentation.mjs +1 -1
  28. package/dist/Stage.d.mts +1 -1
  29. package/dist/Stage.mjs +1 -1
  30. package/dist/{Supervisor-Im6-wbg5.d.mts → Supervisor-CYWFK3vM.d.mts} +106 -56
  31. package/dist/Supervisor-TNKNOVzu.mjs +599 -0
  32. package/dist/Supervisor-TNKNOVzu.mjs.map +1 -0
  33. package/dist/Supervisor.d.mts +2 -2
  34. package/dist/Supervisor.mjs +2 -2
  35. package/dist/index.d.mts +5 -5
  36. package/dist/index.mjs +3 -3
  37. package/dist/{page-BkRcLCWZ.mjs → page-DHeYWEs-.mjs} +27 -14
  38. package/dist/page-DHeYWEs-.mjs.map +1 -0
  39. package/package.json +1 -1
  40. package/src/BrowserEvent.ts +2 -0
  41. package/src/Page.ts +3 -1
  42. package/src/Plan.ts +365 -56
  43. package/src/Supervisor.ts +384 -138
  44. package/src/internal/input/perform.ts +2 -0
  45. package/src/internal/page/bridge.ts +3 -3
  46. package/src/internal/reading/ready.inpage.ts +17 -7
  47. package/src/internal/reading/ready.ts +9 -3
  48. package/src/internal/supervisor/lifecycle.ts +291 -140
  49. package/dist/Plan-5MdsRzE5.mjs.map +0 -1
  50. package/dist/Plan-CNNOU1Tx.d.mts +0 -112
  51. package/dist/Supervisor-BtEG93gR.mjs +0 -420
  52. package/dist/Supervisor-BtEG93gR.mjs.map +0 -1
  53. package/dist/page-BkRcLCWZ.mjs.map +0 -1
@@ -1,8 +1,8 @@
1
- import { c as DisconnectCause } from "./BrowserEvent-DzdNdvoh.mjs";
1
+ import { c as DisconnectCause } from "./BrowserEvent-BRu2juEz.mjs";
2
2
  import { Service, t as Browser_d_exports } from "./Browser.mjs";
3
3
  import { Cause, Duration, Effect, Schedule, Schema, Scope, Stream } from "effect";
4
4
  declare namespace lifecycle_d_exports {
5
- export { Closed, Command, Down, GenerationState, Input, Kept, Live, Lost, Open, Opening, Released, Reopening, Resolution, Settled, State, Step, Unconfirmed, resolve, start, transition };
5
+ export { Closed, Command, Down, Drain, Draining, GenerationState, Held, Input, Kept, Live, Lost, Open, Opening, Released, Reopening, Resolution, Settled, State, Step, Unconfirmed, lookup, resolve, start, transition };
6
6
  }
7
7
  declare const Settled_base: Schema.Class<Settled, Schema.TaggedStruct<"Settled", {}>, {}>;
8
8
  /** The provider confirmed that the generation's browser ended. */
@@ -23,6 +23,12 @@ declare class Reopening extends Reopening_base {}
23
23
  declare const Open_base: Schema.Class<Open, Schema.TaggedStruct<"Open", {}>, {}>;
24
24
  /** Open: `browser` gives this generation until the next one opens. */
25
25
  declare class Open extends Open_base {}
26
+ declare const Draining_base: Schema.Class<Draining, Schema.TaggedStruct<"Draining", {
27
+ readonly reason: Schema.Literals<readonly ["rotated", "lost", "retired"]>;
28
+ readonly revokeAt: Schema.Finite;
29
+ }>, {}>;
30
+ /** No longer serving; holds end at this host-monotonic deadline or when their owners let go. */
31
+ declare class Draining extends Draining_base {}
26
32
  declare const Lost_base: Schema.Class<Lost, Schema.TaggedStruct<"Lost", {
27
33
  readonly cause: Schema.Literals<readonly ["connection", "session", "released"]>;
28
34
  }>, {}>;
@@ -48,99 +54,115 @@ declare const Kept_base: Schema.Class<Kept, Schema.TaggedStruct<"Kept", {}>, {}>
48
54
  * closed, and its provider runs it on, and bills, until something adopts and releases it.
49
55
  */
50
56
  declare class Kept extends Kept_base {}
51
- declare const GenerationState: Schema.Union<readonly [typeof Opening, typeof Reopening, typeof Open, typeof Lost, typeof Down, typeof Closed, typeof Kept]>;
57
+ declare const GenerationState: Schema.Union<readonly [typeof Opening, typeof Reopening, typeof Open, typeof Draining, typeof Lost, typeof Down, typeof Closed, typeof Kept]>;
52
58
  type GenerationState = typeof GenerationState.Type;
53
59
  /** A generation that opened: its number, and what the runtime keeps to serve and end it. */
54
60
  interface Live<A> {
55
61
  readonly number: number;
56
62
  readonly value: A;
57
63
  }
58
- /**
59
- * At most one generation opens and at most one serves. Both do while a rotation makes the next
60
- * before it breaks the current, and `Down` keeps serving one that a rotation failed to replace.
61
- */
62
- type State<A> = {
64
+ interface Held<A, H> extends Live<A> {
65
+ readonly holds: ReadonlySet<H>;
66
+ }
67
+ /** Release ownership remains here until the provider and generation scope have finished. */
68
+ interface Drain<A, H> {
69
+ readonly _tag: "Draining" | "Releasing" | "Leaving";
70
+ readonly live: Held<A, H>;
71
+ readonly ending: Draining;
72
+ }
73
+ /** One serving generation, one shared acquisition, and prior generations still owned. */
74
+ type State<A, H = unknown> = ({
63
75
  readonly _tag: "Opening";
64
76
  readonly number: number;
65
- readonly serving: Live<A> | undefined;
77
+ readonly serving: Held<A, H> | undefined;
66
78
  } | {
67
79
  readonly _tag: "Open";
68
- readonly serving: Live<A>;
80
+ readonly serving: Held<A, H>;
69
81
  } | {
70
82
  readonly _tag: "Down";
71
83
  readonly number: number;
72
84
  readonly detail: string;
73
85
  readonly cause: unknown;
74
- readonly serving: Live<A> | undefined;
86
+ readonly serving: Held<A, H> | undefined;
75
87
  } | {
76
88
  readonly _tag: "Retired";
89
+ }) & {
90
+ readonly draining: ReadonlyMap<number, Drain<A, H>>;
77
91
  };
78
- type Input<A> = {
92
+ type Input<A, H = unknown> = {
79
93
  readonly _tag: "Opened";
80
94
  readonly live: Live<A>;
81
- } |
82
- /** The open of `number` failed for good. */
83
- {
95
+ } | {
84
96
  readonly _tag: "Failed";
85
97
  readonly number: number;
86
98
  readonly detail: string;
87
99
  readonly cause: unknown;
88
- } |
89
- /** The open of `number` was stopped, as on retiring, before it opened. */
90
- {
100
+ } | {
91
101
  readonly _tag: "Abandoned";
92
102
  readonly number: number;
93
103
  } | {
94
104
  readonly _tag: "Lost";
95
105
  readonly number: number;
96
106
  readonly cause: DisconnectCause;
97
- } |
98
- /** A caller asks for the next generation, or the rotation time of `due` came. */
99
- {
107
+ } | {
100
108
  readonly _tag: "Rotate";
101
109
  readonly due?: number | undefined;
102
110
  } | {
103
111
  readonly _tag: "Retire";
104
- } |
105
- /** Stop as `Retire` does, but leave the serving generation running. */
106
- {
112
+ } | {
107
113
  readonly _tag: "Keep";
114
+ } | {
115
+ readonly _tag: "Hold";
116
+ readonly number?: number | undefined;
117
+ readonly hold: H;
118
+ } | {
119
+ readonly _tag: "Let";
120
+ readonly number: number;
121
+ readonly hold: H;
122
+ } | {
123
+ readonly _tag: "Revoke";
124
+ readonly number: number;
108
125
  } | {
109
126
  readonly _tag: "Released";
110
127
  readonly number: number;
111
- readonly released: Released;
128
+ readonly released?: Released | undefined;
112
129
  };
113
- type Command<A> =
114
- /** Open `number`, after the release of `after` has finished. */
115
- {
130
+ type Command<A> = {
116
131
  readonly _tag: "Open";
117
132
  readonly number: number;
118
133
  readonly after: number | undefined;
119
- } |
120
- /** Watch a generation that opened for its loss and its rotation time. */
121
- {
134
+ } | {
122
135
  readonly _tag: "Watch";
123
136
  readonly live: Live<A>;
124
- } | {
125
- readonly _tag: "Release";
137
+ } |
138
+ /** Signal ending and arrange revocation. Repeated only when loss/retirement accelerates it. */
139
+ {
140
+ readonly _tag: "Drain";
126
141
  readonly live: Live<A>;
142
+ readonly ending: Draining;
127
143
  } |
128
- /** Close its scope without asking its provider to release it. */
144
+ /** Revoke/close holds, await their Let inputs, release the provider, then close its scope. */
129
145
  {
146
+ readonly _tag: "Release";
147
+ readonly live: Live<A>;
148
+ readonly ending: Draining;
149
+ } | {
130
150
  readonly _tag: "Leave";
131
151
  readonly live: Live<A>;
152
+ readonly ending: Draining;
132
153
  };
133
- interface Step<A> {
134
- readonly state: State<A>;
135
- /** Generation numbers and their new states, to publish in this order. */
154
+ interface Step<A, H = unknown> {
155
+ readonly state: State<A, H>;
136
156
  readonly events: ReadonlyArray<readonly [number, GenerationState]>;
137
157
  readonly commands: ReadonlyArray<Command<A>>;
138
- /** For `Rotate`, the generation to wait for, unless retired. */
139
158
  readonly reply?: number | undefined;
159
+ readonly borrowed?: Live<A> | undefined;
140
160
  }
141
- declare const start: <A>() => Step<A>;
142
- /** The state after `input`, with the events to publish and the commands to run. */
143
- declare const transition: <A>(state: State<A>, input: Input<A>, exclusive: boolean) => Step<A>;
161
+ declare const start: <A, H = unknown>() => Step<A, H>;
162
+ /** The holds still owned for a generation, including one whose release has begun. */
163
+ declare const lookup: <A, H>(state: State<A, H>, number: number) => Held<A, H> | undefined;
164
+ /** Pure admission and lifecycle changes. A rejected hold preserves state identity. */
165
+ declare const transition: <A, H = unknown>(state: State<A, H>, input: Input<A, H>, exclusive: boolean, now?: number, handover?: number) => Step<A, H>;
144
166
  type Resolution<A> = {
145
167
  readonly _tag: "Serve";
146
168
  readonly live: Live<A>;
@@ -150,18 +172,16 @@ type Resolution<A> = {
150
172
  readonly detail: string;
151
173
  readonly cause?: unknown;
152
174
  };
153
- /**
154
- * What a caller waiting for generation `target`, or for any when it is undefined, gets in
155
- * `state`; undefined while it should go on waiting.
156
- */
157
- declare const resolve: <A>(state: State<A>, target: number | undefined) => Resolution<A> | undefined;
175
+ /** An unheld browser resolution; use obtains its hold atomically through Hold instead. */
176
+ declare const resolve: <A, H>(state: State<A, H>, target: number | undefined) => Resolution<A> | undefined;
158
177
  declare namespace Supervisor_d_exports {
159
- export { Closed, Down, Generation, GenerationState, Kept, Lost, Open, Opened, Opening, Options, Released, Reopening, Settled, Supervisor, Unavailable, Unconfirmed, make };
178
+ export { Closed, Down, Draining, Generation, GenerationState, Kept, Lease, Lost, Open, Opened, Opening, Options, Released, Reopening, Settled, Superseded, Supervisor, Unavailable, Unconfirmed, UseOptions, make };
160
179
  }
161
180
  declare const Generation_base: Schema.Class<Generation, Schema.Struct<{
162
181
  readonly number: Schema.Int;
163
182
  readonly at: Schema.Finite;
164
- readonly state: Schema.Union<readonly [typeof Opening, typeof Reopening, typeof Open, typeof Lost, typeof Down, typeof Closed, typeof Kept]>;
183
+ readonly hostTime: Schema.Finite;
184
+ readonly state: Schema.Union<readonly [typeof Opening, typeof Reopening, typeof Open, typeof Draining, typeof Lost, typeof Down, typeof Closed, typeof Kept]>;
165
185
  }>, {}>;
166
186
  /** One change in a generation's life. `at` is wall-clock epoch milliseconds from the Effect `Clock`. */
167
187
  declare class Generation extends Generation_base {}
@@ -178,7 +198,8 @@ declare class Unavailable extends Unavailable_base {
178
198
  get message(): string;
179
199
  }
180
200
  /** One generation, as a provider opened it in the scope the supervisor gave it. */
181
- interface Opened {
201
+ interface Opened<A = void> {
202
+ readonly value: A;
182
203
  readonly browser: Service;
183
204
  /**
184
205
  * End the generation, and say whether the provider confirmed its end. The supervisor asks it
@@ -187,9 +208,9 @@ interface Opened {
187
208
  */
188
209
  readonly release?: Effect.Effect<Released> | undefined;
189
210
  }
190
- interface Options<E, R> {
211
+ interface Options<E, R, A = void> {
191
212
  /** Opens one generation in the scope it is given. */
192
- readonly open: Effect.Effect<Opened, E, R>;
213
+ readonly open: Effect.Effect<Opened<A>, E, R>;
193
214
  /** When to try a failed open again. Defaults to exponential from 1 second, for 5 minutes. */
194
215
  readonly reopen?: Schedule.Schedule<unknown, E> | undefined;
195
216
  /**
@@ -204,6 +225,8 @@ interface Options<E, R> {
204
225
  readonly rotateBefore?: Duration.Input | undefined;
205
226
  /** Generations must not overlap: a rotation releases the current one before it opens the next. */
206
227
  readonly exclusive?: boolean | undefined;
228
+ /** Finite, nonnegative time outgoing holds may finish; defaults to 30 seconds. */
229
+ readonly handover?: Duration.Input | undefined;
207
230
  /**
208
231
  * Closing the scope leaves the serving generation running, `Kept`: it closes the generation's
209
232
  * scope but never asks `release`. For providers whose scope only disconnects, such as
@@ -213,7 +236,29 @@ interface Options<E, R> {
213
236
  /** How long `browser` and `rotate` wait for a generation to open. Defaults to 2 minutes. */
214
237
  readonly waitTimeout?: Duration.Input | undefined;
215
238
  }
216
- interface Supervisor {
239
+ declare const Superseded_base: Schema.Class<Superseded, Schema.TaggedStruct<"Superseded", {
240
+ readonly generation: Schema.Int;
241
+ readonly reason: Schema.Literals<readonly ["rotated", "lost", "retired"]>;
242
+ readonly revokeAt: Schema.Finite;
243
+ }>, Cause.YieldableError>;
244
+ /** Work whose generation was revoked; input receipts still determine whether input reached a site. */
245
+ declare class Superseded extends Superseded_base {}
246
+ interface Lease<A> {
247
+ readonly generation: number;
248
+ readonly browser: Service;
249
+ readonly value: A;
250
+ /** First notice that serving ended; loss or retirement may revoke before its deadline. */
251
+ readonly ending: Effect.Effect<Superseded>;
252
+ /** An independent scope; its resources close before provider release. Fails once revoked. */
253
+ readonly retain: Effect.Effect<Scope.Closeable, Superseded>;
254
+ }
255
+ interface UseOptions {
256
+ /** Finite, nonnegative wait for a serving generation. Zero makes an immediate attempt. */
257
+ readonly wait?: Duration.Input | undefined;
258
+ }
259
+ interface Supervisor<A = void> {
260
+ /** Scoped work on the current generation. Revocation interrupts it and waits for its cleanup. */
261
+ readonly use: <B, E, R>(work: (lease: Lease<A>) => Effect.Effect<B, E, R>, options?: UseOptions) => Effect.Effect<B, E | Unavailable | Superseded, Exclude<R, Scope.Scope>>;
217
262
  /** The current generation's browser, waiting up to `waitTimeout` while none is open. */
218
263
  readonly browser: Effect.Effect<Service, Unavailable>;
219
264
  /** Each generation's changes, in order. A new reader first gets the latest 64; ends on retiring. */
@@ -223,8 +268,13 @@ interface Supervisor {
223
268
  /** Stop opening at once, release every generation, and wait until each release has finished. */
224
269
  readonly retire: Effect.Effect<void>;
225
270
  }
226
- /** Supervise generations of a provider's browser for as long as the scope is open. */
227
- declare const make: <E, R>(options: Options<E, R>) => Effect.Effect<Supervisor, never, Scope.Scope | Exclude<R, Scope.Scope>>;
271
+ type Provider = Omit<Opened, "value">;
272
+ type MakeOptions<E, R, A> = Omit<Options<E, R, A>, "open"> & {
273
+ readonly open: Effect.Effect<Opened<A> | Provider, E, R>;
274
+ };
275
+ /** Supervise scoped generation values. Browser-only providers retain their existing void value. */
276
+ declare function make<E, R, A = void>(options: Options<E, R, A>): Effect.Effect<Supervisor<A>, never, Scope.Scope | Exclude<R, Scope.Scope>>;
277
+ declare function make<E, R>(options: MakeOptions<E, R, never>): Effect.Effect<Supervisor<void>, never, Scope.Scope | Exclude<R, Scope.Scope>>;
228
278
  //#endregion
229
- export { Settled as _, Supervisor_d_exports as a, Closed as c, Kept as d, Lost as f, Reopening as g, Released as h, Supervisor as i, Down as l, Opening as m, Opened as n, Unavailable as o, Open as p, Options as r, make as s, Generation as t, GenerationState as u, Unconfirmed as v };
230
- //# sourceMappingURL=Supervisor-Im6-wbg5.d.mts.map
279
+ export { Unconfirmed as S, Open as _, Superseded as a, Reopening as b, Unavailable as c, Closed as d, Down as f, Lost as g, Kept as h, Options as i, UseOptions as l, GenerationState as m, Lease as n, Supervisor as o, Draining as p, Opened as r, Supervisor_d_exports as s, Generation as t, make as u, Opening as v, Settled as x, Released as y };
280
+ //# sourceMappingURL=Supervisor-CYWFK3vM.d.mts.map