fibrae 0.1.1 → 0.1.2

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.
@@ -1,13 +1,21 @@
1
- import * as Effect from "effect/Effect";
2
1
  import * as Context from "effect/Context";
3
- import { type VElement } from "./shared.js";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Stream from "effect/Stream";
4
+ import { type ComponentError, type VElement } from "./shared.js";
4
5
  declare const ErrorBoundaryChannel_base: Context.TagClass<ErrorBoundaryChannel, "ErrorBoundaryChannel", {
6
+ /** Report an error to this boundary. Used by event handlers and stream subscriptions. */
5
7
  readonly reportError: (error: unknown) => Effect.Effect<void, never, never>;
8
+ /** Optional unique identifier for this boundary (for debugging/logging) */
9
+ readonly boundaryId?: string;
6
10
  }>;
7
11
  /**
8
- * Error boundary channel - a Deferred that async errors can fail to trigger fallback.
12
+ * Error boundary channel - used by ErrorBoundary for async error reporting.
9
13
  * Created by ErrorBoundary and provided via context to children.
10
- * Children (event handlers, stream subscriptions) can fail this to report errors.
14
+ * Children (event handlers, stream subscriptions) can report errors to this channel.
15
+ *
16
+ * The channel includes:
17
+ * - reportError: for async errors (event handlers, streams)
18
+ * - boundaryId: optional unique identifier for this boundary (for debugging)
11
19
  */
12
20
  export declare class ErrorBoundaryChannel extends ErrorBoundaryChannel_base {
13
21
  }
@@ -29,12 +37,38 @@ export declare const Suspense: (props: {
29
37
  children?: VElement | VElement[];
30
38
  }) => VElement;
31
39
  /**
32
- * ErrorBoundary - catches errors from children and renders fallback.
33
- * Returns a special VElement that renderVElementToDOM handles specially.
40
+ * Creates an Effect-native error boundary around children.
41
+ *
42
+ * Returns a `Stream<VElement, ComponentError, never>` that can be piped with
43
+ * `Stream.catchTags` for fully typed error handling.
44
+ *
45
+ * @example
46
+ * ```tsx
47
+ * // Create a boundary with typed error handlers as a wrapper component
48
+ * const SafeApp = () => ErrorBoundary(<App />).pipe(
49
+ * Stream.catchTags({
50
+ * RenderError: (e) => Stream.succeed(<div>Render failed: {e.componentName}</div>),
51
+ * StreamError: (e) => Stream.succeed(<div>Stream failed: {e.phase}</div>),
52
+ * EventHandlerError: (e) => Stream.succeed(<div>Event {e.eventType} failed</div>),
53
+ * })
54
+ * );
55
+ *
56
+ * // Use it like any other component
57
+ * <SafeApp />
58
+ * ```
59
+ *
60
+ * **How it works:**
61
+ * 1. `ErrorBoundary()` returns a Stream that first emits a BOUNDARY marker element
62
+ * 2. The renderer detects this marker and sets up error handling
63
+ * 3. If any error occurs in the subtree, the Stream fails with that ComponentError
64
+ * 4. `Stream.catchTags` catches the error and produces a fallback Stream
65
+ * 5. The fallback VElement is rendered in place of the failed content
66
+ *
67
+ * **Nesting:** Boundaries nest naturally - inner boundary catches first, unhandled
68
+ * errors propagate to outer boundary following Effect/Stream error propagation rules.
69
+ *
70
+ * @param children - The VElement(s) to wrap in an error boundary
71
+ * @returns Stream<VElement, ComponentError, never> - pipe with Stream.catchTags to handle errors
34
72
  */
35
- export declare const ErrorBoundary: (props: {
36
- fallback: VElement;
37
- onError?: (cause: unknown) => void;
38
- children?: VElement | VElement[];
39
- }) => VElement;
73
+ export declare const ErrorBoundary: (children: VElement | VElement[]) => Stream.Stream<VElement, ComponentError, never>;
40
74
  export {};
