@useavalon/avalon 0.1.13 → 0.1.15
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/dist/mod.js +1 -0
- package/dist/src/build/integration-bundler-plugin.js +1 -0
- package/dist/src/build/integration-config.js +1 -0
- package/dist/src/build/integration-detection-plugin.js +1 -0
- package/dist/src/build/integration-resolver-plugin.js +1 -0
- package/dist/src/build/island-manifest.js +1 -0
- package/dist/src/build/island-types-generator.js +5 -0
- package/dist/src/build/mdx-island-transform.js +2 -0
- package/dist/src/build/mdx-plugin.js +1 -0
- package/dist/src/build/page-island-transform.js +3 -0
- package/dist/src/build/prop-extractors/index.js +1 -0
- package/dist/src/build/prop-extractors/lit.js +1 -0
- package/dist/src/build/prop-extractors/qwik.js +1 -0
- package/dist/src/build/prop-extractors/solid.js +1 -0
- package/dist/src/build/prop-extractors/svelte.js +1 -0
- package/dist/src/build/prop-extractors/vue.js +1 -0
- package/dist/src/build/sidecar-file-manager.js +1 -0
- package/dist/src/build/sidecar-renderer.js +6 -0
- package/dist/src/client/adapters/index.js +1 -0
- package/dist/src/client/components.js +1 -0
- package/dist/src/client/css-hmr-handler.js +1 -0
- package/dist/src/client/framework-adapter.js +13 -0
- package/dist/src/client/hmr-coordinator.js +1 -0
- package/dist/src/client/hmr-error-overlay.js +214 -0
- package/dist/src/client/main.js +39 -0
- package/dist/src/components/Image.js +1 -0
- package/dist/src/components/IslandErrorBoundary.js +1 -0
- package/dist/src/components/LayoutDataErrorBoundary.js +1 -0
- package/dist/src/components/LayoutErrorBoundary.js +1 -0
- package/dist/src/components/PersistentIsland.js +1 -0
- package/dist/src/components/StreamingErrorBoundary.js +1 -0
- package/dist/src/components/StreamingLayout.js +29 -0
- package/dist/src/core/components/component-analyzer.js +1 -0
- package/dist/src/core/components/component-detection.js +5 -0
- package/dist/src/core/components/enhanced-framework-detector.js +1 -0
- package/dist/src/core/components/framework-registry.js +1 -0
- package/dist/src/core/content/mdx-processor.js +1 -0
- package/dist/src/core/integrations/index.js +1 -0
- package/dist/src/core/integrations/loader.js +1 -0
- package/dist/src/core/integrations/registry.js +1 -0
- package/dist/src/core/islands/island-persistence.js +1 -0
- package/dist/src/core/islands/island-state-serializer.js +1 -0
- package/dist/src/core/islands/persistent-island-context.js +1 -0
- package/dist/src/core/islands/use-persistent-state.js +1 -0
- package/dist/src/core/layout/enhanced-layout-resolver.js +1 -0
- package/dist/src/core/layout/layout-cache-manager.js +1 -0
- package/dist/src/core/layout/layout-composer.js +1 -0
- package/dist/src/core/layout/layout-data-loader.js +1 -0
- package/dist/src/core/layout/layout-discovery.js +1 -0
- package/dist/src/core/layout/layout-matcher.js +1 -0
- package/dist/src/core/layout/layout-types.js +1 -0
- package/dist/src/core/modules/framework-module-resolver.js +1 -0
- package/dist/src/islands/component-analysis.js +1 -0
- package/dist/src/islands/css-utils.js +17 -0
- package/dist/src/islands/discovery/index.js +1 -0
- package/dist/src/islands/discovery/registry.js +1 -0
- package/dist/src/islands/discovery/resolver.js +2 -0
- package/dist/src/islands/discovery/scanner.js +1 -0
- package/dist/src/islands/discovery/types.js +1 -0
- package/dist/src/islands/discovery/validator.js +18 -0
- package/dist/src/islands/discovery/watcher.js +1 -0
- package/dist/src/islands/framework-detection.js +1 -0
- package/dist/src/islands/integration-loader.js +1 -0
- package/dist/src/islands/island.js +1 -0
- package/dist/src/islands/render-cache.js +1 -0
- package/dist/src/islands/types.js +1 -0
- package/dist/src/islands/universal-css-collector.js +5 -0
- package/dist/src/islands/universal-head-collector.js +2 -0
- package/dist/src/layout-system.js +1 -0
- package/dist/src/middleware/discovery.js +1 -0
- package/dist/src/middleware/executor.js +1 -0
- package/dist/src/middleware/index.js +1 -0
- package/dist/src/middleware/types.js +1 -0
- package/dist/src/nitro/build-config.js +1 -0
- package/dist/src/nitro/config.js +1 -0
- package/dist/src/nitro/error-handler.js +198 -0
- package/dist/src/nitro/index.js +1 -0
- package/dist/src/nitro/island-manifest.js +2 -0
- package/dist/src/nitro/middleware-adapter.js +1 -0
- package/dist/src/nitro/renderer.js +183 -0
- package/dist/src/nitro/route-discovery.js +1 -0
- package/dist/src/nitro/types.js +1 -0
- package/dist/src/render/collect-css.js +3 -0
- package/dist/src/render/error-pages.js +48 -0
- package/dist/src/render/isolated-ssr-renderer.js +1 -0
- package/dist/src/render/ssr.js +90 -0
- package/dist/src/schemas/api.js +1 -0
- package/dist/src/schemas/core.js +1 -0
- package/dist/src/schemas/index.js +1 -0
- package/dist/src/schemas/layout.js +1 -0
- package/dist/src/schemas/routing/index.js +1 -0
- package/dist/src/schemas/routing.js +1 -0
- package/dist/src/types/as-island.js +1 -0
- package/dist/src/types/layout.js +1 -0
- package/dist/src/types/routing.js +1 -0
- package/dist/src/types/types.js +1 -0
- package/dist/src/utils/dev-logger.js +12 -0
- package/dist/src/utils/fs.js +1 -0
- package/dist/src/vite-plugin/auto-discover.js +1 -0
- package/dist/src/vite-plugin/config.js +1 -0
- package/dist/src/vite-plugin/errors.js +1 -0
- package/dist/src/vite-plugin/image-optimization.js +45 -0
- package/dist/src/vite-plugin/integration-activator.js +1 -0
- package/dist/src/vite-plugin/island-sidecar-plugin.js +1 -0
- package/dist/src/vite-plugin/module-discovery.js +1 -0
- package/dist/src/vite-plugin/nitro-integration.js +42 -0
- package/dist/src/vite-plugin/plugin.js +1 -0
- package/dist/src/vite-plugin/types.js +1 -0
- package/dist/src/vite-plugin/validation.js +2 -0
- package/package.json +14 -20
- package/mod.ts +0 -302
- package/src/build/integration-bundler-plugin.ts +0 -116
- package/src/build/integration-config.ts +0 -168
- package/src/build/integration-detection-plugin.ts +0 -117
- package/src/build/integration-resolver-plugin.ts +0 -90
- package/src/build/island-manifest.ts +0 -269
- package/src/build/island-types-generator.ts +0 -476
- package/src/build/mdx-island-transform.ts +0 -464
- package/src/build/mdx-plugin.ts +0 -98
- package/src/build/page-island-transform.ts +0 -598
- package/src/build/prop-extractors/index.ts +0 -21
- package/src/build/prop-extractors/lit.ts +0 -140
- package/src/build/prop-extractors/qwik.ts +0 -16
- package/src/build/prop-extractors/solid.ts +0 -125
- package/src/build/prop-extractors/svelte.ts +0 -194
- package/src/build/prop-extractors/vue.ts +0 -111
- package/src/build/sidecar-file-manager.ts +0 -104
- package/src/build/sidecar-renderer.ts +0 -30
- package/src/client/adapters/index.ts +0 -21
- package/src/client/components.ts +0 -35
- package/src/client/css-hmr-handler.ts +0 -344
- package/src/client/framework-adapter.ts +0 -462
- package/src/client/hmr-coordinator.ts +0 -396
- package/src/client/hmr-error-overlay.js +0 -533
- package/src/client/main.js +0 -824
- package/src/components/Image.tsx +0 -123
- package/src/components/IslandErrorBoundary.tsx +0 -145
- package/src/components/LayoutDataErrorBoundary.tsx +0 -141
- package/src/components/LayoutErrorBoundary.tsx +0 -127
- package/src/components/PersistentIsland.tsx +0 -52
- package/src/components/StreamingErrorBoundary.tsx +0 -233
- package/src/components/StreamingLayout.tsx +0 -538
- package/src/core/components/component-analyzer.ts +0 -192
- package/src/core/components/component-detection.ts +0 -508
- package/src/core/components/enhanced-framework-detector.ts +0 -500
- package/src/core/components/framework-registry.ts +0 -563
- package/src/core/content/mdx-processor.ts +0 -46
- package/src/core/integrations/index.ts +0 -19
- package/src/core/integrations/loader.ts +0 -125
- package/src/core/integrations/registry.ts +0 -175
- package/src/core/islands/island-persistence.ts +0 -325
- package/src/core/islands/island-state-serializer.ts +0 -258
- package/src/core/islands/persistent-island-context.tsx +0 -80
- package/src/core/islands/use-persistent-state.ts +0 -68
- package/src/core/layout/enhanced-layout-resolver.ts +0 -322
- package/src/core/layout/layout-cache-manager.ts +0 -485
- package/src/core/layout/layout-composer.ts +0 -357
- package/src/core/layout/layout-data-loader.ts +0 -516
- package/src/core/layout/layout-discovery.ts +0 -243
- package/src/core/layout/layout-matcher.ts +0 -299
- package/src/core/layout/layout-types.ts +0 -110
- package/src/core/modules/framework-module-resolver.ts +0 -273
- package/src/islands/component-analysis.ts +0 -213
- package/src/islands/css-utils.ts +0 -565
- package/src/islands/discovery/index.ts +0 -80
- package/src/islands/discovery/registry.ts +0 -340
- package/src/islands/discovery/resolver.ts +0 -477
- package/src/islands/discovery/scanner.ts +0 -386
- package/src/islands/discovery/types.ts +0 -117
- package/src/islands/discovery/validator.ts +0 -544
- package/src/islands/discovery/watcher.ts +0 -368
- package/src/islands/framework-detection.ts +0 -428
- package/src/islands/integration-loader.ts +0 -490
- package/src/islands/island.tsx +0 -565
- package/src/islands/render-cache.ts +0 -550
- package/src/islands/types.ts +0 -80
- package/src/islands/universal-css-collector.ts +0 -157
- package/src/islands/universal-head-collector.ts +0 -137
- package/src/layout-system.ts +0 -218
- package/src/middleware/discovery.ts +0 -268
- package/src/middleware/executor.ts +0 -315
- package/src/middleware/index.ts +0 -76
- package/src/middleware/types.ts +0 -99
- package/src/nitro/build-config.ts +0 -576
- package/src/nitro/config.ts +0 -483
- package/src/nitro/error-handler.ts +0 -636
- package/src/nitro/index.ts +0 -173
- package/src/nitro/island-manifest.ts +0 -584
- package/src/nitro/middleware-adapter.ts +0 -260
- package/src/nitro/renderer.ts +0 -1471
- package/src/nitro/route-discovery.ts +0 -439
- package/src/nitro/types.ts +0 -321
- package/src/render/collect-css.ts +0 -198
- package/src/render/error-pages.ts +0 -79
- package/src/render/isolated-ssr-renderer.ts +0 -654
- package/src/render/ssr.ts +0 -1030
- package/src/schemas/api.ts +0 -30
- package/src/schemas/core.ts +0 -64
- package/src/schemas/index.ts +0 -212
- package/src/schemas/layout.ts +0 -279
- package/src/schemas/routing/index.ts +0 -38
- package/src/schemas/routing.ts +0 -376
- package/src/types/as-island.ts +0 -20
- package/src/types/layout.ts +0 -285
- package/src/types/routing.ts +0 -555
- package/src/types/types.ts +0 -5
- package/src/utils/dev-logger.ts +0 -299
- package/src/utils/fs.ts +0 -151
- package/src/vite-plugin/auto-discover.ts +0 -551
- package/src/vite-plugin/config.ts +0 -266
- package/src/vite-plugin/errors.ts +0 -127
- package/src/vite-plugin/image-optimization.ts +0 -156
- package/src/vite-plugin/integration-activator.ts +0 -126
- package/src/vite-plugin/island-sidecar-plugin.ts +0 -176
- package/src/vite-plugin/module-discovery.ts +0 -189
- package/src/vite-plugin/nitro-integration.ts +0 -1354
- package/src/vite-plugin/plugin.ts +0 -403
- package/src/vite-plugin/types.ts +0 -327
- package/src/vite-plugin/validation.ts +0 -228
- /package/{src → dist/src}/client/types/framework-runtime.d.ts +0 -0
- /package/{src → dist/src}/client/types/vite-hmr.d.ts +0 -0
- /package/{src → dist/src}/client/types/vite-virtual-modules.d.ts +0 -0
- /package/{src → dist/src}/layout-system.d.ts +0 -0
- /package/{src → dist/src}/types/image.d.ts +0 -0
- /package/{src → dist/src}/types/index.d.ts +0 -0
- /package/{src → dist/src}/types/island-jsx.d.ts +0 -0
- /package/{src → dist/src}/types/island-prop.d.ts +0 -0
- /package/{src → dist/src}/types/mdx.d.ts +0 -0
- /package/{src → dist/src}/types/urlpattern.d.ts +0 -0
- /package/{src → dist/src}/types/vite-env.d.ts +0 -0
|
@@ -1,516 +0,0 @@
|
|
|
1
|
-
import type {
|
|
2
|
-
LayoutContext,
|
|
3
|
-
LayoutData,
|
|
4
|
-
LayoutHandler,
|
|
5
|
-
LayoutLoader,
|
|
6
|
-
LayoutErrorInfo,
|
|
7
|
-
} from './layout-types.ts';
|
|
8
|
-
|
|
9
|
-
/**
|
|
10
|
-
* Layout data loading error with context information
|
|
11
|
-
*/
|
|
12
|
-
export class LayoutDataLoadingError extends Error {
|
|
13
|
-
constructor(message: string, public readonly layoutPath: string, public readonly originalError?: Error) {
|
|
14
|
-
super(message);
|
|
15
|
-
this.name = 'LayoutDataLoadingError';
|
|
16
|
-
}
|
|
17
|
-
}
|
|
18
|
-
|
|
19
|
-
/**
|
|
20
|
-
* Result of a layout data loading operation
|
|
21
|
-
*/
|
|
22
|
-
export interface LayoutDataLoadingResult {
|
|
23
|
-
success: boolean;
|
|
24
|
-
data: LayoutData;
|
|
25
|
-
error?: LayoutDataLoadingError;
|
|
26
|
-
loadingTime: number;
|
|
27
|
-
layoutPath: string;
|
|
28
|
-
}
|
|
29
|
-
|
|
30
|
-
/**
|
|
31
|
-
* Options for layout data loading
|
|
32
|
-
*/
|
|
33
|
-
export interface LayoutDataLoadingOptions {
|
|
34
|
-
/**
|
|
35
|
-
* Maximum time to wait for data loading (in milliseconds)
|
|
36
|
-
*/
|
|
37
|
-
timeout?: number;
|
|
38
|
-
|
|
39
|
-
/**
|
|
40
|
-
* Whether to enable parallel loading of multiple loaders
|
|
41
|
-
*/
|
|
42
|
-
enableParallelLoading?: boolean;
|
|
43
|
-
|
|
44
|
-
/**
|
|
45
|
-
* Whether to continue loading other loaders if one fails
|
|
46
|
-
*/
|
|
47
|
-
continueOnError?: boolean;
|
|
48
|
-
|
|
49
|
-
/**
|
|
50
|
-
* Development mode flag for enhanced error reporting
|
|
51
|
-
*/
|
|
52
|
-
developmentMode?: boolean;
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Maximum number of retry attempts for failed loaders
|
|
56
|
-
*/
|
|
57
|
-
maxRetries?: number;
|
|
58
|
-
|
|
59
|
-
/**
|
|
60
|
-
* Delay between retry attempts (in milliseconds)
|
|
61
|
-
*/
|
|
62
|
-
retryDelay?: number;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
/**
|
|
66
|
-
* Layout data loader execution system
|
|
67
|
-
* Handles parallel data loading for multiple layout loaders in the chain
|
|
68
|
-
*
|
|
69
|
-
* Requirements: 2.1, 2.2, 2.3, 2.4, 2.5, 2.6
|
|
70
|
-
*/
|
|
71
|
-
export class LayoutDataLoader {
|
|
72
|
-
private readonly options: Required<LayoutDataLoadingOptions>;
|
|
73
|
-
|
|
74
|
-
constructor(options: LayoutDataLoadingOptions = {}) {
|
|
75
|
-
this.options = {
|
|
76
|
-
timeout: options.timeout ?? 5000,
|
|
77
|
-
enableParallelLoading: options.enableParallelLoading ?? true,
|
|
78
|
-
continueOnError: options.continueOnError ?? true,
|
|
79
|
-
developmentMode: options.developmentMode ?? false,
|
|
80
|
-
maxRetries: options.maxRetries ?? 2,
|
|
81
|
-
retryDelay: options.retryDelay ?? 1000,
|
|
82
|
-
};
|
|
83
|
-
}
|
|
84
|
-
|
|
85
|
-
/**
|
|
86
|
-
* Loads data for all layout handlers in the chain
|
|
87
|
-
* Requirements: 2.1, 2.2, 2.3, 2.4
|
|
88
|
-
*/
|
|
89
|
-
async loadLayoutData(layoutHandlers: LayoutHandler[], context: LayoutContext): Promise<LayoutDataLoadingResult[]> {
|
|
90
|
-
const handlersWithLoaders = layoutHandlers.filter(handler => handler.loader);
|
|
91
|
-
|
|
92
|
-
if (handlersWithLoaders.length === 0) {
|
|
93
|
-
return [];
|
|
94
|
-
}
|
|
95
|
-
|
|
96
|
-
if (this.options.enableParallelLoading) {
|
|
97
|
-
return await this.loadDataInParallel(handlersWithLoaders, context);
|
|
98
|
-
} else {
|
|
99
|
-
return await this.loadDataSequentially(handlersWithLoaders, context);
|
|
100
|
-
}
|
|
101
|
-
}
|
|
102
|
-
|
|
103
|
-
/**
|
|
104
|
-
* Loads data for multiple loaders in parallel with optimized batching
|
|
105
|
-
* Requirements: 2.2, 2.3, 2.4
|
|
106
|
-
*/
|
|
107
|
-
private async loadDataInParallel(
|
|
108
|
-
handlers: LayoutHandler[],
|
|
109
|
-
context: LayoutContext
|
|
110
|
-
): Promise<LayoutDataLoadingResult[]> {
|
|
111
|
-
// Optimize parallel loading with batching for better performance
|
|
112
|
-
const batchSize = Math.min(handlers.length, 5); // Process max 5 loaders concurrently
|
|
113
|
-
const results: LayoutDataLoadingResult[] = [];
|
|
114
|
-
|
|
115
|
-
// Process handlers in batches
|
|
116
|
-
for (let i = 0; i < handlers.length; i += batchSize) {
|
|
117
|
-
const batch = handlers.slice(i, i + batchSize);
|
|
118
|
-
const batchPromises = batch.map(handler => this.loadSingleLayoutData(handler, context));
|
|
119
|
-
|
|
120
|
-
if (this.options.continueOnError) {
|
|
121
|
-
// Use Promise.allSettled to continue even if some loaders fail
|
|
122
|
-
const batchResults = await Promise.allSettled(batchPromises);
|
|
123
|
-
const processedResults = batchResults.map((result, batchIndex) => {
|
|
124
|
-
if (result.status === 'fulfilled') {
|
|
125
|
-
return result.value;
|
|
126
|
-
} else {
|
|
127
|
-
// Create error result for rejected promises
|
|
128
|
-
const handler = batch[batchIndex];
|
|
129
|
-
const error = new LayoutDataLoadingError(
|
|
130
|
-
`Layout data loading failed: ${result.reason}`,
|
|
131
|
-
handler.path,
|
|
132
|
-
result.reason instanceof Error ? result.reason : new Error(String(result.reason))
|
|
133
|
-
);
|
|
134
|
-
|
|
135
|
-
return {
|
|
136
|
-
success: false,
|
|
137
|
-
data: {},
|
|
138
|
-
error,
|
|
139
|
-
loadingTime: 0,
|
|
140
|
-
layoutPath: handler.path,
|
|
141
|
-
};
|
|
142
|
-
}
|
|
143
|
-
});
|
|
144
|
-
results.push(...processedResults);
|
|
145
|
-
} else {
|
|
146
|
-
// Use Promise.all to fail fast if any loader fails
|
|
147
|
-
try {
|
|
148
|
-
const batchResults = await Promise.all(batchPromises);
|
|
149
|
-
results.push(...batchResults);
|
|
150
|
-
} catch (error) {
|
|
151
|
-
// If any loader in the batch fails and continueOnError is false, stop processing
|
|
152
|
-
throw error;
|
|
153
|
-
}
|
|
154
|
-
}
|
|
155
|
-
}
|
|
156
|
-
|
|
157
|
-
return results;
|
|
158
|
-
}
|
|
159
|
-
|
|
160
|
-
/**
|
|
161
|
-
* Loads data for multiple loaders sequentially
|
|
162
|
-
* Requirements: 2.2, 2.3, 2.4
|
|
163
|
-
*/
|
|
164
|
-
private async loadDataSequentially(
|
|
165
|
-
handlers: LayoutHandler[],
|
|
166
|
-
context: LayoutContext
|
|
167
|
-
): Promise<LayoutDataLoadingResult[]> {
|
|
168
|
-
const results: LayoutDataLoadingResult[] = [];
|
|
169
|
-
|
|
170
|
-
for (const handler of handlers) {
|
|
171
|
-
try {
|
|
172
|
-
const result = await this.loadSingleLayoutData(handler, context);
|
|
173
|
-
results.push(result);
|
|
174
|
-
|
|
175
|
-
// If continueOnError is false and this loader failed, stop processing
|
|
176
|
-
if (!this.options.continueOnError && !result.success) {
|
|
177
|
-
break;
|
|
178
|
-
}
|
|
179
|
-
} catch (error) {
|
|
180
|
-
const loadingError = new LayoutDataLoadingError(
|
|
181
|
-
`Layout data loading failed: ${error instanceof Error ? error.message : String(error)}`,
|
|
182
|
-
handler.path,
|
|
183
|
-
error instanceof Error ? error : new Error(String(error))
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
const result: LayoutDataLoadingResult = {
|
|
187
|
-
success: false,
|
|
188
|
-
data: {},
|
|
189
|
-
error: loadingError,
|
|
190
|
-
loadingTime: 0,
|
|
191
|
-
layoutPath: handler.path,
|
|
192
|
-
};
|
|
193
|
-
|
|
194
|
-
results.push(result);
|
|
195
|
-
|
|
196
|
-
// If continueOnError is false, stop processing
|
|
197
|
-
if (!this.options.continueOnError) {
|
|
198
|
-
break;
|
|
199
|
-
}
|
|
200
|
-
}
|
|
201
|
-
}
|
|
202
|
-
|
|
203
|
-
return results;
|
|
204
|
-
}
|
|
205
|
-
|
|
206
|
-
/**
|
|
207
|
-
* Loads data for a single layout handler with retry logic
|
|
208
|
-
* Requirements: 2.1, 2.2, 2.5, 2.6
|
|
209
|
-
*/
|
|
210
|
-
private async loadSingleLayoutData(handler: LayoutHandler, context: LayoutContext): Promise<LayoutDataLoadingResult> {
|
|
211
|
-
if (!handler.loader) {
|
|
212
|
-
return {
|
|
213
|
-
success: true,
|
|
214
|
-
data: {},
|
|
215
|
-
loadingTime: 0,
|
|
216
|
-
layoutPath: handler.path,
|
|
217
|
-
};
|
|
218
|
-
}
|
|
219
|
-
|
|
220
|
-
let lastError: Error | undefined;
|
|
221
|
-
let attempt = 0;
|
|
222
|
-
|
|
223
|
-
while (attempt <= this.options.maxRetries) {
|
|
224
|
-
const startTime = performance.now();
|
|
225
|
-
|
|
226
|
-
try {
|
|
227
|
-
const data = await this.executeLoaderWithTimeout(handler.loader, context);
|
|
228
|
-
const loadingTime = performance.now() - startTime;
|
|
229
|
-
|
|
230
|
-
if (this.options.developmentMode) {
|
|
231
|
-
console.log(`[Layout] Loaded data for ${handler.path} in ${loadingTime.toFixed(2)}ms`);
|
|
232
|
-
}
|
|
233
|
-
|
|
234
|
-
return {
|
|
235
|
-
success: true,
|
|
236
|
-
data,
|
|
237
|
-
loadingTime,
|
|
238
|
-
layoutPath: handler.path,
|
|
239
|
-
};
|
|
240
|
-
} catch (error) {
|
|
241
|
-
lastError = error instanceof Error ? error : new Error(String(error));
|
|
242
|
-
attempt++;
|
|
243
|
-
|
|
244
|
-
if (this.options.developmentMode) {
|
|
245
|
-
console.warn(`[Layout] Data loading attempt ${attempt} failed for ${handler.path}: ${lastError.message}`);
|
|
246
|
-
}
|
|
247
|
-
|
|
248
|
-
// If this wasn't the last attempt, wait before retrying
|
|
249
|
-
if (attempt <= this.options.maxRetries) {
|
|
250
|
-
await this.delay(this.options.retryDelay);
|
|
251
|
-
}
|
|
252
|
-
}
|
|
253
|
-
}
|
|
254
|
-
|
|
255
|
-
// All attempts failed
|
|
256
|
-
const loadingError = new LayoutDataLoadingError(
|
|
257
|
-
`Layout data loading failed after ${this.options.maxRetries + 1} attempts: ${lastError?.message}`,
|
|
258
|
-
handler.path,
|
|
259
|
-
lastError
|
|
260
|
-
);
|
|
261
|
-
|
|
262
|
-
return {
|
|
263
|
-
success: false,
|
|
264
|
-
data: {},
|
|
265
|
-
error: loadingError,
|
|
266
|
-
loadingTime: 0,
|
|
267
|
-
layoutPath: handler.path,
|
|
268
|
-
};
|
|
269
|
-
}
|
|
270
|
-
|
|
271
|
-
/**
|
|
272
|
-
* Executes a layout loader with timeout protection
|
|
273
|
-
* Requirements: 2.1, 2.5
|
|
274
|
-
*/
|
|
275
|
-
private executeLoaderWithTimeout(loader: LayoutLoader, context: LayoutContext): Promise<LayoutData> {
|
|
276
|
-
return new Promise<LayoutData>((resolve, reject) => {
|
|
277
|
-
const timeoutId = setTimeout(() => {
|
|
278
|
-
reject(new Error(`Layout data loading timed out after ${this.options.timeout}ms`));
|
|
279
|
-
}, this.options.timeout);
|
|
280
|
-
|
|
281
|
-
Promise.resolve(loader(context))
|
|
282
|
-
.then(data => {
|
|
283
|
-
clearTimeout(timeoutId);
|
|
284
|
-
resolve(data);
|
|
285
|
-
})
|
|
286
|
-
.catch(error => {
|
|
287
|
-
clearTimeout(timeoutId);
|
|
288
|
-
reject(error);
|
|
289
|
-
});
|
|
290
|
-
});
|
|
291
|
-
}
|
|
292
|
-
|
|
293
|
-
/**
|
|
294
|
-
* Creates enhanced layout context with parent data
|
|
295
|
-
* Requirements: 2.4, 2.6
|
|
296
|
-
*/
|
|
297
|
-
createEnhancedContext(baseContext: LayoutContext, parentData: LayoutData[]): LayoutContext {
|
|
298
|
-
// Create a new context with parent data available
|
|
299
|
-
const enhancedContext: LayoutContext = {
|
|
300
|
-
...baseContext,
|
|
301
|
-
state: new Map(baseContext.state),
|
|
302
|
-
};
|
|
303
|
-
|
|
304
|
-
// Add parent layout data to the context state
|
|
305
|
-
enhancedContext.state.set('parentLayoutData', parentData);
|
|
306
|
-
|
|
307
|
-
return enhancedContext;
|
|
308
|
-
}
|
|
309
|
-
|
|
310
|
-
/**
|
|
311
|
-
* Processes layout data loading results and creates data array for components
|
|
312
|
-
* Requirements: 2.3, 2.4, 2.6
|
|
313
|
-
*/
|
|
314
|
-
processLoadingResults(
|
|
315
|
-
results: LayoutDataLoadingResult[],
|
|
316
|
-
layoutHandlers: LayoutHandler[]
|
|
317
|
-
): { data: LayoutData[]; errors: LayoutErrorInfo[] } {
|
|
318
|
-
const data: LayoutData[] = [];
|
|
319
|
-
const errors: LayoutErrorInfo[] = [];
|
|
320
|
-
|
|
321
|
-
// Create a map of layout path to result for quick lookup
|
|
322
|
-
const resultMap = new Map<string, LayoutDataLoadingResult>();
|
|
323
|
-
results.forEach(result => {
|
|
324
|
-
resultMap.set(result.layoutPath, result);
|
|
325
|
-
});
|
|
326
|
-
|
|
327
|
-
// Process each layout handler in order
|
|
328
|
-
layoutHandlers.forEach(handler => {
|
|
329
|
-
const result = resultMap.get(handler.path);
|
|
330
|
-
|
|
331
|
-
if (result) {
|
|
332
|
-
if (result.success) {
|
|
333
|
-
data.push(result.data);
|
|
334
|
-
} else {
|
|
335
|
-
// Add empty data for failed loaders to maintain array alignment
|
|
336
|
-
data.push({});
|
|
337
|
-
|
|
338
|
-
// Record the error
|
|
339
|
-
if (result.error) {
|
|
340
|
-
errors.push({
|
|
341
|
-
layoutPath: handler.path,
|
|
342
|
-
errorType: 'loader',
|
|
343
|
-
timestamp: Date.now(),
|
|
344
|
-
});
|
|
345
|
-
|
|
346
|
-
if (this.options.developmentMode) {
|
|
347
|
-
console.error(`[Layout] Data loading error for ${handler.path}:`, result.error);
|
|
348
|
-
}
|
|
349
|
-
}
|
|
350
|
-
}
|
|
351
|
-
} else {
|
|
352
|
-
// No loader for this handler, add empty data
|
|
353
|
-
data.push({});
|
|
354
|
-
}
|
|
355
|
-
});
|
|
356
|
-
|
|
357
|
-
return { data, errors };
|
|
358
|
-
}
|
|
359
|
-
|
|
360
|
-
/**
|
|
361
|
-
* Creates fallback data for failed loaders
|
|
362
|
-
* Requirements: 2.5, 2.6
|
|
363
|
-
*/
|
|
364
|
-
createFallbackData(layoutPath: string, error: LayoutDataLoadingError): LayoutData {
|
|
365
|
-
return {
|
|
366
|
-
__layoutError: true,
|
|
367
|
-
__layoutPath: layoutPath,
|
|
368
|
-
__errorMessage: error.message,
|
|
369
|
-
__errorType: 'data-loading',
|
|
370
|
-
__timestamp: Date.now(),
|
|
371
|
-
};
|
|
372
|
-
}
|
|
373
|
-
|
|
374
|
-
/**
|
|
375
|
-
* Validates layout data structure
|
|
376
|
-
* Requirements: 2.1, 2.3
|
|
377
|
-
*/
|
|
378
|
-
validateLayoutData(data: unknown, layoutPath: string): LayoutData {
|
|
379
|
-
if (data === null || data === undefined) {
|
|
380
|
-
return {};
|
|
381
|
-
}
|
|
382
|
-
|
|
383
|
-
if (typeof data !== 'object') {
|
|
384
|
-
throw new LayoutDataLoadingError(`Layout loader must return an object, got ${typeof data}`, layoutPath);
|
|
385
|
-
}
|
|
386
|
-
|
|
387
|
-
// Ensure it's a plain object
|
|
388
|
-
if (Array.isArray(data)) {
|
|
389
|
-
throw new LayoutDataLoadingError('Layout loader must return an object, not an array', layoutPath);
|
|
390
|
-
}
|
|
391
|
-
|
|
392
|
-
return data as LayoutData;
|
|
393
|
-
}
|
|
394
|
-
|
|
395
|
-
/**
|
|
396
|
-
* Utility method to create a delay
|
|
397
|
-
*/
|
|
398
|
-
private delay(ms: number): Promise<void> {
|
|
399
|
-
return new Promise(resolve => setTimeout(resolve, ms));
|
|
400
|
-
}
|
|
401
|
-
|
|
402
|
-
/**
|
|
403
|
-
* Preload data for layouts that are likely to be needed soon
|
|
404
|
-
* Requirements: 2.1, 2.2
|
|
405
|
-
*/
|
|
406
|
-
async preloadLayoutData(
|
|
407
|
-
layoutHandlers: LayoutHandler[],
|
|
408
|
-
context: LayoutContext,
|
|
409
|
-
priority: 'high' | 'medium' | 'low' = 'medium'
|
|
410
|
-
): Promise<void> {
|
|
411
|
-
// Only preload if we have loaders
|
|
412
|
-
const handlersWithLoaders = layoutHandlers.filter(handler => handler.loader);
|
|
413
|
-
if (handlersWithLoaders.length === 0) return;
|
|
414
|
-
|
|
415
|
-
// Adjust timeout based on priority
|
|
416
|
-
const originalTimeout = this.options.timeout;
|
|
417
|
-
switch (priority) {
|
|
418
|
-
case 'high':
|
|
419
|
-
this.options.timeout = originalTimeout * 0.5; // Faster timeout for high priority
|
|
420
|
-
break;
|
|
421
|
-
case 'low':
|
|
422
|
-
this.options.timeout = originalTimeout * 2; // Longer timeout for low priority
|
|
423
|
-
break;
|
|
424
|
-
// medium uses default timeout
|
|
425
|
-
}
|
|
426
|
-
|
|
427
|
-
try {
|
|
428
|
-
// Load data in background without blocking
|
|
429
|
-
const results = await this.loadDataInParallel(handlersWithLoaders, context);
|
|
430
|
-
|
|
431
|
-
if (this.options.developmentMode) {
|
|
432
|
-
const successCount = results.filter(r => r.success).length;
|
|
433
|
-
console.log(`[LayoutDataLoader] Preloaded ${successCount}/${results.length} layouts (priority: ${priority})`);
|
|
434
|
-
}
|
|
435
|
-
} catch (error) {
|
|
436
|
-
if (this.options.developmentMode) {
|
|
437
|
-
console.warn('[LayoutDataLoader] Preload failed:', error);
|
|
438
|
-
}
|
|
439
|
-
} finally {
|
|
440
|
-
// Restore original timeout
|
|
441
|
-
this.options.timeout = originalTimeout;
|
|
442
|
-
}
|
|
443
|
-
}
|
|
444
|
-
|
|
445
|
-
/**
|
|
446
|
-
* Gets current loading options
|
|
447
|
-
*/
|
|
448
|
-
getOptions(): Required<LayoutDataLoadingOptions> {
|
|
449
|
-
return { ...this.options };
|
|
450
|
-
}
|
|
451
|
-
|
|
452
|
-
/**
|
|
453
|
-
* Updates loading options
|
|
454
|
-
*/
|
|
455
|
-
updateOptions(options: Partial<LayoutDataLoadingOptions>): void {
|
|
456
|
-
Object.assign(this.options, options);
|
|
457
|
-
}
|
|
458
|
-
}
|
|
459
|
-
|
|
460
|
-
/**
|
|
461
|
-
* Default layout data loader instance
|
|
462
|
-
*/
|
|
463
|
-
export const defaultLayoutDataLoader = new LayoutDataLoader();
|
|
464
|
-
|
|
465
|
-
/**
|
|
466
|
-
* Utility function to create a layout data loader with specific options
|
|
467
|
-
*/
|
|
468
|
-
export function createLayoutDataLoader(options: LayoutDataLoadingOptions = {}): LayoutDataLoader {
|
|
469
|
-
return new LayoutDataLoader(options);
|
|
470
|
-
}
|
|
471
|
-
|
|
472
|
-
/**
|
|
473
|
-
* Utility function to load data for a single layout
|
|
474
|
-
* Requirements: 2.1, 2.2
|
|
475
|
-
*/
|
|
476
|
-
export async function loadSingleLayoutData(
|
|
477
|
-
handler: LayoutHandler,
|
|
478
|
-
context: LayoutContext,
|
|
479
|
-
options: LayoutDataLoadingOptions = {}
|
|
480
|
-
): Promise<LayoutDataLoadingResult> {
|
|
481
|
-
const loader = new LayoutDataLoader(options);
|
|
482
|
-
const results = await loader.loadLayoutData([handler], context);
|
|
483
|
-
return (
|
|
484
|
-
results[0] || {
|
|
485
|
-
success: true,
|
|
486
|
-
data: {},
|
|
487
|
-
loadingTime: 0,
|
|
488
|
-
layoutPath: handler.path,
|
|
489
|
-
}
|
|
490
|
-
);
|
|
491
|
-
}
|
|
492
|
-
|
|
493
|
-
/**
|
|
494
|
-
* Utility function to merge layout data from multiple sources
|
|
495
|
-
* Requirements: 2.4, 2.6
|
|
496
|
-
*/
|
|
497
|
-
export function mergeLayoutData(...dataSources: LayoutData[]): LayoutData {
|
|
498
|
-
const merged: LayoutData = {};
|
|
499
|
-
|
|
500
|
-
for (const data of dataSources) {
|
|
501
|
-
if (data && typeof data === 'object' && !Array.isArray(data)) {
|
|
502
|
-
Object.assign(merged, data);
|
|
503
|
-
}
|
|
504
|
-
}
|
|
505
|
-
|
|
506
|
-
return merged;
|
|
507
|
-
}
|
|
508
|
-
|
|
509
|
-
/**
|
|
510
|
-
* Utility function to extract parent data from context
|
|
511
|
-
* Requirements: 2.4, 2.6
|
|
512
|
-
*/
|
|
513
|
-
export function getParentLayoutData(context: LayoutContext): LayoutData[] {
|
|
514
|
-
const parentData = context.state.get('parentLayoutData');
|
|
515
|
-
return Array.isArray(parentData) ? parentData : [];
|
|
516
|
-
}
|