fibrae 0.1.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (70) hide show
  1. package/dist/components.d.ts +40 -0
  2. package/dist/components.js +63 -0
  3. package/dist/components.js.map +1 -0
  4. package/dist/core.d.ts +25 -0
  5. package/dist/core.js +46 -0
  6. package/dist/core.js.map +1 -0
  7. package/dist/dom.d.ts +16 -0
  8. package/dist/dom.js +67 -0
  9. package/dist/dom.js.map +1 -0
  10. package/dist/fiber-render.d.ts +33 -0
  11. package/dist/fiber-render.js +1069 -0
  12. package/dist/fiber-render.js.map +1 -0
  13. package/dist/h.d.ts +19 -0
  14. package/dist/h.js +26 -0
  15. package/dist/h.js.map +1 -0
  16. package/dist/hydration.d.ts +30 -0
  17. package/dist/hydration.js +375 -0
  18. package/dist/hydration.js.map +1 -0
  19. package/dist/index.d.ts +26 -0
  20. package/dist/index.js +28 -0
  21. package/dist/index.js.map +1 -0
  22. package/dist/jsx-runtime/index.d.ts +29 -0
  23. package/dist/jsx-runtime/index.js +61 -0
  24. package/dist/jsx-runtime/index.js.map +1 -0
  25. package/dist/render.d.ts +19 -0
  26. package/dist/render.js +325 -0
  27. package/dist/render.js.map +1 -0
  28. package/dist/router/History.d.ts +129 -0
  29. package/dist/router/History.js +241 -0
  30. package/dist/router/History.js.map +1 -0
  31. package/dist/router/Link.d.ts +52 -0
  32. package/dist/router/Link.js +131 -0
  33. package/dist/router/Link.js.map +1 -0
  34. package/dist/router/Navigator.d.ts +108 -0
  35. package/dist/router/Navigator.js +225 -0
  36. package/dist/router/Navigator.js.map +1 -0
  37. package/dist/router/Route.d.ts +65 -0
  38. package/dist/router/Route.js +143 -0
  39. package/dist/router/Route.js.map +1 -0
  40. package/dist/router/Router.d.ts +167 -0
  41. package/dist/router/Router.js +328 -0
  42. package/dist/router/Router.js.map +1 -0
  43. package/dist/router/RouterBuilder.d.ts +128 -0
  44. package/dist/router/RouterBuilder.js +112 -0
  45. package/dist/router/RouterBuilder.js.map +1 -0
  46. package/dist/router/RouterOutlet.d.ts +57 -0
  47. package/dist/router/RouterOutlet.js +132 -0
  48. package/dist/router/RouterOutlet.js.map +1 -0
  49. package/dist/router/RouterState.d.ts +102 -0
  50. package/dist/router/RouterState.js +94 -0
  51. package/dist/router/RouterState.js.map +1 -0
  52. package/dist/router/index.d.ts +28 -0
  53. package/dist/router/index.js +31 -0
  54. package/dist/router/index.js.map +1 -0
  55. package/dist/runtime.d.ts +55 -0
  56. package/dist/runtime.js +68 -0
  57. package/dist/runtime.js.map +1 -0
  58. package/dist/scope-utils.d.ts +14 -0
  59. package/dist/scope-utils.js +29 -0
  60. package/dist/scope-utils.js.map +1 -0
  61. package/dist/server.d.ts +112 -0
  62. package/dist/server.js +313 -0
  63. package/dist/server.js.map +1 -0
  64. package/dist/shared.d.ts +136 -0
  65. package/dist/shared.js +53 -0
  66. package/dist/shared.js.map +1 -0
  67. package/dist/tracking.d.ts +23 -0
  68. package/dist/tracking.js +53 -0
  69. package/dist/tracking.js.map +1 -0
  70. package/package.json +62 -0