@@ -1,13 +1,18 @@
1
- import * as Effect from "effect/Effect";
2
1
  import * as Context from "effect/Context";
2
+ import * as Effect from "effect/Effect";
3
+ import * as Stream from "effect/Stream";
3
4
  import {} from "./shared.js";
4
5
  // =============================================================================
5
6
  // Error Boundary Channel
6
7
  // =============================================================================
7
8
  /**
8
- * Error boundary channel - a Deferred that async errors can fail to trigger fallback.
9
+ * Error boundary channel - used by ErrorBoundary for async error reporting.
9
10
  * Created by ErrorBoundary and provided via context to children.
10
- * Children (event handlers, stream subscriptions) can fail this to report errors.
11
+ * Children (event handlers, stream subscriptions) can report errors to this channel.
12
+ *
13
+ * The channel includes:
14
+ * - reportError: for async errors (event handlers, streams)
15
+ * - boundaryId: optional unique identifier for this boundary (for debugging)
11
16
  */
12
17
  export class ErrorBoundaryChannel extends Context.Tag("ErrorBoundaryChannel")() {
13
18
  }
@@ -45,27 +50,76 @@ export const Suspense = (props) => {
45
50
  },
46
51
  };
47
52
  };
53
+ // =============================================================================
54
+ // Effect-Native Error Boundary
55
+ // =============================================================================
56
+ // Counter for generating unique boundary IDs
57
+ let boundaryIdCounter = 0;
48
58
  /**
49
- * ErrorBoundary - catches errors from children and renders fallback.
50
- * Returns a special VElement that renderVElementToDOM handles specially.
59
+ * Normalize children to an array of VElements.
51
60
  */
