@useavalon/avalon 0.1.23 → 0.1.24

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 (114) hide show
  1. package/dist/mod.d.ts +50 -0
  2. package/dist/src/build/integration-bundler-plugin.d.ts +25 -0
  3. package/dist/src/build/integration-config.d.ts +44 -0
  4. package/dist/src/build/integration-detection-plugin.d.ts +20 -0
  5. package/dist/src/build/integration-resolver-plugin.d.ts +10 -0
  6. package/dist/src/build/island-manifest.d.ts +57 -0
  7. package/dist/src/build/island-types-generator.d.ts +49 -0
  8. package/dist/src/build/mdx-island-transform.d.ts +23 -0
  9. package/dist/src/build/mdx-plugin.d.ts +36 -0
  10. package/dist/src/build/page-island-transform.d.ts +41 -0
  11. package/dist/src/build/prop-extractors/index.d.ts +8 -0
  12. package/dist/src/build/prop-extractors/lit.d.ts +11 -0
  13. package/dist/src/build/prop-extractors/qwik.d.ts +9 -0
  14. package/dist/src/build/prop-extractors/solid.d.ts +12 -0
  15. package/dist/src/build/prop-extractors/svelte.d.ts +13 -0
  16. package/dist/src/build/prop-extractors/vue.d.ts +19 -0
  17. package/dist/src/build/sidecar-file-manager.d.ts +23 -0
  18. package/dist/src/build/sidecar-renderer.d.ts +22 -0
  19. package/dist/src/client/adapters/index.d.ts +15 -0
  20. package/dist/src/client/components.d.ts +21 -0
  21. package/dist/src/client/css-hmr-handler.d.ts +94 -0
  22. package/dist/src/client/framework-adapter.d.ts +225 -0
  23. package/dist/src/client/hmr-coordinator.d.ts +88 -0
  24. package/dist/src/components/Image.d.ts +61 -0
  25. package/dist/src/components/IslandErrorBoundary.d.ts +37 -0
  26. package/dist/src/components/IslandErrorBoundary.js +1 -1
  27. package/dist/src/components/LayoutDataErrorBoundary.d.ts +34 -0
  28. package/dist/src/components/LayoutDataErrorBoundary.js +1 -1
  29. package/dist/src/components/LayoutErrorBoundary.d.ts +25 -0
  30. package/dist/src/components/LayoutErrorBoundary.js +1 -1
  31. package/dist/src/components/PersistentIsland.d.ts +36 -0
  32. package/dist/src/components/StreamingErrorBoundary.d.ts +42 -0
  33. package/dist/src/components/StreamingErrorBoundary.js +1 -1
  34. package/dist/src/components/StreamingLayout.d.ts +83 -0
  35. package/dist/src/components/StreamingLayout.js +1 -1
  36. package/dist/src/core/components/component-analyzer.d.ts +48 -0
  37. package/dist/src/core/components/component-detection.d.ts +72 -0
  38. package/dist/src/core/components/enhanced-framework-detector.d.ts +78 -0
  39. package/dist/src/core/components/framework-registry.d.ts +114 -0
  40. package/dist/src/core/content/mdx-processor.d.ts +14 -0
  41. package/dist/src/core/integrations/index.d.ts +6 -0
  42. package/dist/src/core/integrations/loader.d.ts +35 -0
  43. package/dist/src/core/integrations/registry.d.ts +51 -0
  44. package/dist/src/core/islands/island-persistence.d.ts +74 -0
  45. package/dist/src/core/islands/island-state-serializer.d.ts +53 -0
  46. package/dist/src/core/islands/persistent-island-context.d.ts +36 -0
  47. package/dist/src/core/islands/use-persistent-state.d.ts +17 -0
  48. package/dist/src/core/layout/enhanced-layout-resolver.d.ts +73 -0
  49. package/dist/src/core/layout/layout-cache-manager.d.ts +66 -0
  50. package/dist/src/core/layout/layout-composer.d.ts +63 -0
  51. package/dist/src/core/layout/layout-data-loader.d.ts +146 -0
  52. package/dist/src/core/layout/layout-discovery.d.ts +51 -0
  53. package/dist/src/core/layout/layout-matcher.d.ts +77 -0
  54. package/dist/src/core/layout/layout-types.d.ts +94 -0
  55. package/dist/src/core/modules/framework-module-resolver.d.ts +85 -0
  56. package/dist/src/islands/component-analysis.d.ts +38 -0
  57. package/dist/src/islands/css-utils.d.ts +81 -0
  58. package/dist/src/islands/discovery/index.d.ts +16 -0
  59. package/dist/src/islands/discovery/registry.d.ts +141 -0
  60. package/dist/src/islands/discovery/resolver.d.ts +190 -0
  61. package/dist/src/islands/discovery/scanner.d.ts +55 -0
  62. package/dist/src/islands/discovery/types.d.ts +92 -0
  63. package/dist/src/islands/discovery/validator.d.ts +89 -0
  64. package/dist/src/islands/discovery/watcher.d.ts +95 -0
  65. package/dist/src/islands/framework-detection.d.ts +53 -0
  66. package/dist/src/islands/integration-loader.d.ts +139 -0
  67. package/dist/src/islands/island.d.ts +55 -0
  68. package/dist/src/islands/render-cache.d.ts +203 -0
  69. package/dist/src/islands/types.d.ts +63 -0
  70. package/dist/src/islands/universal-css-collector.d.ts +41 -0
  71. package/dist/src/islands/universal-head-collector.d.ts +42 -0
  72. package/dist/src/layout-system.d.ts +92 -592
  73. package/dist/src/middleware/discovery.d.ts +70 -0
  74. package/dist/src/middleware/executor.d.ts +52 -0
  75. package/dist/src/middleware/index.d.ts +43 -0
  76. package/dist/src/middleware/types.d.ts +89 -0
  77. package/dist/src/nitro/build-config.d.ts +163 -0
  78. package/dist/src/nitro/config.d.ts +268 -0
  79. package/dist/src/nitro/error-handler.d.ts +151 -0
  80. package/dist/src/nitro/index.d.ts +15 -0
  81. package/dist/src/nitro/island-manifest.d.ts +191 -0
  82. package/dist/src/nitro/middleware-adapter.d.ts +151 -0
  83. package/dist/src/nitro/renderer.d.ts +342 -0
  84. package/dist/src/nitro/route-discovery.d.ts +142 -0
  85. package/dist/src/nitro/types.d.ts +278 -0
  86. package/dist/src/render/collect-css.d.ts +28 -0
  87. package/dist/src/render/error-pages.d.ts +14 -0
  88. package/dist/src/render/isolated-ssr-renderer.d.ts +127 -0
  89. package/dist/src/render/ssr.d.ts +56 -0
  90. package/dist/src/schemas/api.d.ts +27 -0
  91. package/dist/src/schemas/core.d.ts +75 -0
  92. package/dist/src/schemas/index.d.ts +79 -0
  93. package/dist/src/schemas/index.js +1 -1
  94. package/dist/src/schemas/layout.d.ts +282 -0
  95. package/dist/src/schemas/routing/index.d.ts +181 -0
  96. package/dist/src/schemas/routing.d.ts +388 -0
  97. package/dist/src/types/as-island.d.ts +17 -0
  98. package/dist/src/types/layout.d.ts +177 -0
  99. package/dist/src/types/routing.d.ts +297 -0
  100. package/dist/src/types/types.d.ts +6 -0
  101. package/dist/src/utils/dev-logger.d.ts +84 -0
  102. package/dist/src/utils/fs.d.ts +41 -0
  103. package/dist/src/vite-plugin/auto-discover.d.ts +72 -0
  104. package/dist/src/vite-plugin/config.d.ts +82 -0
  105. package/dist/src/vite-plugin/errors.d.ts +62 -0
  106. package/dist/src/vite-plugin/image-optimization.d.ts +36 -0
  107. package/dist/src/vite-plugin/integration-activator.d.ts +48 -0
  108. package/dist/src/vite-plugin/island-sidecar-plugin.d.ts +17 -0
  109. package/dist/src/vite-plugin/module-discovery.d.ts +66 -0
  110. package/dist/src/vite-plugin/nitro-integration.d.ts +56 -0
  111. package/dist/src/vite-plugin/plugin.d.ts +51 -0
  112. package/dist/src/vite-plugin/types.d.ts +281 -0
  113. package/dist/src/vite-plugin/validation.d.ts +93 -0
  114. package/package.json +33 -9