package/dist/index.js ADDED
@@ -0,0 +1,28 @@
1
+ // =============================================================================
2
+ // Public API
3
+ // =============================================================================
4
+ // Main render function
5
+ export { render } from "./core.js";
6
+ // Runtime
7
+ export { FibraeRuntime, CustomAtomRegistryLayer } from "./runtime.js";
8
+ // Built-in components
9
+ export { Suspense, ErrorBoundary } from "./components.js";
10
+ // Element creation (JSX factory)
11
+ export { h, createTextElement } from "./h.js";
12
+ // Re-export upstream Effect Atom APIs for consumers
13
+ export { Atom, Registry as AtomRegistry } from "@effect-atom/atom";
14
+ // Router
15
+ export * as Route from "./router/Route.js";
16
+ export * as Router from "./router/Router.js";
17
+ export * as RouterBuilder from "./router/RouterBuilder.js";
18
+ export * as History from "./router/History.js";
19
+ export * as Navigator from "./router/Navigator.js";
20
+ export * as RouterState from "./router/RouterState.js";
21
+ export { RouterHandlers } from "./router/RouterBuilder.js";
22
+ export { History as HistoryTag, BrowserHistoryLive, MemoryHistoryLive } from "./router/History.js";
23
+ export { Navigator as NavigatorTag, NavigatorLive } from "./router/Navigator.js";
24
+ export { createLink } from "./router/Link.js";
25
+ export { RouterOutlet } from "./router/RouterOutlet.js";
26
+ export { CurrentRouteElement } from "./router/Router.js";
27
+ export { RouterStateAtom, RouterStateService, RouterStateSchema, getRouterState, getLoaderData, getRouteParams, } from "./router/RouterState.js";
28
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAAA,gFAAgF;AAChF,aAAa;AACb,gFAAgF;AAEhF,uBAAuB;AACvB,OAAO,EAAE,MAAM,EAAE,MAAM,WAAW,CAAC;AAEnC,UAAU;AACV,OAAO,EAAE,aAAa,EAAE,uBAAuB,EAAE,MAAM,cAAc,CAAC;AAEtE,sBAAsB;AACtB,OAAO,EAAE,QAAQ,EAAE,aAAa,EAAE,MAAM,iBAAiB,CAAC;AAE1D,iCAAiC;AACjC,OAAO,EAAE,CAAC,EAAE,iBAAiB,EAAE,MAAM,QAAQ,CAAC;AAM9C,oDAAoD;AACpD,OAAO,EAAE,IAAI,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AAEnE,SAAS;AACT,OAAO,KAAK,KAAK,MAAM,mBAAmB,CAAC;AAC3C,OAAO,KAAK,MAAM,MAAM,oBAAoB,CAAC;AAC7C,OAAO,KAAK,aAAa,MAAM,2BAA2B,CAAC;AAC3D,OAAO,KAAK,OAAO,MAAM,qBAAqB,CAAC;AAC/C,OAAO,KAAK,SAAS,MAAM,uBAAuB,CAAC;AACnD,OAAO,KAAK,WAAW,MAAM,yBAAyB,CAAC;AAUvD,OAAO,EAAE,cAAc,EAAE,MAAM,2BAA2B,CAAC;AAG3D,OAAO,EAAE,OAAO,IAAI,UAAU,EAAE,kBAAkB,EAAE,iBAAiB,EAAE,MAAM,qBAAqB,CAAC;AAGnG,OAAO,EAAE,SAAS,IAAI,YAAY,EAAE,aAAa,EAAE,MAAM,uBAAuB,CAAC;AAGjF,OAAO,EAAE,UAAU,EAAE,MAAM,kBAAkB,CAAC;AAG9C,OAAO,EAAE,YAAY,EAAE,MAAM,0BAA0B,CAAC;AAQxD,OAAO,EAAE,mBAAmB,EAAE,MAAM,oBAAoB,CAAC;AAEzD,OAAO,EACL,eAAe,EACf,kBAAkB,EAClB,iBAAiB,EACjB,cAAc,EACd,aAAa,EACb,cAAc,GACf,MAAM,yBAAyB,CAAC"}
@@ -0,0 +1,29 @@
1
+ import type * as Effect from "effect/Effect";
2
+ import type * as Stream from "effect/Stream";
3
+ import type { VElement } from "../shared.js";
4
+ export declare const Fragment: "FRAGMENT";
5
+ export type FragmentType = typeof Fragment;
6
+ export type JSXType = typeof Fragment | ((props: object) => VElement | Stream.Stream<VElement> | Effect.Effect<VElement>);
7
+ export type PropsWithChildren<T = object> = T & {
8
+ children?: VElement | string | (VElement | string)[];
9
+ };
10
+ export declare function jsx(type: JSXType, props: PropsWithChildren<{
11
+ [key: string]: unknown;
12
+ }> | null, ...children: (VElement | string)[]): VElement;
13
+ export declare const jsxs: typeof jsx;
14
+ export declare const jsxDEV: typeof jsx;
15
+ export declare const h: typeof jsx;
16
+ declare global {
17
+ namespace JSX {
18
+ type Element = any;
19
+ interface IntrinsicElements {
20
+ [elemName: string]: any;
21
+ }
22
+ interface IntrinsicAttributes {
23
+ key?: string | number;
24
+ }
25
+ interface ElementChildrenAttribute {
26
+ children: {};
27
+ }
28
+ }
29
+ }
@@ -0,0 +1,61 @@
1
+ // A simple Fragment support for Fibrae
2
+ export const Fragment = "FRAGMENT";
3
+ function createTextElement(text) {
4
+ return {
5
+ type: "TEXT_ELEMENT",
6
+ props: {
7
+ nodeValue: String(text),
8
+ children: [],
9
+ },
10
+ };
11
+ }
12
+ function normalizeChild(child) {
13
+ if (child === null || child === undefined || typeof child === "boolean") {
14
+ return null;
15
+ }
16
+ if (typeof child === "string" || typeof child === "number" || typeof child === "bigint") {
17
+ return createTextElement(child);
18
+ }
19
+ // Handle arrays of children
20
+ if (Array.isArray(child)) {
21
+ return child.flatMap(c => {
22
+ const normalized = normalizeChild(c);
23
+ return normalized === null ? [] : Array.isArray(normalized) ? normalized : [normalized];
24
+ });
25
+ }
26
+ // Assume it's an already properly shaped VElement
27
+ return child;
28
+ }
29
+ export function jsx(type, props, ...children) {
30
+ const normalizedProps = props ?? {};
31
+ let finalChildren = [];
32
+ // Prefer children from props (automatic JSX runtime) over rest args (classic runtime)
33
+ if (normalizedProps.children !== undefined) {
34
+ const ch = normalizedProps.children;
35
+ const arr = Array.isArray(ch) ? ch : [ch];
36
+ finalChildren = arr.flatMap(child => {
37
+ const normalized = normalizeChild(child);
38
+ return normalized === null ? [] : Array.isArray(normalized) ? normalized : [normalized];
39
+ });
40
+ }
41
+ else if (children.length > 0) {
42
+ // Fall back to rest args for classic JSX runtime
43
+ finalChildren = children.flatMap(child => {
44
+ const normalized = normalizeChild(child);
45
+ return normalized === null ? [] : Array.isArray(normalized) ? normalized : [normalized];
46
+ });
47
+ }
48
+ return {
49
+ type: type,
50
+ props: {
51
+ ...normalizedProps,
52
+ children: finalChildren,
53
+ },
54
+ };
55
+ }
56
+ export const jsxs = jsx;
57
+ // Development mode JSX transform (used by Bun and other tools)
58
+ export const jsxDEV = jsx;
59
+ // Alias for classic JSX transform (used by esbuild)
60
+ export const h = jsx;
61
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/jsx-runtime/index.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,19 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Scope from "effect/Scope";
3
+ import { type VElement } from "./shared.js";
4
+ import { FibraeRuntime } from "./runtime.js";
5
+ /**
6
+ * Recursively render a VElement tree to DOM.
7
+ * This is the core rendering function that handles:
8
+ * - Function components (with stream subscriptions and atom reactivity)
9
+ * - Host elements (DOM nodes)
10
+ * - Text elements
11
+ * - Fragments
12
+ * - Error boundaries
13
+ *
14
+ * @param vElement - Virtual element to render
15
+ * @param parent - Parent DOM node to append to
16
+ * @param runtime - Fibrae runtime instance
17
+ * @param parentScope - Optional scope for registering cleanup (used for proper DOM node removal)
18
+ */
19
+ export declare const renderVElementToDOM: (vElement: VElement, parent: Node, runtime: FibraeRuntime, parentScope?: Scope.Scope.Closeable) => Effect.Effect<void, unknown, never>;
package/dist/render.js ADDED
@@ -0,0 +1,325 @@
1
+ import * as Effect from "effect/Effect";
2
+ import * as Stream from "effect/Stream";
3
+ import * as Sink from "effect/Sink";
4
+ import * as Scope from "effect/Scope";
5
+ import * as Exit from "effect/Exit";
6
+ import * as Ref from "effect/Ref";
7
+ import * as Option from "effect/Option";
8
+ import * as Fiber from "effect/Fiber";
9
+ import * as Deferred from "effect/Deferred";
10
+ import * as Context from "effect/Context";
11
+ import * as FiberRef from "effect/FiberRef";
12
+ import { Atom, Registry as AtomRegistry } from "@effect-atom/atom";
13
+ import {} from "./shared.js";
14
+ import { FibraeRuntime, runForkWithRuntime } from "./runtime.js";
15
+ import { setDomProperty, attachEventListeners, isProperty } from "./dom.js";
16
+ import { normalizeToStream, makeTrackingRegistry, subscribeToAtoms } from "./tracking.js";
17
+ import { clearContentScope, registerNodeCleanup } from "./scope-utils.js";
18
+ import { ErrorBoundaryChannel } from "./components.js";
19
+ import { h } from "./h.js";
20
+ // =============================================================================
21
+ // Type Guards
22
+ // =============================================================================
23
+ /**
24
+ * Check if a type is a function component
25
+ */
26
+ const isFunctionComponent = (type) => typeof type === "function";
27
+ /**
28
+ * Check if a type is a host element (string tag)
29
+ */
30
+ const isHostElement = (type) => typeof type === "string";
31
+ // =============================================================================
32
+ // Render Implementation
33
+ // =============================================================================
34
+ /**
35
+ * Recursively render a VElement tree to DOM.
36
+ * This is the core rendering function that handles:
37
+ * - Function components (with stream subscriptions and atom reactivity)
38
+ * - Host elements (DOM nodes)
39
+ * - Text elements
40
+ * - Fragments
41
+ * - Error boundaries
42
+ *
43
+ * @param vElement - Virtual element to render
44
+ * @param parent - Parent DOM node to append to
45
+ * @param runtime - Fibrae runtime instance
46
+ * @param parentScope - Optional scope for registering cleanup (used for proper DOM node removal)
47
+ */
48
+ export const renderVElementToDOM = (vElement, parent, runtime, parentScope) => Effect.gen(function* () {
49
+ const type = vElement.type;
50
+ if (isFunctionComponent(type)) {
51
+ // Function component - create wrapper and subscribe to its stream
52
+ const wrapper = document.createElement("span");
53
+ wrapper.style.display = "contents";
54
+ parent.appendChild(wrapper);
55
+ // Register wrapper cleanup with parent scope if provided
56
+ if (parentScope) {
57
+ yield* registerNodeCleanup(wrapper, parentScope);
58
+ }
59
+ // Component scope - for atom subscriptions and stream subscriptions
60
+ const componentScope = yield* Scope.make();
61
+ // Content scope ref - for rendered children (can be cleared/recreated on re-render)
62
+ const initialContentScope = yield* Scope.make();
63
+ const contentScopeRef = yield* Ref.make(initialContentScope);
64
+ const accessedAtoms = new Set();
65
+ const trackingRegistry = makeTrackingRegistry(runtime.registry, accessedAtoms);
66
+ // Capture current runtime context (includes user services like ThemeService, UserService)
67
+ // FiberRef.currentContext gives us the actual runtime context regardless of static types
68
+ // We add our tracking registry to override AtomRegistry while preserving other services
69
+ const currentContext = yield* FiberRef.get(FiberRef.currentContext);
70
+ const contextWithTracking = Context.add(currentContext, AtomRegistry.AtomRegistry, trackingRegistry);
71
+ // Invoke component - use Effect.try to catch sync render-time crashes
72
+ const output = yield* Effect.try({
73
+ try: () => type(vElement.props),
74
+ catch: (e) => e
75
+ }).pipe(Effect.tapError(() => Effect.sync(() => parent.removeChild(wrapper))));
76
+ // Normalize to stream and provide context (with tracking registry) to it
77
+ // This ensures user-provided services like ThemeService are available to component Effects
78
+ const stream = normalizeToStream(output).pipe(Stream.provideContext(contextWithTracking));
79
+ // Use Stream.peel to properly separate first emission from remaining stream
80
+ // Provide componentScope so the remaining stream stays valid for the component's lifetime
81
+ const peelResult = yield* Effect.either(Effect.gen(function* () {
82
+ const [maybeFirst, remainingStream] = yield* Stream.peel(stream, Sink.head()).pipe(Effect.provideService(Scope.Scope, componentScope));
83
+ if (Option.isNone(maybeFirst)) {
84
+ // Empty stream - nothing to render
85
+ return { rendered: false };
86
+ }
87
+ const contentScope = yield* Ref.get(contentScopeRef);
88
+ yield* renderVElementToDOM(maybeFirst.value, wrapper, runtime, contentScope);
89
+ // Subscribe to atom changes for reactivity
90
+ if (accessedAtoms.size > 0) {
91
+ yield* subscribeToAtoms(accessedAtoms, () => {
92
+ // Queue re-render on atom change
93
+ runForkWithRuntime(runtime)(Effect.gen(function* () {
94
+ // Capture focus state before re-render
95
+ const activeElement = document.activeElement;
96
+ const hasFocusInWrapper = activeElement && wrapper.contains(activeElement);
97
+ const focusData = hasFocusInWrapper && activeElement ? {
98
+ tagName: activeElement.tagName,
99
+ dataAttributes: Object.fromEntries(Array.from(activeElement.attributes)
100
+ .filter(attr => attr.name.startsWith("data-"))
101
+ .map(attr => [attr.name, attr.value])),
102
+ name: activeElement.getAttribute("name"),
103
+ id: activeElement.id,
104
+ selectionStart: "selectionStart" in activeElement ? activeElement.selectionStart : null,
105
+ selectionEnd: "selectionEnd" in activeElement ? activeElement.selectionEnd : null,
106
+ } : null;
107
+ // Clear old content via scope (triggers finalizers, removes DOM nodes)
108
+ const newContentScope = yield* clearContentScope(contentScopeRef);
109
+ const newAccessedAtoms = new Set();
110
+ const newTrackingRegistry = makeTrackingRegistry(runtime.registry, newAccessedAtoms);
111
+ // Re-use captured context but with new tracking registry
112
+ const newContextWithTracking = Context.add(currentContext, AtomRegistry.AtomRegistry, newTrackingRegistry);
113
+ // Invoke component - use Effect.try to catch sync render-time crashes
114
+ const newOutput = yield* Effect.try({
115
+ try: () => type(vElement.props),
116
+ catch: (e) => e
117
+ });
118
+ const newStream = normalizeToStream(newOutput).pipe(Stream.provideContext(newContextWithTracking));
119
+ yield* Stream.runForEach(newStream, (reEmitted) => renderVElementToDOM(reEmitted, wrapper, runtime, newContentScope).pipe(Effect.catchAll((e) => Effect.logError("Re-render child error", e))));
120
+ // Restore focus after re-render
121
+ if (focusData) {
122
+ const candidates = wrapper.querySelectorAll(focusData.tagName);
123
+ for (const candidate of candidates) {
124
+ const el = candidate;
125
+ // Match by id first, then name, then data attributes
126
+ const matchById = focusData.id && el.id === focusData.id;
127
+ const matchByName = focusData.name && el.getAttribute("name") === focusData.name;
128
+ const matchByData = Object.entries(focusData.dataAttributes).length > 0 &&
129
+ Object.entries(focusData.dataAttributes).every(([attr, value]) => el.getAttribute(attr) === value);
130
+ if (matchById || matchByName || matchByData) {
131
+ el.focus();
132
+ // Restore cursor position for inputs/textareas
133
+ if (focusData.selectionStart !== null && "setSelectionRange" in el) {
134
+ el.setSelectionRange(focusData.selectionStart, focusData.selectionEnd ?? focusData.selectionStart);
135
+ }
136
+ break;
137
+ }
138
+ }
139
+ }
140
+ }).pipe(
141
+ // Provide captured context to re-render fiber so services (Navigator, etc.) are available
142
+ Effect.provide(currentContext), Effect.catchAllCause((cause) => Effect.logError("Re-render error", cause))));
143
+ }, runtime, componentScope);
144
+ }
145
+ // Fork subscription for remaining emissions
146
+ // Try to report stream errors to error boundary channel if available
147
+ const maybeErrorChannel = Context.getOption(currentContext, ErrorBoundaryChannel);
148
+ const streamErrorHandler = Option.match(maybeErrorChannel, {
149
+ onNone: () => (cause) => Effect.logError("Component stream error (no boundary)", cause),
150
+ onSome: (channel) => (cause) => channel.reportError(cause)
151
+ });
152
+ const subscription = Stream.runForEach(remainingStream, (emitted) => Effect.gen(function* () {
153
+ // Clear old content via scope
154
+ const newContentScope = yield* clearContentScope(contentScopeRef);
155
+ yield* renderVElementToDOM(emitted, wrapper, runtime, newContentScope).pipe(Effect.catchAll((e) => Effect.logError("Stream emission render error", e)));
156
+ })).pipe(Effect.catchAllCause(streamErrorHandler));
157
+ yield* Effect.forkIn(subscription, componentScope);
158
+ return { rendered: true };
159
+ }));
160
+ if (peelResult._tag === "Left") {
161
+ // Stream error before/during first emission - propagate
162
+ const contentScope = yield* Ref.get(contentScopeRef);
163
+ yield* Scope.close(contentScope, Exit.void);
164
+ yield* Scope.close(componentScope, Exit.void);
165
+ parent.removeChild(wrapper);
166
+ return yield* Effect.fail(peelResult.left);
167
+ }
168
+ }
169
+ else if (type === "TEXT_ELEMENT") {
170
+ // Text node
171
+ const textNode = document.createTextNode(String(vElement.props.nodeValue ?? ""));
172
+ parent.appendChild(textNode);
173
+ // Register text node cleanup with parent scope if provided
174
+ if (parentScope) {
175
+ yield* registerNodeCleanup(textNode, parentScope);
176
+ }
177
+ }
178
+ else if (type === "FRAGMENT") {
179
+ // Fragment - render children directly into parent (propagate errors)
180
+ const children = vElement.props.children ?? [];
181
+ for (const child of children) {
182
+ yield* renderVElementToDOM(child, parent, runtime, parentScope);
183
+ }
184
+ }
185
+ else if (type === "ERROR_BOUNDARY") {
186
+ // Error boundary - wrap child rendering in error catching
187
+ // Also catches async errors from event handlers and streams via ErrorBoundaryChannel
188
+ const wrapper = document.createElement("span");
189
+ wrapper.style.display = "contents";
190
+ parent.appendChild(wrapper);
191
+ // Register wrapper cleanup with parent scope if provided
192
+ if (parentScope) {
193
+ yield* registerNodeCleanup(wrapper, parentScope);
194
+ }
195
+ const fallback = vElement.props.fallback;
196
+ const onError = vElement.props.onError;
197
+ const children = vElement.props.children;
198
+ // Create content scope for children - wrapped in Ref so async error handler can access it
199
+ const contentScopeRef = yield* Ref.make(yield* Scope.make());
200
+ // Create error channel for async error reporting
201
+ const errorDeferred = yield* Deferred.make();
202
+ const errorChannel = {
203
+ reportError: (error) => Deferred.fail(errorDeferred, error).pipe(Effect.ignore)
204
+ };
205
+ // Flag to track if we've already shown fallback (to prevent double-triggering)
206
+ const hasTriggeredRef = yield* Ref.make(false);
207
+ // Helper to render fallback (used by both sync and async error paths)
208
+ const renderFallback = (error) => Effect.gen(function* () {
209
+ const alreadyTriggered = yield* Ref.getAndSet(hasTriggeredRef, true);
210
+ if (alreadyTriggered)
211
+ return; // Already showing fallback
212
+ // Close content scope (cleans up DOM nodes), create fallback scope
213
+ const oldContentScope = yield* Ref.get(contentScopeRef);
214
+ yield* Scope.close(oldContentScope, Exit.void);
215
+ const fallbackScope = yield* Scope.make();
216
+ yield* Ref.set(contentScopeRef, fallbackScope);
217
+ onError?.(error);
218
+ yield* Effect.logError("ErrorBoundary caught error", error);
219
+ yield* renderVElementToDOM(fallback, wrapper, runtime, fallbackScope).pipe(Effect.catchAll((e) => Effect.logError("ErrorBoundary fallback render error", e)));
220
+ });
221
+ // Fork listener for async errors (event handlers, stream failures)
222
+ yield* Effect.fork(Deferred.await(errorDeferred).pipe(Effect.catchAllCause((cause) => renderFallback(cause))));
223
+ // Try to render children with error channel in context, catch sync errors
224
+ const contentScope = yield* Ref.get(contentScopeRef);
225
+ const renderResult = yield* Effect.either(Effect.forEach(children, (child) => renderVElementToDOM(child, wrapper, runtime, contentScope), { discard: true }).pipe(Effect.provideService(ErrorBoundaryChannel, errorChannel)));
226
+ if (renderResult._tag === "Left") {
227
+ // Sync error during render - render fallback
228
+ yield* renderFallback(renderResult.left);
229
+ }
230
+ }
231
+ else if (type === "SUSPENSE") {
232
+ // Suspense boundary - show fallback while children are loading
233
+ // Uses proper DOM insertion/removal (not CSS visibility hacks)
234
+ // Children are rendered to a detached container; if they complete within threshold,
235
+ // we append directly. If timeout fires first, we show fallback then swap when ready.
236
+ const fallback = vElement.props.fallback;
237
+ const threshold = vElement.props.threshold ?? 100;
238
+ const children = vElement.props.children;
239
+ const childFragment = h("FRAGMENT", {}, children);
240
+ // Create a DETACHED container for children (not in DOM yet)
241
+ // Using display:contents so it doesn't affect layout when inserted
242
+ const childWrapper = document.createElement("span");
243
+ childWrapper.style.display = "contents";
244
+ // Create scopes for each container
245
+ const fallbackScope = yield* Scope.make();
246
+ const childScope = yield* Scope.make();
247
+ // Deferred to signal when children have completed first render
248
+ const childrenReady = yield* Deferred.make();
249
+ // Fork: render children into DETACHED container, signal when done
250
+ const childFiber = yield* Effect.fork(Effect.gen(function* () {
251
+ yield* renderVElementToDOM(childFragment, childWrapper, runtime, childScope);
252
+ yield* Deferred.succeed(childrenReady, void 0);
253
+ }).pipe(Effect.catchAll((e) => Deferred.fail(childrenReady, e))));
254
+ // Race: wait for children vs timeout
255
+ const childrenWon = yield* Effect.race(Deferred.await(childrenReady).pipe(Effect.as(true)), Effect.sleep(`${threshold} millis`).pipe(Effect.as(false)));
256
+ if (childrenWon) {
257
+ // Children completed before timeout - append directly, skip fallback entirely
258
+ parent.appendChild(childWrapper);
259
+ if (parentScope) {
260
+ yield* registerNodeCleanup(childWrapper, parentScope);
261
+ }
262
+ // Clean up unused fallback scope
263
+ yield* Scope.close(fallbackScope, Exit.void);
264
+ }
265
+ else {
266
+ // Timeout fired first - render fallback to DOM while waiting for children
267
+ const fallbackWrapper = document.createElement("span");
268
+ fallbackWrapper.style.display = "contents";
269
+ parent.appendChild(fallbackWrapper);
270
+ if (parentScope) {
271
+ yield* registerNodeCleanup(fallbackWrapper, parentScope);
272
+ }
273
+ yield* renderVElementToDOM(fallback, fallbackWrapper, runtime, fallbackScope);
274
+ // Wait for children to complete (they're still rendering in background)
275
+ const childResult = yield* Effect.either(Deferred.await(childrenReady));
276
+ if (childResult._tag === "Right") {
277
+ // Children completed successfully - swap: remove fallback, insert children
278
+ fallbackWrapper.remove();
279
+ parent.appendChild(childWrapper);
280
+ if (parentScope) {
281
+ yield* registerNodeCleanup(childWrapper, parentScope);
282
+ }
283
+ // Clean up fallback scope (stops any streams/effects in fallback)
284
+ yield* Scope.close(fallbackScope, Exit.void);
285
+ }
286
+ else {
287
+ // Children failed - keep showing fallback, propagate error
288
+ // (ErrorBoundary above should catch this)
289
+ yield* Fiber.interrupt(childFiber);
290
+ yield* Scope.close(childScope, Exit.void);
291
+ return yield* Effect.fail(childResult.left);
292
+ }
293
+ }
294
+ }
295
+ else if (isHostElement(type)) {
296
+ // Regular host element (div, span, button, etc.)
297
+ const el = document.createElement(type);
298
+ // Apply properties
299
+ for (const [key, value] of Object.entries(vElement.props)) {
300
+ if (isProperty(key)) {
301
+ setDomProperty(el, key, value);
302
+ }
303
+ }
304
+ // Attach event listeners - uses runForkWithRuntime internally for full context
305
+ attachEventListeners(el, vElement.props, runtime);
306
+ // Handle ref
307
+ const ref = vElement.props.ref;
308
+ if (ref && typeof ref === "object" && "current" in ref) {
309
+ ref.current = el;
310
+ }
311
+ parent.appendChild(el);
312
+ // Register element cleanup with parent scope if provided
313
+ if (parentScope) {
314
+ yield* registerNodeCleanup(el, parentScope);
315
+ }
316
+ // Create scope for children of this element
317
+ const childScope = yield* Scope.make();
318
+ // Render children (propagate errors)
319
+ const children = vElement.props.children ?? [];
320
+ for (const child of children) {
321
+ yield* renderVElementToDOM(child, el, runtime, childScope);
322
+ }
323
+ }
324
+ });
325
+ //# sourceMappingURL=render.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"render.js","sourceRoot":"","sources":["../src/render.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,IAAI,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,IAAI,MAAM,aAAa,CAAC;AACpC,OAAO,KAAK,GAAG,MAAM,YAAY,CAAC;AAClC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,KAAK,MAAM,cAAc,CAAC;AACtC,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAC5C,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,QAAQ,MAAM,iBAAiB,CAAC;AAE5C,OAAO,EAAE,IAAI,EAAE,QAAQ,IAAI,YAAY,EAAE,MAAM,mBAAmB,CAAC;AACnE,OAAO,EAAmD,MAAM,aAAa,CAAC;AAC9E,OAAO,EAAE,aAAa,EAAE,kBAAkB,EAAE,MAAM,cAAc,CAAC;AACjE,OAAO,EAAE,cAAc,EAAE,oBAAoB,EAAE,UAAU,EAAE,MAAM,UAAU,CAAC;AAC5E,OAAO,EAAE,iBAAiB,EAAE,oBAAoB,EAAE,gBAAgB,EAAE,MAAM,eAAe,CAAC;AAC1F,OAAO,EAAE,iBAAiB,EAAE,mBAAmB,EAAE,MAAM,kBAAkB,CAAC;AAC1E,OAAO,EAAE,oBAAoB,EAAE,MAAM,iBAAiB,CAAC;AACvD,OAAO,EAAE,CAAC,EAAE,MAAM,QAAQ,CAAC;AAE3B,gFAAgF;AAChF,cAAc;AACd,gFAAgF;AAEhF;;GAEG;AACH,MAAM,mBAAmB,GAAG,CAAC,IAAiB,EAA4G,EAAE,CAC1J,OAAO,IAAI,KAAK,UAAU,CAAC;AAE7B;;GAEG;AACH,MAAM,aAAa,GAAG,CAAC,IAAiB,EAAqB,EAAE,CAC7D,OAAO,IAAI,KAAK,QAAQ,CAAC;AAE3B,gFAAgF;AAChF,wBAAwB;AACxB,gFAAgF;AAEhF;;;;;;;;;;;;;GAaG;AACH,MAAM,CAAC,MAAM,mBAAmB,GAAG,CACjC,QAAkB,EAClB,MAAY,EACZ,OAAsB,EACtB,WAAmC,EACE,EAAE,CACvC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;IAClB,MAAM,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;IAE3B,IAAI,mBAAmB,CAAC,IAAI,CAAC,EAAE,CAAC;QAC9B,kEAAkE;QAClE,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC/C,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,UAAU,CAAC;QACnC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAE5B,yDAAyD;QACzD,IAAI,WAAW,EAAE,CAAC;YAChB,KAAK,CAAC,CAAC,mBAAmB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACnD,CAAC;QAED,oEAAoE;QACpE,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAC3C,oFAAoF;QACpF,MAAM,mBAAmB,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAChD,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,mBAAmB,CAAC,CAAC;QAE7D,MAAM,aAAa,GAAG,IAAI,GAAG,EAAsB,CAAC;QACpD,MAAM,gBAAgB,GAAG,oBAAoB,CAAC,OAAO,CAAC,QAAQ,EAAE,aAAa,CAAC,CAAC;QAE/E,0FAA0F;QAC1F,yFAAyF;QACzF,wFAAwF;QACxF,MAAM,cAAc,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,GAAG,CAAC,QAAQ,CAAC,cAAc,CAA0D,CAAC;QAC7H,MAAM,mBAAmB,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,YAAY,CAAC,YAAY,EAAE,gBAAgB,CAAC,CAAC;QAErG,sEAAsE;QACtE,MAAM,MAAM,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;YAC/B,GAAG,EAAE,GAAG,EAAE,CAAE,IAAoD,CAAC,QAAQ,CAAC,KAAK,CAAC;YAChF,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;SAChB,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,QAAQ,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,IAAI,CAAC,GAAG,EAAE,CAAC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC,CAAC,CACtE,CAAC;QAEF,yEAAyE;QACzE,2FAA2F;QAC3F,MAAM,MAAM,GAAG,iBAAiB,CAAC,MAAsE,CAAC,CAAC,IAAI,CAC3G,MAAM,CAAC,cAAc,CAAC,mBAAmB,CAAC,CAC3C,CAAC;QAEF,4EAA4E;QAC5E,0FAA0F;QAC1F,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CACrC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,MAAM,CAAC,UAAU,EAAE,eAAe,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,MAAM,EAAE,IAAI,CAAC,IAAI,EAAE,CAAC,CAAC,IAAI,CAChF,MAAM,CAAC,cAAc,CAAC,KAAK,CAAC,KAAK,EAAE,cAAc,CAAC,CACnD,CAAC;YAEF,IAAI,MAAM,CAAC,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;gBAC9B,mCAAmC;gBACnC,OAAO,EAAE,QAAQ,EAAE,KAAc,EAAE,CAAC;YACtC,CAAC;YAED,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YACrD,KAAK,CAAC,CAAC,mBAAmB,CAAC,UAAU,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,CAAC;YAE7E,2CAA2C;YAC3C,IAAI,aAAa,CAAC,IAAI,GAAG,CAAC,EAAE,CAAC;gBAC3B,KAAK,CAAC,CAAC,gBAAgB,CAAC,aAAa,EAAE,GAAG,EAAE;oBAC1C,iCAAiC;oBACjC,kBAAkB,CAAC,OAAO,CAAC,CACzB,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;wBAClB,uCAAuC;wBACvC,MAAM,aAAa,GAAG,QAAQ,CAAC,aAAmC,CAAC;wBACnE,MAAM,iBAAiB,GAAG,aAAa,IAAI,OAAO,CAAC,QAAQ,CAAC,aAAa,CAAC,CAAC;wBAC3E,MAAM,SAAS,GAAG,iBAAiB,IAAI,aAAa,CAAC,CAAC,CAAC;4BACrD,OAAO,EAAE,aAAa,CAAC,OAAO;4BAC9B,cAAc,EAAE,MAAM,CAAC,WAAW,CAChC,KAAK,CAAC,IAAI,CAAC,aAAa,CAAC,UAAU,CAAC;iCACjC,MAAM,CAAC,IAAI,CAAC,EAAE,CAAC,IAAI,CAAC,IAAI,CAAC,UAAU,CAAC,OAAO,CAAC,CAAC;iCAC7C,GAAG,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,EAAE,IAAI,CAAC,KAAK,CAAC,CAAC,CACxC;4BACD,IAAI,EAAE,aAAa,CAAC,YAAY,CAAC,MAAM,CAAC;4BACxC,EAAE,EAAE,aAAa,CAAC,EAAE;4BACpB,cAAc,EAAE,gBAAgB,IAAI,aAAa,CAAC,CAAC,CAAE,aAAkC,CAAC,cAAc,CAAC,CAAC,CAAC,IAAI;4BAC7G,YAAY,EAAE,cAAc,IAAI,aAAa,CAAC,CAAC,CAAE,aAAkC,CAAC,YAAY,CAAC,CAAC,CAAC,IAAI;yBACxG,CAAC,CAAC,CAAC,IAAI,CAAC;wBAET,uEAAuE;wBACvE,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;wBAElE,MAAM,gBAAgB,GAAG,IAAI,GAAG,EAAsB,CAAC;wBACvD,MAAM,mBAAmB,GAAG,oBAAoB,CAAC,OAAO,CAAC,QAAQ,EAAE,gBAAgB,CAAC,CAAC;wBACrF,yDAAyD;wBACzD,MAAM,sBAAsB,GAAG,OAAO,CAAC,GAAG,CAAC,cAAc,EAAE,YAAY,CAAC,YAAY,EAAE,mBAAmB,CAAC,CAAC;wBAE3G,sEAAsE;wBACtE,MAAM,SAAS,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,GAAG,CAAC;4BAClC,GAAG,EAAE,GAAG,EAAE,CAAE,IAAoD,CAAC,QAAQ,CAAC,KAAK,CAAC;4BAChF,KAAK,EAAE,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;yBAChB,CAAC,CAAC;wBAEH,MAAM,SAAS,GAAG,iBAAiB,CAAC,SAAyE,CAAC,CAAC,IAAI,CACjH,MAAM,CAAC,cAAc,CAAC,sBAAsB,CAAC,CAC9C,CAAC;wBACF,KAAK,CAAC,CAAC,MAAM,CAAC,UAAU,CAAC,SAAS,EAAE,CAAC,SAAS,EAAE,EAAE,CAChD,mBAAmB,CAAC,SAAS,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC,IAAI,CACpE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,uBAAuB,EAAE,CAAC,CAAC,CAAC,CACpE,CACF,CAAC;wBAEF,gCAAgC;wBAChC,IAAI,SAAS,EAAE,CAAC;4BACd,MAAM,UAAU,GAAG,OAAO,CAAC,gBAAgB,CAAC,SAAS,CAAC,OAAO,CAAC,CAAC;4BAC/D,KAAK,MAAM,SAAS,IAAI,UAAU,EAAE,CAAC;gCACnC,MAAM,EAAE,GAAG,SAAwB,CAAC;gCACpC,qDAAqD;gCACrD,MAAM,SAAS,GAAG,SAAS,CAAC,EAAE,IAAI,EAAE,CAAC,EAAE,KAAK,SAAS,CAAC,EAAE,CAAC;gCACzD,MAAM,WAAW,GAAG,SAAS,CAAC,IAAI,IAAI,EAAE,CAAC,YAAY,CAAC,MAAM,CAAC,KAAK,SAAS,CAAC,IAAI,CAAC;gCACjF,MAAM,WAAW,GAAG,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,MAAM,GAAG,CAAC;oCACrE,MAAM,CAAC,OAAO,CAAC,SAAS,CAAC,cAAc,CAAC,CAAC,KAAK,CAC5C,CAAC,CAAC,IAAI,EAAE,KAAK,CAAC,EAAE,EAAE,CAAC,EAAE,CAAC,YAAY,CAAC,IAAI,CAAC,KAAK,KAAK,CACnD,CAAC;gCAEJ,IAAI,SAAS,IAAI,WAAW,IAAI,WAAW,EAAE,CAAC;oCAC5C,EAAE,CAAC,KAAK,EAAE,CAAC;oCACX,+CAA+C;oCAC/C,IAAI,SAAS,CAAC,cAAc,KAAK,IAAI,IAAI,mBAAmB,IAAI,EAAE,EAAE,CAAC;wCAClE,EAAuB,CAAC,iBAAiB,CACxC,SAAS,CAAC,cAAc,EACxB,SAAS,CAAC,YAAY,IAAI,SAAS,CAAC,cAAc,CACnD,CAAC;oCACJ,CAAC;oCACD,MAAM;gCACR,CAAC;4BACH,CAAC;wBACH,CAAC;oBACH,CAAC,CAAC,CAAC,IAAI;oBACL,0FAA0F;oBAC1F,MAAM,CAAC,OAAO,CAAC,cAAc,CAAC,EAC9B,MAAM,CAAC,aAAa,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,iBAAiB,EAAE,KAAK,CAAC,CAAC,CAC3E,CACF,CAAC;gBACJ,CAAC,EAAE,OAAO,EAAE,cAAc,CAAC,CAAC;YAC9B,CAAC;YAED,4CAA4C;YAC5C,qEAAqE;YACrE,MAAM,iBAAiB,GAAG,OAAO,CAAC,SAAS,CAAC,cAAc,EAAE,oBAAoB,CAAC,CAAC;YAClF,MAAM,kBAAkB,GAAG,MAAM,CAAC,KAAK,CAAC,iBAAiB,EAAE;gBACzD,MAAM,EAAE,GAAG,EAAE,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,sCAAsC,EAAE,KAAK,CAAC;gBAChG,MAAM,EAAE,CAAC,OAAO,EAAE,EAAE,CAAC,CAAC,KAAc,EAAE,EAAE,CAAC,OAAO,CAAC,WAAW,CAAC,KAAK,CAAC;aACpE,CAAC,CAAC;YAEH,MAAM,YAAY,GAAG,MAAM,CAAC,UAAU,CAAC,eAAe,EAAE,CAAC,OAAO,EAAE,EAAE,CAClE,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;gBAClB,8BAA8B;gBAC9B,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,iBAAiB,CAAC,eAAe,CAAC,CAAC;gBAClE,KAAK,CAAC,CAAC,mBAAmB,CAAC,OAAO,EAAE,OAAO,EAAE,OAAO,EAAE,eAAe,CAAC,CAAC,IAAI,CACzE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,8BAA8B,EAAE,CAAC,CAAC,CAAC,CAC3E,CAAC;YACJ,CAAC,CAAC,CACH,CAAC,IAAI,CACJ,MAAM,CAAC,aAAa,CAAC,kBAAkB,CAAC,CACzC,CAAC;YAEF,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,YAAY,EAAE,cAAc,CAAC,CAAC;YAEnD,OAAO,EAAE,QAAQ,EAAE,IAAa,EAAE,CAAC;QACrC,CAAC,CAAC,CACH,CAAC;QAEF,IAAI,UAAU,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YAC/B,wDAAwD;YACxD,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YACrD,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,YAAY,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC5C,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,cAAc,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC9C,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;YAC5B,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,UAAU,CAAC,IAAI,CAAC,CAAC;QAC7C,CAAC;IAEH,CAAC;SAAM,IAAI,IAAI,KAAK,cAAc,EAAE,CAAC;QACnC,YAAY;QACZ,MAAM,QAAQ,GAAG,QAAQ,CAAC,cAAc,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,SAAS,IAAI,EAAE,CAAC,CAAC,CAAC;QACjF,MAAM,CAAC,WAAW,CAAC,QAAQ,CAAC,CAAC;QAE7B,2DAA2D;QAC3D,IAAI,WAAW,EAAE,CAAC;YAChB,KAAK,CAAC,CAAC,mBAAmB,CAAC,QAAQ,EAAE,WAAW,CAAC,CAAC;QACpD,CAAC;IAEH,CAAC;SAAM,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,qEAAqE;QACrE,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;QAC/C,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,KAAK,CAAC,CAAC,mBAAmB,CAAC,KAAK,EAAE,MAAM,EAAE,OAAO,EAAE,WAAW,CAAC,CAAC;QAClE,CAAC;IAEH,CAAC;SAAM,IAAI,IAAI,KAAK,gBAAgB,EAAE,CAAC;QACrC,0DAA0D;QAC1D,qFAAqF;QACrF,MAAM,OAAO,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QAC/C,OAAO,CAAC,KAAK,CAAC,OAAO,GAAG,UAAU,CAAC;QACnC,MAAM,CAAC,WAAW,CAAC,OAAO,CAAC,CAAC;QAE5B,yDAAyD;QACzD,IAAI,WAAW,EAAE,CAAC;YAChB,KAAK,CAAC,CAAC,mBAAmB,CAAC,OAAO,EAAE,WAAW,CAAC,CAAC;QACnD,CAAC;QAED,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAoB,CAAC;QACrD,MAAM,OAAO,GAAG,QAAQ,CAAC,KAAK,CAAC,OAAiD,CAAC;QACjF,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAsB,CAAC;QAEvD,0FAA0F;QAC1F,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC,CAAC;QAE7D,iDAAiD;QACjD,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAkB,CAAC;QAC7D,MAAM,YAAY,GAAqD;YACrE,WAAW,EAAE,CAAC,KAAc,EAAE,EAAE,CAC9B,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,MAAM,CAAC;SAC1D,CAAC;QAEF,+EAA+E;QAC/E,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;QAE/C,sEAAsE;QACtE,MAAM,cAAc,GAAG,CAAC,KAAc,EAAE,EAAE,CAAC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAC7D,MAAM,gBAAgB,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,SAAS,CAAC,eAAe,EAAE,IAAI,CAAC,CAAC;YACrE,IAAI,gBAAgB;gBAAE,OAAO,CAAC,2BAA2B;YAEzD,mEAAmE;YACnE,MAAM,eAAe,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;YACxD,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,eAAe,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/C,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;YAC1C,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,eAAe,EAAE,aAAa,CAAC,CAAC;YAE/C,OAAO,EAAE,CAAC,KAAK,CAAC,CAAC;YACjB,KAAK,CAAC,CAAC,MAAM,CAAC,QAAQ,CAAC,4BAA4B,EAAE,KAAK,CAAC,CAAC;YAC5D,KAAK,CAAC,CAAC,mBAAmB,CAAC,QAAQ,EAAE,OAAO,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC,IAAI,CACxE,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,MAAM,CAAC,QAAQ,CAAC,qCAAqC,EAAE,CAAC,CAAC,CAAC,CAClF,CAAC;QACJ,CAAC,CAAC,CAAC;QAEH,mEAAmE;QACnE,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAChB,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,IAAI,CAChC,MAAM,CAAC,aAAa,CAAC,CAAC,KAAK,EAAE,EAAE,CAAC,cAAc,CAAC,KAAK,CAAC,CAAC,CACvD,CACF,CAAC;QAEF,0EAA0E;QAC1E,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,GAAG,CAAC,GAAG,CAAC,eAAe,CAAC,CAAC;QACrD,MAAM,YAAY,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CACvC,MAAM,CAAC,OAAO,CAAC,QAAQ,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,mBAAmB,CAAC,KAAK,EAAE,OAAO,EAAE,OAAO,EAAE,YAAY,CAAC,EAAE,EAAE,OAAO,EAAE,IAAI,EAAE,CAAC,CAAC,IAAI,CACrH,MAAM,CAAC,cAAc,CAAC,oBAAoB,EAAE,YAAY,CAAC,CAC1D,CACF,CAAC;QAEF,IAAI,YAAY,CAAC,IAAI,KAAK,MAAM,EAAE,CAAC;YACjC,6CAA6C;YAC7C,KAAK,CAAC,CAAC,cAAc,CAAC,YAAY,CAAC,IAAI,CAAC,CAAC;QAC3C,CAAC;IAEH,CAAC;SAAM,IAAI,IAAI,KAAK,UAAU,EAAE,CAAC;QAC/B,+DAA+D;QAC/D,+DAA+D;QAC/D,qFAAqF;QACrF,qFAAqF;QACrF,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAoB,CAAC;QACrD,MAAM,SAAS,GAAI,QAAQ,CAAC,KAAK,CAAC,SAAoB,IAAI,GAAG,CAAC;QAC9D,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAsB,CAAC;QACvD,MAAM,aAAa,GAAG,CAAC,CAAC,UAAU,EAAE,EAAE,EAAE,QAAQ,CAAC,CAAC;QAElD,4DAA4D;QAC5D,mEAAmE;QACnE,MAAM,YAAY,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;QACpD,YAAY,CAAC,KAAK,CAAC,OAAO,GAAG,UAAU,CAAC;QAExC,mCAAmC;QACnC,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAC1C,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAEvC,+DAA+D;QAC/D,MAAM,aAAa,GAAG,KAAK,CAAC,CAAC,QAAQ,CAAC,IAAI,EAAiB,CAAC;QAE5D,kEAAkE;QAClE,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACnC,MAAM,CAAC,GAAG,CAAC,QAAQ,CAAC;YAClB,KAAK,CAAC,CAAC,mBAAmB,CAAC,aAAa,EAAE,YAAY,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;YAC7E,KAAK,CAAC,CAAC,QAAQ,CAAC,OAAO,CAAC,aAAa,EAAE,KAAK,CAAC,CAAC,CAAC;QACjD,CAAC,CAAC,CAAC,IAAI,CACL,MAAM,CAAC,QAAQ,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,QAAQ,CAAC,IAAI,CAAC,aAAa,EAAE,CAAC,CAAC,CAAC,CACxD,CACF,CAAC;QAEF,qCAAqC;QACrC,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CACpC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,IAAI,CAAC,CAAC,EACnD,MAAM,CAAC,KAAK,CAAC,GAAG,SAAS,SAAS,CAAC,CAAC,IAAI,CAAC,MAAM,CAAC,EAAE,CAAC,KAAK,CAAC,CAAC,CAC3D,CAAC;QAEF,IAAI,WAAW,EAAE,CAAC;YAChB,8EAA8E;YAC9E,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;YACjC,IAAI,WAAW,EAAE,CAAC;gBAChB,KAAK,CAAC,CAAC,mBAAmB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;YACxD,CAAC;YACD,iCAAiC;YACjC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;QAC/C,CAAC;aAAM,CAAC;YACN,0EAA0E;YAC1E,MAAM,eAAe,GAAG,QAAQ,CAAC,aAAa,CAAC,MAAM,CAAC,CAAC;YACvD,eAAe,CAAC,KAAK,CAAC,OAAO,GAAG,UAAU,CAAC;YAC3C,MAAM,CAAC,WAAW,CAAC,eAAe,CAAC,CAAC;YAEpC,IAAI,WAAW,EAAE,CAAC;gBAChB,KAAK,CAAC,CAAC,mBAAmB,CAAC,eAAe,EAAE,WAAW,CAAC,CAAC;YAC3D,CAAC;YAED,KAAK,CAAC,CAAC,mBAAmB,CAAC,QAAQ,EAAE,eAAe,EAAE,OAAO,EAAE,aAAa,CAAC,CAAC;YAE9E,wEAAwE;YACxE,MAAM,WAAW,GAAG,KAAK,CAAC,CAAC,MAAM,CAAC,MAAM,CAAC,QAAQ,CAAC,KAAK,CAAC,aAAa,CAAC,CAAC,CAAC;YAExE,IAAI,WAAW,CAAC,IAAI,KAAK,OAAO,EAAE,CAAC;gBACjC,2EAA2E;gBAC3E,eAAe,CAAC,MAAM,EAAE,CAAC;gBACzB,MAAM,CAAC,WAAW,CAAC,YAAY,CAAC,CAAC;gBAEjC,IAAI,WAAW,EAAE,CAAC;oBAChB,KAAK,CAAC,CAAC,mBAAmB,CAAC,YAAY,EAAE,WAAW,CAAC,CAAC;gBACxD,CAAC;gBAED,kEAAkE;gBAClE,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,aAAa,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;YAC/C,CAAC;iBAAM,CAAC;gBACN,2DAA2D;gBAC3D,0CAA0C;gBAC1C,KAAK,CAAC,CAAC,KAAK,CAAC,SAAS,CAAC,UAAU,CAAC,CAAC;gBACnC,KAAK,CAAC,CAAC,KAAK,CAAC,KAAK,CAAC,UAAU,EAAE,IAAI,CAAC,IAAI,CAAC,CAAC;gBAC1C,OAAO,KAAK,CAAC,CAAC,MAAM,CAAC,IAAI,CAAC,WAAW,CAAC,IAAI,CAAC,CAAC;YAC9C,CAAC;QACH,CAAC;IAEH,CAAC;SAAM,IAAI,aAAa,CAAC,IAAI,CAAC,EAAE,CAAC;QAC/B,iDAAiD;QACjD,MAAM,EAAE,GAAG,QAAQ,CAAC,aAAa,CAAC,IAAI,CAAC,CAAC;QAExC,mBAAmB;QACnB,KAAK,MAAM,CAAC,GAAG,EAAE,KAAK,CAAC,IAAI,MAAM,CAAC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAC,EAAE,CAAC;YAC1D,IAAI,UAAU,CAAC,GAAG,CAAC,EAAE,CAAC;gBACpB,cAAc,CAAC,EAAE,EAAE,GAAG,EAAE,KAAK,CAAC,CAAC;YACjC,CAAC;QACH,CAAC;QAED,+EAA+E;QAC/E,oBAAoB,CAAC,EAAE,EAAE,QAAQ,CAAC,KAAgC,EAAE,OAAO,CAAC,CAAC;QAE7E,aAAa;QACb,MAAM,GAAG,GAAG,QAAQ,CAAC,KAAK,CAAC,GAAG,CAAC;QAC/B,IAAI,GAAG,IAAI,OAAO,GAAG,KAAK,QAAQ,IAAI,SAAS,IAAI,GAAG,EAAE,CAAC;YACtD,GAA4B,CAAC,OAAO,GAAG,EAAE,CAAC;QAC7C,CAAC;QAED,MAAM,CAAC,WAAW,CAAC,EAAE,CAAC,CAAC;QAEvB,yDAAyD;QACzD,IAAI,WAAW,EAAE,CAAC;YAChB,KAAK,CAAC,CAAC,mBAAmB,CAAC,EAAE,EAAE,WAAW,CAAC,CAAC;QAC9C,CAAC;QAED,4CAA4C;QAC5C,MAAM,UAAU,GAAG,KAAK,CAAC,CAAC,KAAK,CAAC,IAAI,EAAE,CAAC;QAEvC,qCAAqC;QACrC,MAAM,QAAQ,GAAG,QAAQ,CAAC,KAAK,CAAC,QAAQ,IAAI,EAAE,CAAC;QAC/C,KAAK,MAAM,KAAK,IAAI,QAAQ,EAAE,CAAC;YAC7B,KAAK,CAAC,CAAC,mBAAmB,CAAC,KAAK,EAAE,EAAE,EAAE,OAAO,EAAE,UAAU,CAAC,CAAC;QAC7D,CAAC;IACH,CAAC;AACH,CAAC,CAAC,CAAC"}
@@ -0,0 +1,129 @@
1
+ /**
2
+ * History service - track and manage browser navigation history.
3
+ *
4
+ * Features:
5
+ * - Current location (pathname, search, hash, state)
6
+ * - Navigation methods (push, replace, back, forward, go)
7
+ * - BrowserHistoryLive - real browser history with popstate handling
8
+ * - MemoryHistoryLive - in-memory history for testing/SSR
9
+ * - Cleanly manages event listeners with Effect finalizers
10
+ *
11
+ * Design:
12
+ * - Uses Atom for reactive location updates
13
+ * - Browser history: listens to window.popstate for back/forward
14
+ * - Memory history: in-memory stack, useful for SSR/testing
15
+ * - All navigation returns Effects, integrates with Effect runtime
16
+ */
17
+ import * as Effect from "effect/Effect";
18
+ import * as Context from "effect/Context";
19
+ import * as Layer from "effect/Layer";
20
+ import { Atom, Registry as AtomRegistry } from "@effect-atom/atom";
21
+ /**
22
+ * Current location - pathname, search, hash, and state.
23
+ */
24
+ export interface HistoryLocation {
25
+ readonly pathname: string;
26
+ readonly search: string;
27
+ readonly hash: string;
28
+ readonly state?: unknown;
29
+ }
30
+ /**
31
+ * History service interface.
32
+ * Provides location access and navigation methods.
33
+ */
34
+ export interface HistoryService {
35
+ /**
36
+ * Current location atom - reactive and serializable.
37
+ */
38
+ readonly location: Atom.Writable<HistoryLocation, HistoryLocation>;
39
+ /**
40
+ * Navigate to a new location (push new entry).
41
+ */
42
+ readonly push: (path: string, state?: unknown) => Effect.Effect<void, never, AtomRegistry.AtomRegistry>;
43
+ /**
44
+ * Replace current location (same entry).
45
+ */
46
+ readonly replace: (path: string, state?: unknown) => Effect.Effect<void, never, AtomRegistry.AtomRegistry>;
47
+ /**
48
+ * Go back in history.
49
+ */
50
+ readonly back: Effect.Effect<void, never, never>;
51
+ /**
52
+ * Go forward in history.
53
+ */
54
+ readonly forward: Effect.Effect<void, never, never>;
55
+ /**
56
+ * Go n entries in history.
57
+ */
58
+ readonly go: (n: number) => Effect.Effect<void, never, never>;
59
+ /**
60
+ * Check if can go back (optional, simplified version).
61
+ */
62
+ readonly canGoBack: Effect.Effect<boolean, never, never>;
63
+ }
64
+ declare const History_base: Context.TagClass<History, "fibrae/History", HistoryService>;
65
+ /**
66
+ * History service tag for Effect dependency injection.
67
+ */
68
+ export declare class History extends History_base {
69
+ }
70
+ /**
71
+ * Browser history layer - real browser history with popstate handling.
72
+ *
73
+ * Features:
74
+ * - Tracks current location in an Atom
75
+ * - Listens to popstate for back/forward
76
+ * - Provides push/replace/go navigation methods
77
+ * - Cleanly removes event listener on scope close
78
+ * - Properly cleans up event listeners on scope close
79
+ */
80
+ export declare const BrowserHistoryLive: Layer.Layer<History, never, AtomRegistry.AtomRegistry>;
81
+ /**
82
+ * Options for creating memory history.
83
+ */
84
+ export interface MemoryHistoryOptions {
85
+ /** Initial location (defaults to "/") */
86
+ readonly initialPathname?: string;
87
+ /** Initial search params (defaults to "") */
88
+ readonly initialSearch?: string;
89
+ /** Initial hash (defaults to "") */
90
+ readonly initialHash?: string;
91
+ /** Initial state (defaults to undefined) */
92
+ readonly initialState?: unknown;
93
+ }
94
+ /**
95
+ * Create a memory history layer - useful for testing/SSR.
96
+ *
97
+ * Features:
98
+ * - In-memory navigation stack
99
+ * - Tracks current location in an Atom
100
+ * - No browser API usage (safe for SSR/testing)
101
+ * - Supports push/replace/back/forward/go navigation
102
+ * - Optional initial location/state configuration
103
+ */
104
+ export declare function MemoryHistoryLive(options?: MemoryHistoryOptions): Layer.Layer<History, never, AtomRegistry.AtomRegistry>;
105
+ /**
106
+ * Get current location.
107
+ */
108
+ export declare const getLocation: Effect.Effect<HistoryLocation, never, History | AtomRegistry.AtomRegistry>;
109
+ /**
110
+ * Push a new location.
111
+ */
112
+ export declare const push: (path: string, state?: unknown) => Effect.Effect<void, never, History | AtomRegistry.AtomRegistry>;
113
+ /**
114
+ * Replace current location.
115
+ */
116
+ export declare const replace: (path: string, state?: unknown) => Effect.Effect<void, never, History | AtomRegistry.AtomRegistry>;
117
+ /**
118
+ * Go back in history.
119
+ */
120
+ export declare const back: Effect.Effect<void, never, History>;
121
+ /**
122
+ * Go forward in history.
123
+ */
124
+ export declare const forward: Effect.Effect<void, never, History>;
125
+ /**
126
+ * Go n entries in history.
127
+ */
128
+ export declare const go: (n: number) => Effect.Effect<void, never, History>;
129
+ export {};