@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,50 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.render = exports.live = exports.make = void 0;
4
+ const effect_1 = require("effect");
5
+ const definition_js_1 = require("../definition/definition.js");
6
+ const track_js_1 = require("../internal/track.js");
7
+ const host_js_1 = require("./host.js");
8
+ const props_js_1 = require("./props.js");
9
+ /**
10
+ * A component's logic. The *definition* (`Composition.make`) is a reflectable
11
+ * manifest that doubles as a requirement/tag; the *implementation*
12
+ * (`Composition.live`) is the synchronous body, provided separately and
13
+ * checked against it.
14
+ */
15
+ const make = (name,
16
+ // Constrain `ui` to the full `UiClass<C>` so `C` is inferred here; the stored
17
+ // manifest still sees only the erased `{ manifest }` carrier (CompositionConfig),
18
+ // so the manifest type — and its variance — is unchanged.
19
+ config) => {
20
+ const tag = effect_1.Context.GenericTag(`reform/composition/${name}`);
21
+ const manifest = { kind: 'Composition', name, ...config };
22
+ return (0, definition_js_1.definitionClass)({ manifest, tag });
23
+ };
24
+ exports.make = make;
25
+ /**
26
+ * Wire a composition's synchronous logic (D2): read state, acquire triggers,
27
+ * resolve the UI, return the view. Its requirements (minus `Props`, which the
28
+ * host injects per render) surface as the Layer's `RIn`; the runtime runs the
29
+ * body per render within the captured context.
30
+ */
31
+ const live = (
32
+ // `live` doesn't use the contract type; accept any composition.
33
+ composition, body) => {
34
+ const logic = effect_1.Effect.gen(body);
35
+ return effect_1.Layer.effect(composition.tag, effect_1.Effect.gen(function* () {
36
+ // Capture the build-time context (state stores, calc, ui, bus). `Props`,
37
+ // the tracker, and slots are injected per render below.
38
+ const context = yield* effect_1.Effect.context();
39
+ const render = (env) =>
40
+ // Total once fully provided: the body is synchronous, reads can't fail,
41
+ // and every requirement is now satisfied (D2). `Effect.gen` widens the
42
+ // error channel to `unknown` for a generic body, so we restate it.
43
+ logic.pipe(effect_1.Effect.provideService(props_js_1.Props, env.props), effect_1.Effect.provideService(track_js_1.CurrentTracker, env.tracker), effect_1.Effect.provideService(host_js_1.CurrentSlots, env.slots), effect_1.Effect.provide(context));
44
+ return { render };
45
+ }));
46
+ };
47
+ exports.live = live;
48
+ /** Run a mounted composition for one frame, producing its node. */
49
+ const render = (service, env) => service.render(env);
50
+ exports.render = render;
@@ -0,0 +1,8 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CurrentSlots = void 0;
4
+ const effect_1 = require("effect");
5
+ /** The active composition's slot bindings, provided per render by the host. */
6
+ class CurrentSlots extends effect_1.Context.Tag('reform/Slots')() {
7
+ }
8
+ exports.CurrentSlots = CurrentSlots;
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.Props = void 0;
4
+ const effect_1 = require("effect");
5
+ /**
6
+ * The current composition instance's props. Bound per render by the runtime; a
7
+ * composition body reads them with `const { todo } = yield* Props`.
8
+ *
9
+ * (Per-instance typing of Props is DESIGN #26 — for now the value is opaque and
10
+ * narrowed at the use site against the composition's declared props schema.)
11
+ */
12
+ class Props extends effect_1.Context.Tag('reform/Props')() {
13
+ }
14
+ exports.Props = Props;
@@ -0,0 +1,30 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.provide = provide;
4
+ const effect_1 = require("effect");
5
+ const errors_js_1 = require("../internal/errors.js");
6
+ const feature_js_1 = require("../feature/feature.js");
7
+ const slot_js_1 = require("./slot.js");
8
+ const ui_js_1 = require("./ui.js");
9
+ function provide(target, impl) {
10
+ // Discriminate the target by its nominal brand, not by which DI-hole property
11
+ // happens to exist: a UI contract provides under its `impl` tag, a slot under
12
+ // its `tag`. Anything else is a wiring mistake. The overloads above pair
13
+ // `impl` with the chosen tag; this implementation sees both erased, so view
14
+ // the tag loosely (the one documented cast) to provide the service under it.
15
+ const tag = ((0, ui_js_1.isUi)(target) ? target.impl : (0, slot_js_1.isSlot)(target) ? target.tag : undefined);
16
+ if (tag === undefined)
17
+ throw new errors_js_1.InvalidProvideTarget();
18
+ if ((0, feature_js_1.isFeature)(impl)) {
19
+ const eager = impl.eagerModule;
20
+ // Lazy: bind the `FeatureBinding`; the host drives load → mount, painting the
21
+ // placeholders. Default: bind the composition (so the existing `Compose` path
22
+ // renders it, no host, no flash) and merge the eager `.live` layer, whose `RIn`
23
+ // surfaces to the scene. Either way the overload's return type carries the
24
+ // shared `RIn`, so the scene still type-demands `Core`.
25
+ return eager === undefined
26
+ ? effect_1.Layer.succeed(tag, impl.binding)
27
+ : effect_1.Layer.merge(effect_1.Layer.succeed(tag, impl.binding.composition), eager.layer);
28
+ }
29
+ return effect_1.Layer.succeed(tag, impl);
30
+ }
@@ -0,0 +1,27 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.slot = exports.isSlot = exports.SlotTypeId = void 0;
4
+ const effect_1 = require("effect");
5
+ const definition_js_1 = require("../definition/definition.js");
6
+ /**
7
+ * A DI hole for a child composition. The parent declares
8
+ * `slot('Item')<typeof TodoItem>()` and renders through it; the concrete child
9
+ * is wired with `provide(Item, TodoItem)`, so the parent never imports the
10
+ * child's *implementation* (the `typeof` is a type-only reference to the
11
+ * definition). `Comp` lives only in the phantom instance (so `SlotClass` is
12
+ * covariant and a `{ Item: ItemSlot }` map is well-typed); the match is enforced
13
+ * by `provide`'s signature, not the (invariant) tag.
14
+ */
15
+ /** Nominal brand identifying a slot at runtime (Effect's `TypeId` idiom). */
16
+ exports.SlotTypeId = Symbol.for('reform/Slot');
17
+ /** Whether a value is a slot — discriminates a `provide` target by brand. */
18
+ const isSlot = (u) => (typeof u === 'function' || typeof u === 'object') && u !== null && exports.SlotTypeId in u;
19
+ exports.isSlot = isSlot;
20
+ const slot = (name) =>
21
+ // Defaulted so a slot whose child carries no meaningful props/contract can be
22
+ // declared bare (`slot('Tree')()`); pass `typeof Child` to type the facade.
23
+ () => {
24
+ const tag = effect_1.Context.GenericTag(`reform/slot/${name}`);
25
+ return (0, definition_js_1.definitionClass)({ [exports.SlotTypeId]: exports.SlotTypeId, kind: 'Slot', tag });
26
+ };
27
+ exports.slot = slot;
@@ -0,0 +1,61 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.make = exports.ui = exports.isUi = exports.UiTypeId = void 0;
4
+ const effect_1 = require("effect");
5
+ const definition_js_1 = require("../definition/definition.js");
6
+ const capture_js_1 = require("../internal/capture.js");
7
+ const errors_js_1 = require("../internal/errors.js");
8
+ const host_js_1 = require("./host.js");
9
+ /** Nominal brand identifying a UI contract at runtime (Effect's `TypeId` idiom). */
10
+ exports.UiTypeId = Symbol.for('reform/Ui');
11
+ /** Whether a value is a UI contract — discriminates a `provide` target by brand. */
12
+ const isUi = (u) => (typeof u === 'function' || typeof u === 'object') && u !== null && exports.UiTypeId in u;
13
+ exports.isUi = isUi;
14
+ /**
15
+ * A renderer-neutral UI contract. The logic resolves it (`yield* TodoAppUi`) to
16
+ * a `(props, events) => node` view with slots already bound; `.make` authors the
17
+ * presentation. Core defines the contract; `@reform/react` does the rendering.
18
+ */
19
+ const ui = (name) => () => {
20
+ const impl = effect_1.Context.GenericTag(`reform/ui/${name}`);
21
+ const read = effect_1.Effect.gen(function* () {
22
+ const render = yield* impl;
23
+ // Slots are bound by the host (`@reform/react`) per composition instance.
24
+ // Core has no renderer, so without a host every slot access throws.
25
+ const host = yield* effect_1.Effect.serviceOption(host_js_1.CurrentSlots);
26
+ const slots = new Proxy({}, {
27
+ get(_t, key) {
28
+ if (effect_1.Option.isNone(host)) {
29
+ throw new errors_js_1.SlotRenderingUnavailable({ slot: String(key) });
30
+ }
31
+ return host.value.slot(String(key));
32
+ },
33
+ });
34
+ // A capturing host (proofs, the dev tool) reports each render's observable
35
+ // surface without replacing the presentation. Absent in production.
36
+ const sink = yield* effect_1.Effect.serviceOption(capture_js_1.CaptureSink);
37
+ return (props, events) => {
38
+ if (effect_1.Option.isSome(sink)) {
39
+ sink.value.record({
40
+ name,
41
+ props,
42
+ events: (events ?? {}),
43
+ });
44
+ }
45
+ return render(props, slots, (events ?? {}));
46
+ };
47
+ });
48
+ return (0, definition_js_1.yieldableClass)(read, {
49
+ [exports.UiTypeId]: exports.UiTypeId,
50
+ manifest: { kind: 'Ui', name },
51
+ impl,
52
+ });
53
+ };
54
+ exports.ui = ui;
55
+ /**
56
+ * Author the pure presentation for a contract — `Ui.make(TodoAppUi, (props,
57
+ * slots, events) => node)`. The contract argument fixes the view's types; wire
58
+ * the result with `provide(contract, view)`.
59
+ */
60
+ const make = (_contract, view) => view;
61
+ exports.make = make;
@@ -0,0 +1,46 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.definitionClass = exports.yieldableClass = void 0;
4
+ const effect_1 = require("effect");
5
+ const inspect_js_1 = require("../internal/inspect.js");
6
+ /** A definition's `toJSON`: its reflectable manifest, else its raw statics. */
7
+ const describe = (statics) => statics.manifest ?? statics;
8
+ /**
9
+ * Build a class whose *static* side is itself an Effect, so `yield* TheClass`
10
+ * runs `read` and returns its value (the same mechanism `Context.Tag` uses).
11
+ * Subclasses inherit the protocol through the prototype chain, so the user's
12
+ * `class FeedState extends State.make(...) {}` is yieldable too.
13
+ *
14
+ * `statics` (manifest, `.live`, tag, …) are attached as own properties
15
+ * and likewise inherited by the subclass.
16
+ */
17
+ const yieldableClass = (read, statics) => {
18
+ class Base {
19
+ }
20
+ Object.setPrototypeOf(Base, read);
21
+ // `defineProperty` over `Reflect.ownKeys`, not `Object.assign` over
22
+ // `Object.entries`: a static can shadow a non-writable own property of the
23
+ // class function (notably `name`, which a `Source`-shaped definition like a
24
+ // Calc carries) and `assign` would throw on those; and `ownKeys` (unlike
25
+ // `entries`) carries symbol-keyed statics — the `TypeId` brands.
26
+ for (const key of Reflect.ownKeys(statics)) {
27
+ const value = statics[key];
28
+ Object.defineProperty(Base, key, { value, writable: true, enumerable: true, configurable: true });
29
+ }
30
+ // Print like an Effect value (the manifest), not `[object Object]`.
31
+ (0, inspect_js_1.attachInspectable)(Base, () => describe(statics));
32
+ return Base;
33
+ };
34
+ exports.yieldableClass = yieldableClass;
35
+ /**
36
+ * Build a *definition class*: an empty constructible carrying static marker data
37
+ * (manifest, tag, policy, members, …) that the editor and proof packages reflect
38
+ * on. Definition interfaces declare phantom, type-only fields — a composition's
39
+ * `Props`, a family instance's `Key` — that exist purely for inference and have
40
+ * no runtime value, so the assembled object cannot *structurally* satisfy the
41
+ * interface. The one assertion to `Class` lives here, documented, instead of a
42
+ * scattered `as never` / `as unknown as` at every `*.make`.
43
+ */
44
+ const definitionClass = (statics) => (0, inspect_js_1.attachInspectable)(Object.assign(class {
45
+ }, statics), () => describe(statics));
46
+ exports.definitionClass = definitionClass;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.trigger = exports.dispatch = exports.construct = exports.make = void 0;
4
+ const effect_1 = require("effect");
5
+ const definition_js_1 = require("../definition/definition.js");
6
+ const bus_js_1 = require("../runtime/bus.js");
7
+ /** A pure data fact. Events depend on nothing — only reducers tie them to state. */
8
+ const make = (name, schema) => {
9
+ const build = (payload) => ({ _tag: name, ...payload });
10
+ const trigger = effect_1.Effect.gen(function* () {
11
+ const bus = yield* bus_js_1.Bus;
12
+ const runtime = yield* effect_1.Effect.runtime();
13
+ // Dispatch synchronously: on the unbounded bus `publish` only enqueues and
14
+ // returns, so `runSync` never suspends and no fiber is forked per UI event.
15
+ // The drain loop still folds reducers on its own fiber — publish is pure offer.
16
+ return (payload) => {
17
+ effect_1.Runtime.runSync(runtime)(effect_1.PubSub.publish(bus, { priority: 'High', event: build(payload) }));
18
+ };
19
+ });
20
+ return (0, definition_js_1.definitionClass)({
21
+ manifest: { kind: 'Event', name, schema },
22
+ tag: name,
23
+ build,
24
+ trigger,
25
+ });
26
+ };
27
+ exports.make = make;
28
+ /** Construct the tagged value for an event (used for `boot` events). */
29
+ const construct = (event, payload) => event.build(payload);
30
+ exports.construct = construct;
31
+ /** Dispatch as a follow-up (Normal priority) from a procedure/effect. */
32
+ const dispatch = (event, payload) => (0, bus_js_1.publish)('Normal', event.build(payload));
33
+ exports.dispatch = dispatch;
34
+ /** A callback for the UI that dispatches at High priority via the runtime. */
35
+ const trigger = (event) => event.trigger;
36
+ exports.trigger = trigger;
@@ -0,0 +1,7 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.make = void 0;
4
+ const definition_js_1 = require("../definition/definition.js");
5
+ /** Compose events into a group, the same variadic shape as `StateGroup`/`RpcGroup`. */
6
+ const make = (...members) => (0, definition_js_1.definitionClass)({ kind: 'EventGroup', members });
7
+ exports.make = make;
@@ -0,0 +1,102 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.mountFeature = exports.make = exports.isFeature = exports.isFeatureBinding = exports.FeatureBindingTypeId = exports.lazyImport = exports.featureModule = void 0;
4
+ const effect_1 = require("effect");
5
+ const errors_js_1 = require("../internal/errors.js");
6
+ const definition_js_1 = require("../definition/definition.js");
7
+ const bus_js_1 = require("../runtime/bus.js");
8
+ /**
9
+ * Publish a feature's lazy half: pair its `requires` (a runtime tuple of shared
10
+ * carriers) with its `layer`. The covariant `RIn` bound does the checking — a
11
+ * layer that reaches for any service outside `EngineServices | ProvidedBy<requires>`
12
+ * is not assignable, so it fails to compile right here, next to the layer, with no
13
+ * cast. Listing an unused carrier is harmless; omitting a needed one is a type error.
14
+ *
15
+ * The bound also forbids a feature from *providing* `EngineServices` (they may only
16
+ * be open `RIn`), structurally enforcing the liveness rule: a feature can never
17
+ * bundle its own engine — it always shares the root's bus and registries.
18
+ */
19
+ const featureModule = (requires, layer) => ({ requires, layer });
20
+ exports.featureModule = featureModule;
21
+ /**
22
+ * Wrap a dynamic `import()` of a feature's `.live` module as an `Effect` — Reform
23
+ * never exposes a Promise/`await` on the feature surface. The unavoidable thenable
24
+ * is sealed here; a rejected import (missing chunk, network failure, module-eval
25
+ * throw) surfaces as a typed `FeatureLoadFailed` the host hands to
26
+ * `placeholder.failed`. The module's default export is its `FeatureModule`.
27
+ */
28
+ const lazyImport = (thunk) => effect_1.Effect.tryPromise({
29
+ try: thunk,
30
+ catch: (cause) => new errors_js_1.FeatureLoadFailed({ cause }),
31
+ }).pipe(effect_1.Effect.map((module) => module.default));
32
+ exports.lazyImport = lazyImport;
33
+ /** Nominal brand identifying the value a `provide(slot, Feature)` puts under a slot tag. */
34
+ exports.FeatureBindingTypeId = Symbol.for('reform/FeatureBinding');
35
+ /** Whether a slot's bound child is a lazy/eager feature (vs a plain composition). */
36
+ const isFeatureBinding = (u) => typeof u === 'object' && u !== null && exports.FeatureBindingTypeId in u;
37
+ exports.isFeatureBinding = isFeatureBinding;
38
+ /** Whether a value is a feature definition (its target shape in `provide(slot, Feature)`). */
39
+ const isFeature = (u) => (typeof u === 'function' || typeof u === 'object') &&
40
+ u !== null &&
41
+ 'manifest' in u &&
42
+ u.manifest?.kind === 'Feature';
43
+ exports.isFeature = isFeature;
44
+ /**
45
+ * Define a feature. The whole-app shape (this manifest, the composition, the
46
+ * placeholders) stays eager and reflectable; the `.live` layer in `module`/`load`
47
+ * is the deferred chunk. Flip `loadingStrategy` from `'default'` to `'lazy'` and
48
+ * the discriminated config *requires* `placeholder` — the compiler walks you to a
49
+ * complete code-split feature.
50
+ */
51
+ const make = (name, config) => {
52
+ const strategy = config.loadingStrategy ?? 'default';
53
+ const load = 'load' in config ? config.load : effect_1.Effect.succeed(config.module);
54
+ const eagerModule = 'module' in config ? config.module : undefined;
55
+ const placeholder = 'placeholder' in config ? config.placeholder : undefined;
56
+ const manifest = {
57
+ kind: 'Feature',
58
+ name,
59
+ strategy,
60
+ composition: config.composition.manifest,
61
+ ...(placeholder
62
+ ? { placeholder: { loading: placeholder.loading.manifest, failed: placeholder.failed.manifest } }
63
+ : {}),
64
+ };
65
+ const binding = {
66
+ [exports.FeatureBindingTypeId]: exports.FeatureBindingTypeId,
67
+ manifest,
68
+ composition: config.composition,
69
+ strategy,
70
+ // The host is strategy-uniform: `default`'s `load` resolves immediately. The
71
+ // assignment to the erased `LoadedModule` needs no cast — see `LoadedModule`.
72
+ load,
73
+ ...(placeholder ? { placeholder: { loading: placeholder.loading, failed: placeholder.failed } } : {}),
74
+ boot: config.boot ?? [],
75
+ };
76
+ return (0, definition_js_1.definitionClass)({ manifest, load, binding, eagerModule });
77
+ };
78
+ exports.make = make;
79
+ /**
80
+ * Mount a feature against a live engine. The renderer-neutral lifecycle, run on a
81
+ * per-feature `Scope`: load the module (an Effect — lazy = dynamic import; default
82
+ * = immediate), build its `.live` layer against the host's live `engineContext`
83
+ * (so its reducers/procedures register into the SHARED registries and its fibers
84
+ * fork onto this scope), then dispatch the feature's `boot`. Returns the merged
85
+ * context — engine services + the feature's own services — for the host to read
86
+ * the feature's composition and stores. Closing the scope disposes exactly this
87
+ * feature: its fibers stop and its stores are reclaimed.
88
+ *
89
+ * The single boundary cast (mirroring `buildRuntime`): `module.layer` is erased to
90
+ * `LoadedModule` so the host stays strategy- and type-uniform. The feature's real
91
+ * `RIn` was verified cast-free at `provide(slot, Feature)` and scene wiring; here
92
+ * we re-attach the concrete `engineContext` it builds against. `R` is the engine
93
+ * context's service set, supplied by the host.
94
+ */
95
+ const mountFeature = (binding, engineContext) => effect_1.Effect.gen(function* () {
96
+ const { layer } = yield* binding.load;
97
+ const featureLayer = layer;
98
+ const context = yield* effect_1.Layer.build(effect_1.Layer.provideMerge(featureLayer, effect_1.Layer.succeedContext(engineContext)));
99
+ yield* effect_1.Effect.forEach(binding.boot, (event) => (0, bus_js_1.publish)('High', event), { discard: true }).pipe(effect_1.Effect.provide(context));
100
+ return context;
101
+ });
102
+ exports.mountFeature = mountFeature;
@@ -0,0 +1,116 @@
1
+ "use strict";
2
+ var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
3
+ if (k2 === undefined) k2 = k;
4
+ var desc = Object.getOwnPropertyDescriptor(m, k);
5
+ if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
6
+ desc = { enumerable: true, get: function() { return m[k]; } };
7
+ }
8
+ Object.defineProperty(o, k2, desc);
9
+ }) : (function(o, m, k, k2) {
10
+ if (k2 === undefined) k2 = k;
11
+ o[k2] = m[k];
12
+ }));
13
+ var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
14
+ Object.defineProperty(o, "default", { enumerable: true, value: v });
15
+ }) : function(o, v) {
16
+ o["default"] = v;
17
+ });
18
+ var __importStar = (this && this.__importStar) || (function () {
19
+ var ownKeys = function(o) {
20
+ ownKeys = Object.getOwnPropertyNames || function (o) {
21
+ var ar = [];
22
+ for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
23
+ return ar;
24
+ };
25
+ return ownKeys(o);
26
+ };
27
+ return function (mod) {
28
+ if (mod && mod.__esModule) return mod;
29
+ var result = {};
30
+ if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
31
+ __setModuleDefault(result, mod);
32
+ return result;
33
+ };
34
+ })();
35
+ Object.defineProperty(exports, "__esModule", { value: true });
36
+ exports.defaultScheduler = exports.UnknownGroupState = exports.SlotRenderingUnavailable = exports.InvalidProvideTarget = exports.FeatureLoadFailed = exports.DuplicateRegistration = exports.AsyncReducer = exports.CaptureSink = exports.CurrentTracker = exports.Procedures = exports.Channels = exports.Reducers = exports.Engine = exports.publish = exports.Bus = exports.seedScene = exports.scene = exports.isScene = exports.mountFeature = exports.lazyImport = exports.isFeatureBinding = exports.isFeature = exports.featureModule = exports.FeatureBindingTypeId = exports.Feature = exports.provide = exports.UiTypeId = exports.ui = exports.isUi = exports.Ui = exports.CurrentSlots = exports.SlotTypeId = exports.slot = exports.isSlot = exports.Props = exports.Composition = exports.Channel = exports.Procedure = exports.Boundary = exports.RemoteState = exports.AsyncCalc = exports.CalcFamily = exports.Calc = exports.Reducer = exports.EventGroup = exports.Event = exports.StateToken = exports.StateFamily = exports.StateGroup = exports.State = void 0;
37
+ exports.notificationsLayer = exports.Notifications = exports.makeScheduler = void 0;
38
+ // Reform core — the renderer-neutral primitives and runtime.
39
+ // Definitions (`X.make`) are separate from implementations (`.live`)
40
+ // throughout, and nothing self-registers on import (principle #1, #6).
41
+ exports.State = __importStar(require("./state/state.js"));
42
+ exports.StateGroup = __importStar(require("./state/stateGroup.js"));
43
+ exports.StateFamily = __importStar(require("./state/stateFamily.js"));
44
+ var token_js_1 = require("./state/token.js");
45
+ Object.defineProperty(exports, "StateToken", { enumerable: true, get: function () { return token_js_1.StateToken; } });
46
+ exports.Event = __importStar(require("./event/event.js"));
47
+ exports.EventGroup = __importStar(require("./event/eventGroup.js"));
48
+ exports.Reducer = __importStar(require("./reducer/reducer.js"));
49
+ exports.Calc = __importStar(require("./calc/calc.js"));
50
+ exports.CalcFamily = __importStar(require("./calc/calcFamily.js"));
51
+ exports.AsyncCalc = __importStar(require("./calc/asyncCalc.js"));
52
+ exports.RemoteState = __importStar(require("./remote/remoteState.js"));
53
+ exports.Boundary = __importStar(require("./boundary/boundary.js"));
54
+ exports.Procedure = __importStar(require("./procedure/procedure.js"));
55
+ exports.Channel = __importStar(require("./channel/channel.js"));
56
+ exports.Composition = __importStar(require("./compose/composition.js"));
57
+ var props_js_1 = require("./compose/props.js");
58
+ Object.defineProperty(exports, "Props", { enumerable: true, get: function () { return props_js_1.Props; } });
59
+ var slot_js_1 = require("./compose/slot.js");
60
+ Object.defineProperty(exports, "isSlot", { enumerable: true, get: function () { return slot_js_1.isSlot; } });
61
+ Object.defineProperty(exports, "slot", { enumerable: true, get: function () { return slot_js_1.slot; } });
62
+ Object.defineProperty(exports, "SlotTypeId", { enumerable: true, get: function () { return slot_js_1.SlotTypeId; } });
63
+ var host_js_1 = require("./compose/host.js");
64
+ Object.defineProperty(exports, "CurrentSlots", { enumerable: true, get: function () { return host_js_1.CurrentSlots; } });
65
+ exports.Ui = __importStar(require("./compose/ui.js"));
66
+ var ui_js_1 = require("./compose/ui.js");
67
+ Object.defineProperty(exports, "isUi", { enumerable: true, get: function () { return ui_js_1.isUi; } });
68
+ Object.defineProperty(exports, "ui", { enumerable: true, get: function () { return ui_js_1.ui; } });
69
+ Object.defineProperty(exports, "UiTypeId", { enumerable: true, get: function () { return ui_js_1.UiTypeId; } });
70
+ var provide_js_1 = require("./compose/provide.js");
71
+ Object.defineProperty(exports, "provide", { enumerable: true, get: function () { return provide_js_1.provide; } });
72
+ // Feature: the lazy/eager code-split unit. Definitions stay eager and reflectable;
73
+ // the heavy `.live` layer loads on demand (an Effect, never a Promise). See LAZY.md.
74
+ exports.Feature = __importStar(require("./feature/feature.js"));
75
+ var feature_js_1 = require("./feature/feature.js");
76
+ Object.defineProperty(exports, "FeatureBindingTypeId", { enumerable: true, get: function () { return feature_js_1.FeatureBindingTypeId; } });
77
+ Object.defineProperty(exports, "featureModule", { enumerable: true, get: function () { return feature_js_1.featureModule; } });
78
+ Object.defineProperty(exports, "isFeature", { enumerable: true, get: function () { return feature_js_1.isFeature; } });
79
+ Object.defineProperty(exports, "isFeatureBinding", { enumerable: true, get: function () { return feature_js_1.isFeatureBinding; } });
80
+ Object.defineProperty(exports, "lazyImport", { enumerable: true, get: function () { return feature_js_1.lazyImport; } });
81
+ Object.defineProperty(exports, "mountFeature", { enumerable: true, get: function () { return feature_js_1.mountFeature; } });
82
+ // A scene bundles a composition with the closed wiring that runs it — the single
83
+ // handle the react host, proofs, and the dev tool all consume.
84
+ var scene_js_1 = require("./scene/scene.js");
85
+ Object.defineProperty(exports, "isScene", { enumerable: true, get: function () { return scene_js_1.isScene; } });
86
+ Object.defineProperty(exports, "scene", { enumerable: true, get: function () { return scene_js_1.scene; } });
87
+ Object.defineProperty(exports, "seedScene", { enumerable: true, get: function () { return scene_js_1.seedScene; } });
88
+ // Runtime surface for hosts (`@reform/react`) and headless tests.
89
+ var bus_js_1 = require("./runtime/bus.js");
90
+ Object.defineProperty(exports, "Bus", { enumerable: true, get: function () { return bus_js_1.Bus; } });
91
+ Object.defineProperty(exports, "publish", { enumerable: true, get: function () { return bus_js_1.publish; } });
92
+ var loop_js_1 = require("./runtime/loop.js");
93
+ Object.defineProperty(exports, "Engine", { enumerable: true, get: function () { return loop_js_1.Engine; } });
94
+ Object.defineProperty(exports, "Reducers", { enumerable: true, get: function () { return loop_js_1.Reducers; } });
95
+ var channel_js_1 = require("./channel/channel.js");
96
+ Object.defineProperty(exports, "Channels", { enumerable: true, get: function () { return channel_js_1.Channels; } });
97
+ Object.defineProperty(exports, "Procedures", { enumerable: true, get: function () { return channel_js_1.Procedures; } });
98
+ var track_js_1 = require("./internal/track.js");
99
+ Object.defineProperty(exports, "CurrentTracker", { enumerable: true, get: function () { return track_js_1.CurrentTracker; } });
100
+ var capture_js_1 = require("./internal/capture.js");
101
+ Object.defineProperty(exports, "CaptureSink", { enumerable: true, get: function () { return capture_js_1.CaptureSink; } });
102
+ var errors_js_1 = require("./internal/errors.js");
103
+ Object.defineProperty(exports, "AsyncReducer", { enumerable: true, get: function () { return errors_js_1.AsyncReducer; } });
104
+ Object.defineProperty(exports, "DuplicateRegistration", { enumerable: true, get: function () { return errors_js_1.DuplicateRegistration; } });
105
+ Object.defineProperty(exports, "FeatureLoadFailed", { enumerable: true, get: function () { return errors_js_1.FeatureLoadFailed; } });
106
+ Object.defineProperty(exports, "InvalidProvideTarget", { enumerable: true, get: function () { return errors_js_1.InvalidProvideTarget; } });
107
+ Object.defineProperty(exports, "SlotRenderingUnavailable", { enumerable: true, get: function () { return errors_js_1.SlotRenderingUnavailable; } });
108
+ Object.defineProperty(exports, "UnknownGroupState", { enumerable: true, get: function () { return errors_js_1.UnknownGroupState; } });
109
+ // Notification scheduler: hosts that need per-runtime isolation (concurrent SSR,
110
+ // multiple mounted roots) provide `Notifications` upstream of their state layers;
111
+ // everything else coalesces on the process-wide default.
112
+ var scheduler_js_1 = require("./internal/scheduler.js");
113
+ Object.defineProperty(exports, "defaultScheduler", { enumerable: true, get: function () { return scheduler_js_1.defaultScheduler; } });
114
+ Object.defineProperty(exports, "makeScheduler", { enumerable: true, get: function () { return scheduler_js_1.makeScheduler; } });
115
+ Object.defineProperty(exports, "Notifications", { enumerable: true, get: function () { return scheduler_js_1.Notifications; } });
116
+ Object.defineProperty(exports, "notificationsLayer", { enumerable: true, get: function () { return scheduler_js_1.notificationsLayer; } });
@@ -0,0 +1,14 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.CaptureSink = void 0;
4
+ const effect_1 = require("effect");
5
+ /**
6
+ * An OPTIONAL service. Core's `ui` read consults it via `serviceOption`: when a
7
+ * capturing host provides it (proofs, the dev tool), every resolved view reports
8
+ * its `(props, events)` before rendering, giving a faithful tree without
9
+ * replacing any presentation. Production never provides it, so nothing is
10
+ * recorded and there is no cost beyond one `serviceOption` lookup per render.
11
+ */
12
+ class CaptureSink extends effect_1.Context.Tag('reform/internal/CaptureSink')() {
13
+ }
14
+ exports.CaptureSink = CaptureSink;
@@ -0,0 +1,2 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
@@ -0,0 +1,62 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.DuplicateRegistration = exports.AsyncReducer = exports.FeatureLoadFailed = exports.UnknownGroupState = exports.InvalidProvideTarget = exports.SlotRenderingUnavailable = void 0;
4
+ const effect_1 = require("effect");
5
+ /**
6
+ * Tagged errors for the framework's synchronous boundaries. Even when thrown
7
+ * (React render, layer build, reflection), an error carries a `_tag` and its
8
+ * structured fields — never a bare `Error` — so callers and tooling can match on
9
+ * it. `Data.TaggedError` subclasses are real `Error`s, so `throw` still works.
10
+ */
11
+ /** A `<slots.X/>` was rendered without a render-target host to realize it. */
12
+ class SlotRenderingUnavailable extends effect_1.Data.TaggedError('reform/SlotRenderingUnavailable') {
13
+ get message() {
14
+ return `reform: rendering slot '${this.slot}' requires @reform/react`;
15
+ }
16
+ }
17
+ exports.SlotRenderingUnavailable = SlotRenderingUnavailable;
18
+ /** `provide(target, …)` was handed something that is neither a ui contract nor a slot. */
19
+ class InvalidProvideTarget extends effect_1.Data.TaggedError('reform/InvalidProvideTarget') {
20
+ get message() {
21
+ return 'reform: provide target is neither a ui contract nor a slot';
22
+ }
23
+ }
24
+ exports.InvalidProvideTarget = InvalidProvideTarget;
25
+ /** `StateGroup.select(group, name)` named a state the group does not contain. */
26
+ class UnknownGroupState extends effect_1.Data.TaggedError('reform/UnknownGroupState') {
27
+ get message() {
28
+ return `reform: unknown state '${this.name}' in group`;
29
+ }
30
+ }
31
+ exports.UnknownGroupState = UnknownGroupState;
32
+ /**
33
+ * A lazy `Feature`'s `load` Effect failed — the dynamic `import()` rejected (a
34
+ * missing chunk, a network failure, a module-eval throw). Surfaced as a typed
35
+ * failure the host hands to the feature's `placeholder.failed`, never a bare
36
+ * rejection. `cause` is the original rejection value.
37
+ */
38
+ class FeatureLoadFailed extends effect_1.Data.TaggedError('reform/FeatureLoadFailed') {
39
+ get message() {
40
+ return `reform: a feature failed to load (${String(this.cause)})`;
41
+ }
42
+ }
43
+ exports.FeatureLoadFailed = FeatureLoadFailed;
44
+ /** A reducer fold returned a thenable — folds must be pure synchronous writes. */
45
+ class AsyncReducer extends effect_1.Data.TaggedError('reform/AsyncReducer') {
46
+ get message() {
47
+ return 'reform: a reducer fold must be synchronous (it returned a Promise)';
48
+ }
49
+ }
50
+ exports.AsyncReducer = AsyncReducer;
51
+ /**
52
+ * Two distinct primitives were registered under one name into the same runtime —
53
+ * a silent footgun, since names key DI tags and channel lanes. Thrown for a
54
+ * channel name reused with a different policy (the second would otherwise be
55
+ * dropped). Reducer/procedure name clashes are warned (logged), not thrown.
56
+ */
57
+ class DuplicateRegistration extends effect_1.Data.TaggedError('reform/DuplicateRegistration') {
58
+ get message() {
59
+ return `reform: duplicate ${this.kind} registered under name '${this.name}'`;
60
+ }
61
+ }
62
+ exports.DuplicateRegistration = DuplicateRegistration;
@@ -0,0 +1,36 @@
1
+ "use strict";
2
+ Object.defineProperty(exports, "__esModule", { value: true });
3
+ exports.attachInspectable = exports.inspectable = exports.NodeInspectSymbol = void 0;
4
+ const Inspectable_1 = require("effect/Inspectable");
5
+ Object.defineProperty(exports, "NodeInspectSymbol", { enumerable: true, get: function () { return Inspectable_1.NodeInspectSymbol; } });
6
+ /**
7
+ * The `Inspectable` trio built around a `toJSON`, so every reform value prints
8
+ * like an Effect value — `_id`-tagged JSON under `console.log`, Node's
9
+ * inspector, `JSON.stringify`, and `String(...)` — instead of `[object Object]`.
10
+ * Mirrors Effect's `BaseProto` / `Inspectable.Class` (`Inspectable.ts:170`).
11
+ */
12
+ const inspectable = (toJSON) => ({
13
+ toJSON,
14
+ toString: () => (0, Inspectable_1.format)(toJSON()),
15
+ [Inspectable_1.NodeInspectSymbol]: () => toJSON(),
16
+ });
17
+ exports.inspectable = inspectable;
18
+ /**
19
+ * Attach the `Inspectable` trio to an existing object as *non-enumerable* own
20
+ * properties (so they don't show up in `Object.keys`/`for…in` over a definition
21
+ * class). Used where the value is built by other means — the definition classes,
22
+ * whose statics are merged in separately.
23
+ */
24
+ const attachInspectable = (target, toJSON) => {
25
+ const trio = (0, exports.inspectable)(toJSON);
26
+ for (const key of Reflect.ownKeys(trio)) {
27
+ Object.defineProperty(target, key, {
28
+ value: trio[key],
29
+ enumerable: false,
30
+ writable: true,
31
+ configurable: true,
32
+ });
33
+ }
34
+ return target;
35
+ };
36
+ exports.attachInspectable = attachInspectable;