@@ -0,0 +1,225 @@
1
+ /**
2
+ * Framework HMR Adapter Interface
3
+ *
4
+ * Defines the contract for framework-specific HMR adapters.
5
+ * Each supported framework (React, Preact, Vue, Svelte, Solid, Lit) implements this interface
6
+ * to provide framework-specific hot module replacement behavior.
7
+ *
8
+ * Requirements: 2.1-2.7
9
+ */
10
+ /**
11
+ * State snapshot for preserving component state across HMR updates
12
+ */
13
+ export interface StateSnapshot {
14
+ /**
15
+ * Framework name (e.g., 'react', 'vue', 'svelte')
16
+ */
17
+ framework: string;
18
+ /**
19
+ * Timestamp when state was captured
20
+ */
21
+ timestamp: number;
22
+ /**
23
+ * Framework-specific state data
24
+ * - React: hooks state, context values
25
+ * - Vue: reactive data, computed properties
26
+ * - Svelte: component state, store subscriptions
27
+ * - Solid: signal values, reactive computations
28
+ * - Lit: element properties, attributes
29
+ */
30
+ data: Record<string, unknown>;
31
+ /**
32
+ * DOM state (scroll, focus, form values)
33
+ */
34
+ dom?: {
35
+ scrollPosition?: {
36
+ x: number;
37
+ y: number;
38
+ };
39
+ focusedElement?: string;
40
+ formValues?: Record<string, unknown>;
41
+ };
42
+ }
43
+ /**
44
+ * Framework-specific HMR adapter interface
45
+ *
46
+ * Each framework adapter implements this interface to provide:
47
+ * - Component identification (canHandle)
48
+ * - State preservation (preserveState, restoreState)
49
+ * - Hot updates (update)
50
+ * - Error handling (handleError)
51
+ */
52
+ export interface FrameworkHMRAdapter {
53
+ /**
54
+ * Framework name (e.g., 'react', 'preact', 'vue', 'svelte', 'solid', 'lit')
55
+ */
56
+ readonly name: string;
57
+ /**
58
+ * Check if this adapter can handle HMR for a given component
59
+ *
60
+ * @param component - The component to check
61
+ * @returns true if this adapter can handle the component
62
+ *
63
+ * Example:
64
+ * - React: Check for React.Component or function with hooks
65
+ * - Vue: Check for Vue component options object
66
+ * - Svelte: Check for Svelte component class
67
+ */
68
+ canHandle(component: unknown): boolean;
69
+ /**
70
+ * Preserve component state before HMR update
71
+ *
72
+ * Captures the current state of the component so it can be restored after update.
73
+ * Returns null if state preservation is not supported or fails.
74
+ *
75
+ * @param island - The island DOM element containing the component
76
+ * @returns State snapshot or null if preservation fails
77
+ *
78
+ * Requirements: 1.3, 4.1-4.5
79
+ */
80
+ preserveState(island: HTMLElement): StateSnapshot | null;
81
+ /**
82
+ * Update the component with a new module
83
+ *
84
+ * Performs the actual hot module replacement:
85
+ * - Unmounts old component (if needed)
86
+ * - Mounts new component with same props
87
+ * - Integrates with framework-specific HMR APIs
88
+ *
89
+ * @param island - The island DOM element
90
+ * @param newComponent - The new component class/function
91
+ * @param props - Component props
92
+ *
93
+ * Requirements: 2.1-2.6
94
+ */
95
+ update(island: HTMLElement, newComponent: unknown, props: Record<string, unknown>): Promise<void>;
96
+ /**
97
+ * Restore component state after HMR update
98
+ *
99
+ * Applies the previously captured state to the updated component.
100
+ * Should handle cases where state structure has changed.
101
+ *
102
+ * @param island - The island DOM element
103
+ * @param state - Previously captured state snapshot
104
+ *
105
+ * Requirements: 1.3, 4.1-4.5
106
+ */
107
+ restoreState(island: HTMLElement, state: StateSnapshot): void;
108
+ /**
109
+ * Handle errors during HMR update
110
+ *
111
+ * Provides framework-specific error handling:
112
+ * - Display error overlay
113
+ * - Preserve SSR HTML as fallback
114
+ * - Log diagnostic information
115
+ *
116
+ * @param island - The island DOM element
117
+ * @param error - The error that occurred
118
+ *
119
+ * Requirements: 1.4, 7.1-7.5
120
+ */
121
+ handleError(island: HTMLElement, error: Error): void;
122
+ }
123
+ /**
124
+ * Adapter registry for managing framework-specific HMR adapters
125
+ */
126
+ export declare class AdapterRegistry {
127
+ private adapters;
128
+ /**
129
+ * Register a framework-specific HMR adapter
130
+ *
131
+ * @param framework - Framework name (case-insensitive)
132
+ * @param adapter - The adapter implementation
133
+ * @throws Error if adapter is invalid or already registered
134
+ *
135
+ * Requirements: 2.1-2.7
136
+ */
137
+ register(framework: string, adapter: FrameworkHMRAdapter): void;
138
+ /**
139
+ * Get an adapter for a specific framework
140
+ *
141
+ * @param framework - Framework name (case-insensitive)
142
+ * @returns The adapter or undefined if not found
143
+ */
144
+ get(framework: string): FrameworkHMRAdapter | undefined;
145
+ /**
146
+ * Check if an adapter is registered for a framework
147
+ *
148
+ * @param framework - Framework name (case-insensitive)
149
+ * @returns true if adapter is registered
150
+ */
151
+ has(framework: string): boolean;
152
+ /**
153
+ * Get all registered framework names
154
+ *
155
+ * @returns Array of registered framework names
156
+ */
157
+ getRegisteredFrameworks(): string[];
158
+ /**
159
+ * Find an adapter that can handle a specific component
160
+ *
161
+ * Iterates through all registered adapters and returns the first one
162
+ * that can handle the component.
163
+ *
164
+ * @param component - The component to check
165
+ * @returns The adapter that can handle the component, or undefined
166
+ */
167
+ findAdapter(component: unknown): FrameworkHMRAdapter | undefined;
168
+ /**
169
+ * Unregister an adapter
170
+ *
171
+ * @param framework - Framework name (case-insensitive)
172
+ * @returns true if adapter was removed, false if not found
173
+ */
174
+ unregister(framework: string): boolean;
175
+ /**
176
+ * Clear all registered adapters
177
+ */
178
+ clear(): void;
179
+ /**
180
+ * Get the number of registered adapters
181
+ */
182
+ get size(): number;
183
+ }
184
+ /**
185
+ * Base adapter class with common functionality
186
+ *
187
+ * Framework-specific adapters can extend this class to inherit common behavior
188
+ * and only override framework-specific methods.
189
+ */
190
+ export declare abstract class BaseFrameworkAdapter implements FrameworkHMRAdapter {
191
+ abstract readonly name: string;
192
+ abstract canHandle(component: unknown): boolean;
193
+ abstract update(island: HTMLElement, newComponent: unknown, props: Record<string, unknown>): Promise<void>;
194
+ /**
195
+ * Default state preservation implementation
196
+ * Captures DOM state (scroll, focus, form values)
197
+ *
198
+ * Subclasses should override to add framework-specific state
199
+ */
200
+ preserveState(island: HTMLElement): StateSnapshot | null;
201
+ /**
202
+ * Default state restoration implementation
203
+ * Restores DOM state (scroll, focus, form values)
204
+ *
205
+ * Subclasses should override to add framework-specific state restoration
206
+ */
207
+ restoreState(island: HTMLElement, state: StateSnapshot): void;
208
+ /**
209
+ * Default error handling implementation
210
+ * Shows error indicator and preserves SSR HTML
211
+ */
212
+ handleError(island: HTMLElement, error: Error): void;
213
+ /**
214
+ * Capture DOM state (scroll, focus, form values)
215
+ */
216
+ protected captureDOMState(island: HTMLElement): StateSnapshot['dom'];
217
+ /**
218
+ * Restore DOM state (scroll, focus, form values)
219
+ */
220
+ protected restoreDOMState(island: HTMLElement, dom: StateSnapshot['dom']): void;
221
+ /**
222
+ * Get a CSS selector for an element
223
+ */
224
+ protected getElementSelector(element: HTMLElement): string | null;
225
+ }
@@ -0,0 +1,88 @@
1
+ /**
2
+ * HMR Coordinator
3
+ *
4
+ * Central orchestrator for all HMR operations in Avalon.
5
+ * Integrates with Vite's HMR API and coordinates island updates across frameworks.
6
+ */
7
+ import { type FrameworkHMRAdapter, AdapterRegistry } from './framework-adapter.ts';
8
+ /**
9
+ * Vite HMR types (defined locally to avoid import issues)
10
+ */
11
+ export interface HMRPayload {
12
+ type: string;
13
+ updates?: Update[];
14
+ timestamp?: number;
15
+ }
16
+ export interface ErrorPayload {
17
+ type: 'error';
18
+ err: {
19
+ message: string;
20
+ stack: string;
21
+ id?: string;
22
+ frame?: string;
23
+ plugin?: string;
24
+ pluginCode?: string;
25
+ loc?: {
26
+ file?: string;
27
+ line: number;
28
+ column: number;
29
+ };
30
+ };
31
+ }
32
+ export interface Update {
33
+ type: 'js-update' | 'css-update';
34
+ path: string;
35
+ acceptedPath: string;
36
+ timestamp: number;
37
+ explicitImportRequired?: boolean;
38
+ }
39
+ /**
40
+ * HMR update payload from Vite
41
+ */
42
+ export interface HMRUpdatePayload extends HMRPayload {
43
+ type: 'update' | 'full-reload' | 'prune' | 'error';
44
+ updates?: ModuleUpdate[];
45
+ timestamp?: number;
46
+ err?: ErrorPayload;
47
+ }
48
+ /**
49
+ * Individual module update information
50
+ */
51
+ export interface ModuleUpdate {
52
+ type: 'js-update' | 'css-update';
53
+ path: string;
54
+ acceptedPath: string;
55
+ timestamp: number;
56
+ }
57
+ export type { FrameworkHMRAdapter, StateSnapshot } from './framework-adapter.ts';
58
+ /**
59
+ * HMR Coordinator class
60
+ * Manages HMR lifecycle and coordinates updates across islands
61
+ */
62
+ export declare class HMRCoordinator {
63
+ private readonly registry;
64
+ private readonly stateSnapshots;
65
+ private readonly updateQueue;
66
+ private isProcessing;
67
+ /**
68
+ * Initialize the HMR coordinator
69
+ * Sets up Vite HMR listeners and accepts updates
70
+ */
71
+ initialize(): void;
72
+ registerAdapter(framework: string, adapter: FrameworkHMRAdapter): void;
73
+ getRegistry(): AdapterRegistry;
74
+ handleUpdate(payload: HMRUpdatePayload): Promise<void>;
75
+ private processCSSUpdates;
76
+ private queueJSUpdates;
77
+ private processUpdateQueue;
78
+ findAffectedIslands(modulePath: string): HTMLElement[];
79
+ updateIsland(island: HTMLElement): Promise<void>;
80
+ private resolveComponent;
81
+ private handleBeforeFullReload;
82
+ private handleError;
83
+ private normalizePath;
84
+ private isIslandModule;
85
+ private getIslandId;
86
+ }
87
+ export declare function getHMRCoordinator(): HMRCoordinator;
88
+ export declare function initializeHMR(): void;
@@ -0,0 +1,61 @@
1
+ /**
2
+ * Image Component for Avalon
3
+ *
4
+ * A responsive image component that works with vite-imagetools to provide
5
+ * optimized images with automatic srcset generation.
6
+ *
7
+ * Usage:
8
+ * ```tsx
9
+ * import { Image } from '@useavalon/avalon/client';
10
+ * import heroSrc from './hero.jpg?w=400;800;1200&format=webp&as=srcset';
11
+ *
12
+ * <Image
13
+ * src={heroSrc}
14
+ * alt="Hero image"
15
+ * sizes="(max-width: 600px) 400px, (max-width: 1200px) 800px, 1200px"
16
+ * />
17
+ * ```
18
+ *
19
+ * Or with the simpler single-image approach:
20
+ * ```tsx
21
+ * import heroSrc from './hero.jpg?w=800&format=webp';
22
+ *
23
+ * <Image src={heroSrc} alt="Hero image" width={800} height={600} />
24
+ * ```
25
+ */
26
+ import type { JSX } from "preact";
27
+ export interface ImageProps {
28
+ /**
29
+ * Image source - can be:
30
+ * - A string URL (single image)
31
+ * - A srcset string from ?as=srcset (contains " Xw" width descriptors)
32
+ * - An object with src/srcset/width/height from vite-imagetools
33
+ */
34
+ src: string | {
35
+ src: string;
36
+ srcset?: string;
37
+ width?: number;
38
+ height?: number;
39
+ };
40
+ /** Alt text for accessibility (required) */
41
+ alt: string;
42
+ /** Sizes attribute for responsive images (required when using srcset) */
43
+ sizes?: string;
44
+ /** Loading strategy */
45
+ loading?: "lazy" | "eager";
46
+ /** Decoding hint */
47
+ decoding?: "async" | "sync" | "auto";
48
+ /** Optional width (auto-detected from srcset if available) */
49
+ width?: number | string;
50
+ /** Optional height (auto-detected from srcset if available) */
51
+ height?: number | string;
52
+ /** CSS class name */
53
+ className?: string;
54
+ /** Inline styles */
55
+ style?: string | Record<string, string | number>;
56
+ }
57
+ /**
58
+ * Responsive image component with built-in optimization support
59
+ */
60
+ export declare function Image({ src, alt, sizes, loading, decoding, width, height, className, style, }: Readonly<ImageProps>): JSX.Element;
61
+ export default Image;
@@ -0,0 +1,37 @@
1
+ import { Component, ComponentChildren, ComponentType } from 'preact';
2
+ import type { LayoutErrorInfo } from '../types/layout.ts';
3
+ export interface IslandErrorBoundaryProps {
4
+ children: ComponentChildren;
5
+ islandId: string;
6
+ onError?: (error: Error, errorInfo: LayoutErrorInfo) => void;
7
+ fallback?: (error: Error, islandId: string) => ComponentChildren;
8
+ isolateError?: boolean;
9
+ }
10
+ export interface IslandErrorBoundaryState {
11
+ hasError: boolean;
12
+ error: Error | null;
13
+ errorInfo: LayoutErrorInfo | null;
14
+ }
15
+ /**
16
+ * Specialized error boundary for island components
17
+ * Provides error isolation to prevent island errors from affecting the main layout
18
+ */
19
+ export declare class IslandErrorBoundary extends Component<IslandErrorBoundaryProps, IslandErrorBoundaryState> {
20
+ constructor(props: IslandErrorBoundaryProps);
21
+ static getDerivedStateFromError(error: Error): Partial<IslandErrorBoundaryState>;
22
+ componentDidCatch(error: Error, errorInfo: {
23
+ componentStack?: string;
24
+ }): void;
25
+ private handleRemoveIsland;
26
+ private handleReloadIsland;
27
+ private renderFallback;
28
+ render(): ComponentChildren;
29
+ }
30
+ /**
31
+ * Higher-order component to wrap islands with error boundaries
32
+ */
33
+ export declare function withIslandErrorBoundary<P extends object>(WrappedComponent: ComponentType<P>, islandId: string, options?: {
34
+ fallback?: (error: Error, islandId: string) => ComponentChildren;
35
+ isolateError?: boolean;
36
+ onError?: (error: Error, errorInfo: LayoutErrorInfo) => void;
37
+ }): (props: P) => import("preact").JSX.Element;
@@ -1 +1 @@
1
- import{Component as e}from"preact";import{jsx as t,jsxs as n}from"preact/jsx-runtime";export class IslandErrorBoundary extends e{constructor(e){super(e),this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}componentDidCatch(e,t){let n={layoutPath:`island:${this.props.islandId}`,errorType:`island`,timestamp:Date.now(),componentStack:t.componentStack,errorBoundary:`IslandErrorBoundary`};if(this.setState({errorInfo:n}),this.props.onError&&this.props.onError(e,n),typeof Deno<`u`&&Deno.env.get(`NODE_ENV`)===`development`&&console.error(`Island Error [${this.props.islandId}]:`,e),!this.props.isolateError)throw e}handleRemoveIsland=()=>{let e=document.querySelector(`[data-island-id="${this.props.islandId}"]`);e&&e.remove()};handleReloadIsland=()=>{this.setState({hasError:!1,error:null,errorInfo:null})};renderFallback(){let{error:e}=this.state,{fallback:r,islandId:i}=this.props;if(r&&e)return r(e,i);let a=typeof Deno<`u`&&Deno.env.get(`NODE_ENV`)===`development`;return t(`div`,{class:`island-error-boundary`,"data-island-error":i,children:n(`div`,{class:`island-error-container`,children:[n(`div`,{class:`island-error-header`,children:[t(`span`,{class:`island-error-icon`,children:`⚠️`}),t(`span`,{class:`island-error-title`,children:`Island Error`})]}),n(`p`,{class:`island-error-message`,children:[`An error occurred in island "`,i,`". The rest of the page should work normally.`]}),n(`div`,{class:`island-error-actions`,children:[t(`button`,{onClick:this.handleReloadIsland,class:`island-reload-button`,children:`Reload Island`}),t(`button`,{onClick:this.handleRemoveIsland,class:`island-remove-button`,children:`Remove Island`})]}),a&&e&&n(`details`,{class:`island-error-details`,children:[t(`summary`,{children:`Error Details (Development)`}),n(`div`,{class:`island-error-info`,children:[n(`p`,{children:[t(`strong`,{children:`Island ID:`}),` `,i]}),n(`p`,{children:[t(`strong`,{children:`Error:`}),` `,e.message]})]}),t(`pre`,{class:`island-error-stack`,children:e.stack})]})]})})}render(){return this.state.hasError?this.renderFallback():this.props.children}}export function withIslandErrorBoundary(e,n,i){return function(a){return t(IslandErrorBoundary,{islandId:n,fallback:i?.fallback,isolateError:i?.isolateError??!0,onError:i?.onError,children:t(e,{...a})})}}
1
+ import{Component as e}from"preact";import{jsx as t,jsxs as n}from"preact/jsx-runtime";export class IslandErrorBoundary extends e{constructor(e){super(e),this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}componentDidCatch(e,t){let n={layoutPath:`island:${this.props.islandId}`,errorType:`island`,timestamp:Date.now(),componentStack:t.componentStack,errorBoundary:`IslandErrorBoundary`};if(this.setState({errorInfo:n}),this.props.onError&&this.props.onError(e,n),typeof process<`u`&&process.env?.NODE_ENV===`development`&&console.error(`Island Error [${this.props.islandId}]:`,e),!this.props.isolateError)throw e}handleRemoveIsland=()=>{let e=document.querySelector(`[data-island-id="${this.props.islandId}"]`);e&&e.remove()};handleReloadIsland=()=>{this.setState({hasError:!1,error:null,errorInfo:null})};renderFallback(){let{error:e}=this.state,{fallback:r,islandId:i}=this.props;if(r&&e)return r(e,i);let a=typeof process<`u`&&process.env?.NODE_ENV===`development`;return t(`div`,{class:`island-error-boundary`,"data-island-error":i,children:n(`div`,{class:`island-error-container`,children:[n(`div`,{class:`island-error-header`,children:[t(`span`,{class:`island-error-icon`,children:`⚠️`}),t(`span`,{class:`island-error-title`,children:`Island Error`})]}),n(`p`,{class:`island-error-message`,children:[`An error occurred in island "`,i,`". The rest of the page should work normally.`]}),n(`div`,{class:`island-error-actions`,children:[t(`button`,{onClick:this.handleReloadIsland,class:`island-reload-button`,children:`Reload Island`}),t(`button`,{onClick:this.handleRemoveIsland,class:`island-remove-button`,children:`Remove Island`})]}),a&&e&&n(`details`,{class:`island-error-details`,children:[t(`summary`,{children:`Error Details (Development)`}),n(`div`,{class:`island-error-info`,children:[n(`p`,{children:[t(`strong`,{children:`Island ID:`}),` `,i]}),n(`p`,{children:[t(`strong`,{children:`Error:`}),` `,e.message]})]}),t(`pre`,{class:`island-error-stack`,children:e.stack})]})]})})}render(){return this.state.hasError?this.renderFallback():this.props.children}}export function withIslandErrorBoundary(e,n,i){return function(a){return t(IslandErrorBoundary,{islandId:n,fallback:i?.fallback,isolateError:i?.isolateError??!0,onError:i?.onError,children:t(e,{...a})})}}
@@ -0,0 +1,34 @@
1
+ import { Component, ComponentChildren } from 'preact';
2
+ import type { LayoutErrorInfo, LayoutContext, LayoutData } from '../types/layout.ts';
3
+ export interface LayoutDataErrorBoundaryProps {
4
+ children: ComponentChildren;
5
+ layoutPath: string;
6
+ context: LayoutContext;
7
+ onError?: (error: Error, errorInfo: LayoutErrorInfo) => void;
8
+ fallbackData?: LayoutData;
9
+ retryLoader?: () => Promise<LayoutData>;
10
+ }
11
+ export interface LayoutDataErrorBoundaryState {
12
+ hasError: boolean;
13
+ error: Error | null;
14
+ errorInfo: LayoutErrorInfo | null;
15
+ retryCount: number;
16
+ isRetrying: boolean;
17
+ fallbackData: LayoutData | null;
18
+ }
19
+ /**
20
+ * Specialized error boundary for layout data loading errors
21
+ * Provides specific handling for data loader failures with retry and fallback mechanisms
22
+ */
23
+ export declare class LayoutDataErrorBoundary extends Component<LayoutDataErrorBoundaryProps, LayoutDataErrorBoundaryState> {
24
+ private maxRetries;
25
+ constructor(props: LayoutDataErrorBoundaryProps);
26
+ static getDerivedStateFromError(error: Error): Partial<LayoutDataErrorBoundaryState>;
27
+ componentDidCatch(error: Error, errorInfo: {
28
+ componentStack?: string;
29
+ }): void;
30
+ private handleRetry;
31
+ private handleUseFallback;
32
+ private renderErrorUI;
33
+ render(): ComponentChildren;
34
+ }
@@ -1 +1 @@
1
- import{Component as e}from"preact";import{jsx as t,jsxs as n}from"preact/jsx-runtime";export class LayoutDataErrorBoundary extends e{maxRetries=3;constructor(e){super(e),this.state={hasError:!1,error:null,errorInfo:null,retryCount:0,isRetrying:!1,fallbackData:e.fallbackData||null}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}componentDidCatch(e,t){let n={layoutPath:this.props.layoutPath,errorType:`loader`,timestamp:Date.now(),componentStack:t.componentStack,errorBoundary:`LayoutDataErrorBoundary`};this.setState({errorInfo:n}),this.props.onError&&this.props.onError(e,n)}handleRetry=async()=>{if(!(this.state.retryCount>=this.maxRetries||!this.props.retryLoader)){this.setState({isRetrying:!0});try{let e=await this.props.retryLoader();this.setState({hasError:!1,error:null,errorInfo:null,retryCount:this.state.retryCount+1,isRetrying:!1,fallbackData:e})}catch(e){this.setState({retryCount:this.state.retryCount+1,isRetrying:!1,error:e instanceof Error?e:Error(String(e))})}}};handleUseFallback=()=>{this.state.fallbackData&&this.setState({hasError:!1,error:null,errorInfo:null})};renderErrorUI(){let{error:e,retryCount:r,isRetrying:i,fallbackData:a}=this.state,o=r<this.maxRetries&&this.props.retryLoader,s=a!==null,c=typeof Deno<`u`&&Deno.env.get(`NODE_ENV`)===`development`;return t(`div`,{class:`layout-data-error-boundary`,children:n(`div`,{class:`error-container`,children:[t(`h3`,{children:`Data Loading Error`}),n(`p`,{children:[`Failed to load data for layout: `,this.props.layoutPath]}),n(`div`,{class:`error-actions`,children:[o&&t(`button`,{onClick:this.handleRetry,disabled:i,class:`retry-button`,children:i?`Retrying...`:`Retry (${this.maxRetries-r} left)`}),s&&t(`button`,{onClick:this.handleUseFallback,class:`fallback-button`,children:`Use Cached Data`})]}),c&&e&&n(`details`,{class:`error-details`,children:[t(`summary`,{children:`Error Details (Development)`}),n(`div`,{class:`error-info`,children:[n(`p`,{children:[t(`strong`,{children:`Error:`}),` `,e.message]}),n(`p`,{children:[t(`strong`,{children:`Layout:`}),` `,this.props.layoutPath]}),n(`p`,{children:[t(`strong`,{children:`Retry Count:`}),` `,r]})]}),t(`pre`,{class:`error-stack`,children:e.stack})]})]})})}render(){return this.state.hasError?this.renderErrorUI():this.props.children}}
1
+ import{Component as e}from"preact";import{jsx as t,jsxs as n}from"preact/jsx-runtime";export class LayoutDataErrorBoundary extends e{maxRetries=3;constructor(e){super(e),this.state={hasError:!1,error:null,errorInfo:null,retryCount:0,isRetrying:!1,fallbackData:e.fallbackData||null}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}componentDidCatch(e,t){let n={layoutPath:this.props.layoutPath,errorType:`loader`,timestamp:Date.now(),componentStack:t.componentStack,errorBoundary:`LayoutDataErrorBoundary`};this.setState({errorInfo:n}),this.props.onError&&this.props.onError(e,n)}handleRetry=async()=>{if(!(this.state.retryCount>=this.maxRetries||!this.props.retryLoader)){this.setState({isRetrying:!0});try{let e=await this.props.retryLoader();this.setState({hasError:!1,error:null,errorInfo:null,retryCount:this.state.retryCount+1,isRetrying:!1,fallbackData:e})}catch(e){this.setState({retryCount:this.state.retryCount+1,isRetrying:!1,error:e instanceof Error?e:Error(String(e))})}}};handleUseFallback=()=>{this.state.fallbackData&&this.setState({hasError:!1,error:null,errorInfo:null})};renderErrorUI(){let{error:e,retryCount:r,isRetrying:i,fallbackData:a}=this.state,o=r<this.maxRetries&&this.props.retryLoader,s=a!==null,c=typeof process<`u`&&process.env?.NODE_ENV===`development`;return t(`div`,{class:`layout-data-error-boundary`,children:n(`div`,{class:`error-container`,children:[t(`h3`,{children:`Data Loading Error`}),n(`p`,{children:[`Failed to load data for layout: `,this.props.layoutPath]}),n(`div`,{class:`error-actions`,children:[o&&t(`button`,{onClick:this.handleRetry,disabled:i,class:`retry-button`,children:i?`Retrying...`:`Retry (${this.maxRetries-r} left)`}),s&&t(`button`,{onClick:this.handleUseFallback,class:`fallback-button`,children:`Use Cached Data`})]}),c&&e&&n(`details`,{class:`error-details`,children:[t(`summary`,{children:`Error Details (Development)`}),n(`div`,{class:`error-info`,children:[n(`p`,{children:[t(`strong`,{children:`Error:`}),` `,e.message]}),n(`p`,{children:[t(`strong`,{children:`Layout:`}),` `,this.props.layoutPath]}),n(`p`,{children:[t(`strong`,{children:`Retry Count:`}),` `,r]})]}),t(`pre`,{class:`error-stack`,children:e.stack})]})]})})}render(){return this.state.hasError?this.renderErrorUI():this.props.children}}
@@ -0,0 +1,25 @@
1
+ import { Component, ComponentChildren } from 'preact';
2
+ import type { LayoutErrorInfo, ErrorRecoveryStrategy } from '../types/layout.ts';
3
+ export interface LayoutErrorBoundaryProps {
4
+ children: ComponentChildren;
5
+ fallback?: (error: Error, retry: () => void) => ComponentChildren;
6
+ onError?: (error: Error, errorInfo: LayoutErrorInfo) => void;
7
+ recoveryStrategy?: ErrorRecoveryStrategy;
8
+ layoutPath?: string;
9
+ errorType?: 'component' | 'loader' | 'rendering' | 'island';
10
+ }
11
+ export interface LayoutErrorBoundaryState {
12
+ hasError: boolean;
13
+ error: Error | null;
14
+ errorInfo: LayoutErrorInfo | null;
15
+ retryCount: number;
16
+ }
17
+ export declare class LayoutErrorBoundary extends Component<LayoutErrorBoundaryProps, LayoutErrorBoundaryState> {
18
+ private maxRetries;
19
+ constructor(props: LayoutErrorBoundaryProps);
20
+ static getDerivedStateFromError(error: Error): Partial<LayoutErrorBoundaryState>;
21
+ componentDidCatch(error: Error, errorInfo: any): void;
22
+ private handleRetry;
23
+ private renderFallback;
24
+ render(): ComponentChildren;
25
+ }
@@ -1 +1 @@
1
- import{Component as e}from"preact";import{jsxs as t,jsx as n}from"preact/jsx-runtime";export class LayoutErrorBoundary extends e{maxRetries=3;constructor(e){super(e),this.state={hasError:!1,error:null,errorInfo:null,retryCount:0}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}componentDidCatch(e,t){let n={layoutPath:this.props.layoutPath||`unknown`,errorType:this.props.errorType||`component`,timestamp:Date.now(),componentStack:t.componentStack,errorBoundary:this.constructor.name};this.setState({errorInfo:n}),this.props.onError&&this.props.onError(e,n),typeof Deno<`u`&&Deno.env.get(`NODE_ENV`)===`development`&&(console.error(`Layout Error Boundary caught an error:`,e),console.error(`Error Info:`,n),console.error(`Component Stack:`,t.componentStack))}handleRetry=()=>{this.state.retryCount<this.maxRetries&&this.setState({hasError:!1,error:null,errorInfo:null,retryCount:this.state.retryCount+1})};renderFallback(){let{error:e}=this.state,{fallback:r}=this.props;return r&&e?r(e,this.handleRetry):n(`div`,{class:`layout-error-boundary`,children:t(`div`,{class:`error-container`,children:[n(`h2`,{children:`Something went wrong`}),n(`p`,{children:`An error occurred while rendering this layout.`}),this.state.retryCount<this.maxRetries&&t(`button`,{onClick:this.handleRetry,class:`retry-button`,children:[`Try Again (`,this.maxRetries-this.state.retryCount,` attempts left)`]}),typeof Deno<`u`&&Deno.env.get(`NODE_ENV`)===`development`&&t(`details`,{class:`error-details`,children:[n(`summary`,{children:`Error Details (Development)`}),n(`pre`,{children:e?.stack}),this.state.errorInfo&&t(`div`,{children:[t(`p`,{children:[n(`strong`,{children:`Layout Path:`}),` `,this.state.errorInfo.layoutPath]}),t(`p`,{children:[n(`strong`,{children:`Error Type:`}),` `,this.state.errorInfo.errorType]}),t(`p`,{children:[n(`strong`,{children:`Timestamp:`}),` `,new Date(this.state.errorInfo.timestamp).toISOString()]})]})]})]})})}render(){return this.state.hasError?this.renderFallback():this.props.children}}
1
+ import{Component as e}from"preact";import{jsxs as t,jsx as n}from"preact/jsx-runtime";export class LayoutErrorBoundary extends e{maxRetries=3;constructor(e){super(e),this.state={hasError:!1,error:null,errorInfo:null,retryCount:0}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}componentDidCatch(e,t){let n={layoutPath:this.props.layoutPath||`unknown`,errorType:this.props.errorType||`component`,timestamp:Date.now(),componentStack:t.componentStack,errorBoundary:this.constructor.name};this.setState({errorInfo:n}),this.props.onError&&this.props.onError(e,n),typeof process<`u`&&process.env?.NODE_ENV===`development`&&(console.error(`Layout Error Boundary caught an error:`,e),console.error(`Error Info:`,n),console.error(`Component Stack:`,t.componentStack))}handleRetry=()=>{this.state.retryCount<this.maxRetries&&this.setState({hasError:!1,error:null,errorInfo:null,retryCount:this.state.retryCount+1})};renderFallback(){let{error:e}=this.state,{fallback:r}=this.props;return r&&e?r(e,this.handleRetry):n(`div`,{class:`layout-error-boundary`,children:t(`div`,{class:`error-container`,children:[n(`h2`,{children:`Something went wrong`}),n(`p`,{children:`An error occurred while rendering this layout.`}),this.state.retryCount<this.maxRetries&&t(`button`,{onClick:this.handleRetry,class:`retry-button`,children:[`Try Again (`,this.maxRetries-this.state.retryCount,` attempts left)`]}),typeof process<`u`&&process.env?.NODE_ENV===`development`&&t(`details`,{class:`error-details`,children:[n(`summary`,{children:`Error Details (Development)`}),n(`pre`,{children:e?.stack}),this.state.errorInfo&&t(`div`,{children:[t(`p`,{children:[n(`strong`,{children:`Layout Path:`}),` `,this.state.errorInfo.layoutPath]}),t(`p`,{children:[n(`strong`,{children:`Error Type:`}),` `,this.state.errorInfo.errorType]}),t(`p`,{children:[n(`strong`,{children:`Timestamp:`}),` `,new Date(this.state.errorInfo.timestamp).toISOString()]})]})]})]})})}render(){return this.state.hasError?this.renderFallback():this.props.children}}
@@ -0,0 +1,36 @@
1
+ /** @jsxImportSource preact */
2
+ import type { ComponentChildren } from 'preact';
3
+ import { type IslandPersistence } from '../core/islands/island-persistence.ts';
4
+ interface PersistentIslandProps {
5
+ /** Unique ID used as the storage key for this island's state */
6
+ persistentId: string;
7
+ /** The island component(s) to wrap with persistence context */
8
+ children: ComponentChildren;
9
+ /** Custom persistence instance (defaults to sessionStorage-backed) */
10
+ persistence?: IslandPersistence;
11
+ }
12
+ /**
13
+ * PersistentIsland — provides automatic state persistence context to child islands.
14
+ *
15
+ * Wrap any island with this component and use `usePersistentIslandContext()` inside
16
+ * the island to get `saveState`, `loadState`, and `clearState` functions.
17
+ *
18
+ * Usage in a page:
19
+ * ```tsx
20
+ * <PersistentIsland persistentId="my-counter" island={{ condition: 'on:client' }}>
21
+ * <MyCounter />
22
+ * </PersistentIsland>
23
+ * ```
24
+ *
25
+ * Usage inside the island:
26
+ * ```tsx
27
+ * import { usePersistentIslandContext } from '@useavalon/avalon';
28
+ *
29
+ * function MyCounter() {
30
+ * const { saveState, loadState, clearState } = usePersistentIslandContext();
31
+ * // ...
32
+ * }
33
+ * ```
34
+ */
35
+ export declare function PersistentIsland({ persistentId, children, persistence, }: Readonly<PersistentIslandProps>): import("preact").JSX.Element;
36
+ export default PersistentIsland;
@@ -0,0 +1,42 @@
1
+ /**
2
+ * StreamingErrorBoundary - Error boundary component for streaming contexts
3
+ *
4
+ * This component provides error isolation for Suspense boundaries in streaming SSR.
5
+ * It ensures that errors in one component don't break the entire page.
6
+ */
7
+ import { Component, type ComponentChildren } from 'preact';
8
+ export interface StreamingErrorBoundaryProps {
9
+ children: ComponentChildren;
10
+ fallback?: (error: Error, retry: () => void) => ComponentChildren;
11
+ onError?: (error: Error, errorInfo: any) => void;
12
+ componentId?: string;
13
+ isolateError?: boolean;
14
+ }
15
+ export interface StreamingErrorBoundaryState {
16
+ hasError: boolean;
17
+ error: Error | null;
18
+ errorInfo: any;
19
+ }
20
+ /**
21
+ * Error boundary component for streaming contexts
22
+ *
23
+ * Wraps Suspense boundaries to provide error isolation and recovery.
24
+ * Prevents errors in one component from breaking the entire page.
25
+ */
26
+ export declare class StreamingErrorBoundary extends Component<StreamingErrorBoundaryProps, StreamingErrorBoundaryState> {
27
+ constructor(props: StreamingErrorBoundaryProps);
28
+ static getDerivedStateFromError(error: Error): Partial<StreamingErrorBoundaryState>;
29
+ componentDidCatch(error: Error, errorInfo: any): void;
30
+ private handleRetry;
31
+ private renderFallback;
32
+ render(): ComponentChildren;
33
+ }
34
+ /**
35
+ * Higher-order component to wrap components with streaming error boundaries
36
+ */
37
+ export declare function withStreamingErrorBoundary<P extends object>(WrappedComponent: (props: P) => ComponentChildren, options?: {
38
+ fallback?: (error: Error, retry: () => void) => ComponentChildren;
39
+ componentId?: string;
40
+ isolateError?: boolean;
41
+ onError?: (error: Error, errorInfo: any) => void;
42
+ }): (props: P) => import("preact").JSX.Element;
@@ -1 +1 @@
1
- import{Component as e}from"preact";import{jsx as t,jsxs as n}from"preact/jsx-runtime";export class StreamingErrorBoundary extends e{constructor(e){super(e),this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}componentDidCatch(e,t){if(this.setState({errorInfo:t}),console.error(`[StreamingErrorBoundary] Caught error:`,{componentId:this.props.componentId,error:e.message,stack:e.stack,componentStack:t.componentStack}),this.props.onError&&this.props.onError(e,t),!this.props.isolateError)throw e}handleRetry=()=>{this.setState({hasError:!1,error:null,errorInfo:null})};renderFallback(){let{error:e}=this.state,{fallback:r,componentId:i}=this.props;if(r&&e)return r(e,this.handleRetry);let a=typeof Deno<`u`&&Deno.env.get(`DENO_ENV`)!==`production`;return n(`div`,{class:`streaming-error-boundary`,"data-error-boundary":`true`,"data-component-id":i,style:{background:`#fff3cd`,border:`2px solid #ffc107`,borderRadius:`8px`,padding:`20px`,margin:`20px 0`,fontFamily:`system-ui, -apple-system, sans-serif`},children:[n(`div`,{class:`error-boundary-header`,style:{display:`flex`,alignItems:`center`,gap:`10px`,marginBottom:`10px`},children:[t(`span`,{style:{fontSize:`24px`},children:`⚠️`}),t(`h3`,{style:{margin:0,color:`#856404`},children:`Component Error`})]}),t(`p`,{style:{margin:`10px 0`,color:`#856404`},children:`An error occurred while rendering this component. The rest of the page should work normally.`}),t(`button`,{onClick:this.handleRetry,style:{background:`#ffc107`,border:`none`,borderRadius:`4px`,padding:`8px 16px`,cursor:`pointer`,fontWeight:`bold`,color:`#856404`,marginTop:`10px`},children:`Retry`}),a&&e&&n(`details`,{style:{marginTop:`15px`},children:[t(`summary`,{style:{cursor:`pointer`,color:`#856404`,fontWeight:`bold`},children:`Error Details (Development Mode)`}),n(`div`,{style:{marginTop:`10px`},children:[i&&n(`p`,{children:[t(`strong`,{children:`Component ID:`}),` `,i]}),n(`p`,{children:[t(`strong`,{children:`Error:`}),` `,e.message]}),e.stack&&t(`pre`,{style:{background:`#f5f5f5`,padding:`10px`,borderRadius:`4px`,overflowX:`auto`,fontSize:`12px`,marginTop:`10px`},children:e.stack}),this.state.errorInfo?.componentStack&&n(`div`,{children:[t(`p`,{children:t(`strong`,{children:`Component Stack:`})}),t(`pre`,{style:{background:`#f5f5f5`,padding:`10px`,borderRadius:`4px`,overflowX:`auto`,fontSize:`12px`,marginTop:`10px`},children:this.state.errorInfo.componentStack})]})]})]})]})}render(){return this.state.hasError?this.renderFallback():this.props.children}}export function withStreamingErrorBoundary(e,n){return function(i){return t(StreamingErrorBoundary,{componentId:n?.componentId,fallback:n?.fallback,isolateError:n?.isolateError??!0,onError:n?.onError,children:t(e,{...i})})}}
1
+ import{Component as e}from"preact";import{jsx as t,jsxs as n}from"preact/jsx-runtime";export class StreamingErrorBoundary extends e{constructor(e){super(e),this.state={hasError:!1,error:null,errorInfo:null}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}componentDidCatch(e,t){if(this.setState({errorInfo:t}),console.error(`[StreamingErrorBoundary] Caught error:`,{componentId:this.props.componentId,error:e.message,stack:e.stack,componentStack:t.componentStack}),this.props.onError&&this.props.onError(e,t),!this.props.isolateError)throw e}handleRetry=()=>{this.setState({hasError:!1,error:null,errorInfo:null})};renderFallback(){let{error:e}=this.state,{fallback:r,componentId:i}=this.props;if(r&&e)return r(e,this.handleRetry);let a=typeof process<`u`&&process.env?.NODE_ENV!==`production`;return n(`div`,{class:`streaming-error-boundary`,"data-error-boundary":`true`,"data-component-id":i,style:{background:`#fff3cd`,border:`2px solid #ffc107`,borderRadius:`8px`,padding:`20px`,margin:`20px 0`,fontFamily:`system-ui, -apple-system, sans-serif`},children:[n(`div`,{class:`error-boundary-header`,style:{display:`flex`,alignItems:`center`,gap:`10px`,marginBottom:`10px`},children:[t(`span`,{style:{fontSize:`24px`},children:`⚠️`}),t(`h3`,{style:{margin:0,color:`#856404`},children:`Component Error`})]}),t(`p`,{style:{margin:`10px 0`,color:`#856404`},children:`An error occurred while rendering this component. The rest of the page should work normally.`}),t(`button`,{onClick:this.handleRetry,style:{background:`#ffc107`,border:`none`,borderRadius:`4px`,padding:`8px 16px`,cursor:`pointer`,fontWeight:`bold`,color:`#856404`,marginTop:`10px`},children:`Retry`}),a&&e&&n(`details`,{style:{marginTop:`15px`},children:[t(`summary`,{style:{cursor:`pointer`,color:`#856404`,fontWeight:`bold`},children:`Error Details (Development Mode)`}),n(`div`,{style:{marginTop:`10px`},children:[i&&n(`p`,{children:[t(`strong`,{children:`Component ID:`}),` `,i]}),n(`p`,{children:[t(`strong`,{children:`Error:`}),` `,e.message]}),e.stack&&t(`pre`,{style:{background:`#f5f5f5`,padding:`10px`,borderRadius:`4px`,overflowX:`auto`,fontSize:`12px`,marginTop:`10px`},children:e.stack}),this.state.errorInfo?.componentStack&&n(`div`,{children:[t(`p`,{children:t(`strong`,{children:`Component Stack:`})}),t(`pre`,{style:{background:`#f5f5f5`,padding:`10px`,borderRadius:`4px`,overflowX:`auto`,fontSize:`12px`,marginTop:`10px`},children:this.state.errorInfo.componentStack})]})]})]})]})}render(){return this.state.hasError?this.renderFallback():this.props.children}}export function withStreamingErrorBoundary(e,n){return function(i){return t(StreamingErrorBoundary,{componentId:n?.componentId,fallback:n?.fallback,isolateError:n?.isolateError??!0,onError:n?.onError,children:t(e,{...i})})}}