@useavalon/avalon 0.1.46 → 0.1.48
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.
- package/README.md +54 -54
- package/dist/mod.d.ts +8 -9
- package/dist/mod.js +1 -1
- package/dist/src/client/adapters/lit-adapter.js +1 -0
- package/dist/src/client/adapters/preact-adapter.js +1 -0
- package/dist/src/client/adapters/qwik-adapter.js +1 -0
- package/dist/src/client/adapters/react-adapter.js +1 -0
- package/dist/src/client/adapters/solid-adapter.js +1 -0
- package/dist/src/client/adapters/svelte-adapter.js +1 -0
- package/dist/src/client/adapters/vue-adapter.js +1 -0
- package/dist/src/client/components.d.ts +8 -16
- package/dist/src/client/components.js +1 -1
- package/dist/src/client/custom-directives.d.ts +25 -0
- package/dist/src/client/custom-directives.js +1 -0
- package/dist/src/client/main.js +3 -3
- package/dist/src/client/types/framework-runtime.d.ts +68 -68
- package/dist/src/client/types/vite-hmr.d.ts +46 -46
- package/dist/src/client/types/vite-virtual-modules.d.ts +70 -70
- package/dist/src/components/IslandErrorBoundary.d.ts +48 -9
- package/dist/src/components/IslandErrorBoundary.js +1 -1
- package/dist/src/components/LayoutErrorBoundary.d.ts +74 -9
- package/dist/src/components/LayoutErrorBoundary.js +1 -1
- package/dist/src/islands/builtin-directives.d.ts +15 -0
- package/dist/src/islands/builtin-directives.js +1 -0
- package/dist/src/islands/hydration-directives.d.ts +89 -0
- package/dist/src/islands/hydration-directives.js +1 -0
- package/dist/src/islands/island.d.ts +5 -3
- package/dist/src/islands/island.js +1 -1
- package/dist/src/islands/types.d.ts +4 -2
- package/dist/src/layout-system.d.ts +0 -13
- package/dist/src/layout-system.js +1 -1
- package/dist/src/nitro/config.d.ts +41 -2
- package/dist/src/nitro/config.js +1 -1
- package/dist/src/nitro/renderer.d.ts +14 -1
- package/dist/src/nitro/renderer.js +6 -6
- package/dist/src/persistence/island-state-serializer.d.ts +19 -0
- package/dist/src/persistence/island-state-serializer.js +1 -0
- package/dist/src/persistence/use-persistent-state.d.ts +31 -0
- package/dist/src/persistence/use-persistent-state.js +1 -0
- package/dist/src/prerender/index.d.ts +53 -0
- package/dist/src/prerender/index.js +1 -0
- package/dist/src/prerender/prerender.d.ts +20 -0
- package/dist/src/prerender/prerender.js +1 -0
- package/dist/src/schemas/layout.d.ts +1 -1
- package/dist/src/schemas/layout.js +1 -1
- package/dist/src/types/image.d.ts +106 -106
- package/dist/src/types/index.d.ts +22 -22
- package/dist/src/types/island-jsx.d.ts +33 -33
- package/dist/src/types/island-prop.d.ts +22 -20
- package/dist/src/types/layout.d.ts +0 -8
- package/dist/src/types/layout.js +1 -1
- package/dist/src/types/mdx.d.ts +6 -6
- package/dist/src/types/urlpattern.d.ts +49 -49
- package/dist/src/types/vite-env.d.ts +11 -11
- package/dist/src/vite-plugin/nitro-integration.d.ts +3 -3
- package/dist/src/vite-plugin/nitro-integration.js +14 -14
- package/package.json +7 -3
- package/dist/src/components/LayoutDataErrorBoundary.d.ts +0 -34
- package/dist/src/components/LayoutDataErrorBoundary.js +0 -1
- package/dist/src/components/PersistentIsland.d.ts +0 -36
- package/dist/src/components/PersistentIsland.js +0 -1
- package/dist/src/components/StreamingErrorBoundary.d.ts +0 -42
- package/dist/src/components/StreamingErrorBoundary.js +0 -1
- package/dist/src/components/StreamingLayout.d.ts +0 -83
- package/dist/src/components/StreamingLayout.js +0 -29
- package/dist/src/core/islands/island-persistence.d.ts +0 -74
- package/dist/src/core/islands/island-persistence.js +0 -1
- package/dist/src/core/islands/island-state-serializer.d.ts +0 -53
- package/dist/src/core/islands/island-state-serializer.js +0 -1
- package/dist/src/core/islands/persistent-island-context.d.ts +0 -36
- package/dist/src/core/islands/persistent-island-context.js +0 -1
- package/dist/src/core/islands/use-persistent-state.d.ts +0 -17
- package/dist/src/core/islands/use-persistent-state.js +0 -1
|
@@ -1,70 +1,70 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Type declarations for Vite virtual modules
|
|
3
|
-
*
|
|
4
|
-
* These modules are resolved by Vite at runtime in the browser.
|
|
5
|
-
* They don't exist as actual files but are provided by Vite's plugin system.
|
|
6
|
-
*/
|
|
7
|
-
|
|
8
|
-
declare module '/@useavalon/preact/client' {
|
|
9
|
-
export function hydrate(container: Element, component: unknown, props?: Record<string, unknown>): void;
|
|
10
|
-
export function getHydrationScript(): string;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
declare module '/@useavalon/react/client' {
|
|
14
|
-
export function hydrate(container: Element, component: unknown, props?: Record<string, unknown>): void;
|
|
15
|
-
export function getHydrationScript(): string;
|
|
16
|
-
}
|
|
17
|
-
|
|
18
|
-
declare module '/@useavalon/vue/client' {
|
|
19
|
-
export function hydrate(container: Element, component: unknown, props?: Record<string, unknown>): void;
|
|
20
|
-
export function getHydrationScript(): string;
|
|
21
|
-
}
|
|
22
|
-
|
|
23
|
-
declare module '/@useavalon/svelte/client' {
|
|
24
|
-
export function hydrate(container: Element, component: unknown, props?: Record<string, unknown>): void;
|
|
25
|
-
export function getHydrationScript(): string;
|
|
26
|
-
}
|
|
27
|
-
|
|
28
|
-
declare module '/@useavalon/solid/client' {
|
|
29
|
-
export function hydrate(container: Element, component: unknown, props?: Record<string, unknown>): void;
|
|
30
|
-
export function getHydrationScript(): string;
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
declare module '/@useavalon/lit/client' {
|
|
34
|
-
export function hydrate(container: Element, component: unknown, props?: Record<string, unknown>): void;
|
|
35
|
-
export function getHydrationScript(): string;
|
|
36
|
-
}
|
|
37
|
-
|
|
38
|
-
declare module '/@useavalon/qwik/client' {
|
|
39
|
-
export function hydrate(container: Element, component: unknown, props?: Record<string, unknown>): void;
|
|
40
|
-
export function getHydrationScript(): string;
|
|
41
|
-
}
|
|
42
|
-
|
|
43
|
-
// HMR adapter virtual modules
|
|
44
|
-
declare module '/@useavalon/react/client/hmr' {
|
|
45
|
-
export { reactAdapter } from '@useavalon/react/client/hmr';
|
|
46
|
-
}
|
|
47
|
-
|
|
48
|
-
declare module '/@useavalon/preact/client/hmr' {
|
|
49
|
-
export { preactAdapter } from '@useavalon/preact/client/hmr';
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
declare module '/@useavalon/vue/client/hmr' {
|
|
53
|
-
export { vueAdapter } from '@useavalon/vue/client/hmr';
|
|
54
|
-
}
|
|
55
|
-
|
|
56
|
-
declare module '/@useavalon/svelte/client/hmr' {
|
|
57
|
-
export { svelteAdapter } from '@useavalon/svelte/client/hmr';
|
|
58
|
-
}
|
|
59
|
-
|
|
60
|
-
declare module '/@useavalon/solid/client/hmr' {
|
|
61
|
-
export { solidAdapter } from '@useavalon/solid/client/hmr';
|
|
62
|
-
}
|
|
63
|
-
|
|
64
|
-
declare module '/@useavalon/lit/client/hmr' {
|
|
65
|
-
export { litAdapter } from '@useavalon/lit/client/hmr';
|
|
66
|
-
}
|
|
67
|
-
|
|
68
|
-
declare module '/@useavalon/qwik/client/hmr' {
|
|
69
|
-
export { qwikAdapter } from '@useavalon/qwik/client/hmr';
|
|
70
|
-
}
|
|
1
|
+
/**
|
|
2
|
+
* Type declarations for Vite virtual modules
|
|
3
|
+
*
|
|
4
|
+
* These modules are resolved by Vite at runtime in the browser.
|
|
5
|
+
* They don't exist as actual files but are provided by Vite's plugin system.
|
|
6
|
+
*/
|
|
7
|
+
|
|
8
|
+
declare module '/@useavalon/preact/client' {
|
|
9
|
+
export function hydrate(container: Element, component: unknown, props?: Record<string, unknown>): void;
|
|
10
|
+
export function getHydrationScript(): string;
|
|
11
|
+
}
|
|
12
|
+
|
|
13
|
+
declare module '/@useavalon/react/client' {
|
|
14
|
+
export function hydrate(container: Element, component: unknown, props?: Record<string, unknown>): void;
|
|
15
|
+
export function getHydrationScript(): string;
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
declare module '/@useavalon/vue/client' {
|
|
19
|
+
export function hydrate(container: Element, component: unknown, props?: Record<string, unknown>): void;
|
|
20
|
+
export function getHydrationScript(): string;
|
|
21
|
+
}
|
|
22
|
+
|
|
23
|
+
declare module '/@useavalon/svelte/client' {
|
|
24
|
+
export function hydrate(container: Element, component: unknown, props?: Record<string, unknown>): void;
|
|
25
|
+
export function getHydrationScript(): string;
|
|
26
|
+
}
|
|
27
|
+
|
|
28
|
+
declare module '/@useavalon/solid/client' {
|
|
29
|
+
export function hydrate(container: Element, component: unknown, props?: Record<string, unknown>): void;
|
|
30
|
+
export function getHydrationScript(): string;
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
declare module '/@useavalon/lit/client' {
|
|
34
|
+
export function hydrate(container: Element, component: unknown, props?: Record<string, unknown>): void;
|
|
35
|
+
export function getHydrationScript(): string;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
declare module '/@useavalon/qwik/client' {
|
|
39
|
+
export function hydrate(container: Element, component: unknown, props?: Record<string, unknown>): void;
|
|
40
|
+
export function getHydrationScript(): string;
|
|
41
|
+
}
|
|
42
|
+
|
|
43
|
+
// HMR adapter virtual modules
|
|
44
|
+
declare module '/@useavalon/react/client/hmr' {
|
|
45
|
+
export { reactAdapter } from '@useavalon/react/client/hmr';
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
declare module '/@useavalon/preact/client/hmr' {
|
|
49
|
+
export { preactAdapter } from '@useavalon/preact/client/hmr';
|
|
50
|
+
}
|
|
51
|
+
|
|
52
|
+
declare module '/@useavalon/vue/client/hmr' {
|
|
53
|
+
export { vueAdapter } from '@useavalon/vue/client/hmr';
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
declare module '/@useavalon/svelte/client/hmr' {
|
|
57
|
+
export { svelteAdapter } from '@useavalon/svelte/client/hmr';
|
|
58
|
+
}
|
|
59
|
+
|
|
60
|
+
declare module '/@useavalon/solid/client/hmr' {
|
|
61
|
+
export { solidAdapter } from '@useavalon/solid/client/hmr';
|
|
62
|
+
}
|
|
63
|
+
|
|
64
|
+
declare module '/@useavalon/lit/client/hmr' {
|
|
65
|
+
export { litAdapter } from '@useavalon/lit/client/hmr';
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
declare module '/@useavalon/qwik/client/hmr' {
|
|
69
|
+
export { qwikAdapter } from '@useavalon/qwik/client/hmr';
|
|
70
|
+
}
|
|
@@ -1,20 +1,51 @@
|
|
|
1
|
-
|
|
2
|
-
import type
|
|
1
|
+
/** @jsxImportSource preact */
|
|
2
|
+
import { Component, type ComponentChildren, type ComponentType } from 'preact';
|
|
3
|
+
import type { LayoutErrorInfo } from '../schemas/layout.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Props for {@link IslandErrorBoundary}.
|
|
6
|
+
*
|
|
7
|
+
* @example
|
|
8
|
+
* ```tsx
|
|
9
|
+
* <IslandErrorBoundary
|
|
10
|
+
* islandId="counter"
|
|
11
|
+
* isolateError
|
|
12
|
+
* onError={(err, info) => console.error(info.errorBoundary, err)}
|
|
13
|
+
* fallback={(err, id) => <p>Island "{id}" failed: {err.message}</p>}
|
|
14
|
+
* >
|
|
15
|
+
* <Counter />
|
|
16
|
+
* </IslandErrorBoundary>
|
|
17
|
+
* ```
|
|
18
|
+
*/
|
|
3
19
|
export interface IslandErrorBoundaryProps {
|
|
20
|
+
/** The content to render inside the error boundary. */
|
|
4
21
|
children: ComponentChildren;
|
|
22
|
+
/** Unique identifier for the island — used in error reports and DOM attributes. */
|
|
5
23
|
islandId: string;
|
|
24
|
+
/** Called when the island throws. Receives the error and structured error info. */
|
|
6
25
|
onError?: (error: Error, errorInfo: LayoutErrorInfo) => void;
|
|
26
|
+
/** Custom fallback UI. When omitted a default error card is shown. */
|
|
7
27
|
fallback?: (error: Error, islandId: string) => ComponentChildren;
|
|
28
|
+
/** When `true` (default for HOC), the error is caught and isolated. When `false`, it re-throws to parent boundaries. */
|
|
8
29
|
isolateError?: boolean;
|
|
9
30
|
}
|
|
10
|
-
|
|
31
|
+
interface IslandErrorBoundaryState {
|
|
11
32
|
hasError: boolean;
|
|
12
33
|
error: Error | null;
|
|
13
34
|
errorInfo: LayoutErrorInfo | null;
|
|
14
35
|
}
|
|
15
36
|
/**
|
|
16
|
-
*
|
|
17
|
-
*
|
|
37
|
+
* Error boundary that wraps individual islands to prevent one broken island
|
|
38
|
+
* from taking down the entire page.
|
|
39
|
+
*
|
|
40
|
+
* Renders a default error card with "Reload" / "Remove" actions, or your
|
|
41
|
+
* custom `fallback` if provided. In development mode, a stack trace is shown.
|
|
42
|
+
*
|
|
43
|
+
* @example
|
|
44
|
+
* ```tsx
|
|
45
|
+
* <IslandErrorBoundary islandId="cart" isolateError>
|
|
46
|
+
* <CartIsland />
|
|
47
|
+
* </IslandErrorBoundary>
|
|
48
|
+
* ```
|
|
18
49
|
*/
|
|
19
50
|
export declare class IslandErrorBoundary extends Component<IslandErrorBoundaryProps, IslandErrorBoundaryState> {
|
|
20
51
|
constructor(props: IslandErrorBoundaryProps);
|
|
@@ -22,16 +53,24 @@ export declare class IslandErrorBoundary extends Component<IslandErrorBoundaryPr
|
|
|
22
53
|
componentDidCatch(error: Error, errorInfo: {
|
|
23
54
|
componentStack?: string;
|
|
24
55
|
}): void;
|
|
25
|
-
private handleRemoveIsland;
|
|
26
|
-
private handleReloadIsland;
|
|
27
|
-
private renderFallback;
|
|
56
|
+
private readonly handleRemoveIsland;
|
|
57
|
+
private readonly handleReloadIsland;
|
|
28
58
|
render(): ComponentChildren;
|
|
29
59
|
}
|
|
30
60
|
/**
|
|
31
|
-
*
|
|
61
|
+
* HOC that wraps a component with {@link IslandErrorBoundary}.
|
|
62
|
+
*
|
|
63
|
+
* @example
|
|
64
|
+
* ```tsx
|
|
65
|
+
* const SafeCounter = withIslandErrorBoundary(Counter, 'counter', {
|
|
66
|
+
* isolateError: true,
|
|
67
|
+
* fallback: (err) => <p>Oops: {err.message}</p>,
|
|
68
|
+
* });
|
|
69
|
+
* ```
|
|
32
70
|
*/
|
|
33
71
|
export declare function withIslandErrorBoundary<P extends object>(WrappedComponent: ComponentType<P>, islandId: string, options?: {
|
|
34
72
|
fallback?: (error: Error, islandId: string) => ComponentChildren;
|
|
35
73
|
isolateError?: boolean;
|
|
36
74
|
onError?: (error: Error, errorInfo: LayoutErrorInfo) => void;
|
|
37
75
|
}): (props: P) => import("preact").JSX.Element;
|
|
76
|
+
export {};
|
|
@@ -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
|
|
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?.(e,n),!this.props.isolateError)throw e}handleRemoveIsland=()=>{document.querySelector(`[data-island-id="${this.props.islandId}"]`)?.remove()};handleReloadIsland=()=>{this.setState({hasError:!1,error:null,errorInfo:null})};render(){if(!this.state.hasError)return this.props.children;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`,{className:`island-error-boundary`,"data-island-error":i,children:n(`div`,{className:`island-error-container`,children:[n(`div`,{className:`island-error-header`,children:[t(`span`,{className:`island-error-icon`,children:`⚠️`}),t(`span`,{className:`island-error-title`,children:`Island Error`})]}),n(`p`,{className:`island-error-message`,children:[`An error occurred in island "`,i,`".`]}),n(`div`,{className:`island-error-actions`,children:[t(`button`,{onClick:this.handleReloadIsland,className:`island-reload-button`,children:`Reload Island`}),t(`button`,{onClick:this.handleRemoveIsland,className:`island-remove-button`,children:`Remove Island`})]}),a&&e&&n(`details`,{className:`island-error-details`,children:[t(`summary`,{children:`Error Details (Development)`}),n(`p`,{children:[t(`strong`,{children:`Island ID:`}),` `,i]}),n(`p`,{children:[t(`strong`,{children:`Error:`}),` `,e.message]}),t(`pre`,{className:`island-error-stack`,children:e.stack})]})]})})}}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,25 +1,90 @@
|
|
|
1
|
-
|
|
2
|
-
import
|
|
1
|
+
/** @jsxImportSource preact */
|
|
2
|
+
import { Component, type ComponentChildren } from 'preact';
|
|
3
|
+
import type { LayoutErrorInfo, LayoutData } from '../schemas/layout.ts';
|
|
4
|
+
/**
|
|
5
|
+
* Props for {@link LayoutErrorBoundary}.
|
|
6
|
+
*
|
|
7
|
+
* @example Basic usage
|
|
8
|
+
* ```tsx
|
|
9
|
+
* <LayoutErrorBoundary onError={(err) => logToSentry(err)}>
|
|
10
|
+
* <DashboardLayout />
|
|
11
|
+
* </LayoutErrorBoundary>
|
|
12
|
+
* ```
|
|
13
|
+
*
|
|
14
|
+
* @example Custom fallback with retry
|
|
15
|
+
* ```tsx
|
|
16
|
+
* <LayoutErrorBoundary
|
|
17
|
+
* fallback={(err, retry) => (
|
|
18
|
+
* <div>
|
|
19
|
+
* <p>Layout crashed: {err.message}</p>
|
|
20
|
+
* <button onClick={retry}>Retry</button>
|
|
21
|
+
* </div>
|
|
22
|
+
* )}
|
|
23
|
+
* >
|
|
24
|
+
* <DashboardLayout />
|
|
25
|
+
* </LayoutErrorBoundary>
|
|
26
|
+
* ```
|
|
27
|
+
*
|
|
28
|
+
* @example Data loading with async retry and cached fallback
|
|
29
|
+
* ```tsx
|
|
30
|
+
* <LayoutErrorBoundary
|
|
31
|
+
* retryLoader={() => fetch('/api/blog').then(r => r.json())}
|
|
32
|
+
* fallbackData={{ posts: [] }}
|
|
33
|
+
* >
|
|
34
|
+
* <BlogLayout />
|
|
35
|
+
* </LayoutErrorBoundary>
|
|
36
|
+
* ```
|
|
37
|
+
*/
|
|
3
38
|
export interface LayoutErrorBoundaryProps {
|
|
39
|
+
/** The layout tree to protect. */
|
|
4
40
|
children: ComponentChildren;
|
|
41
|
+
/** Custom fallback UI. Receives the error and a retry callback. */
|
|
5
42
|
fallback?: (error: Error, retry: () => void) => ComponentChildren;
|
|
43
|
+
/** Called when the layout throws. */
|
|
6
44
|
onError?: (error: Error, errorInfo: LayoutErrorInfo) => void;
|
|
7
|
-
|
|
8
|
-
layoutPath?: string;
|
|
45
|
+
/** Categorises the error for structured logging. Defaults to `'component'`. */
|
|
9
46
|
errorType?: 'component' | 'loader' | 'rendering' | 'island';
|
|
47
|
+
/** Async function to re-attempt data loading. Enables the async retry button (up to 3 attempts). */
|
|
48
|
+
retryLoader?: () => Promise<LayoutData>;
|
|
49
|
+
/** Static data to offer as a "Use Cached Data" option when the loader fails. */
|
|
50
|
+
fallbackData?: LayoutData;
|
|
10
51
|
}
|
|
11
|
-
|
|
52
|
+
interface LayoutErrorBoundaryState {
|
|
12
53
|
hasError: boolean;
|
|
13
54
|
error: Error | null;
|
|
14
55
|
errorInfo: LayoutErrorInfo | null;
|
|
15
56
|
retryCount: number;
|
|
57
|
+
isRetrying: boolean;
|
|
58
|
+
fallbackData: LayoutData | null;
|
|
16
59
|
}
|
|
60
|
+
/**
|
|
61
|
+
* Error boundary for Avalon layouts.
|
|
62
|
+
*
|
|
63
|
+
* Catches render and data-loading errors in the wrapped layout tree.
|
|
64
|
+
* Shows a default error card with up to 3 retries, or your custom
|
|
65
|
+
* `fallback`. When `retryLoader` is provided, retry is async. When
|
|
66
|
+
* `fallbackData` is provided, a "Use Cached Data" button appears.
|
|
67
|
+
*
|
|
68
|
+
* @example
|
|
69
|
+
* ```tsx
|
|
70
|
+
* <LayoutErrorBoundary
|
|
71
|
+
* retryLoader={() => fetchDashboardData()}
|
|
72
|
+
* fallbackData={{ widgets: [] }}
|
|
73
|
+
* onError={(err) => logToSentry(err)}
|
|
74
|
+
* >
|
|
75
|
+
* <DashboardLayout />
|
|
76
|
+
* </LayoutErrorBoundary>
|
|
77
|
+
* ```
|
|
78
|
+
*/
|
|
17
79
|
export declare class LayoutErrorBoundary extends Component<LayoutErrorBoundaryProps, LayoutErrorBoundaryState> {
|
|
18
|
-
private maxRetries;
|
|
80
|
+
private readonly maxRetries;
|
|
19
81
|
constructor(props: LayoutErrorBoundaryProps);
|
|
20
82
|
static getDerivedStateFromError(error: Error): Partial<LayoutErrorBoundaryState>;
|
|
21
|
-
componentDidCatch(error: Error, errorInfo:
|
|
22
|
-
|
|
23
|
-
|
|
83
|
+
componentDidCatch(error: Error, errorInfo: {
|
|
84
|
+
componentStack?: string;
|
|
85
|
+
}): void;
|
|
86
|
+
private readonly handleRetry;
|
|
87
|
+
private readonly handleUseFallback;
|
|
24
88
|
render(): ComponentChildren;
|
|
25
89
|
}
|
|
90
|
+
export {};
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{Component as e}from"preact";import{
|
|
1
|
+
import{Component as e}from"preact";import{jsx as t,jsxs 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,isRetrying:!1,fallbackData:e.fallbackData??null}}static getDerivedStateFromError(e){return{hasError:!0,error:e}}componentDidCatch(e,t){let n={errorType:this.props.errorType??`component`,timestamp:Date.now(),componentStack:t.componentStack,errorBoundary:`LayoutErrorBoundary`,layoutPath:void 0};this.setState({errorInfo:n}),this.props.onError?.(e,n)}handleRetry=async()=>{if(!(this.state.retryCount>=this.maxRetries))if(this.props.retryLoader){this.setState({isRetrying:!0});try{let e=await this.props.retryLoader();this.setState(t=>({hasError:!1,error:null,errorInfo:null,retryCount:t.retryCount+1,isRetrying:!1,fallbackData:e}))}catch(e){this.setState(t=>({retryCount:t.retryCount+1,isRetrying:!1,error:e instanceof Error?e:Error(String(e))}))}}else this.setState(e=>({hasError:!1,error:null,errorInfo:null,retryCount:e.retryCount+1}))};handleUseFallback=()=>{this.state.fallbackData&&this.setState({hasError:!1,error:null,errorInfo:null})};render(){if(!this.state.hasError)return this.props.children;let{error:e,retryCount:r,isRetrying:i,fallbackData:a}=this.state;if(this.props.fallback&&e)return this.props.fallback(e,this.handleRetry);let o=r<this.maxRetries,s=typeof process<`u`&&process.env?.NODE_ENV===`development`;return t(`div`,{className:`layout-error-boundary`,children:n(`div`,{className:`error-container`,children:[t(`h2`,{children:`Something went wrong`}),t(`p`,{children:`An error occurred while rendering this layout.`}),n(`div`,{className:`error-actions`,children:[o&&t(`button`,{onClick:this.handleRetry,disabled:i,className:`retry-button`,children:i?`Retrying...`:`Try Again (${this.maxRetries-r} left)`}),a!==null&&t(`button`,{onClick:this.handleUseFallback,className:`fallback-button`,children:`Use Cached Data`})]}),s&&e&&n(`details`,{className:`error-details`,children:[t(`summary`,{children:`Error Details (Development)`}),n(`p`,{children:[t(`strong`,{children:`Error:`}),` `,e.message]}),this.state.errorInfo&&n(`p`,{children:[t(`strong`,{children:`Error Type:`}),` `,this.state.errorInfo.errorType]}),t(`pre`,{className:`error-stack`,children:e.stack})]})]})})}}
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Built-in custom hydration directives.
|
|
3
|
+
*
|
|
4
|
+
* These extend the core set (on:client, on:visible, on:interaction, on:idle, media:*)
|
|
5
|
+
* with additional strategies that users can opt into.
|
|
6
|
+
*
|
|
7
|
+
* Import and call `registerBuiltinDirectives()` in your server entry
|
|
8
|
+
* to make them available.
|
|
9
|
+
*
|
|
10
|
+
* @module islands/builtin-directives
|
|
11
|
+
*/
|
|
12
|
+
/**
|
|
13
|
+
* Register all built-in custom directives.
|
|
14
|
+
*/
|
|
15
|
+
export declare function registerBuiltinDirectives(): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{registerHydrationDirective as e}from"./hydration-directives.js";export function registerBuiltinDirectives(){e(`on:delay`,{name:`on:delay`,script:(e,t,n)=>{setTimeout(t,Number.parseInt(n||`1000`,10))}}),e(`on:event`,{name:`on:event`,script:(e,t,n)=>{if(!n){t();return}let r=()=>{document.removeEventListener(n,r),t()};document.addEventListener(n,r,{once:!0})}}),e(`on:scroll`,{name:`on:scroll`,script:(e,t,n)=>{let r=Number.parseInt(n||`100`,10),i=()=>{globalThis.scrollY>=r&&(globalThis.removeEventListener(`scroll`,i),t())};globalThis.addEventListener(`scroll`,i,{passive:!0}),globalThis.scrollY>=r&&(globalThis.removeEventListener(`scroll`,i),t())}}),e(`on:match`,{name:`on:match`,script:(e,t,n)=>{if(!n){t();return}let r=globalThis.matchMedia(n);if(r.matches){t();return}let i=e=>{e.matches&&(r.removeEventListener(`change`,i),t())};r.addEventListener(`change`,i)}})}
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Custom Hydration Directives
|
|
3
|
+
*
|
|
4
|
+
* Allows users to define custom hydration strategies for islands.
|
|
5
|
+
* A directive controls _when_ an island hydrates on the client.
|
|
6
|
+
*
|
|
7
|
+
* Built-in directives (on:client, on:visible, on:interaction, on:idle, media:*)
|
|
8
|
+
* are handled natively in main.js. This module enables user-defined directives
|
|
9
|
+
* that extend the system with arbitrary trigger logic.
|
|
10
|
+
*
|
|
11
|
+
* @example
|
|
12
|
+
* @example
|
|
13
|
+
* ```ts
|
|
14
|
+
* // Register a directive that hydrates after a delay
|
|
15
|
+
* registerHydrationDirective('on:delay', {
|
|
16
|
+
* name: 'on:delay',
|
|
17
|
+
* // Runs on the client — receives the island element and a hydrate callback
|
|
18
|
+
* script: (el, hydrate, arg) => {
|
|
19
|
+
* const ms = parseInt(arg || '1000', 10);
|
|
20
|
+
* setTimeout(hydrate, ms);
|
|
21
|
+
* },
|
|
22
|
+
* });
|
|
23
|
+
*
|
|
24
|
+
* // Use in a page via the island prop
|
|
25
|
+
* <Counter island={{ condition: 'on:delay', conditionArg: '2000' }} />
|
|
26
|
+
* ```
|
|
27
|
+
* @module islands/hydration-directives
|
|
28
|
+
*/
|
|
29
|
+
/**
|
|
30
|
+
* A client-side hydration directive function.
|
|
31
|
+
*
|
|
32
|
+
* Called once per island element when the page initializes.
|
|
33
|
+
* The function must call `hydrate()` exactly once when the island
|
|
34
|
+
* should become interactive.
|
|
35
|
+
*
|
|
36
|
+
* @param el - The `<avalon-island>` DOM element
|
|
37
|
+
* @param hydrate - Callback that triggers hydration. Call it once.
|
|
38
|
+
* @param arg - Optional argument string from `conditionArg` prop
|
|
39
|
+
*/
|
|
40
|
+
export type HydrationDirectiveFn = (el: HTMLElement, hydrate: () => void, arg?: string) => void | (() => void);
|
|
41
|
+
/**
|
|
42
|
+
* Definition of a custom hydration directive.
|
|
43
|
+
*/
|
|
44
|
+
export interface HydrationDirectiveDefinition {
|
|
45
|
+
/** Directive name — must match the `condition` prop value (e.g. "on:delay") */
|
|
46
|
+
name: string;
|
|
47
|
+
/**
|
|
48
|
+
* Client-side script that controls when hydration fires.
|
|
49
|
+
*
|
|
50
|
+
* Can be either:
|
|
51
|
+
* - A function (will be serialized to the client)
|
|
52
|
+
* - A string of JavaScript (inlined directly)
|
|
53
|
+
*/
|
|
54
|
+
script: HydrationDirectiveFn | string;
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Register a custom hydration directive.
|
|
58
|
+
*
|
|
59
|
+
* @param name - Directive name (e.g. "on:delay", "on:event")
|
|
60
|
+
* @param definition - The directive definition
|
|
61
|
+
*/
|
|
62
|
+
export declare function registerHydrationDirective(name: string, definition: HydrationDirectiveDefinition): void;
|
|
63
|
+
/**
|
|
64
|
+
* Unregister a custom hydration directive.
|
|
65
|
+
*/
|
|
66
|
+
export declare function unregisterHydrationDirective(name: string): boolean;
|
|
67
|
+
/**
|
|
68
|
+
* Check whether a condition string maps to a registered custom directive.
|
|
69
|
+
*/
|
|
70
|
+
export declare function isCustomDirective(condition: string): boolean;
|
|
71
|
+
/**
|
|
72
|
+
* Get a registered directive definition by name.
|
|
73
|
+
*/
|
|
74
|
+
export declare function getDirective(name: string): HydrationDirectiveDefinition | undefined;
|
|
75
|
+
/**
|
|
76
|
+
* Get all registered custom directive names.
|
|
77
|
+
*/
|
|
78
|
+
export declare function getRegisteredDirectives(): string[];
|
|
79
|
+
/**
|
|
80
|
+
* Serialize a directive's script to an inline-safe string.
|
|
81
|
+
* Used by the SSR renderer to embed the directive logic in the HTML
|
|
82
|
+
* so the client can execute it without an extra network request.
|
|
83
|
+
*/
|
|
84
|
+
export declare function serializeDirectiveScript(name: string): string | null;
|
|
85
|
+
/**
|
|
86
|
+
* Clear all registered directives. Useful for testing.
|
|
87
|
+
* @internal
|
|
88
|
+
*/
|
|
89
|
+
export declare function clearDirectives(): void;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
const e=new Map;export function registerHydrationDirective(t,n){e.has(t)&&console.warn(`[avalon] Hydration directive "${t}" is already registered. Overwriting.`),e.set(t,n)}export function unregisterHydrationDirective(t){return e.delete(t)}export function isCustomDirective(t){return e.has(t)}export function getDirective(t){return e.get(t)}export function getRegisteredDirectives(){return[...e.keys()]}export function serializeDirectiveScript(t){let n=e.get(t);return n?typeof n.script==`string`?n.script:n.script.toString():null}export function clearDirectives(){e.clear()}
|
|
@@ -6,7 +6,7 @@ declare global {
|
|
|
6
6
|
var __viteDevServer: ViteDevServer | undefined;
|
|
7
7
|
}
|
|
8
8
|
/** Supported hydration conditions for island components */
|
|
9
|
-
export type HydrationCondition = 'on:visible' | 'on:interaction' | 'on:idle' | 'on:client' | `media:${string}`;
|
|
9
|
+
export type HydrationCondition = 'on:visible' | 'on:interaction' | 'on:idle' | 'on:client' | `media:${string}` | `on:${string}`;
|
|
10
10
|
/** Supported framework identifiers (without "unknown") */
|
|
11
11
|
export type FrameworkId = Exclude<Framework, 'unknown'>;
|
|
12
12
|
export interface IslandProps {
|
|
@@ -14,6 +14,8 @@ export interface IslandProps {
|
|
|
14
14
|
src: string;
|
|
15
15
|
/** Hydration condition */
|
|
16
16
|
condition?: HydrationCondition;
|
|
17
|
+
/** Optional argument passed to custom hydration directives */
|
|
18
|
+
conditionArg?: string;
|
|
17
19
|
/** Props to pass to the island component */
|
|
18
20
|
props?: Record<string, unknown>;
|
|
19
21
|
/** Children to render inside the island (for SSR) */
|
|
@@ -37,7 +39,7 @@ export interface IslandProps {
|
|
|
37
39
|
* Uses custom elements instead of div wrappers for cleaner, more semantic markup.
|
|
38
40
|
* Supports intelligent rendering strategy detection to skip hydration for SSR-only components.
|
|
39
41
|
*/
|
|
40
|
-
export default function Island({ src, condition, props, children, ssr, framework, ssrOnly, renderOptions, hydrationData, }: IslandProps): JSX.Element;
|
|
42
|
+
export default function Island({ src, condition, conditionArg, props, children, ssr, framework, ssrOnly, renderOptions, hydrationData, }: IslandProps): JSX.Element;
|
|
41
43
|
/**
|
|
42
44
|
* Universal renderIsland function – auto-detects framework and handles SSR + hydration.
|
|
43
45
|
*
|
|
@@ -54,4 +56,4 @@ export default function Island({ src, condition, props, children, ssr, framework
|
|
|
54
56
|
* Error isolation: If SSR fails, returns an error placeholder instead of throwing,
|
|
55
57
|
* allowing the page to continue rendering other islands.
|
|
56
58
|
*/
|
|
57
|
-
export declare function renderIsland({ src, condition, props, children, ssr, framework, ssrOnly, renderOptions, component: preloadedComponent, }: IslandProps): Promise<JSX.Element>;
|
|
59
|
+
export declare function renderIsland({ src, condition, conditionArg, props, children, ssr, framework, ssrOnly, renderOptions, component: preloadedComponent, }: IslandProps): Promise<JSX.Element>;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{h as e}from"preact";import{detectFramework as t}from"./framework-detection.js";import{analyzeComponentFile as n,renderComponentSSROnly as r}from"./component-analysis.js";import{loadIntegration as i,detectFrameworkFromPath as a}from"./integration-loader.js";import{addUniversalCSS as o}from"./universal-css-collector.js";import{addUniversalHead as s}from"./universal-head-collector.js";import{getIslandBundlePath as c}from"../build/island-manifest.js";import{isDev as l,devLog as u,devWarn as d,devError as f,logRenderTiming as p}from"../utils/dev-logger.js";function
|
|
1
|
+
import{h as e}from"preact";import{detectFramework as t}from"./framework-detection.js";import{analyzeComponentFile as n,renderComponentSSROnly as r}from"./component-analysis.js";import{loadIntegration as i,detectFrameworkFromPath as a}from"./integration-loader.js";import{addUniversalCSS as o}from"./universal-css-collector.js";import{addUniversalHead as s}from"./universal-head-collector.js";import{getIslandBundlePath as c}from"../build/island-manifest.js";import{isDev as l,devLog as u,devWarn as d,devError as f,logRenderTiming as p}from"../utils/dev-logger.js";import{isCustomDirective as m,serializeDirectiveScript as h}from"./hydration-directives.js";function g(e){return`island-${e.replaceAll(/[^a-zA-Z0-9]/g,`-`)}`}function _(e){let t={};e.renderId&&(t[`data-solid-render-id`]=e.renderId);let n=e.metadata;return n?.tagName&&(t[`data-tag-name`]=n.tagName),t}function v(e,t,n,r,i){let a={"data-condition":t,"data-src":c(e),"data-props":JSON.stringify(n),"data-render-strategy":`hydrate`,..._(r)};if(m(t)){a[`data-custom-directive`]=t;let e=h(t);e&&(a[`data-directive-script`]=e)}return i&&(a[`data-condition-arg`]=i),a}function y(e){return e.startsWith(`<script`)?`script`:e.startsWith(`<style`)?`style`:e.startsWith(`<meta`)?`meta`:e.startsWith(`<link`)?`link`:e.includes(`window._$HY`)||e.includes(`_$HY=`)?`script`:`other`}function b(e){let t=e.match(/<style[^>]*>([\s\S]*?)<\/style>/i);return t?t[1].trim():null}function x(e,t,n,r){if(e.css&&o(e.css,t,n,e.scopeId),e.head){let i=e.head.trim(),a=y(i);if(a===`style`){let a=b(i);a&&(u(`${r} Extracting CSS from head <style> tag`),o(a,t,n,e.scopeId));return}s(e.head,t,n,a)}}function S(t){let{islandId:n,detectedFramework:r,shouldSkipHydration:i,src:a,condition:o,conditionArg:s,props:c,hydrationData:l,children:d}=t,f={id:n,"data-framework":r},p=i?{"data-render-strategy":`ssr-only`}:v(a,o,c,l,s);r===`lit`&&u(`🔍 [Island Component] ${a} - Lit hydration data:`,{hydrationDataKeys:Object.keys(l),metadata:l.metadata});let m={...f,...p};return typeof d==`string`?e(`avalon-island`,{...m,dangerouslySetInnerHTML:{__html:d}}):e(`avalon-island`,m,d)}function C(t){let{islandId:n,detectedFramework:r,shouldSkipHydration:i,src:a,condition:o,props:s,hydrationData:l,conditionArg:u}=t;if(i)return e(`avalon-island`,{id:n,"data-render-strategy":`ssr-only`,"data-framework":r});let d={id:n,"data-condition":o,"data-src":c(a),"data-props":JSON.stringify(s),"data-render-strategy":`hydrate`,"data-framework":r,..._(l)};if(m(o)){d[`data-custom-directive`]=o;let e=h(o);e&&(d[`data-directive-script`]=e)}return u&&(d[`data-condition-arg`]=u),e(`avalon-island`,d)}export default function w({src:e,condition:t=`on:client`,conditionArg:n,props:r={},children:i,ssr:o=t!==`on:client`,framework:s,ssrOnly:c=!1,renderOptions:l={},hydrationData:f={}}){let p=g(e),m=c||!!l.forceSSROnly,h=s||a(e),_=i!=null&&i!==``;return u(`🔍 [Island Component] ${e}`,{ssr:o,ssrOnly:c,hasChildren:_,framework:s,condition:t}),o&&_?S({islandId:p,detectedFramework:h,shouldSkipHydration:m,src:e,condition:t,conditionArg:n,props:r,hydrationData:f,children:i}):(o&&!_&&m&&d(`${e}: SSR-only component has no rendered content. This may indicate a rendering error.`),C({islandId:p,detectedFramework:h,shouldSkipHydration:m,src:e,condition:t,props:r,hydrationData:f,conditionArg:n}))}function T(t,n){let r=n instanceof Error?n.message:String(n);return f(`🚨 Island SSR failed for ${t}:`,n),n instanceof Error&&n.stack&&f(`Stack trace:`,n.stack),e(`avalon-island`,{id:g(t),"data-src":c(t),"data-ssr-error":r,"data-render-strategy":`client-only`})}async function E({src:e,condition:t,conditionArg:n,props:r,children:a,ssr:o,framework:s,ssrOnly:c,renderOptions:u,component:d}){let p=`🏝️ [${e}]`;if(!o||a)return w({src:e,condition:t,conditionArg:n,props:r,children:a,ssr:o,framework:s,ssrOnly:c,renderOptions:u});let m;try{m=await i(s)}catch(i){return f(`${p} Failed to load ${s} integration:`,i),w({src:e,condition:t,conditionArg:n,props:r,ssr:!1,framework:s,ssrOnly:c,renderOptions:u})}try{let i=await m.render({component:d??null,props:r,src:e,condition:t,ssrOnly:c,viteServer:globalThis.__viteDevServer,isDev:l()});return x(i,e,s,p),w({src:e,condition:t,conditionArg:n,props:r,children:i.html,ssr:!0,framework:s,ssrOnly:c,renderOptions:u,hydrationData:c?void 0:i.hydrationData})}catch(i){return f(`${p} Fast path SSR failed:`,i),w({src:e,condition:t,conditionArg:n,props:r,ssr:!1,framework:s,ssrOnly:c,renderOptions:u})}}async function D(e,t,r,i){if(t||r.detectScripts===!1)return t;try{let t=await n(e,r);if(t.decision.warnings?.length)for(let e of t.decision.warnings)d(`${i} Analysis warning: ${e}`);return!t.decision.shouldHydrate}catch(e){return d(`${i} Component analysis failed:`,e),t}}async function O(e){return e.endsWith(`.vue`)?`vue`:e.endsWith(`.svelte`)?`svelte`:e.endsWith(`.tsx`)||e.endsWith(`.jsx`)||e.endsWith(`.ts`)||e.endsWith(`.js`)?t(e):`unknown`}async function k(e,t,n,r,i,a,o){let s=await O(e),c=s,u=await(await A(s,a)).render({component:o??null,props:n,src:e,condition:t,ssrOnly:r,viteServer:globalThis.__viteDevServer,isDev:l()});return x(u,e,s,a),w({src:e,condition:t,props:n,children:u.html,ssr:!0,framework:c,ssrOnly:r,renderOptions:i,hydrationData:r?void 0:u.hydrationData})}async function A(e,t){try{u(`${t} Loading integration for framework: ${e}`);let n=await i(e);return u(`${t} ✅ Integration loaded successfully`),n}catch(n){throw f(`${t} Failed to load ${e} integration:`,n),Error(`Failed to load integration for framework '${e}'. Make sure @useavalon/${e} is installed.\nInstall it with: deno add @useavalon/${e}`,{cause:n})}}export async function renderIsland({src:e,condition:t=`on:client`,conditionArg:n,props:r={},children:i,ssr:a=t!==`on:client`,framework:o,ssrOnly:s=!1,renderOptions:c={},component:u}){let d=l()?performance.now():0,f=`🏝️ [${e}]`;try{return s&&!a&&(a=!0),o?await E({src:e,condition:t,conditionArg:n,props:r,children:i,ssr:a,framework:o,ssrOnly:s,renderOptions:c,component:u}):await j({src:e,condition:t,conditionArg:n,props:r,children:i,ssr:a,ssrOnly:s,renderOptions:c,logPrefix:f,component:u})}catch(t){return T(e,t)}finally{l()&&p(e,performance.now()-d)}}async function j(e){let{src:t,condition:n,conditionArg:r,props:i,children:a,ssr:o,ssrOnly:s,renderOptions:c,logPrefix:l,component:d}=e;if(u(`🔍 [renderIsland] ${t} - Starting render (slow path)`,{ssr:o,ssrOnly:s,hasChildren:!!a,condition:n}),await D(t,s,c,l))return M(t,n,i,a,o,c,l);if(!o||a)return w({src:t,condition:n,conditionArg:r,props:i,children:a,ssr:o,renderOptions:c});try{return await k(t,n,i,s,c,l,d)}catch(e){let a=await O(t);return f(`${l} Framework rendering failed:`,e),w({src:t,condition:n,conditionArg:r,props:i,ssr:!1,framework:a,renderOptions:c})}}function M(e,t,n,i,a,o,s){return a&&!i?r({src:e,condition:t,props:n,renderOptions:o}).catch(r=>(f(`${s} SSR failed for SSR-only component:`,r),w({src:e,condition:t,props:n,ssr:!1,ssrOnly:!0,renderOptions:o}))):w({src:e,condition:t,props:n,children:i,ssr:a,ssrOnly:!0,renderOptions:o})}
|
|
@@ -12,8 +12,10 @@ export type Framework = "solid" | "vue" | "svelte" | "preact" | "react" | "lit"
|
|
|
12
12
|
export interface IslandProps {
|
|
13
13
|
/** Path to the island component (e.g., "/islands/Counter.tsx") */
|
|
14
14
|
src: string;
|
|
15
|
-
/** Hydration condition */
|
|
16
|
-
condition?: "on:visible" | "on:interaction" | "on:idle" | "on:client" | `media:${string}`;
|
|
15
|
+
/** Hydration condition (built-in or custom directive name) */
|
|
16
|
+
condition?: "on:visible" | "on:interaction" | "on:idle" | "on:client" | `media:${string}` | `on:${string}`;
|
|
17
|
+
/** Optional argument passed to custom hydration directives */
|
|
18
|
+
conditionArg?: string;
|
|
17
19
|
/** Props to pass to the island component */
|
|
18
20
|
props?: Record<string, unknown>;
|
|
19
21
|
/** Children to render inside the island (for SSR) */
|
|
@@ -14,25 +14,12 @@ export { LayoutComposer } from './core/layout/layout-composer.ts';
|
|
|
14
14
|
export type { LayoutConfig } from './schemas/layout.ts';
|
|
15
15
|
export { EnhancedLayoutResolver, createEnhancedLayoutResolver, EnhancedLayoutResolverUtils, } from './core/layout/enhanced-layout-resolver.ts';
|
|
16
16
|
export type { EnhancedLayoutResolverOptions } from './core/layout/enhanced-layout-resolver.ts';
|
|
17
|
-
export { IslandPersistence, defaultIslandPersistence } from './core/islands/island-persistence.ts';
|
|
18
|
-
export { IslandStateSerializer } from './core/islands/island-state-serializer.ts';
|
|
19
|
-
export { createPersistentIslandContext, usePersistentIslandContext, PersistentIslandProvider, } from './core/islands/persistent-island-context.tsx';
|
|
20
|
-
export { PersistentIsland } from './components/PersistentIsland.tsx';
|
|
21
|
-
export type { IslandState, PersistentIslandProps, PersistentIslandContext } from './schemas/layout.ts';
|
|
22
|
-
export { LayoutErrorBoundary } from './components/LayoutErrorBoundary.tsx';
|
|
23
|
-
export { LayoutDataErrorBoundary } from './components/LayoutDataErrorBoundary.tsx';
|
|
24
|
-
export { IslandErrorBoundary, withIslandErrorBoundary } from './components/IslandErrorBoundary.tsx';
|
|
25
|
-
export { StreamingErrorBoundary, withStreamingErrorBoundary } from './components/StreamingErrorBoundary.tsx';
|
|
26
|
-
export type { LayoutErrorInfo, LayoutErrorBoundaryProps, ErrorRecoveryStrategy } from './schemas/layout.ts';
|
|
27
|
-
export { StreamingLayout, StreamingSuspense, withStreaming, useStreamingState } from './components/StreamingLayout.tsx';
|
|
28
|
-
export type { StreamingLayoutProps, StreamingComponent } from './schemas/layout.ts';
|
|
29
17
|
export { LayoutCacheManager } from './core/layout/layout-cache-manager.ts';
|
|
30
18
|
export type { CacheEntry, CacheStats, CacheConfig, } from './core/layout/layout-cache-manager.ts';
|
|
31
19
|
export type { LayoutContext, LayoutData, LayoutHandler, LayoutProps, LayoutLoader, ResolvedLayout, LayoutCache, EnhancedLayoutContext, LayoutMatcherFunction, LayoutErrorHandler, LayoutRetryFunction, LayoutFallbackRenderer, IslandStateSaver, IslandStateLoader, IslandStateClearer, StreamingReadyCheck, } from './schemas/layout.ts';
|
|
32
20
|
export type { ILayoutDiscovery, ILayoutMatcher, ILayoutComposer, IIslandPersistence, ILayoutErrorRecovery, ILayoutStreaming, IEnhancedLayoutResolver, ILayoutComponent, IPersistentIslandComponent, ILayoutErrorBoundaryComponent, IStreamingLayoutComponent, LayoutModule, PageModule, LayoutResolutionContext, LayoutPerformanceMetrics, LayoutDebugInfo, LayoutEventType, LayoutEventData, LayoutEventHandler, ILayoutEventEmitter, } from './types/layout.ts';
|
|
33
21
|
export { LayoutContextSchema, LayoutDataSchema, LayoutRouteSchema, LayoutHandlerSchema, LayoutPropsSchema, LayoutDiscoveryOptionsSchema, RouteInfoSchema, LayoutRuleSchema, LayoutConfigSchema, IslandStateSchema, PersistentIslandPropsSchema, PersistentIslandContextSchema, LayoutErrorInfoSchema, LayoutErrorBoundaryPropsSchema, ErrorRecoveryStrategySchema, StreamingLayoutPropsSchema, StreamingComponentSchema, ResolvedLayoutSchema, LayoutCacheSchema, EnhancedLayoutContextSchema, } from './schemas/layout.ts';
|
|
34
22
|
export { EnhancedLayoutResolver as LayoutSystem } from './core/layout/enhanced-layout-resolver.ts';
|
|
35
|
-
export { defaultIslandPersistence as defaultPersistence } from './core/islands/island-persistence.ts';
|
|
36
23
|
export { createEnhancedLayoutResolver as createLayoutSystem } from './core/layout/enhanced-layout-resolver.ts';
|
|
37
24
|
/**
|
|
38
25
|
* Layout System Version Information
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export{LayoutDiscovery}from"./core/layout/layout-discovery.js";export{LayoutDataLoader,LayoutDataLoadingError,loadSingleLayoutData,mergeLayoutData,getParentLayoutData,defaultLayoutDataLoader}from"./core/layout/layout-data-loader.js";export{LayoutMatcher as LayoutMatcherClass,BuiltInLayoutRules}from"./core/layout/layout-matcher.js";export{LayoutComposer}from"./core/layout/layout-composer.js";export{EnhancedLayoutResolver,createEnhancedLayoutResolver,EnhancedLayoutResolverUtils}from"./core/layout/enhanced-layout-resolver.js";export{
|
|
1
|
+
export{LayoutDiscovery}from"./core/layout/layout-discovery.js";export{LayoutDataLoader,LayoutDataLoadingError,loadSingleLayoutData,mergeLayoutData,getParentLayoutData,defaultLayoutDataLoader}from"./core/layout/layout-data-loader.js";export{LayoutMatcher as LayoutMatcherClass,BuiltInLayoutRules}from"./core/layout/layout-matcher.js";export{LayoutComposer}from"./core/layout/layout-composer.js";export{EnhancedLayoutResolver,createEnhancedLayoutResolver,EnhancedLayoutResolverUtils}from"./core/layout/enhanced-layout-resolver.js";export{LayoutCacheManager}from"./core/layout/layout-cache-manager.js";export{LayoutContextSchema,LayoutDataSchema,LayoutRouteSchema,LayoutHandlerSchema,LayoutPropsSchema,LayoutDiscoveryOptionsSchema,RouteInfoSchema,LayoutRuleSchema,LayoutConfigSchema,IslandStateSchema,PersistentIslandPropsSchema,PersistentIslandContextSchema,LayoutErrorInfoSchema,LayoutErrorBoundaryPropsSchema,ErrorRecoveryStrategySchema,StreamingLayoutPropsSchema,StreamingComponentSchema,ResolvedLayoutSchema,LayoutCacheSchema,EnhancedLayoutContextSchema}from"./schemas/layout.js";export{EnhancedLayoutResolver as LayoutSystem}from"./core/layout/enhanced-layout-resolver.js";export{createEnhancedLayoutResolver as createLayoutSystem}from"./core/layout/enhanced-layout-resolver.js";export const LAYOUT_SYSTEM_VERSION=`1.0.0`;export const LAYOUT_SYSTEM_FEATURES={DISCOVERY:!0,DATA_LOADING:!0,CONDITIONAL_RENDERING:!0,COMPOSITION_CONTROL:!0,PERSISTENT_ISLANDS:!0,ERROR_BOUNDARIES:!0,STREAMING:!0,CACHING:!0,PERFORMANCE_MONITORING:!0,DEBUG_UTILITIES:!0};export const LAYOUT_SYSTEM_DEFAULTS={DISCOVERY:{baseDirectory:`src/pages`,filePattern:`_layout.tsx`,excludeDirectories:[`node_modules`,`.git`,`dist`],enableWatching:!1,developmentMode:!1},CACHING:{enabled:!0,ttl:3e5,maxSize:100,cleanupInterval:6e4},STREAMING:{enabled:!0,priority:`medium`,timeout:5e3},ERROR_BOUNDARIES:{enabled:!0,maxRetries:3,fallbackStrategy:`component`},PERFORMANCE:{monitoring:!0,thresholds:{discoveryTime:100,dataLoadingTime:500,renderingTime:200,totalTime:1e3}}};
|