@playfast/reform 0.0.1

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 (204) hide show
  1. package/README.md +64 -0
  2. package/dist/cjs/boundary/boundary.js +86 -0
  3. package/dist/cjs/calc/asyncCalc.js +128 -0
  4. package/dist/cjs/calc/asyncData.js +37 -0
  5. package/dist/cjs/calc/calc.js +58 -0
  6. package/dist/cjs/calc/calcFamily.js +127 -0
  7. package/dist/cjs/channel/channel.js +142 -0
  8. package/dist/cjs/compose/composition.js +50 -0
  9. package/dist/cjs/compose/host.js +8 -0
  10. package/dist/cjs/compose/props.js +14 -0
  11. package/dist/cjs/compose/provide.js +30 -0
  12. package/dist/cjs/compose/slot.js +27 -0
  13. package/dist/cjs/compose/ui.js +61 -0
  14. package/dist/cjs/definition/definition.js +46 -0
  15. package/dist/cjs/event/event.js +36 -0
  16. package/dist/cjs/event/eventGroup.js +7 -0
  17. package/dist/cjs/feature/feature.js +102 -0
  18. package/dist/cjs/index.js +116 -0
  19. package/dist/cjs/internal/capture.js +14 -0
  20. package/dist/cjs/internal/ctx.js +2 -0
  21. package/dist/cjs/internal/errors.js +62 -0
  22. package/dist/cjs/internal/inspect.js +36 -0
  23. package/dist/cjs/internal/queryDriver.js +138 -0
  24. package/dist/cjs/internal/reuse.js +71 -0
  25. package/dist/cjs/internal/scheduler.js +73 -0
  26. package/dist/cjs/internal/seeds.js +19 -0
  27. package/dist/cjs/internal/sources.js +61 -0
  28. package/dist/cjs/internal/store.js +77 -0
  29. package/dist/cjs/internal/track.js +22 -0
  30. package/dist/cjs/package.json +4 -0
  31. package/dist/cjs/procedure/procedure.js +52 -0
  32. package/dist/cjs/reducer/reducer.js +64 -0
  33. package/dist/cjs/remote/remoteState.js +307 -0
  34. package/dist/cjs/runtime/bus.js +25 -0
  35. package/dist/cjs/runtime/loop.js +119 -0
  36. package/dist/cjs/scene/scene.js +36 -0
  37. package/dist/cjs/state/state.js +47 -0
  38. package/dist/cjs/state/stateFamily.js +101 -0
  39. package/dist/cjs/state/stateGroup.js +47 -0
  40. package/dist/cjs/state/token.js +23 -0
  41. package/dist/cjs/ui/node.js +2 -0
  42. package/dist/cjs/ui/trigger.js +2 -0
  43. package/dist/dts/boundary/boundary.d.ts +72 -0
  44. package/dist/dts/boundary/boundary.d.ts.map +1 -0
  45. package/dist/dts/calc/asyncCalc.d.ts +91 -0
  46. package/dist/dts/calc/asyncCalc.d.ts.map +1 -0
  47. package/dist/dts/calc/asyncData.d.ts +55 -0
  48. package/dist/dts/calc/asyncData.d.ts.map +1 -0
  49. package/dist/dts/calc/calc.d.ts +57 -0
  50. package/dist/dts/calc/calc.d.ts.map +1 -0
  51. package/dist/dts/calc/calcFamily.d.ts +57 -0
  52. package/dist/dts/calc/calcFamily.d.ts.map +1 -0
  53. package/dist/dts/channel/channel.d.ts +115 -0
  54. package/dist/dts/channel/channel.d.ts.map +1 -0
  55. package/dist/dts/compose/composition.d.ts +72 -0
  56. package/dist/dts/compose/composition.d.ts.map +1 -0
  57. package/dist/dts/compose/host.d.ts +17 -0
  58. package/dist/dts/compose/host.d.ts.map +1 -0
  59. package/dist/dts/compose/props.d.ts +13 -0
  60. package/dist/dts/compose/props.d.ts.map +1 -0
  61. package/dist/dts/compose/provide.d.ts +22 -0
  62. package/dist/dts/compose/provide.d.ts.map +1 -0
  63. package/dist/dts/compose/slot.d.ts +49 -0
  64. package/dist/dts/compose/slot.d.ts.map +1 -0
  65. package/dist/dts/compose/ui.d.ts +50 -0
  66. package/dist/dts/compose/ui.d.ts.map +1 -0
  67. package/dist/dts/definition/definition.d.ts +33 -0
  68. package/dist/dts/definition/definition.d.ts.map +1 -0
  69. package/dist/dts/event/event.d.ts +33 -0
  70. package/dist/dts/event/event.d.ts.map +1 -0
  71. package/dist/dts/event/eventGroup.d.ts +9 -0
  72. package/dist/dts/event/eventGroup.d.ts.map +1 -0
  73. package/dist/dts/feature/feature.d.ts +220 -0
  74. package/dist/dts/feature/feature.d.ts.map +1 -0
  75. package/dist/dts/index.d.ts +43 -0
  76. package/dist/dts/index.d.ts.map +1 -0
  77. package/dist/dts/internal/capture.d.ts +28 -0
  78. package/dist/dts/internal/capture.d.ts.map +1 -0
  79. package/dist/dts/internal/ctx.d.ts +12 -0
  80. package/dist/dts/internal/ctx.d.ts.map +1 -0
  81. package/dist/dts/internal/errors.d.ts +69 -0
  82. package/dist/dts/internal/errors.d.ts.map +1 -0
  83. package/dist/dts/internal/inspect.d.ts +17 -0
  84. package/dist/dts/internal/inspect.d.ts.map +1 -0
  85. package/dist/dts/internal/queryDriver.d.ts +65 -0
  86. package/dist/dts/internal/queryDriver.d.ts.map +1 -0
  87. package/dist/dts/internal/reuse.d.ts +10 -0
  88. package/dist/dts/internal/reuse.d.ts.map +1 -0
  89. package/dist/dts/internal/scheduler.d.ts +47 -0
  90. package/dist/dts/internal/scheduler.d.ts.map +1 -0
  91. package/dist/dts/internal/seeds.d.ts +17 -0
  92. package/dist/dts/internal/seeds.d.ts.map +1 -0
  93. package/dist/dts/internal/sources.d.ts +39 -0
  94. package/dist/dts/internal/sources.d.ts.map +1 -0
  95. package/dist/dts/internal/store.d.ts +47 -0
  96. package/dist/dts/internal/store.d.ts.map +1 -0
  97. package/dist/dts/internal/track.d.ts +33 -0
  98. package/dist/dts/internal/track.d.ts.map +1 -0
  99. package/dist/dts/procedure/procedure.d.ts +40 -0
  100. package/dist/dts/procedure/procedure.d.ts.map +1 -0
  101. package/dist/dts/reducer/reducer.d.ts +44 -0
  102. package/dist/dts/reducer/reducer.d.ts.map +1 -0
  103. package/dist/dts/remote/remoteState.d.ts +119 -0
  104. package/dist/dts/remote/remoteState.d.ts.map +1 -0
  105. package/dist/dts/runtime/bus.d.ts +27 -0
  106. package/dist/dts/runtime/bus.d.ts.map +1 -0
  107. package/dist/dts/runtime/loop.d.ts +45 -0
  108. package/dist/dts/runtime/loop.d.ts.map +1 -0
  109. package/dist/dts/scene/scene.d.ts +44 -0
  110. package/dist/dts/scene/scene.d.ts.map +1 -0
  111. package/dist/dts/state/state.d.ts +37 -0
  112. package/dist/dts/state/state.d.ts.map +1 -0
  113. package/dist/dts/state/stateFamily.d.ts +79 -0
  114. package/dist/dts/state/stateFamily.d.ts.map +1 -0
  115. package/dist/dts/state/stateGroup.d.ts +36 -0
  116. package/dist/dts/state/stateGroup.d.ts.map +1 -0
  117. package/dist/dts/state/token.d.ts +30 -0
  118. package/dist/dts/state/token.d.ts.map +1 -0
  119. package/dist/dts/ui/node.d.ts +9 -0
  120. package/dist/dts/ui/node.d.ts.map +1 -0
  121. package/dist/dts/ui/trigger.d.ts +7 -0
  122. package/dist/dts/ui/trigger.d.ts.map +1 -0
  123. package/dist/esm/boundary/boundary.js +83 -0
  124. package/dist/esm/boundary/boundary.js.map +1 -0
  125. package/dist/esm/calc/asyncCalc.js +95 -0
  126. package/dist/esm/calc/asyncCalc.js.map +1 -0
  127. package/dist/esm/calc/asyncData.js +34 -0
  128. package/dist/esm/calc/asyncData.js.map +1 -0
  129. package/dist/esm/calc/calc.js +58 -0
  130. package/dist/esm/calc/calc.js.map +1 -0
  131. package/dist/esm/calc/calcFamily.js +124 -0
  132. package/dist/esm/calc/calcFamily.js.map +1 -0
  133. package/dist/esm/channel/channel.js +136 -0
  134. package/dist/esm/channel/channel.js.map +1 -0
  135. package/dist/esm/compose/composition.js +46 -0
  136. package/dist/esm/compose/composition.js.map +1 -0
  137. package/dist/esm/compose/host.js +5 -0
  138. package/dist/esm/compose/host.js.map +1 -0
  139. package/dist/esm/compose/props.js +11 -0
  140. package/dist/esm/compose/props.js.map +1 -0
  141. package/dist/esm/compose/provide.js +28 -0
  142. package/dist/esm/compose/provide.js.map +1 -0
  143. package/dist/esm/compose/slot.js +23 -0
  144. package/dist/esm/compose/slot.js.map +1 -0
  145. package/dist/esm/compose/ui.js +57 -0
  146. package/dist/esm/compose/ui.js.map +1 -0
  147. package/dist/esm/definition/definition.js +42 -0
  148. package/dist/esm/definition/definition.js.map +1 -0
  149. package/dist/esm/event/event.js +30 -0
  150. package/dist/esm/event/event.js.map +1 -0
  151. package/dist/esm/event/eventGroup.js +4 -0
  152. package/dist/esm/event/eventGroup.js.map +1 -0
  153. package/dist/esm/feature/feature.js +98 -0
  154. package/dist/esm/feature/feature.js.map +1 -0
  155. package/dist/esm/index.js +45 -0
  156. package/dist/esm/index.js.map +1 -0
  157. package/dist/esm/internal/capture.js +11 -0
  158. package/dist/esm/internal/capture.js.map +1 -0
  159. package/dist/esm/internal/ctx.js +2 -0
  160. package/dist/esm/internal/ctx.js.map +1 -0
  161. package/dist/esm/internal/errors.js +54 -0
  162. package/dist/esm/internal/errors.js.map +1 -0
  163. package/dist/esm/internal/inspect.js +32 -0
  164. package/dist/esm/internal/inspect.js.map +1 -0
  165. package/dist/esm/internal/queryDriver.js +134 -0
  166. package/dist/esm/internal/queryDriver.js.map +1 -0
  167. package/dist/esm/internal/reuse.js +68 -0
  168. package/dist/esm/internal/reuse.js.map +1 -0
  169. package/dist/esm/internal/scheduler.js +69 -0
  170. package/dist/esm/internal/scheduler.js.map +1 -0
  171. package/dist/esm/internal/seeds.js +17 -0
  172. package/dist/esm/internal/seeds.js.map +1 -0
  173. package/dist/esm/internal/sources.js +59 -0
  174. package/dist/esm/internal/sources.js.map +1 -0
  175. package/dist/esm/internal/store.js +73 -0
  176. package/dist/esm/internal/store.js.map +1 -0
  177. package/dist/esm/internal/track.js +18 -0
  178. package/dist/esm/internal/track.js.map +1 -0
  179. package/dist/esm/package.json +4 -0
  180. package/dist/esm/procedure/procedure.js +50 -0
  181. package/dist/esm/procedure/procedure.js.map +1 -0
  182. package/dist/esm/reducer/reducer.js +63 -0
  183. package/dist/esm/reducer/reducer.js.map +1 -0
  184. package/dist/esm/remote/remoteState.js +270 -0
  185. package/dist/esm/remote/remoteState.js.map +1 -0
  186. package/dist/esm/runtime/bus.js +20 -0
  187. package/dist/esm/runtime/bus.js.map +1 -0
  188. package/dist/esm/runtime/loop.js +116 -0
  189. package/dist/esm/runtime/loop.js.map +1 -0
  190. package/dist/esm/scene/scene.js +31 -0
  191. package/dist/esm/scene/scene.js.map +1 -0
  192. package/dist/esm/state/state.js +43 -0
  193. package/dist/esm/state/state.js.map +1 -0
  194. package/dist/esm/state/stateFamily.js +96 -0
  195. package/dist/esm/state/stateFamily.js.map +1 -0
  196. package/dist/esm/state/stateGroup.js +46 -0
  197. package/dist/esm/state/stateGroup.js.map +1 -0
  198. package/dist/esm/state/token.js +20 -0
  199. package/dist/esm/state/token.js.map +1 -0
  200. package/dist/esm/ui/node.js +2 -0
  201. package/dist/esm/ui/node.js.map +1 -0
  202. package/dist/esm/ui/trigger.js +2 -0
  203. package/dist/esm/ui/trigger.js.map +1 -0
  204. package/package.json +33 -0