52
- export const ErrorBoundary = (props) => {
53
- const childrenArray = Array.isArray(props.children)
54
- ? props.children
55
- : props.children
56
- ? [props.children]
57
- : [];
61
+ const normalizeChildren = (children) => Array.isArray(children) ? children : [children];
62
+ /**
63
+ * Creates an Effect-native error boundary around children.
64
+ *
65
+ * Returns a `Stream<VElement, ComponentError, never>` that can be piped with
66
+ * `Stream.catchTags` for fully typed error handling.
67
+ *
68
+ * @example
69
+ * ```tsx
70
+ * // Create a boundary with typed error handlers as a wrapper component
71
+ * const SafeApp = () => ErrorBoundary(<App />).pipe(
72
+ * Stream.catchTags({
73
+ * RenderError: (e) => Stream.succeed(<div>Render failed: {e.componentName}</div>),
74
+ * StreamError: (e) => Stream.succeed(<div>Stream failed: {e.phase}</div>),
75
+ * EventHandlerError: (e) => Stream.succeed(<div>Event {e.eventType} failed</div>),
76
+ * })
77
+ * );
78
+ *
79
+ * // Use it like any other component
80
+ * <SafeApp />
81
+ * ```
82
+ *
83
+ * **How it works:**
84
+ * 1. `ErrorBoundary()` returns a Stream that first emits a BOUNDARY marker element
85
+ * 2. The renderer detects this marker and sets up error handling
86
+ * 3. If any error occurs in the subtree, the Stream fails with that ComponentError
87
+ * 4. `Stream.catchTags` catches the error and produces a fallback Stream
88
+ * 5. The fallback VElement is rendered in place of the failed content
89
+ *
90
+ * **Nesting:** Boundaries nest naturally - inner boundary catches first, unhandled
91
+ * errors propagate to outer boundary following Effect/Stream error propagation rules.
92
+ *
93
+ * @param children - The VElement(s) to wrap in an error boundary
94
+ * @returns Stream<VElement, ComponentError, never> - pipe with Stream.catchTags to handle errors
95
+ */
96
+ export const ErrorBoundary = (children) => {
97
+ const boundaryId = `boundary-${++boundaryIdCounter}`;
98
+ const childrenArray = normalizeChildren(children);
58
99
  if (childrenArray.length === 0) {
59
- throw new Error("ErrorBoundary requires at least one child");
100
+ return Stream.die("ErrorBoundary() requires at least one child");
60
101
  }
61
- // Return a special marker element that renderVElementToDOM will handle
62
- return {
63
- type: "ERROR_BOUNDARY",
64
- props: {
65
- fallback: props.fallback,
66
- onError: props.onError,
67
- children: childrenArray,
68
- },
69
- };
102
+ // Create a stream that:
103
+ // 1. Emits the BOUNDARY marker with an onError callback
104
+ // 2. When onError is called, the stream fails with that error
105
+ // 3. Stream stays open until error or unmount
106
+ return Stream.async((emit) => {
107
+ // Create the BOUNDARY marker with error callback wired to stream failure
108
+ const boundaryElement = {
109
+ type: "BOUNDARY",
110
+ props: {
111
+ children: childrenArray,
112
+ boundaryId,
113
+ // When renderer detects an error in subtree, it calls this
114
+ onError: (error) => {
115
+ void emit.fail(error);
116
+ },
117
+ },
118
+ };
119
+ // Emit the marker immediately
120
+ void emit.single(boundaryElement);
121
+ // Stream stays open - it will fail when onError is called
122
+ // or be cancelled when the component unmounts
123
+ });
70
124
  };
71
125
  //# sourceMappingURL=components.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"components.js","sourceRoot":"","sources":["../src/components.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAE1C,OAAO,EAAiB,MAAM,aAAa,CAAC;AAE5C,gFAAgF;AAChF,yBAAyB;AACzB,gFAAgF;AAEhF;;;;GAIG;AACH,MAAM,OAAO,oBAAqB,SAAQ,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,EAK1E;CAAG;AAEN,gFAAgF;AAChF,sBAAsB;AACtB,gFAAgF;AAEhF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAIxB,EAAY,EAAE;IACb,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;QACjD,CAAC,CAAC,KAAK,CAAC,QAAQ;QAChB,CAAC,CAAC,KAAK,CAAC,QAAQ;YACd,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC;YAClB,CAAC,CAAC,EAAE,CAAC;IAET,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IAED,uEAAuE;IACvE,OAAO;QACL,IAAI,EAAE,UAAmB;QACzB,KAAK,EAAE;YACL,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,GAAG;YACjC,QAAQ,EAAE,aAAa;SACxB;KACF,CAAC;AACJ,CAAC,CAAC;AAEF;;;GAGG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAAC,KAI7B,EAAY,EAAE;IACb,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;QACjD,CAAC,CAAC,KAAK,CAAC,QAAQ;QAChB,CAAC,CAAC,KAAK,CAAC,QAAQ;YACd,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC;YAClB,CAAC,CAAC,EAAE,CAAC;IAET,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,2CAA2C,CAAC,CAAC;IAC/D,CAAC;IAED,uEAAuE;IACvE,OAAO;QACL,IAAI,EAAE,gBAAyB;QAC/B,KAAK,EAAE;YACL,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,OAAO,EAAE,KAAK,CAAC,OAAO;YACtB,QAAQ,EAAE,aAAa;SACxB;KACF,CAAC;AACJ,CAAC,CAAC"}
1
+ {"version":3,"file":"components.js","sourceRoot":"","sources":["../src/components.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,OAAO,MAAM,gBAAgB,CAAC;AAC1C,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AACxC,OAAO,KAAK,MAAM,MAAM,eAAe,CAAC;AAExC,OAAO,EAAsC,MAAM,aAAa,CAAC;AAEjE,gFAAgF;AAChF,yBAAyB;AACzB,gFAAgF;AAEhF;;;;;;;;GAQG;AACH,MAAM,OAAO,oBAAqB,SAAQ,OAAO,CAAC,GAAG,CAAC,sBAAsB,CAAC,EAQ1E;CAAG;AAEN,gFAAgF;AAChF,sBAAsB;AACtB,gFAAgF;AAEhF;;;;;;;;;;;GAWG;AACH,MAAM,CAAC,MAAM,QAAQ,GAAG,CAAC,KAIxB,EAAY,EAAE;IACb,MAAM,aAAa,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,QAAQ,CAAC;QACjD,CAAC,CAAC,KAAK,CAAC,QAAQ;QAChB,CAAC,CAAC,KAAK,CAAC,QAAQ;YACd,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,CAAC;YAClB,CAAC,CAAC,EAAE,CAAC;IAET,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,MAAM,IAAI,KAAK,CAAC,sCAAsC,CAAC,CAAC;IAC1D,CAAC;IAED,uEAAuE;IACvE,OAAO;QACL,IAAI,EAAE,UAAmB;QACzB,KAAK,EAAE;YACL,QAAQ,EAAE,KAAK,CAAC,QAAQ;YACxB,SAAS,EAAE,KAAK,CAAC,SAAS,IAAI,GAAG;YACjC,QAAQ,EAAE,aAAa;SACxB;KACF,CAAC;AACJ,CAAC,CAAC;AAEF,gFAAgF;AAChF,+BAA+B;AAC/B,gFAAgF;AAEhF,6CAA6C;AAC7C,IAAI,iBAAiB,GAAG,CAAC,CAAC;AAE1B;;GAEG;AACH,MAAM,iBAAiB,GAAG,CAAC,QAA+B,EAAc,EAAE,CACxE,KAAK,CAAC,OAAO,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AAElD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAiCG;AACH,MAAM,CAAC,MAAM,aAAa,GAAG,CAC3B,QAA+B,EACiB,EAAE;IAClD,MAAM,UAAU,GAAG,YAAY,EAAE,iBAAiB,EAAE,CAAC;IACrD,MAAM,aAAa,GAAG,iBAAiB,CAAC,QAAQ,CAAC,CAAC;IAElD,IAAI,aAAa,CAAC,MAAM,KAAK,CAAC,EAAE,CAAC;QAC/B,OAAO,MAAM,CAAC,GAAG,CAAC,6CAA6C,CAAC,CAAC;IACnE,CAAC;IAED,wBAAwB;IACxB,wDAAwD;IACxD,8DAA8D;IAC9D,8CAA8C;IAC9C,OAAO,MAAM,CAAC,KAAK,CAA2B,CAAC,IAAI,EAAE,EAAE;QACrD,yEAAyE;QACzE,MAAM,eAAe,GAAa;YAChC,IAAI,EAAE,UAAmB;YACzB,KAAK,EAAE;gBACL,QAAQ,EAAE,aAAa;gBACvB,UAAU;gBACV,2DAA2D;gBAC3D,OAAO,EAAE,CAAC,KAAqB,EAAE,EAAE;oBACjC,KAAK,IAAI,CAAC,IAAI,CAAC,KAAK,CAAC,CAAC;gBACxB,CAAC;aACF;SACF,CAAC;QAEF,8BAA8B;QAC9B,KAAK,IAAI,CAAC,MAAM,CAAC,eAAe,CAAC,CAAC;QAElC,0DAA0D;QAC1D,8CAA8C;IAChD,CAAC,CAAC,CAAC;AACL,CAAC,CAAC"}
package/dist/dom.d.ts CHANGED
@@ -1,4 +1,6 @@
1
+ import * as Effect from "effect/Effect";
1
2
  import { FibraeRuntime } from "./runtime.js";
3
+ import { EventHandlerError } from "./shared.js";
2
4
  /**
3
5
  * Property update strategies for different DOM properties
4
6
  */
@@ -12,5 +14,6 @@ export declare const setDomProperty: (el: HTMLElement, name: string, value: unkn
12
14
  /**
13
15
  * Attach event listeners to a DOM element.
14
16
  * Uses runForkWithRuntime to get the full application context.
17
+ * When an event handler Effect fails, converts to EventHandlerError and calls onError callback.
15
18
  */
16
- export declare const attachEventListeners: (el: HTMLElement, props: Record<string, unknown>, runtime: FibraeRuntime) => void;
19
+ export declare const attachEventListeners: (el: HTMLElement, props: Record<string, unknown>, runtime: FibraeRuntime, onError?: (error: EventHandlerError) => Effect.Effect<unknown, never, unknown>) => void;
package/dist/dom.js CHANGED
@@ -1,5 +1,7 @@
1
1
  import * as Effect from "effect/Effect";
2
+ import * as Cause from "effect/Cause";
2
3
  import { FibraeRuntime, runForkWithRuntime } from "./runtime.js";
4
+ import { EventHandlerError } from "./shared.js";
3
5
  // =============================================================================
4
6
  // DOM Property Handling
5
7
  // =============================================================================
@@ -48,8 +50,9 @@ export const setDomProperty = (el, name, value) => {
48
50
  /**
49
51
  * Attach event listeners to a DOM element.
50
52
  * Uses runForkWithRuntime to get the full application context.
53
+ * When an event handler Effect fails, converts to EventHandlerError and calls onError callback.
51
54
  */
52
- export const attachEventListeners = (el, props, runtime) => {
55
+ export const attachEventListeners = (el, props, runtime, onError) => {
53
56
  for (const [key, handler] of Object.entries(props)) {
54
57
  if (isEvent(key) && typeof handler === "function") {
55
58
  const eventType = key.toLowerCase().substring(2);
@@ -57,7 +60,17 @@ export const attachEventListeners = (el, props, runtime) => {
57
60
  const result = handler(event);
58
61
  if (Effect.isEffect(result)) {
59
62
  // Use runForkWithRuntime to get the full application context
60
- const effectWithErrorHandling = result.pipe(Effect.catchAllCause((cause) => Effect.logError("Event handler error", cause)));
63
+ const effectWithErrorHandling = result.pipe(Effect.catchAllCause((cause) => {
64
+ // Convert to EventHandlerError with the event type
65
+ const error = new EventHandlerError({
66
+ cause: Cause.squash(cause),
67
+ eventType,
68
+ });
69
+ if (onError) {
70
+ return onError(error);
71
+ }
72
+ return Effect.logError("Event handler error", error);
73
+ }));
61
74
  runForkWithRuntime(runtime)(effectWithErrorHandling);
62
75
  }
63
76
  });
package/dist/dom.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"file":"dom.js","sourceRoot":"","sources":["../src/dom.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"dom.js","sourceRoot":"","sources":["../src/dom.ts"],"names":[],"mappings":"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"}
@@ -25,9 +25,11 @@ import { FibraeRuntime } from "./runtime.js";
25
25
  */
26
26
  export declare const renderFiber: (element: VElement, container: HTMLElement) => Effect.Effect<never, never, FibraeRuntime>;
27
27
  /**
28
- * Hydrate an existing DOM tree with a VElement tree.
28
+ * Hydrate an existing DOM tree by building a fiber tree that references
29
+ * the existing DOM nodes. This enables event handlers and reactivity
30
+ * without replacing the DOM.
29
31
  *
30
- * This walks the existing DOM and builds a fiber tree that matches it,
31
- * enabling reactive updates without re-creating the DOM.
32
+ * Uses cursor-based DOM walking (like React) to match VElement tree
33
+ * against existing DOM, skipping whitespace-only text nodes and comments.
32
34
  */
33
35
  export declare const hydrateFiber: (element: VElement, container: HTMLElement) => Effect.Effect<never, unknown, FibraeRuntime>;