@@ -0,0 +1,119 @@
1
+ import { Context, Effect, Layer, Schema } from 'effect';
2
+ import { AsyncData } from '../calc/asyncData.js';
3
+ import * as Channel from '../channel/channel.js';
4
+ import { type Manifest } from '../definition/definition.js';
5
+ import * as Event from '../event/event.js';
6
+ import { type GatedOf } from '../internal/queryDriver.js';
7
+ import { type InputsObject, type InputStores, type InvalidateBy } from '../internal/sources.js';
8
+ import { type Store } from '../internal/store.js';
9
+ import { Bus } from '../runtime/bus.js';
10
+ import { Reducers } from '../runtime/loop.js';
11
+ import { type AnySource, StateToken } from '../state/token.js';
12
+ /** One queued intent: the dispatched event value plus the lifecycle metadata. */
13
+ export interface PendingIntent<I> {
14
+ readonly opId: string;
15
+ /** The dispatched intent event (`{ _tag, ...payload }`). */
16
+ readonly intent: I;
17
+ /** `'sending'` until the RPC acks; `'confirmed'` until the post-ack refetch lands. */
18
+ readonly status: 'sending' | 'confirmed';
19
+ }
20
+ /** The payload of the public `Failed` event: which intent, and what `send` raised. */
21
+ export interface FailedIntent<I> {
22
+ readonly intent: I;
23
+ readonly error: unknown;
24
+ }
25
+ export interface RemoteStateManifest<N extends string, A, E> extends Manifest {
26
+ readonly kind: 'RemoteState';
27
+ readonly name: N;
28
+ /** Schema of the server value (`Success` arm / `apply`'s domain). */
29
+ readonly output: Schema.Schema<A, any>;
30
+ readonly error?: Schema.Schema<E, any>;
31
+ /** Whether the query can be disabled (drives the `Idle` arm). */
32
+ readonly gated: boolean;
33
+ /** The mutation vocabulary — intent event tags, reflectable without running logic. */
34
+ readonly intents: ReadonlyArray<string>;
35
+ }
36
+ export interface RemoteStateClass<out N extends string, out Inputs extends ReadonlyArray<AnySource>, in out Intents extends ReadonlyArray<Event.AnyEvent>, in out A, in out E, in out Gated extends boolean> extends Effect.Effect<AsyncData<A, E, Gated>, never, Store<AsyncData<A, E, Gated>>> {
37
+ new (): {};
38
+ readonly manifest: RemoteStateManifest<N, A, E>;
39
+ /** The OVERLAID view (`pending.reduce(apply, truth)`) — what `yield*` reads. */
40
+ readonly store: Context.Tag<Store<AsyncData<A, E, Gated>>, Store<AsyncData<A, E, Gated>>>;
41
+ /** The name, so the class doubles as a `Source` input to another calc. */
42
+ readonly name: N;
43
+ /** Marker data read by `RemoteState.live`. */
44
+ readonly inputs: Inputs;
45
+ /** The intent event definitions (marker data; read by `RemoteState.live`). */
46
+ readonly intents: Intents;
47
+ /** Runtime mirror of `Gated`: whether `disabled` is honored / `Idle` can occur. */
48
+ readonly gated: Gated;
49
+ /** The un-overlaid query lifecycle — for chrome that must show server truth. */
50
+ readonly truth: StateToken<`${N}/truth`, AsyncData<A, E, Gated>>;
51
+ /**
52
+ * The pending queue as a read-only `Source` (badges, "saving…" chrome). Not a
53
+ * `StateClass`, so no user reducer can target it — the hidden queue reducer
54
+ * is its sole writer.
55
+ */
56
+ readonly pending: StateToken<`${N}/pending`, ReadonlyArray<PendingIntent<Event.EventType<Intents[number]>>>>;
57
+ /** Public fact: a send failed; its intent left the queue and the view reverted. */
58
+ readonly Failed: Event.EventClass<`${N}/Failed`, FailedIntent<Event.EventType<Intents[number]>>>;
59
+ }
60
+ export interface RemoteStateConfig<Inputs extends ReadonlyArray<AnySource>, Intents extends ReadonlyArray<Event.AnyEvent>, A, E, AlwaysOn extends boolean> {
61
+ readonly inputs: Inputs;
62
+ /** Schema of the server value. */
63
+ readonly output: Schema.Schema<A, any>;
64
+ /** Schema of the query failure. Omitted ⇒ infallible query, no `Error` arm. */
65
+ readonly error?: Schema.Schema<E, any>;
66
+ /** `true` ⇒ the query is always on: no `Idle` arm and `disabled` is rejected on `.live`. */
67
+ readonly alwaysOn?: AlwaysOn;
68
+ /** The mutation vocabulary: ordinary `Event.make` definitions. */
69
+ readonly intents: Intents;
70
+ }
71
+ /**
72
+ * Define a remote state: a query (like `AsyncCalc.make`) plus the intent
73
+ * events that mutate it. `yield* TheClass` reads the overlaid view;
74
+ * `TheClass.truth` / `TheClass.pending` / `TheClass.Failed` expose the rest of
75
+ * the surface. The query/send/apply logic is supplied by `RemoteState.live`.
76
+ */
77
+ export declare const make: <const N extends string, const Inputs extends ReadonlyArray<AnySource>, const Intents extends ReadonlyArray<Event.AnyEvent>, A, E = never, const AlwaysOn extends boolean = false>(name: N, config: RemoteStateConfig<Inputs, Intents, A, E, AlwaysOn>) => RemoteStateClass<N, Inputs, Intents, A, E, GatedOf<AlwaysOn>>;
78
+ /**
79
+ * The `.live` config: the query (same contract as `AsyncCalc.live`), the
80
+ * delivery effect, and the pure per-intent fold.
81
+ */
82
+ export type RemoteStateLive<Inputs extends ReadonlyArray<AnySource>, Intents extends ReadonlyArray<Event.AnyEvent>, A, E, Gated extends boolean, R, R2> = {
83
+ readonly query: (inputs: InputsObject<Inputs>) => Effect.Effect<A, E, R>;
84
+ /**
85
+ * Deliver one intent to the server. ANY failure (typed failure or defect)
86
+ * settles the intent and dispatches `Failed`; the result value is ignored —
87
+ * truth comes back through the invalidated query, never through the response.
88
+ */
89
+ readonly send: (intent: Event.EventType<Intents[number]>) => Effect.Effect<unknown, unknown, R2>;
90
+ /**
91
+ * The pure per-intent fold over the server value (typically one
92
+ * `Match.exhaustive` over the intent union). MUST be idempotent against
93
+ * truth that already carries the intent — see the module doc.
94
+ */
95
+ readonly apply: (value: A, intent: Event.EventType<Intents[number]>) => A;
96
+ /** The send lane. Default: a generated `${name}/sends` merge channel. */
97
+ readonly channel?: Channel.ChannelClass;
98
+ readonly invalidateBy?: InvalidateBy<Inputs>;
99
+ /** Extra refetch triggers (realtime pushes, unrelated mutations) — `AsyncCalc`'s sugar. */
100
+ readonly invalidateOn?: ReadonlyArray<Event.AnyEvent>;
101
+ /** Refetch conciliation — see `AsyncCalc.live`. Mutation bursts favor `'trailing'`. */
102
+ readonly coalesce?: 'switch' | 'trailing';
103
+ /** Structural sharing across refetches AND overlay recomputes — see `AsyncCalc.live`. */
104
+ readonly reuse?: boolean;
105
+ } & (Gated extends true ? {
106
+ readonly disabled?: (inputs: InputsObject<Inputs>) => boolean;
107
+ } : {
108
+ readonly disabled?: never;
109
+ });
110
+ /**
111
+ * Wire a remote state: the query driver (truth), the overlay (visible view),
112
+ * the hidden queue reducer, the send procedure, and the settle link between
113
+ * them — one layer. Hidden names minted per call, namespaced by the remote
114
+ * state's name: events `…/Queued`/`…/Acked`/`…/Settled`/`…/Invalidated`, state
115
+ * `…/revision`, reducers `…/pending`/`…/revision`, procedure `…/send`, default
116
+ * channel `…/sends`.
117
+ */
118
+ export declare const live: <N extends string, Inputs extends ReadonlyArray<AnySource>, Intents extends ReadonlyArray<Event.AnyEvent>, A, E, Gated extends boolean, R, R2>(remote: RemoteStateClass<N, Inputs, Intents, A, E, Gated>, config: RemoteStateLive<Inputs, Intents, A, E, Gated, R, R2>) => Layer.Layer<Store<AsyncData<A, E, Gated>> | Store<ReadonlyArray<PendingIntent<Event.EventType<Intents[number]>>>>, never, InputStores<Inputs> | R | R2 | Reducers | Channel.Procedures | Channel.Channels | Bus>;
119
+ //# sourceMappingURL=remoteState.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"remoteState.d.ts","sourceRoot":"","sources":["../../../src/remote/remoteState.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,27 @@
1
+ import { Context, Effect, Layer, PubSub } from 'effect';
2
+ /** A dispatched event: a tagged data record (`{ _tag, ...payload }`). */
3
+ export interface Tagged {
4
+ readonly _tag: string;
5
+ }
6
+ /**
7
+ * Re-narrow an erased `Tagged` envelope to a handler's declared event union. The
8
+ * loop and channels only route events whose tag is in a handler's `handles`, so
9
+ * at runtime the envelope IS one of those events; the registries store it as the
10
+ * generic `Tagged`, and this restores the typed view. The one documented home
11
+ * for that boundary cast, shared by `Reducer.live` and `Procedure.live`.
12
+ */
13
+ export declare const narrowHandled: <E>(event: Tagged) => E;
14
+ /** UI-originated events are High; procedure-emitted follow-ups are Normal (DESIGN #46). */
15
+ export type Priority = 'High' | 'Normal';
16
+ export interface Envelope {
17
+ readonly priority: Priority;
18
+ readonly event: Tagged;
19
+ }
20
+ declare const Bus_base: Context.TagClass<Bus, "reform/Bus", PubSub.PubSub<Envelope>>;
21
+ /** The single dispatch bus: an unbounded PubSub fanned out to the loop and procedures. */
22
+ export declare class Bus extends Bus_base {
23
+ }
24
+ export declare const busLayer: Layer.Layer<Bus, never, never>;
25
+ export declare const publish: (priority: Priority, event: Tagged) => Effect.Effect<void, never, Bus>;
26
+ export {};
27
+ //# sourceMappingURL=bus.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"bus.d.ts","sourceRoot":"","sources":["../../../src/runtime/bus.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,EAAE,MAAM,QAAQ,CAAA;AAEvD,yEAAyE;AACzE,MAAM,WAAW,MAAM;IACrB,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;CACtB;AAED;;;;;;GAMG;AACH,eAAO,MAAM,aAAa,GAAI,CAAC,EAAE,OAAO,MAAM,KAAG,CAAmB,CAAA;AAEpE,2FAA2F;AAC3F,MAAM,MAAM,QAAQ,GAAG,MAAM,GAAG,QAAQ,CAAA;AAExC,MAAM,WAAW,QAAQ;IACvB,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAA;IAC3B,QAAQ,CAAC,KAAK,EAAE,MAAM,CAAA;CACvB;;AAED,0FAA0F;AAC1F,qBAAa,GAAI,SAAQ,QAAyD;CAAG;AAOrF,eAAO,MAAM,QAAQ,gCAAkD,CAAA;AAEvE,eAAO,MAAM,OAAO,GAAI,UAAU,QAAQ,EAAE,OAAO,MAAM,KAAG,MAAM,CAAC,MAAM,CAAC,IAAI,EAAE,KAAK,EAAE,GAAG,CAClB,CAAA"}
@@ -0,0 +1,45 @@
1
+ import { Context, Layer } from 'effect';
2
+ import { Channels, Procedures } from '../channel/channel.js';
3
+ import { Bus, type Tagged } from './bus.js';
4
+ /**
5
+ * A registered reducer, with its target store(s) already captured at
6
+ * registration. `apply` is a pure synchronous write, so the loop needs no
7
+ * state services in its own context — it just routes events to writers.
8
+ */
9
+ export interface ReducerEntry {
10
+ /** The reducer's name — used only to warn on duplicate registration. */
11
+ readonly name: string;
12
+ readonly handles: ReadonlySet<string>;
13
+ readonly apply: (event: Tagged) => void;
14
+ }
15
+ /**
16
+ * Mutable collector the central loop drains; reducer `.live` layers register
17
+ * here. `byTag` indexes entries by the event tags they handle, so dispatch is
18
+ * O(matching reducers) per event rather than O(all reducers) — the difference
19
+ * that matters once an app has hundreds of reducers.
20
+ */
21
+ export interface ReducerRegistry {
22
+ readonly entries: Array<ReducerEntry>;
23
+ readonly byTag: Map<string, Array<ReducerEntry>>;
24
+ readonly register: (entry: ReducerEntry) => void;
25
+ /**
26
+ * Remove a previously-registered entry. Eager reducers (built on the root scope)
27
+ * never call this; a lazy feature's `Reducer.live` registers on mount and
28
+ * unregisters on unmount (scope close), so an unmounted feature stops folding and
29
+ * its entry is reclaimed instead of leaking + writing to an orphaned store.
30
+ */
31
+ readonly unregister: (entry: ReducerEntry) => void;
32
+ }
33
+ declare const Reducers_base: Context.TagClass<Reducers, "reform/Reducers", ReducerRegistry>;
34
+ export declare class Reducers extends Reducers_base {
35
+ }
36
+ export declare const reducersLayer: Layer.Layer<Reducers, never, never>;
37
+ /**
38
+ * The reform engine: provides the bus + reducer/channel/procedure registries +
39
+ * the per-runtime notification scheduler to the application and forks the single
40
+ * drain loop. Registration mutates the live collections, so reducers/procedures/
41
+ * channels merged alongside are picked up before the first dispatch (boot).
42
+ */
43
+ export declare const Engine: Layer.Layer<Bus | Reducers | Channels | Procedures>;
44
+ export {};
45
+ //# sourceMappingURL=loop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"loop.d.ts","sourceRoot":"","sources":["../../../src/runtime/loop.ts"],"names":[],"mappings":"AAAA,OAAO,EAAS,OAAO,EAAU,KAAK,EAAiB,MAAM,QAAQ,CAAA;AACrE,OAAO,EACL,QAAQ,EAER,UAAU,EAEX,MAAM,oBAAoB,CAAA;AAE3B,OAAO,EAAE,GAAG,EAA2B,KAAK,MAAM,EAAE,MAAM,OAAO,CAAA;AAEjE;;;;GAIG;AACH,MAAM,WAAW,YAAY;IAC3B,wEAAwE;IACxE,QAAQ,CAAC,IAAI,EAAE,MAAM,CAAA;IACrB,QAAQ,CAAC,OAAO,EAAE,WAAW,CAAC,MAAM,CAAC,CAAA;IACrC,QAAQ,CAAC,KAAK,EAAE,CAAC,KAAK,EAAE,MAAM,KAAK,IAAI,CAAA;CACxC;AAED;;;;;GAKG;AACH,MAAM,WAAW,eAAe;IAC9B,QAAQ,CAAC,OAAO,EAAE,KAAK,CAAC,YAAY,CAAC,CAAA;IACrC,QAAQ,CAAC,KAAK,EAAE,GAAG,CAAC,MAAM,EAAE,KAAK,CAAC,YAAY,CAAC,CAAC,CAAA;IAChD,QAAQ,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;IAChD;;;;;OAKG;IACH,QAAQ,CAAC,UAAU,EAAE,CAAC,KAAK,EAAE,YAAY,KAAK,IAAI,CAAA;CACnD;;AAED,qBAAa,QAAS,SAAQ,aAA2D;CAAG;AAiC5F,eAAO,MAAM,aAAa,qCAA4C,CAAA;AAkFtE;;;;;GAKG;AACH,eAAO,MAAM,MAAM,EAAE,KAAK,CAAC,KAAK,CAAC,GAAG,GAAG,QAAQ,GAAG,QAAQ,GAAG,UAAU,CAMtE,CAAA"}
@@ -0,0 +1,44 @@
1
+ import { Layer } from 'effect';
2
+ import type { CompositionClass, CompositionService } from '../compose/composition.js';
3
+ import type { UiContract } from '../compose/ui.js';
4
+ import type { Bus, Tagged } from '../runtime/bus.js';
5
+ /**
6
+ * The services a built reform runtime exposes to its host: every composition's
7
+ * logic and the event `Bus`. A scene's `provide` must close to these (a fully
8
+ * wired app layer provides far more; this is the subset hosts read directly).
9
+ */
10
+ export type MountedServices = CompositionService | Bus;
11
+ export interface Scene<C extends UiContract = UiContract> {
12
+ readonly kind: 'Scene';
13
+ /** The composition to run, with its contract preserved for typed consumers. */
14
+ readonly composition: CompositionClass<unknown, C>;
15
+ /** Closed wiring (logic + views), each layer seeding its own live state. */
16
+ readonly provide: ReadonlyArray<Layer.Layer<MountedServices, never, never>>;
17
+ /** Events dispatched once the runtime is live (e.g. `RequestedTodos`). */
18
+ readonly boot?: ReadonlyArray<Tagged>;
19
+ }
20
+ /**
21
+ * Define a scene — `scene(TodoApp, { provide: [makeTestApp(client, seeds)] })`.
22
+ * The composition's contract flows through `C`, so consumers stay typed.
23
+ */
24
+ export declare const scene: <C extends UiContract>(composition: CompositionClass<unknown, C>, config: {
25
+ readonly provide: ReadonlyArray<Layer.Layer<MountedServices, never, never>>;
26
+ readonly boot?: ReadonlyArray<Tagged>;
27
+ }) => Scene<C>;
28
+ /**
29
+ * Overlay seed values onto a CLOSED scene — the tooling/test seam (dev-tool
30
+ * inspector overrides, proofs). Scenes stay closed for authors: this does not
31
+ * reopen `provide`, it wraps each layer with `Layer.locally(CurrentSeedOverrides,
32
+ * seeds)` so `State.live` boots matching stores from the override instead of
33
+ * the authored seed.
34
+ *
35
+ * Keys are state MEMBER NAMES as reflected in `manifest.states` (e.g. `count`),
36
+ * not group names. If two groups in one scene share a member name, both receive
37
+ * the override (documented limitation). Values are schema-validated at build:
38
+ * an invalid value silently falls back to the authored seed. `StateFamily`
39
+ * entries are not covered.
40
+ */
41
+ export declare const seedScene: <C extends UiContract>(base: Scene<C>, seeds: Readonly<Record<string, unknown>>) => Scene<C>;
42
+ /** Reflection guard: is this exported value a scene? */
43
+ export declare const isScene: (v: unknown) => v is Scene;
44
+ //# sourceMappingURL=scene.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"scene.d.ts","sourceRoot":"","sources":["../../../src/scene/scene.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAC9B,OAAO,KAAK,EAAE,gBAAgB,EAAE,kBAAkB,EAAE,MAAM,wBAAwB,CAAA;AAClF,OAAO,KAAK,EAAE,UAAU,EAAE,MAAM,eAAe,CAAA;AAE/C,OAAO,KAAK,EAAE,GAAG,EAAE,MAAM,EAAE,MAAM,gBAAgB,CAAA;AAcjD;;;;GAIG;AACH,MAAM,MAAM,eAAe,GAAG,kBAAkB,GAAG,GAAG,CAAA;AAEtD,MAAM,WAAW,KAAK,CAAC,CAAC,SAAS,UAAU,GAAG,UAAU;IACtD,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,+EAA+E;IAC/E,QAAQ,CAAC,WAAW,EAAE,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,CAAA;IAClD,4EAA4E;IAC5E,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAA;IAC3E,0EAA0E;IAC1E,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CACtC;AAED;;;GAGG;AACH,eAAO,MAAM,KAAK,GAAI,CAAC,SAAS,UAAU,EACxC,aAAa,gBAAgB,CAAC,OAAO,EAAE,CAAC,CAAC,EACzC,QAAQ;IACN,QAAQ,CAAC,OAAO,EAAE,aAAa,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAA;IAC3E,QAAQ,CAAC,IAAI,CAAC,EAAE,aAAa,CAAC,MAAM,CAAC,CAAA;CACtC,KACA,KAAK,CAAC,CAAC,CAKR,CAAA;AAEF;;;;;;;;;;;;GAYG;AACH,eAAO,MAAM,SAAS,GAAI,CAAC,SAAS,UAAU,EAC5C,MAAM,KAAK,CAAC,CAAC,CAAC,EACd,OAAO,QAAQ,CAAC,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC,KACvC,KAAK,CAAC,CAAC,CAG8E,CAAA;AAExF,wDAAwD;AACxD,eAAO,MAAM,OAAO,GAAI,GAAG,OAAO,KAAG,CAAC,IAAI,KACkD,CAAA"}
@@ -0,0 +1,37 @@
1
+ import { Context, Effect, Layer, Schema } from 'effect';
2
+ import { type Manifest } from '../definition/definition.js';
3
+ import { type Store } from '../internal/store.js';
4
+ export interface StateOptions {
5
+ readonly title?: string;
6
+ readonly description?: string;
7
+ }
8
+ export interface StateManifest<N extends string, A> extends Manifest {
9
+ readonly kind: 'State';
10
+ readonly name: N;
11
+ readonly schema: Schema.Schema<A, any>;
12
+ readonly title?: string;
13
+ readonly description?: string;
14
+ }
15
+ export interface StateClass<out N extends string, in out A> extends Effect.Effect<A, never, Store<A>> {
16
+ new (): {};
17
+ readonly manifest: StateManifest<N, A>;
18
+ /** Internal DI tag holding the live store. The loop reads/writes through it. */
19
+ readonly store: Context.Tag<Store<A>, Store<A>>;
20
+ }
21
+ export type AnyState = StateClass<string, any>;
22
+ export type StateValue<S> = S extends StateClass<string, infer A> ? A : never;
23
+ export type StateName<S> = S extends StateClass<infer N, any> ? N : never;
24
+ /**
25
+ * Atomic reactive state. `State.make` is the *definition* (a reflectable
26
+ * manifest + an internal store tag); it carries no starting value — the seed is
27
+ * an implementation detail supplied at create-time by `State.live(state, seed)`.
28
+ * Composed into a `StateGroup` exactly as `@effect/rpc` composes rpcs.
29
+ */
30
+ export declare const make: <const N extends string, A>(name: N, schema: Schema.Schema<A, any>, options?: StateOptions) => StateClass<N, A>;
31
+ /**
32
+ * Allocate a state's store, seeded with `initial` — `State.live(Feed, seed)`.
33
+ * The seed lives here (implementation), not on the definition, so the same
34
+ * definition can boot from different values in app vs. test wiring.
35
+ */
36
+ export declare const live: <S extends AnyState>(state: S, initial: StateValue<S>) => Layer.Layer<Store<StateValue<S>>>;
37
+ //# sourceMappingURL=state.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"state.d.ts","sourceRoot":"","sources":["../../../src/state/state.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAY,KAAK,EAAU,MAAM,EAAE,MAAM,QAAQ,CAAA;AACzE,OAAO,EAAE,KAAK,QAAQ,EAAkB,MAAM,0BAA0B,CAAA;AAGxE,OAAO,EAAa,KAAK,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAGzD,MAAM,WAAW,YAAY;IAC3B,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAC9B;AAED,MAAM,WAAW,aAAa,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,CAAE,SAAQ,QAAQ;IAClE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;IACtB,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IAChB,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,CAAA;IACtC,QAAQ,CAAC,KAAK,CAAC,EAAE,MAAM,CAAA;IACvB,QAAQ,CAAC,WAAW,CAAC,EAAE,MAAM,CAAA;CAC9B;AAED,MAAM,WAAW,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAE,SAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IACnG,QAAQ,EAAE,CAAA;IACV,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC,EAAE,CAAC,CAAC,CAAA;IACtC,gFAAgF;IAChF,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;CAChD;AAED,MAAM,MAAM,QAAQ,GAAG,UAAU,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAC9C,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,MAAM,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;AAC7E,MAAM,MAAM,SAAS,CAAC,CAAC,IAAI,CAAC,SAAS,UAAU,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;AAEzE;;;;;GAKG;AACH,eAAO,MAAM,IAAI,GAAI,KAAK,CAAC,CAAC,SAAS,MAAM,EAAE,CAAC,EAC5C,MAAM,CAAC,EACP,QAAQ,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,GAAG,CAAC,EAC7B,UAAS,YAAiB,KACzB,UAAU,CAAC,CAAC,EAAE,CAAC,CAWjB,CAAA;AAwBD;;;;GAIG;AACH,eAAO,MAAM,IAAI,GAAI,CAAC,SAAS,QAAQ,EACrC,OAAO,CAAC,EACR,SAAS,UAAU,CAAC,CAAC,CAAC,KACrB,KAAK,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,CAAC,CAAC,CAAC,CAAC,CAMhC,CAAA"}
@@ -0,0 +1,79 @@
1
+ import { Context, Effect, Layer, type Schema } from 'effect';
2
+ import { type Manifest } from '../definition/definition.js';
3
+ import { type Store } from '../internal/store.js';
4
+ /**
5
+ * A reducer fold returns this to evict the key it folded over, instead of a new
6
+ * value. The loop drops the entry's store from the family, so a normalized
7
+ * collection (chat messages, search hits, transient rows) does not grow without
8
+ * bound — the one fix for the otherwise-unbounded per-key `Map`.
9
+ */
10
+ export declare const Tombstone: unique symbol;
11
+ export type Tombstone = typeof Tombstone;
12
+ /** Per-key stores, created lazily so a write to one key wakes only its subscribers. */
13
+ export interface FamilyStore<K, V> {
14
+ at(key: K): Store<V>;
15
+ /**
16
+ * Drop a key's store so it stops occupying memory. A live subscriber keeps its
17
+ * own closure over the previous store, so eviction is for keys whose entity is
18
+ * gone (the component is unmounting) — re-`at`-ing the key allocates a fresh,
19
+ * reseeded store.
20
+ */
21
+ forget(key: K): void;
22
+ /** Drop every key's store — a wholesale reset of the family. */
23
+ clear(): void;
24
+ /** Number of live keys — for tests/diagnostics. */
25
+ size(): number;
26
+ }
27
+ /** Options for a family's keyed store. */
28
+ export interface FamilyOptions {
29
+ /**
30
+ * Drop a key's store automatically once it has no live subscribers (checked on
31
+ * the next microtask, so a same-commit re-subscribe — e.g. a key that just moved
32
+ * position in a list — cancels the eviction). This bounds an otherwise-unbounded
33
+ * family without explicit `Tombstone`s, but it also DISCARDS the key's value —
34
+ * re-`at`-ing a dropped key reseeds from `initial`. Use only for keys whose value
35
+ * is disposable when nothing renders them (search hits, transient rows); for a
36
+ * source-of-truth entity that may be temporarily off-screen (a virtualized list),
37
+ * keep this off and reclaim with an explicit reducer `Tombstone`. Default: off.
38
+ */
39
+ readonly evictWhenUnused?: boolean;
40
+ }
41
+ export interface StateFamilyManifest<N extends string, K, V> extends Manifest {
42
+ readonly kind: 'StateFamily';
43
+ readonly name: N;
44
+ readonly key: Schema.Schema<K, any>;
45
+ readonly value: Schema.Schema<V, any>;
46
+ readonly title?: string;
47
+ readonly description?: string;
48
+ }
49
+ export interface StateFamilyClass<out N extends string, in out K, in out V> {
50
+ /** Instance carries the key phantom so `Family['Key']` resolves in `keyOf` types. */
51
+ new (): {
52
+ readonly Key: K;
53
+ };
54
+ readonly manifest: StateFamilyManifest<N, K, V>;
55
+ readonly store: Context.Tag<FamilyStore<K, V>, FamilyStore<K, V>>;
56
+ }
57
+ export type AnyFamily = StateFamilyClass<string, any, any>;
58
+ export type FamilyKey<F> = F extends StateFamilyClass<any, infer K, any> ? K : never;
59
+ export type FamilyValue<F> = F extends StateFamilyClass<any, any, infer V> ? V : never;
60
+ /**
61
+ * Normalized keyed state: one logical State per key, backed by a single family
62
+ * store. Scales with the collection without re-rendering unrelated entries.
63
+ */
64
+ export declare const make: <const N extends string, K, V>(name: N, key: Schema.Schema<K, any>, value: Schema.Schema<V, any>, options?: {
65
+ readonly title?: string;
66
+ readonly description?: string;
67
+ }) => StateFamilyClass<N, K, V>;
68
+ /**
69
+ * Read one entry by key — `StateFamily.read(ItemUi, id)`. Inside a render it
70
+ * subscribes that key's slice; elsewhere it just snapshots (D5).
71
+ */
72
+ export declare const read: <N extends string, K, V>(family: StateFamilyClass<N, K, V>, key: K) => Effect.Effect<V, never, FamilyStore<K, V>>;
73
+ /**
74
+ * Allocate a family's keyed store — `StateFamily.live(ItemUi, seed)`. The seed
75
+ * is a plain value or a factory; a factory receives the key, so a new entry can
76
+ * derive its starting value from its own id (`(id) => ({ ...blank, id }))`).
77
+ */
78
+ export declare const live: <N extends string, K, V>(family: StateFamilyClass<N, K, V>, initial: V | ((key: K) => V), options?: FamilyOptions) => Layer.Layer<FamilyStore<K, V>>;
79
+ //# sourceMappingURL=stateFamily.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stateFamily.d.ts","sourceRoot":"","sources":["../../../src/state/stateFamily.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,36 @@
1
+ import { Layer } from 'effect';
2
+ import { type StoresOf } from '../internal/sources.js';
3
+ import { type AnyState, type StateClass, type StateName } from './state.js';
4
+ import { StateToken } from './token.js';
5
+ type ValueForName<Members extends ReadonlyArray<AnyState>, N extends string> = Extract<Members[number], StateClass<N, any>> extends StateClass<any, infer A> ? A : never;
6
+ export interface StateGroupClass<Members extends ReadonlyArray<AnyState>> {
7
+ new (): {};
8
+ readonly kind: 'StateGroup';
9
+ readonly members: Members;
10
+ /** Members indexed by name, so `select` is an O(1) lookup instead of a scan. */
11
+ readonly byName: ReadonlyMap<string, AnyState>;
12
+ }
13
+ export type AnyStateGroup = StateGroupClass<ReadonlyArray<AnyState>>;
14
+ export type GroupSeeds<G extends AnyStateGroup> = G extends StateGroupClass<infer Members> ? {
15
+ readonly [N in StateName<Members[number]>]: ValueForName<Members, N>;
16
+ } : never;
17
+ /** Compose atomic States into a group provided (and addressed) as a unit. */
18
+ export declare const make: <const Members extends ReadonlyArray<AnyState>>(...members: Members) => StateGroupClass<Members>;
19
+ /**
20
+ * Address a member by its tag — `StateGroup.select(TodosStates, 'feed')` —
21
+ * yielding a `StateToken` for reads and calc inputs (still `yield*`-able).
22
+ *
23
+ * Data-first only (not `dual`): the member name's type depends on the group, and
24
+ * a group is not `Pipeable`, so a data-last form would be both more verbose and
25
+ * harder to type than the direct call. Effect reserves `dual` for operators on a
26
+ * `Pipeable` self with an independent value arg (e.g. `ref.pipe(Ref.set(v))`);
27
+ * this is not that shape.
28
+ */
29
+ export declare const select: <Members extends ReadonlyArray<AnyState>, N extends StateName<Members[number]>>(group: StateGroupClass<Members>, name: N) => StateToken<N, ValueForName<Members, N>>;
30
+ /**
31
+ * Allocate every member's store as one merged layer, each seeded from `seeds`
32
+ * keyed by member name — `StateGroup.live(BoardStates, { board: { _tag: 'Idle' } })`.
33
+ */
34
+ export declare const live: <Members extends ReadonlyArray<AnyState>>(group: StateGroupClass<Members>, seeds: GroupSeeds<StateGroupClass<Members>>) => Layer.Layer<StoresOf<Members>>;
35
+ export {};
36
+ //# sourceMappingURL=stateGroup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stateGroup.d.ts","sourceRoot":"","sources":["../../../src/state/stateGroup.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,KAAK,EAAE,MAAM,QAAQ,CAAA;AAM9B,OAAO,EAAE,KAAK,QAAQ,EAAE,MAAM,qBAAqB,CAAA;AACnD,OAAO,EAAE,KAAK,QAAQ,EAAqB,KAAK,UAAU,EAAE,KAAK,SAAS,EAAE,MAAM,SAAS,CAAA;AAC3F,OAAO,EAAE,UAAU,EAAE,MAAM,SAAS,CAAA;AAEpC,KAAK,YAAY,CAAC,OAAO,SAAS,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC,SAAS,MAAM,IACzE,OAAO,CAAC,OAAO,CAAC,MAAM,CAAC,EAAE,UAAU,CAAC,CAAC,EAAE,GAAG,CAAC,CAAC,SAAS,UAAU,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;AAE3F,MAAM,WAAW,eAAe,CAAC,OAAO,SAAS,aAAa,CAAC,QAAQ,CAAC;IACtE,QAAQ,EAAE,CAAA;IACV,QAAQ,CAAC,IAAI,EAAE,YAAY,CAAA;IAC3B,QAAQ,CAAC,OAAO,EAAE,OAAO,CAAA;IACzB,gFAAgF;IAChF,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,MAAM,EAAE,QAAQ,CAAC,CAAA;CAC/C;AAED,MAAM,MAAM,aAAa,GAAG,eAAe,CAAC,aAAa,CAAC,QAAQ,CAAC,CAAC,CAAA;AAMpE,MAAM,MAAM,UAAU,CAAC,CAAC,SAAS,aAAa,IAC5C,CAAC,SAAS,eAAe,CAAC,MAAM,OAAO,CAAC,GACpC;IAAE,QAAQ,EAAE,CAAC,IAAI,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,GAAG,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC;CAAE,GACxE,KAAK,CAAA;AAEX,6EAA6E;AAC7E,eAAO,MAAM,IAAI,GAAI,KAAK,CAAC,OAAO,SAAS,aAAa,CAAC,QAAQ,CAAC,EAChE,GAAG,SAAS,OAAO,KAClB,eAAe,CAAC,OAAO,CAKtB,CAAA;AAEJ;;;;;;;;;GASG;AACH,eAAO,MAAM,MAAM,GAAI,OAAO,SAAS,aAAa,CAAC,QAAQ,CAAC,EAAE,CAAC,SAAS,SAAS,CAAC,OAAO,CAAC,MAAM,CAAC,CAAC,EAClG,OAAO,eAAe,CAAC,OAAO,CAAC,EAC/B,MAAM,CAAC,KACN,UAAU,CAAC,CAAC,EAAE,YAAY,CAAC,OAAO,EAAE,CAAC,CAAC,CAIxC,CAAA;AAED;;;GAGG;AACH,eAAO,MAAM,IAAI,GAAI,OAAO,SAAS,aAAa,CAAC,QAAQ,CAAC,EAC1D,OAAO,eAAe,CAAC,OAAO,CAAC,EAC/B,OAAO,UAAU,CAAC,eAAe,CAAC,OAAO,CAAC,CAAC,KAC1C,KAAK,CAAC,KAAK,CAAC,QAAQ,CAAC,OAAO,CAAC,CAS/B,CAAA"}
@@ -0,0 +1,30 @@
1
+ import { Context, Effect, Effectable } from 'effect';
2
+ import type { Store } from '../internal/store.js';
3
+ /**
4
+ * A reference to one slice of state: yieldable to its current value (`yield*`
5
+ * reads + — under React — subscribes) and carrying the metadata calcs need
6
+ * (its `name` and backing store tag). Returned by `StateGroup.select(group, name)`.
7
+ */
8
+ export declare class StateToken<out N extends string, in out A> extends Effectable.Class<A, never, Store<A>> {
9
+ readonly name: N;
10
+ readonly store: Context.Tag<Store<A>, Store<A>>;
11
+ constructor(name: N, store: Context.Tag<Store<A>, Store<A>>);
12
+ commit(): Effect.Effect<A, never, Store<A>>;
13
+ }
14
+ /**
15
+ * Anything a derived value can read and depend on: a named slice backed by a
16
+ * subscribable store tag. A `StateToken` (group member), a `Calc`, and an
17
+ * `AsyncCalc` all structurally satisfy this — so a `Calc`/`AsyncCalc` can take
18
+ * any of them as an input. The `name` becomes the key in the inputs object.
19
+ *
20
+ * `StateToken` is the one concrete, *yieldable* `Source`; `Calc`/`AsyncCalc`
21
+ * satisfy the same shape so the three are interchangeable as calc inputs.
22
+ */
23
+ export interface Source<out N extends string, in out A> {
24
+ readonly name: N;
25
+ readonly store: Context.Tag<Store<A>, Store<A>>;
26
+ }
27
+ export type AnySource = Source<string, any>;
28
+ export type SourceName<S> = S extends Source<infer N, any> ? N : never;
29
+ export type SourceValue<S> = S extends Source<any, infer A> ? A : never;
30
+ //# sourceMappingURL=token.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"token.d.ts","sourceRoot":"","sources":["../../../src/state/token.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,EAAE,UAAU,EAAE,MAAM,QAAQ,CAAA;AACpD,OAAO,KAAK,EAAE,KAAK,EAAE,MAAM,mBAAmB,CAAA;AAG9C;;;;GAIG;AACH,qBAAa,UAAU,CAAC,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC,CAAE,SAAQ,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAEhG,QAAQ,CAAC,IAAI,EAAE,CAAC;IAChB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;gBADtC,IAAI,EAAE,CAAC,EACP,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;IAIjD,MAAM,IAAI,MAAM,CAAC,MAAM,CAAC,CAAC,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;CAG5C;AAED;;;;;;;;GAQG;AACH,MAAM,WAAW,MAAM,CAAC,GAAG,CAAC,CAAC,SAAS,MAAM,EAAE,EAAE,CAAC,GAAG,CAAC,CAAC;IACpD,QAAQ,CAAC,IAAI,EAAE,CAAC,CAAA;IAChB,QAAQ,CAAC,KAAK,EAAE,OAAO,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC,CAAA;CAChD;AAED,MAAM,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,EAAE,GAAG,CAAC,CAAA;AAC3C,MAAM,MAAM,UAAU,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,MAAM,CAAC,EAAE,GAAG,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA;AACtE,MAAM,MAAM,WAAW,CAAC,CAAC,IAAI,CAAC,SAAS,MAAM,CAAC,GAAG,EAAE,MAAM,CAAC,CAAC,GAAG,CAAC,GAAG,KAAK,CAAA"}
@@ -0,0 +1,9 @@
1
+ import type { ReactNode } from 'react';
2
+ /**
3
+ * What a view renders. Reform targets React, so a node is a `ReactNode` — this
4
+ * is a *type-only* dependency: core never imports the React runtime nor renders
5
+ * anything itself (that is `@reform/react`). Typing it precisely lets the `.ui`
6
+ * presentations author real JSX and lets slots be valid components.
7
+ */
8
+ export type Node = ReactNode;
9
+ //# sourceMappingURL=node.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"node.d.ts","sourceRoot":"","sources":["../../../src/ui/node.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,OAAO,CAAA;AAEtC;;;;;GAKG;AACH,MAAM,MAAM,IAAI,GAAG,SAAS,CAAA"}
@@ -0,0 +1,7 @@
1
+ /**
2
+ * A handler handed to the UI: a plain callback. Calling it dispatches the event
3
+ * (High priority) through the runtime. The UI never sees Effect — it just calls
4
+ * `events.submit({ text })`.
5
+ */
6
+ export type Trigger<P> = (payload: P) => void;
7
+ //# sourceMappingURL=trigger.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"trigger.d.ts","sourceRoot":"","sources":["../../../src/ui/trigger.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AACH,MAAM,MAAM,OAAO,CAAC,CAAC,IAAI,CAAC,OAAO,EAAE,CAAC,KAAK,IAAI,CAAA"}
@@ -0,0 +1,83 @@
1
+ import { Context, Data, Effect, Layer, MutableRef, Predicate } from 'effect';
2
+ import { yieldableClass } from '../definition/definition.js';
3
+ import { resolveScheduler } from '../internal/scheduler.js';
4
+ import { sameKey, wireSources } from '../internal/sources.js';
5
+ import { makeDerivedStore } from '../internal/store.js';
6
+ import { readTracked } from '../internal/track.js';
7
+ import {} from '../state/token.js';
8
+ // Stable arm references: repeated recomputes return the same object, so the
9
+ // derived store's Equal gate (and `useSyncExternalStore`'s stable-snapshot
10
+ // contract) hold without a wrapper. `Errored` carries data, so it is a `Data`
11
+ // struct — value-equal failures coalesce the same way.
12
+ const pendingArm = { _tag: 'Pending' };
13
+ const readyArm = { _tag: 'Ready' };
14
+ const erroredArm = (errors) => Data.struct({ _tag: 'Errored', errors: Data.array(errors) });
15
+ /**
16
+ * Define a boundary over async sources. `yield* MyBoundary` reads the merged
17
+ * `Pending | Errored | Ready` lifecycle; the consuming view renders ONE
18
+ * fallback on Pending and its content slot on Ready — content reveals
19
+ * together, with data already present (fetching never waited on rendering).
20
+ */
21
+ export const make = (name, config) => {
22
+ const store = Context.GenericTag(`reform/boundary/${name}`);
23
+ const manifest = { kind: 'Boundary', name };
24
+ const read = Effect.flatMap(store, readTracked);
25
+ return yieldableClass(read, { manifest, store, name, over: config.over });
26
+ };
27
+ // The snapshot values arrive through `wireSources`' erased key projection
28
+ // (`ReadonlyArray<unknown>`), so read the two facts the merge needs through
29
+ // honest structural guards — no cast back to `AnyAsyncData`.
30
+ const tagOf = (arm) => Predicate.hasProperty(arm, '_tag') && Predicate.isString(arm._tag) ? arm._tag : '';
31
+ const errorOf = (arm) => Predicate.hasProperty(arm, 'error') && tagOf(arm) === 'Error' ? [arm.error] : [];
32
+ /**
33
+ * Wire the merge. A derived store over the covered stores (sensed through the
34
+ * same `wireSources` plumbing every calc uses): recomputes are memoized on the
35
+ * input snapshots and the arms are stable references, so input churn that does
36
+ * not move the merged arm wakes nobody.
37
+ */
38
+ export const live = (boundary, options = {}) =>
39
+ // Scoped so the source subscriptions are released with the layer's scope.
40
+ Layer.scoped(boundary.store, Effect.gen(function* () {
41
+ const scheduler = yield* resolveScheduler;
42
+ const sources = yield* wireSources(boundary.over);
43
+ const latched = MutableRef.make(false);
44
+ const memo = MutableRef.make(undefined);
45
+ const recompute = () => {
46
+ if (options.once === true && MutableRef.get(latched))
47
+ return readyArm;
48
+ const arms = sources.keyOf(sources.snapshot());
49
+ const prev = MutableRef.get(memo);
50
+ if (prev !== undefined && sameKey(arms, prev.key))
51
+ return prev.value;
52
+ const errors = arms.flatMap(errorOf);
53
+ const value = errors.length > 0
54
+ ? erroredArm(errors)
55
+ : arms.some((arm) => tagOf(arm) === 'Loading')
56
+ ? pendingArm
57
+ : readyArm;
58
+ MutableRef.set(memo, { key: arms, value });
59
+ return value;
60
+ };
61
+ const derived = makeDerivedStore(recompute, sources.subscribe, scheduler);
62
+ yield* Effect.addFinalizer(() => Effect.sync(derived.unsubscribe));
63
+ if (options.once === true) {
64
+ // Latch on CONVERGED values only — at build and on (coalesced,
65
+ // post-fixpoint) notifications — never inside `recompute`. A chained
66
+ // gate with a plain Calc hop between the async stores (bootstrap →
67
+ // current-workspace → boards) propagates over TWO flush rounds, so a
68
+ // mid-flush recompute can observe the frame where the downstream
69
+ // driver has not yet flipped its query to Loading. That intermediate
70
+ // Ready self-corrects within the flush for readers, but a latch taken
71
+ // there would freeze it; a subscriber runs only after the fixpoint,
72
+ // where the value is converged.
73
+ if (recompute()._tag === 'Ready')
74
+ MutableRef.set(latched, true);
75
+ const offSelf = derived.store.subscribe(() => {
76
+ if (derived.store.get()._tag === 'Ready')
77
+ MutableRef.set(latched, true);
78
+ });
79
+ yield* Effect.addFinalizer(() => Effect.sync(offSelf));
80
+ }
81
+ return derived.store;
82
+ }));
83
+ //# sourceMappingURL=boundary.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"boundary.js","sourceRoot":"","sources":["../../../src/boundary/boundary.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,IAAI,EAAE,MAAM,EAAE,KAAK,EAAE,UAAU,EAAE,SAAS,EAAE,MAAM,QAAQ,CAAA;AAC5E,OAAO,EAAiB,cAAc,EAAE,MAAM,0BAA0B,CAAA;AACxE,OAAO,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAA;AACxD,OAAO,EAAoB,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAA;AAC5E,OAAO,EAAE,gBAAgB,EAAc,MAAM,mBAAmB,CAAA;AAChE,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAA;AAC/C,OAAO,EAAe,MAAM,gBAAgB,CAAA;AAiD5C,4EAA4E;AAC5E,2EAA2E;AAC3E,8EAA8E;AAC9E,uDAAuD;AACvD,MAAM,UAAU,GAAkB,EAAE,IAAI,EAAE,SAAS,EAAE,CAAA;AACrD,MAAM,QAAQ,GAAkB,EAAE,IAAI,EAAE,OAAO,EAAE,CAAA;AACjD,MAAM,UAAU,GAAG,CAAC,MAA8B,EAAiB,EAAE,CACnE,IAAI,CAAC,MAAM,CAAC,EAAE,IAAI,EAAE,SAAkB,EAAE,MAAM,EAAE,IAAI,CAAC,KAAK,CAAC,MAAM,CAAC,EAAE,CAAC,CAAA;AA6CvE;;;;;GAKG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAClB,IAAO,EACP,MAA4B,EACJ,EAAE;IAC1B,MAAM,KAAK,GAAG,OAAO,CAAC,UAAU,CAC9B,mBAAmB,IAAI,EAAE,CAC1B,CAAA;IACD,MAAM,QAAQ,GAAwB,EAAE,IAAI,EAAE,UAAU,EAAE,IAAI,EAAE,CAAA;IAChE,MAAM,IAAI,GAAG,MAAM,CAAC,OAAO,CAAC,KAAK,EAAE,WAAW,CAAC,CAAA;IAC/C,OAAO,cAAc,CAAC,IAAI,EAAE,EAAE,QAAQ,EAAE,KAAK,EAAE,IAAI,EAAE,IAAI,EAAE,MAAM,CAAC,IAAI,EAAE,CAAC,CAAA;AAC3E,CAAC,CAAA;AAED,0EAA0E;AAC1E,4EAA4E;AAC5E,6DAA6D;AAC7D,MAAM,KAAK,GAAG,CAAC,GAAY,EAAU,EAAE,CACrC,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,MAAM,CAAC,IAAI,SAAS,CAAC,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAA;AACpF,MAAM,OAAO,GAAG,CAAC,GAAY,EAA0B,EAAE,CACvD,SAAS,CAAC,WAAW,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,KAAK,CAAC,GAAG,CAAC,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAA;AAElF;;;;;GAKG;AACH,MAAM,CAAC,MAAM,IAAI,GAAG,CAClB,QAAgC,EAChC,UAA2B,EAAE,EACgC,EAAE;AAC/D,0EAA0E;AAC1E,KAAK,CAAC,MAAM,CACV,QAAQ,CAAC,KAAK,EACd,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,gBAAgB,CAAA;IACzC,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,WAAW,CAAC,QAAQ,CAAC,IAAI,CAAC,CAAA;IAEjD,MAAM,OAAO,GAAG,UAAU,CAAC,IAAI,CAAC,KAAK,CAAC,CAAA;IACtC,MAAM,IAAI,GAAG,UAAU,CAAC,IAAI,CAE1B,SAAS,CAAC,CAAA;IACZ,MAAM,SAAS,GAAG,GAAkB,EAAE;QACpC,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,IAAI,UAAU,CAAC,GAAG,CAAC,OAAO,CAAC;YAAE,OAAO,QAAQ,CAAA;QACrE,MAAM,IAAI,GAAG,OAAO,CAAC,KAAK,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,CAAA;QAC9C,MAAM,IAAI,GAAG,UAAU,CAAC,GAAG,CAAC,IAAI,CAAC,CAAA;QACjC,IAAI,IAAI,KAAK,SAAS,IAAI,OAAO,CAAC,IAAI,EAAE,IAAI,CAAC,GAAG,CAAC;YAAE,OAAO,IAAI,CAAC,KAAK,CAAA;QACpE,MAAM,MAAM,GAAG,IAAI,CAAC,OAAO,CAAC,OAAO,CAAC,CAAA;QACpC,MAAM,KAAK,GACT,MAAM,CAAC,MAAM,GAAG,CAAC;YACf,CAAC,CAAC,UAAU,CAAC,MAAM,CAAC;YACpB,CAAC,CAAC,IAAI,CAAC,IAAI,CAAC,CAAC,GAAG,EAAE,EAAE,CAAC,KAAK,CAAC,GAAG,CAAC,KAAK,SAAS,CAAC;gBAC5C,CAAC,CAAC,UAAU;gBACZ,CAAC,CAAC,QAAQ,CAAA;QAChB,UAAU,CAAC,GAAG,CAAC,IAAI,EAAE,EAAE,GAAG,EAAE,IAAI,EAAE,KAAK,EAAE,CAAC,CAAA;QAC1C,OAAO,KAAK,CAAA;IACd,CAAC,CAAA;IAED,MAAM,OAAO,GAAG,gBAAgB,CAAC,SAAS,EAAE,OAAO,CAAC,SAAS,EAAE,SAAS,CAAC,CAAA;IACzE,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,WAAW,CAAC,CAAC,CAAA;IAElE,IAAI,OAAO,CAAC,IAAI,KAAK,IAAI,EAAE,CAAC;QAC1B,+DAA+D;QAC/D,qEAAqE;QACrE,mEAAmE;QACnE,qEAAqE;QACrE,iEAAiE;QACjE,qEAAqE;QACrE,sEAAsE;QACtE,oEAAoE;QACpE,gCAAgC;QAChC,IAAI,SAAS,EAAE,CAAC,IAAI,KAAK,OAAO;YAAE,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QAC/D,MAAM,OAAO,GAAG,OAAO,CAAC,KAAK,CAAC,SAAS,CAAC,GAAG,EAAE;YAC3C,IAAI,OAAO,CAAC,KAAK,CAAC,GAAG,EAAE,CAAC,IAAI,KAAK,OAAO;gBAAE,UAAU,CAAC,GAAG,CAAC,OAAO,EAAE,IAAI,CAAC,CAAA;QACzE,CAAC,CAAC,CAAA;QACF,KAAK,CAAC,CAAC,MAAM,CAAC,YAAY,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC,CAAA;IACxD,CAAC;IACD,OAAO,OAAO,CAAC,KAAK,CAAA;AACtB,CAAC,CAAC,CACH,CAAA"}