vite-plugin-react-server 1.4.2 → 1.4.4

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 (74) hide show
  1. package/README.md +48 -313
  2. package/dist/package.json +123 -13
  3. package/dist/plugin/bundle/deferredStaticGeneration.js +14 -39
  4. package/dist/plugin/bundle/manifests.js +30 -48
  5. package/dist/plugin/config/autoDiscover/resolveAutoDiscover.d.ts.map +1 -1
  6. package/dist/plugin/config/autoDiscover/resolveAutoDiscover.js +4 -1
  7. package/dist/plugin/config/envPrefixFromConfig.js +12 -7
  8. package/dist/plugin/config/getCondition.d.ts.map +1 -1
  9. package/dist/plugin/config/getCondition.js +7 -5
  10. package/dist/plugin/dev-server/virtualRscHmrPlugin.js +23 -23
  11. package/dist/plugin/environments/createBuildEventPlugin.js +88 -98
  12. package/dist/plugin/environments/createEnvironmentPlugin.js +222 -250
  13. package/dist/plugin/helpers/createRscRenderHelpers.js +33 -34
  14. package/dist/plugin/helpers/createSharedLoader.d.ts.map +1 -1
  15. package/dist/plugin/helpers/createSharedLoader.js +4 -2
  16. package/dist/plugin/helpers/headlessStreamReuseHandler.js +30 -22
  17. package/dist/plugin/helpers/headlessStreamState.js +15 -28
  18. package/dist/plugin/helpers/resolveComponent.d.ts.map +1 -1
  19. package/dist/plugin/helpers/resolveComponent.js +4 -2
  20. package/dist/plugin/index.client.d.ts +5 -0
  21. package/dist/plugin/index.client.d.ts.map +1 -0
  22. package/dist/plugin/index.client.js +4 -0
  23. package/dist/plugin/index.d.ts +4 -3
  24. package/dist/plugin/index.d.ts.map +1 -1
  25. package/dist/plugin/index.js +10 -5
  26. package/dist/plugin/index.server.d.ts +5 -0
  27. package/dist/plugin/index.server.d.ts.map +1 -0
  28. package/dist/plugin/index.server.js +4 -0
  29. package/dist/plugin/metrics/createWorkerStartupMetrics.js +31 -13
  30. package/dist/plugin/orchestrator/createPluginOrchestrator.client.js +41 -38
  31. package/dist/plugin/orchestrator/createPluginOrchestrator.server.js +43 -46
  32. package/dist/plugin/plugin.client.js +2 -2
  33. package/dist/plugin/plugin.server.js +2 -2
  34. package/dist/plugin/react-static/createBuildLoader.client.js +12 -6
  35. package/dist/plugin/react-static/createBuildLoader.server.js +255 -235
  36. package/dist/plugin/react-static/plugin.client.js +684 -770
  37. package/dist/plugin/react-static/plugin.server.js +517 -603
  38. package/dist/plugin/react-static/processCssFilesForPages.js +103 -88
  39. package/dist/plugin/react-static/renderPage.client.js +455 -529
  40. package/dist/plugin/react-static/renderPage.server.js +485 -508
  41. package/dist/plugin/react-static/renderPagesBatched.js +277 -275
  42. package/dist/plugin/react-static/rscToHtmlStream.client.js +48 -29
  43. package/dist/plugin/react-static/rscToHtmlStream.server.js +62 -37
  44. package/dist/plugin/react-static/temporaryReferences.server.js +11 -2
  45. package/dist/plugin/stream/createMainThreadHandlers.js +40 -31
  46. package/dist/plugin/stream/renderRscStream.server.d.ts.map +1 -1
  47. package/dist/plugin/stream/renderRscStream.server.js +127 -144
  48. package/dist/plugin/transformer/createTransformerPlugin.js +226 -265
  49. package/dist/plugin/utils/checkReactVersion.d.ts +7 -0
  50. package/dist/plugin/utils/checkReactVersion.d.ts.map +1 -0
  51. package/dist/plugin/utils/checkReactVersion.js +23 -0
  52. package/dist/plugin/utils/envUrls.node.js +12 -11
  53. package/dist/plugin/vendor/vendor-alias.js +84 -114
  54. package/dist/plugin/vendor/vendor.client.d.ts.map +1 -1
  55. package/dist/plugin/vendor/vendor.client.js +1 -3
  56. package/dist/plugin/worker/rsc/handleRscRender.d.ts.map +1 -1
  57. package/dist/plugin/worker/rsc/handleRscRender.js +3 -1
  58. package/dist/tsconfig.tsbuildinfo +1 -1
  59. package/package.json +123 -13
  60. package/plugin/config/autoDiscover/resolveAutoDiscover.ts +4 -0
  61. package/plugin/config/getCondition.ts +6 -4
  62. package/plugin/helpers/createRscRenderHelpers.ts +1 -1
  63. package/plugin/helpers/createSharedLoader.ts +6 -1
  64. package/plugin/helpers/resolveComponent.ts +6 -1
  65. package/plugin/index.client.ts +4 -0
  66. package/plugin/index.server.ts +4 -0
  67. package/plugin/index.ts +12 -5
  68. package/plugin/plugin.client.ts +1 -1
  69. package/plugin/plugin.server.ts +1 -1
  70. package/plugin/stream/renderRscStream.server.ts +3 -0
  71. package/plugin/utils/checkReactVersion.ts +28 -0
  72. package/plugin/vendor/vendor.client.ts +0 -2
  73. package/plugin/worker/rsc/handleRscRender.ts +2 -0
  74. package/scripts/generate-toc.mjs +27 -294
@@ -1,295 +1,297 @@
1
- import { handleError } from "../error/handleError.js";
2
- import { fileWriter } from "./fileWriter.js";
3
- import { createRenderMetrics } from "../metrics/createRenderMetrics.js";
4
- import { createStreamMetrics } from "../metrics/createStreamMetrics.js";
1
+ /**
2
+ * vite-plugin-react-server
3
+ * Copyright (c) Nico Brinkkemper
4
+ * MIT License
5
+ */
6
+ import { handleError } from '../error/handleError.js';
7
+ import { fileWriter } from './fileWriter.js';
8
+ import { createRenderMetrics } from '../metrics/createRenderMetrics.js';
9
+ import { createStreamMetrics } from '../metrics/createStreamMetrics.js';
10
+
5
11
  const DEFAULT_BATCH_SIZE = 8;
6
12
  function resolvePathWithManifest(path, manifest) {
7
- const entry = manifest[path];
8
- if (entry && entry.file) {
9
- return entry.file;
10
- }
11
- return path;
13
+ const entry = manifest[path];
14
+ if (entry && entry.file) {
15
+ return entry.file;
16
+ }
17
+ return path;
12
18
  }
13
- /**
14
- * Renders a single route completely, consuming all yields from renderPage
15
- * and writing the RSC and HTML files. Collects metrics and handles events
16
- * identically to the sequential renderPages.
17
- */
18
19
  async function renderSingleRoute(route, handlerOptions, renderPage, manifest, failedRoutes) {
19
- const { autoDiscoveredFiles, cssFilesByPage, ...options } = handlerOptions;
20
- const { page, props, root, html } = autoDiscoveredFiles.urlMap?.get(route) || {};
21
- if (!page) {
22
- return { route, results: [], error: new Error(`No page found for route ${route}`) };
23
- }
24
- try {
25
- const resolvedPagePath = page ? resolvePathWithManifest(page, manifest) : undefined;
26
- const resolvedPropsPath = props ? resolvePathWithManifest(props, manifest) : undefined;
27
- const resolvedRootPath = root ? resolvePathWithManifest(root, manifest) : undefined;
28
- const resolvedHtmlPath = html ? resolvePathWithManifest(html, manifest) : undefined;
29
- // Store results for metrics tracking
30
- const routeResults = new Map();
31
- // Create onEvent wrapper that handles route.error and metrics collection
32
- // This mirrors the sequential renderPages behavior exactly
33
- const wrapperOnEvent = (event) => {
34
- // Call the original onEvent first
35
- if (options.onEvent) {
36
- options.onEvent(event);
37
- }
38
- // Handle route.error events
39
- if (event.type === "route.error") {
40
- const detectedPanicError = handleError({
41
- error: event.data.error,
42
- logger: options.logger,
43
- panicThreshold: event.data.panicThreshold,
44
- context: `route.error (${event.data.route})`,
45
- });
46
- if (detectedPanicError != null) {
47
- options.logger?.error(`[renderPagesBatched] Panic error for route ${event.data.route}: ${event.data.error.message}`);
48
- failedRoutes.set(event.data.route, event.data.error);
49
- }
50
- else {
51
- options.logger?.warn(`[renderPagesBatched] Non-panic error for route ${event.data.route}: ${event.data.error.message}`);
52
- }
20
+ const { autoDiscoveredFiles, cssFilesByPage, ...options } = handlerOptions;
21
+ const { page, props, root, html } = autoDiscoveredFiles.urlMap?.get(route) || {};
22
+ if (!page) {
23
+ return { route, results: [], error: new Error(`No page found for route ${route}`) };
24
+ }
25
+ try {
26
+ const resolvedPagePath = page ? resolvePathWithManifest(page, manifest) : void 0;
27
+ const resolvedPropsPath = props ? resolvePathWithManifest(props, manifest) : void 0;
28
+ const resolvedRootPath = root ? resolvePathWithManifest(root, manifest) : void 0;
29
+ const resolvedHtmlPath = html ? resolvePathWithManifest(html, manifest) : void 0;
30
+ const routeResults = /* @__PURE__ */ new Map();
31
+ const wrapperOnEvent = (event) => {
32
+ if (options.onEvent) {
33
+ options.onEvent(event);
34
+ }
35
+ if (event.type === "route.error") {
36
+ const detectedPanicError = handleError({
37
+ error: event.data.error,
38
+ logger: options.logger,
39
+ panicThreshold: event.data.panicThreshold,
40
+ context: `route.error (${event.data.route})`
41
+ });
42
+ if (detectedPanicError != null) {
43
+ options.logger?.error(
44
+ `[renderPagesBatched] Panic error for route ${event.data.route}: ${event.data.error.message}`
45
+ );
46
+ failedRoutes.set(event.data.route, event.data.error);
47
+ } else {
48
+ options.logger?.warn(
49
+ `[renderPagesBatched] Non-panic error for route ${event.data.route}: ${event.data.error.message}`
50
+ );
51
+ }
52
+ }
53
+ if (event.type === "file.write.done" && event.data.route === route) {
54
+ const routeResult = routeResults.get(route);
55
+ if (routeResult && routeResult.type === "success") {
56
+ if (event.data.fileType === "html") {
57
+ const endTime = performance.now();
58
+ const htmlMetrics = createRenderMetrics({
59
+ route,
60
+ type: routeResult.metrics.html.type,
61
+ fromMainThread: routeResult.metrics.html.fromMainThread,
62
+ fromRscWorker: routeResult.metrics.html.fromRscWorker,
63
+ fromHtmlWorker: routeResult.metrics.html.fromHtmlWorker,
64
+ fileSize: event.data.content.length,
65
+ chunks: event.data.chunks || 0,
66
+ processingTime: endTime - routeResult.metrics.html.streamMetrics.startTime,
67
+ chunkRate: (event.data.chunks || 0) / ((endTime - routeResult.metrics.html.streamMetrics.startTime) / 1e3),
68
+ fileName: event.data.fileName,
69
+ outputPath: event.data.path,
70
+ baseDir: event.data.baseDir,
71
+ routePath: event.data.routePath,
72
+ streamMetrics: createStreamMetrics({
73
+ ...routeResult.metrics.html.streamMetrics,
74
+ chunks: event.data.chunks || 0,
75
+ bytes: event.data.content.length,
76
+ duration: endTime - routeResult.metrics.html.streamMetrics.startTime,
77
+ endTime
78
+ })
79
+ });
80
+ if (options.onMetrics) {
81
+ options.onMetrics(htmlMetrics);
53
82
  }
54
- // Handle metrics collection on file.write.done
55
- if (event.type === "file.write.done" && event.data.route === route) {
56
- const routeResult = routeResults.get(route);
57
- if (routeResult && routeResult.type === "success") {
58
- if (event.data.fileType === "html") {
59
- const endTime = performance.now();
60
- const htmlMetrics = createRenderMetrics({
61
- route: route,
62
- type: routeResult.metrics.html.type,
63
- fromMainThread: routeResult.metrics.html.fromMainThread,
64
- fromRscWorker: routeResult.metrics.html.fromRscWorker,
65
- fromHtmlWorker: routeResult.metrics.html.fromHtmlWorker,
66
- fileSize: event.data.content.length,
67
- chunks: event.data.chunks || 0,
68
- processingTime: endTime - routeResult.metrics.html.streamMetrics.startTime,
69
- chunkRate: (event.data.chunks || 0) / ((endTime - routeResult.metrics.html.streamMetrics.startTime) / 1000),
70
- fileName: event.data.fileName,
71
- outputPath: event.data.path,
72
- baseDir: event.data.baseDir,
73
- routePath: event.data.routePath,
74
- streamMetrics: createStreamMetrics({
75
- ...routeResult.metrics.html.streamMetrics,
76
- chunks: event.data.chunks || 0,
77
- bytes: event.data.content.length,
78
- duration: endTime - routeResult.metrics.html.streamMetrics.startTime,
79
- endTime: endTime,
80
- }),
81
- });
82
- if (options.onMetrics) {
83
- options.onMetrics(htmlMetrics);
84
- }
85
- // Also emit RSC Full metrics if available
86
- if (routeResult.metrics?.rscFull) {
87
- const rscFullEndTime = performance.now();
88
- const rscFullMetrics = createRenderMetrics({
89
- route: route,
90
- type: routeResult.metrics.rscFull.type,
91
- fromMainThread: routeResult.metrics.rscFull.fromMainThread,
92
- fromRscWorker: routeResult.metrics.rscFull.fromRscWorker,
93
- fromHtmlWorker: routeResult.metrics.rscFull.fromHtmlWorker,
94
- processingTime: rscFullEndTime - routeResult.metrics.rscFull.streamMetrics.startTime,
95
- chunks: routeResult.metrics.rscFull.streamMetrics.chunks,
96
- chunkRate: routeResult.metrics.rscFull.streamMetrics.chunks / ((rscFullEndTime - routeResult.metrics.rscFull.streamMetrics.startTime) / 1000),
97
- fileName: event.data.fileName,
98
- outputPath: event.data.path,
99
- baseDir: event.data.baseDir,
100
- routePath: event.data.routePath,
101
- streamMetrics: createStreamMetrics({
102
- ...routeResult.metrics.rscFull.streamMetrics,
103
- duration: rscFullEndTime - routeResult.metrics.rscFull.streamMetrics.startTime,
104
- endTime: rscFullEndTime,
105
- }),
106
- });
107
- if (options.onMetrics) {
108
- options.onMetrics(rscFullMetrics);
109
- }
110
- }
111
- }
112
- else if (event.data.fileType === "rsc") {
113
- const rscEndTime = performance.now();
114
- const rscMetrics = createRenderMetrics({
115
- route: route,
116
- type: routeResult.metrics.rscHeadless.type,
117
- fromMainThread: routeResult.metrics.rscHeadless.fromMainThread,
118
- fromRscWorker: routeResult.metrics.rscHeadless.fromRscWorker,
119
- fromHtmlWorker: routeResult.metrics.rscHeadless.fromHtmlWorker,
120
- fileSize: event.data.content.length,
121
- chunks: event.data.chunks || 0,
122
- processingTime: rscEndTime - routeResult.metrics.rscHeadless.streamMetrics.startTime,
123
- chunkRate: (event.data.chunks || 0) / ((rscEndTime - routeResult.metrics.rscHeadless.streamMetrics.startTime) / 1000),
124
- fileName: event.data.fileName,
125
- outputPath: event.data.path,
126
- baseDir: event.data.baseDir,
127
- routePath: event.data.routePath,
128
- streamMetrics: createStreamMetrics({
129
- ...routeResult.metrics.rscHeadless.streamMetrics,
130
- chunks: event.data.chunks || 0,
131
- bytes: event.data.content.length,
132
- duration: rscEndTime - routeResult.metrics.rscHeadless.streamMetrics.startTime,
133
- endTime: rscEndTime,
134
- }),
135
- });
136
- if (options.onMetrics) {
137
- options.onMetrics(rscMetrics);
138
- }
139
- }
140
- }
83
+ if (routeResult.metrics?.rscFull) {
84
+ const rscFullEndTime = performance.now();
85
+ const rscFullMetrics = createRenderMetrics({
86
+ route,
87
+ type: routeResult.metrics.rscFull.type,
88
+ fromMainThread: routeResult.metrics.rscFull.fromMainThread,
89
+ fromRscWorker: routeResult.metrics.rscFull.fromRscWorker,
90
+ fromHtmlWorker: routeResult.metrics.rscFull.fromHtmlWorker,
91
+ processingTime: rscFullEndTime - routeResult.metrics.rscFull.streamMetrics.startTime,
92
+ chunks: routeResult.metrics.rscFull.streamMetrics.chunks,
93
+ chunkRate: routeResult.metrics.rscFull.streamMetrics.chunks / ((rscFullEndTime - routeResult.metrics.rscFull.streamMetrics.startTime) / 1e3),
94
+ fileName: event.data.fileName,
95
+ outputPath: event.data.path,
96
+ baseDir: event.data.baseDir,
97
+ routePath: event.data.routePath,
98
+ streamMetrics: createStreamMetrics({
99
+ ...routeResult.metrics.rscFull.streamMetrics,
100
+ duration: rscFullEndTime - routeResult.metrics.rscFull.streamMetrics.startTime,
101
+ endTime: rscFullEndTime
102
+ })
103
+ });
104
+ if (options.onMetrics) {
105
+ options.onMetrics(rscFullMetrics);
106
+ }
141
107
  }
142
- };
143
- const routeHandlerOptions = {
144
- ...options,
145
- manifest,
146
- route,
147
- pagePath: resolvedPagePath,
148
- propsPath: resolvedPropsPath,
149
- rootPath: resolvedRootPath,
150
- htmlPath: resolvedHtmlPath,
151
- cssFiles: cssFilesByPage?.get(route) ?? new Map(),
152
- globalCss: options.globalCss ?? new Map(),
153
- id: `${route}-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
154
- onEvent: wrapperOnEvent,
155
- };
156
- const pageRenderer = renderPage(routeHandlerOptions);
157
- const results = [];
158
- let routeError;
159
- // Consume all yields from the page renderer and write files
160
- for await (const result of pageRenderer) {
161
- results.push(result);
162
- if (result.type === "error" && result.error) {
163
- routeError = result.error instanceof Error ? result.error : new Error(String(result.error));
108
+ } else if (event.data.fileType === "rsc") {
109
+ const rscEndTime = performance.now();
110
+ const rscMetrics = createRenderMetrics({
111
+ route,
112
+ type: routeResult.metrics.rscHeadless.type,
113
+ fromMainThread: routeResult.metrics.rscHeadless.fromMainThread,
114
+ fromRscWorker: routeResult.metrics.rscHeadless.fromRscWorker,
115
+ fromHtmlWorker: routeResult.metrics.rscHeadless.fromHtmlWorker,
116
+ fileSize: event.data.content.length,
117
+ chunks: event.data.chunks || 0,
118
+ processingTime: rscEndTime - routeResult.metrics.rscHeadless.streamMetrics.startTime,
119
+ chunkRate: (event.data.chunks || 0) / ((rscEndTime - routeResult.metrics.rscHeadless.streamMetrics.startTime) / 1e3),
120
+ fileName: event.data.fileName,
121
+ outputPath: event.data.path,
122
+ baseDir: event.data.baseDir,
123
+ routePath: event.data.routePath,
124
+ streamMetrics: createStreamMetrics({
125
+ ...routeResult.metrics.rscHeadless.streamMetrics,
126
+ chunks: event.data.chunks || 0,
127
+ bytes: event.data.content.length,
128
+ duration: rscEndTime - routeResult.metrics.rscHeadless.streamMetrics.startTime,
129
+ endTime: rscEndTime
130
+ })
131
+ });
132
+ if (options.onMetrics) {
133
+ options.onMetrics(rscMetrics);
164
134
  }
165
- if (result.type === "success" || result.type === "skip") {
166
- // Store result for metrics tracking (wrapperOnEvent needs this)
167
- routeResults.set(route, result);
168
- const rscWritePromise = fileWriter(result.rsc, "rsc", { ...options, route, onEvent: wrapperOnEvent, logger: options.logger }, options.signal);
169
- const htmlWritePromise = fileWriter(result.html, "html", { ...options, route, onEvent: wrapperOnEvent, logger: options.logger }, options.signal);
170
- await Promise.all([rscWritePromise, htmlWritePromise]);
171
- }
172
- }
173
- if (routeError) {
174
- return { route, results, error: routeError };
135
+ }
175
136
  }
176
- return { route, results };
137
+ }
138
+ };
139
+ const routeHandlerOptions = {
140
+ ...options,
141
+ manifest,
142
+ route,
143
+ pagePath: resolvedPagePath,
144
+ propsPath: resolvedPropsPath,
145
+ rootPath: resolvedRootPath,
146
+ htmlPath: resolvedHtmlPath,
147
+ cssFiles: cssFilesByPage?.get(route) ?? /* @__PURE__ */ new Map(),
148
+ globalCss: options.globalCss ?? /* @__PURE__ */ new Map(),
149
+ id: `${route}-${Date.now()}-${Math.random().toString(36).substring(2, 11)}`,
150
+ onEvent: wrapperOnEvent
151
+ };
152
+ const pageRenderer = renderPage(routeHandlerOptions);
153
+ const results = [];
154
+ let routeError;
155
+ for await (const result of pageRenderer) {
156
+ results.push(result);
157
+ if (result.type === "error" && result.error) {
158
+ routeError = result.error instanceof Error ? result.error : new Error(String(result.error));
159
+ }
160
+ if (result.type === "success" || result.type === "skip") {
161
+ routeResults.set(route, result);
162
+ const rscWritePromise = fileWriter(
163
+ result.rsc,
164
+ "rsc",
165
+ { ...options, route, onEvent: wrapperOnEvent, logger: options.logger },
166
+ options.signal
167
+ );
168
+ const htmlWritePromise = fileWriter(
169
+ result.html,
170
+ "html",
171
+ { ...options, route, onEvent: wrapperOnEvent, logger: options.logger },
172
+ options.signal
173
+ );
174
+ await Promise.all([rscWritePromise, htmlWritePromise]);
175
+ }
177
176
  }
178
- catch (error) {
179
- return { route, results: [], error: error };
177
+ if (routeError) {
178
+ return { route, results, error: routeError };
180
179
  }
180
+ return { route, results };
181
+ } catch (error) {
182
+ return { route, results: [], error };
183
+ }
181
184
  }
182
- /**
183
- * Splits array into chunks of specified size
184
- */
185
185
  function chunk(array, size) {
186
- const chunks = [];
187
- for (let i = 0; i < array.length; i += size) {
188
- chunks.push(array.slice(i, i + size));
189
- }
190
- return chunks;
186
+ const chunks = [];
187
+ for (let i = 0; i < array.length; i += size) {
188
+ chunks.push(array.slice(i, i + size));
189
+ }
190
+ return chunks;
191
191
  }
192
- /**
193
- * Batched version of renderPages that renders pages in parallel batches
194
- */
195
- export const renderPagesBatched = (routes, handlerOptions, renderPage) => {
196
- const { autoDiscoveredFiles, manifest = {}, ...options } = handlerOptions;
197
- const batchSize = options.batchSize ?? DEFAULT_BATCH_SIZE;
198
- const completedRoutes = new Set();
199
- const failedRoutes = new Map();
200
- const results = new Map();
201
- if (!autoDiscoveredFiles?.urlMap) {
202
- return (async function* _renderPagesBatched() {
192
+ const renderPagesBatched = (routes, handlerOptions, renderPage) => {
193
+ const {
194
+ autoDiscoveredFiles,
195
+ manifest = {},
196
+ ...options
197
+ } = handlerOptions;
198
+ const batchSize = options.batchSize ?? DEFAULT_BATCH_SIZE;
199
+ const completedRoutes = /* @__PURE__ */ new Set();
200
+ const failedRoutes = /* @__PURE__ */ new Map();
201
+ const results = /* @__PURE__ */ new Map();
202
+ if (!autoDiscoveredFiles?.urlMap) {
203
+ return async function* _renderPagesBatched() {
204
+ const errorResult = {
205
+ type: "error",
206
+ error: new Error("No urlMap provided to renderPages"),
207
+ route: "",
208
+ failedRoutes: /* @__PURE__ */ new Map(),
209
+ completedRoutes: /* @__PURE__ */ new Set(),
210
+ results: /* @__PURE__ */ new Map()
211
+ };
212
+ yield errorResult;
213
+ return errorResult;
214
+ }();
215
+ }
216
+ return async function* _renderPagesBatched() {
217
+ const routeArray = Array.from(routes);
218
+ const batches = chunk(routeArray, batchSize);
219
+ if (options.verbose) {
220
+ options.logger?.info(
221
+ `[renderPagesBatched] Rendering ${routeArray.length} pages in ${batches.length} batches of ${batchSize}`
222
+ );
223
+ }
224
+ for (const batch of batches) {
225
+ if (options.signal?.aborted) {
226
+ const abortResult = {
227
+ type: "error",
228
+ error: options.signal.reason || new Error("Build aborted"),
229
+ route: batch[0] || "",
230
+ failedRoutes,
231
+ completedRoutes,
232
+ results
233
+ };
234
+ yield abortResult;
235
+ return abortResult;
236
+ }
237
+ const batchPromises = batch.map(
238
+ (route) => renderSingleRoute(route, handlerOptions, renderPage, manifest, failedRoutes)
239
+ );
240
+ const batchResults = await Promise.all(batchPromises);
241
+ for (const { route, results: pageResults, error } of batchResults) {
242
+ if (error) {
243
+ const panicError = handleError({
244
+ error,
245
+ logger: options.logger,
246
+ panicThreshold: options.panicThreshold});
247
+ if (panicError != null) {
248
+ failedRoutes.set(route, error);
249
+ options.logger?.error(`[renderPagesBatched] Panic error for route ${route}: ${error.message}`);
203
250
  const errorResult = {
204
- type: "error",
205
- error: new Error("No urlMap provided to renderPages"),
206
- route: "",
207
- failedRoutes: new Map(),
208
- completedRoutes: new Set(),
209
- results: new Map(),
251
+ type: "error",
252
+ error,
253
+ route,
254
+ failedRoutes,
255
+ completedRoutes,
256
+ results
210
257
  };
211
258
  yield errorResult;
212
259
  return errorResult;
213
- })();
214
- }
215
- return (async function* _renderPagesBatched() {
216
- const routeArray = Array.from(routes);
217
- const batches = chunk(routeArray, batchSize);
218
- if (options.verbose) {
219
- options.logger?.info(`[renderPagesBatched] Rendering ${routeArray.length} pages in ${batches.length} batches of ${batchSize}`);
220
- }
221
- for (const batch of batches) {
222
- // Check for abort signal
223
- if (options.signal?.aborted) {
224
- const abortResult = {
225
- type: "error",
226
- error: options.signal.reason || new Error("Build aborted"),
227
- route: batch[0] || "",
228
- failedRoutes,
229
- completedRoutes,
230
- results,
231
- };
232
- yield abortResult;
233
- return abortResult;
234
- }
235
- // Render all pages in this batch concurrently
236
- const batchPromises = batch.map(route => renderSingleRoute(route, handlerOptions, renderPage, manifest, failedRoutes));
237
- const batchResults = await Promise.all(batchPromises);
238
- // Process results from this batch
239
- for (const { route, results: pageResults, error } of batchResults) {
240
- if (error) {
241
- const panicError = handleError({
242
- error,
243
- logger: options.logger,
244
- panicThreshold: options.panicThreshold,
245
- context: `renderPagesBatched(${route})`,
246
- });
247
- if (panicError != null) {
248
- failedRoutes.set(route, error);
249
- options.logger?.error(`[renderPagesBatched] Panic error for route ${route}: ${error.message}`);
250
- const errorResult = {
251
- type: "error",
252
- error,
253
- route,
254
- failedRoutes,
255
- completedRoutes,
256
- results,
257
- };
258
- yield errorResult;
259
- return errorResult;
260
- }
261
- else {
262
- options.logger?.warn(`[renderPagesBatched] Non-panic error for route ${route}: ${error.message}`);
263
- }
264
- }
265
- else {
266
- completedRoutes.add(route);
267
- for (const result of pageResults) {
268
- if (result.type === "success" || result.type === "skip") {
269
- results.set(route, result);
270
- yield {
271
- type: "success",
272
- route,
273
- failedRoutes,
274
- completedRoutes,
275
- results,
276
- };
277
- }
278
- }
279
- }
280
- }
281
- if (options.verbose) {
282
- options.logger?.info(`[renderPagesBatched] Completed batch: ${completedRoutes.size}/${routeArray.length} pages`);
260
+ } else {
261
+ options.logger?.warn(`[renderPagesBatched] Non-panic error for route ${route}: ${error.message}`);
262
+ }
263
+ } else {
264
+ completedRoutes.add(route);
265
+ for (const result of pageResults) {
266
+ if (result.type === "success" || result.type === "skip") {
267
+ results.set(route, result);
268
+ yield {
269
+ type: "success",
270
+ route,
271
+ failedRoutes,
272
+ completedRoutes,
273
+ results
274
+ };
283
275
  }
276
+ }
284
277
  }
285
- // Final success result
286
- const finalResult = {
287
- type: "success",
288
- route: "",
289
- failedRoutes,
290
- completedRoutes,
291
- results,
292
- };
293
- return finalResult;
294
- })();
278
+ }
279
+ if (options.verbose) {
280
+ options.logger?.info(
281
+ `[renderPagesBatched] Completed batch: ${completedRoutes.size}/${routeArray.length} pages`
282
+ );
283
+ }
284
+ }
285
+ const finalResult = {
286
+ type: "success",
287
+ route: "",
288
+ failedRoutes,
289
+ completedRoutes,
290
+ results
291
+ };
292
+ return finalResult;
293
+ }();
295
294
  };
295
+
296
+ export { renderPagesBatched };
297
+ //# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicmVuZGVyUGFnZXNCYXRjaGVkLmpzIiwic291cmNlcyI6WyIuLi8uLi8uLi9wbHVnaW4vcmVhY3Qtc3RhdGljL3JlbmRlclBhZ2VzQmF0Y2hlZC50cyJdLCJzb3VyY2VzQ29udGVudCI6WyIvKipcbiAqIHJlbmRlclBhZ2VzQmF0Y2hlZC50c1xuICpcbiAqIEJhdGNoZWQgdmVyc2lvbiBvZiByZW5kZXJQYWdlcyB0aGF0IHJlbmRlcnMgbXVsdGlwbGUgcGFnZXMgY29uY3VycmVudGx5LlxuICogVXNlcyBQcm9taXNlLmFsbCBvbiBiYXRjaGVzIHRvIHBhcmFsbGVsaXplIHJlbmRlcmluZyB3aGlsZSBwcmVzZXJ2aW5nXG4gKiB0aGUgYXN5bmMgZ2VuZXJhdG9yIGludGVyZmFjZSBmb3IgY29tcGF0aWJpbGl0eS5cbiAqL1xuaW1wb3J0IHR5cGUgeyBSZW5kZXJQYWdlc1Jlc3VsdCwgUmVuZGVyUGFnZVJlc3VsdCB9IGZyb20gXCIuLi90eXBlcy5qc1wiO1xuaW1wb3J0IHR5cGUgeyBSZW5kZXJQYWdlc0ZuLCBSZW5kZXJQYWdlRm4sIFJlbmRlclBhZ2VzSGFuZGxlck9wdGlvbnMgfSBmcm9tIFwiLi90eXBlcy5qc1wiO1xuaW1wb3J0IHsgaGFuZGxlRXJyb3IgfSBmcm9tIFwiLi4vZXJyb3IvaGFuZGxlRXJyb3IuanNcIjtcbmltcG9ydCB7IGZpbGVXcml0ZXIgfSBmcm9tIFwiLi9maWxlV3JpdGVyLmpzXCI7XG5pbXBvcnQgdHlwZSB7IE1hbmlmZXN0IH0gZnJvbSBcInZpdGVcIjtcbmltcG9ydCB7IGNyZWF0ZVJlbmRlck1ldHJpY3MgfSBmcm9tIFwiLi4vbWV0cmljcy9jcmVhdGVSZW5kZXJNZXRyaWNzLmpzXCI7XG5pbXBvcnQgeyBjcmVhdGVTdHJlYW1NZXRyaWNzIH0gZnJvbSBcIi4uL21ldHJpY3MvY3JlYXRlU3RyZWFtTWV0cmljcy5qc1wiO1xuXG5jb25zdCBERUZBVUxUX0JBVENIX1NJWkUgPSA4O1xuXG5mdW5jdGlvbiByZXNvbHZlUGF0aFdpdGhNYW5pZmVzdChwYXRoOiBzdHJpbmcsIG1hbmlmZXN0OiBNYW5pZmVzdCk6IHN0cmluZyB7XG4gIGNvbnN0IGVudHJ5ID0gbWFuaWZlc3RbcGF0aF07XG4gIGlmIChlbnRyeSAmJiBlbnRyeS5maWxlKSB7XG4gICAgcmV0dXJuIGVudHJ5LmZpbGU7XG4gIH1cbiAgcmV0dXJuIHBhdGg7XG59XG5cbi8qKlxuICogUmVuZGVycyBhIHNpbmdsZSByb3V0ZSBjb21wbGV0ZWx5LCBjb25zdW1pbmcgYWxsIHlpZWxkcyBmcm9tIHJlbmRlclBhZ2VcbiAqIGFuZCB3cml0aW5nIHRoZSBSU0MgYW5kIEhUTUwgZmlsZXMuIENvbGxlY3RzIG1ldHJpY3MgYW5kIGhhbmRsZXMgZXZlbnRzXG4gKiBpZGVudGljYWxseSB0byB0aGUgc2VxdWVudGlhbCByZW5kZXJQYWdlcy5cbiAqL1xuYXN5bmMgZnVuY3Rpb24gcmVuZGVyU2luZ2xlUm91dGUoXG4gIHJvdXRlOiBzdHJpbmcsXG4gIGhhbmRsZXJPcHRpb25zOiBSZW5kZXJQYWdlc0hhbmRsZXJPcHRpb25zLFxuICByZW5kZXJQYWdlOiBSZW5kZXJQYWdlRm4sXG4gIG1hbmlmZXN0OiBNYW5pZmVzdCxcbiAgZmFpbGVkUm91dGVzOiBNYXA8c3RyaW5nLCB1bmtub3duPixcbik6IFByb21pc2U8eyByb3V0ZTogc3RyaW5nOyByZXN1bHRzOiBSZW5kZXJQYWdlUmVzdWx0W107IGVycm9yPzogRXJyb3IgfT4ge1xuICBjb25zdCB7IGF1dG9EaXNjb3ZlcmVkRmlsZXMsIGNzc0ZpbGVzQnlQYWdlLCAuLi5vcHRpb25zIH0gPSBoYW5kbGVyT3B0aW9ucztcbiAgY29uc3QgeyBwYWdlLCBwcm9wcywgcm9vdCwgaHRtbCB9ID0gYXV0b0Rpc2NvdmVyZWRGaWxlcy51cmxNYXA/LmdldChyb3V0ZSkgfHwge307XG4gIFxuICBpZiAoIXBhZ2UpIHtcbiAgICByZXR1cm4geyByb3V0ZSwgcmVzdWx0czogW10sIGVycm9yOiBuZXcgRXJyb3IoYE5vIHBhZ2UgZm91bmQgZm9yIHJvdXRlICR7cm91dGV9YCkgfTtcbiAgfVxuXG4gIHRyeSB7XG4gICAgY29uc3QgcmVzb2x2ZWRQYWdlUGF0aCA9IHBhZ2UgPyByZXNvbHZlUGF0aFdpdGhNYW5pZmVzdChwYWdlLCBtYW5pZmVzdCkgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgcmVzb2x2ZWRQcm9wc1BhdGggPSBwcm9wcyA/IHJlc29sdmVQYXRoV2l0aE1hbmlmZXN0KHByb3BzLCBtYW5pZmVzdCkgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgcmVzb2x2ZWRSb290UGF0aCA9IHJvb3QgPyByZXNvbHZlUGF0aFdpdGhNYW5pZmVzdChyb290LCBtYW5pZmVzdCkgOiB1bmRlZmluZWQ7XG4gICAgY29uc3QgcmVzb2x2ZWRIdG1sUGF0aCA9IGh0bWwgPyByZXNvbHZlUGF0aFdpdGhNYW5pZmVzdChodG1sLCBtYW5pZmVzdCkgOiB1bmRlZmluZWQ7XG5cbiAgICAvLyBTdG9yZSByZXN1bHRzIGZvciBtZXRyaWNzIHRyYWNraW5nXG4gICAgY29uc3Qgcm91dGVSZXN1bHRzID0gbmV3IE1hcDxzdHJpbmcsIFJlbmRlclBhZ2VSZXN1bHQ+KCk7XG5cbiAgICAvLyBDcmVhdGUgb25FdmVudCB3cmFwcGVyIHRoYXQgaGFuZGxlcyByb3V0ZS5lcnJvciBhbmQgbWV0cmljcyBjb2xsZWN0aW9uXG4gICAgLy8gVGhpcyBtaXJyb3JzIHRoZSBzZXF1ZW50aWFsIHJlbmRlclBhZ2VzIGJlaGF2aW9yIGV4YWN0bHlcbiAgICBjb25zdCB3cmFwcGVyT25FdmVudCA9IChldmVudDogYW55KSA9PiB7XG4gICAgICAvLyBDYWxsIHRoZSBvcmlnaW5hbCBvbkV2ZW50IGZpcnN0XG4gICAgICBpZiAob3B0aW9ucy5vbkV2ZW50KSB7XG4gICAgICAgIG9wdGlvbnMub25FdmVudChldmVudCk7XG4gICAgICB9XG5cbiAgICAgIC8vIEhhbmRsZSByb3V0ZS5lcnJvciBldmVudHNcbiAgICAgIGlmIChldmVudC50eXBlID09PSBcInJvdXRlLmVycm9yXCIpIHtcbiAgICAgICAgY29uc3QgZGV0ZWN0ZWRQYW5pY0Vycm9yID0gaGFuZGxlRXJyb3Ioe1xuICAgICAgICAgIGVycm9yOiBldmVudC5kYXRhLmVycm9yLFxuICAgICAgICAgIGxvZ2dlcjogb3B0aW9ucy5sb2dnZXIsXG4gICAgICAgICAgcGFuaWNUaHJlc2hvbGQ6IGV2ZW50LmRhdGEucGFuaWNUaHJlc2hvbGQsXG4gICAgICAgICAgY29udGV4dDogYHJvdXRlLmVycm9yICgke2V2ZW50LmRhdGEucm91dGV9KWAsXG4gICAgICAgIH0pO1xuICAgICAgICBcbiAgICAgICAgaWYgKGRldGVjdGVkUGFuaWNFcnJvciAhPSBudWxsKSB7XG4gICAgICAgICAgb3B0aW9ucy5sb2dnZXI/LmVycm9yKFxuICAgICAgICAgICAgYFtyZW5kZXJQYWdlc0JhdGNoZWRdIFBhbmljIGVycm9yIGZvciByb3V0ZSAke2V2ZW50LmRhdGEucm91dGV9OiAke2V2ZW50LmRhdGEuZXJyb3IubWVzc2FnZX1gXG4gICAgICAgICAgKTtcbiAgICAgICAgICBmYWlsZWRSb3V0ZXMuc2V0KGV2ZW50LmRhdGEucm91dGUsIGV2ZW50LmRhdGEuZXJyb3IpO1xuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIG9wdGlvbnMubG9nZ2VyPy53YXJuKFxuICAgICAgICAgICAgYFtyZW5kZXJQYWdlc0JhdGNoZWRdIE5vbi1wYW5pYyBlcnJvciBmb3Igcm91dGUgJHtldmVudC5kYXRhLnJvdXRlfTogJHtldmVudC5kYXRhLmVycm9yLm1lc3NhZ2V9YFxuICAgICAgICAgICk7XG4gICAgICAgIH1cbiAgICAgIH1cblxuICAgICAgLy8gSGFuZGxlIG1ldHJpY3MgY29sbGVjdGlvbiBvbiBmaWxlLndyaXRlLmRvbmVcbiAgICAgIGlmIChldmVudC50eXBlID09PSBcImZpbGUud3JpdGUuZG9uZVwiICYmIGV2ZW50LmRhdGEucm91dGUgPT09IHJvdXRlKSB7XG4gICAgICAgIGNvbnN0IHJvdXRlUmVzdWx0ID0gcm91dGVSZXN1bHRzLmdldChyb3V0ZSk7XG4gICAgICAgIGlmIChyb3V0ZVJlc3VsdCAmJiByb3V0ZVJlc3VsdC50eXBlID09PSBcInN1Y2Nlc3NcIikge1xuICAgICAgICAgIGlmIChldmVudC5kYXRhLmZpbGVUeXBlID09PSBcImh0bWxcIikge1xuICAgICAgICAgICAgY29uc3QgZW5kVGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgICAgICAgICAgY29uc3QgaHRtbE1ldHJpY3MgPSBjcmVhdGVSZW5kZXJNZXRyaWNzKHtcbiAgICAgICAgICAgICAgcm91dGU6IHJvdXRlLFxuICAgICAgICAgICAgICB0eXBlOiByb3V0ZVJlc3VsdC5tZXRyaWNzLmh0bWwudHlwZSxcbiAgICAgICAgICAgICAgZnJvbU1haW5UaHJlYWQ6IHJvdXRlUmVzdWx0Lm1ldHJpY3MuaHRtbC5mcm9tTWFpblRocmVhZCxcbiAgICAgICAgICAgICAgZnJvbVJzY1dvcmtlcjogcm91dGVSZXN1bHQubWV0cmljcy5odG1sLmZyb21Sc2NXb3JrZXIsXG4gICAgICAgICAgICAgIGZyb21IdG1sV29ya2VyOiByb3V0ZVJlc3VsdC5tZXRyaWNzLmh0bWwuZnJvbUh0bWxXb3JrZXIsXG4gICAgICAgICAgICAgIGZpbGVTaXplOiBldmVudC5kYXRhLmNvbnRlbnQubGVuZ3RoLFxuICAgICAgICAgICAgICBjaHVua3M6IGV2ZW50LmRhdGEuY2h1bmtzIHx8IDAsXG4gICAgICAgICAgICAgIHByb2Nlc3NpbmdUaW1lOiBlbmRUaW1lIC0gcm91dGVSZXN1bHQubWV0cmljcy5odG1sLnN0cmVhbU1ldHJpY3Muc3RhcnRUaW1lLFxuICAgICAgICAgICAgICBjaHVua1JhdGU6IChldmVudC5kYXRhLmNodW5rcyB8fCAwKSAvICgoZW5kVGltZSAtIHJvdXRlUmVzdWx0Lm1ldHJpY3MuaHRtbC5zdHJlYW1NZXRyaWNzLnN0YXJ0VGltZSkgLyAxMDAwKSxcbiAgICAgICAgICAgICAgZmlsZU5hbWU6IGV2ZW50LmRhdGEuZmlsZU5hbWUsXG4gICAgICAgICAgICAgIG91dHB1dFBhdGg6IGV2ZW50LmRhdGEucGF0aCxcbiAgICAgICAgICAgICAgYmFzZURpcjogZXZlbnQuZGF0YS5iYXNlRGlyLFxuICAgICAgICAgICAgICByb3V0ZVBhdGg6IGV2ZW50LmRhdGEucm91dGVQYXRoLFxuICAgICAgICAgICAgICBzdHJlYW1NZXRyaWNzOiBjcmVhdGVTdHJlYW1NZXRyaWNzKHtcbiAgICAgICAgICAgICAgICAuLi5yb3V0ZVJlc3VsdC5tZXRyaWNzLmh0bWwuc3RyZWFtTWV0cmljcyxcbiAgICAgICAgICAgICAgICBjaHVua3M6IGV2ZW50LmRhdGEuY2h1bmtzIHx8IDAsXG4gICAgICAgICAgICAgICAgYnl0ZXM6IGV2ZW50LmRhdGEuY29udGVudC5sZW5ndGgsXG4gICAgICAgICAgICAgICAgZHVyYXRpb246IGVuZFRpbWUgLSByb3V0ZVJlc3VsdC5tZXRyaWNzLmh0bWwuc3RyZWFtTWV0cmljcy5zdGFydFRpbWUsXG4gICAgICAgICAgICAgICAgZW5kVGltZTogZW5kVGltZSxcbiAgICAgICAgICAgICAgfSksXG4gICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgaWYgKG9wdGlvbnMub25NZXRyaWNzKSB7XG4gICAgICAgICAgICAgIG9wdGlvbnMub25NZXRyaWNzKGh0bWxNZXRyaWNzKTtcbiAgICAgICAgICAgIH1cblxuICAgICAgICAgICAgLy8gQWxzbyBlbWl0IFJTQyBGdWxsIG1ldHJpY3MgaWYgYXZhaWxhYmxlXG4gICAgICAgICAgICBpZiAocm91dGVSZXN1bHQubWV0cmljcz8ucnNjRnVsbCkge1xuICAgICAgICAgICAgICBjb25zdCByc2NGdWxsRW5kVGltZSA9IHBlcmZvcm1hbmNlLm5vdygpO1xuICAgICAgICAgICAgICBjb25zdCByc2NGdWxsTWV0cmljcyA9IGNyZWF0ZVJlbmRlck1ldHJpY3Moe1xuICAgICAgICAgICAgICAgIHJvdXRlOiByb3V0ZSxcbiAgICAgICAgICAgICAgICB0eXBlOiByb3V0ZVJlc3VsdC5tZXRyaWNzLnJzY0Z1bGwudHlwZSxcbiAgICAgICAgICAgICAgICBmcm9tTWFpblRocmVhZDogcm91dGVSZXN1bHQubWV0cmljcy5yc2NGdWxsLmZyb21NYWluVGhyZWFkLFxuICAgICAgICAgICAgICAgIGZyb21Sc2NXb3JrZXI6IHJvdXRlUmVzdWx0Lm1ldHJpY3MucnNjRnVsbC5mcm9tUnNjV29ya2VyLFxuICAgICAgICAgICAgICAgIGZyb21IdG1sV29ya2VyOiByb3V0ZVJlc3VsdC5tZXRyaWNzLnJzY0Z1bGwuZnJvbUh0bWxXb3JrZXIsXG4gICAgICAgICAgICAgICAgcHJvY2Vzc2luZ1RpbWU6IHJzY0Z1bGxFbmRUaW1lIC0gcm91dGVSZXN1bHQubWV0cmljcy5yc2NGdWxsLnN0cmVhbU1ldHJpY3Muc3RhcnRUaW1lLFxuICAgICAgICAgICAgICAgIGNodW5rczogcm91dGVSZXN1bHQubWV0cmljcy5yc2NGdWxsLnN0cmVhbU1ldHJpY3MuY2h1bmtzLFxuICAgICAgICAgICAgICAgIGNodW5rUmF0ZTogcm91dGVSZXN1bHQubWV0cmljcy5yc2NGdWxsLnN0cmVhbU1ldHJpY3MuY2h1bmtzIC8gKChyc2NGdWxsRW5kVGltZSAtIHJvdXRlUmVzdWx0Lm1ldHJpY3MucnNjRnVsbC5zdHJlYW1NZXRyaWNzLnN0YXJ0VGltZSkgLyAxMDAwKSxcbiAgICAgICAgICAgICAgICBmaWxlTmFtZTogZXZlbnQuZGF0YS5maWxlTmFtZSxcbiAgICAgICAgICAgICAgICBvdXRwdXRQYXRoOiBldmVudC5kYXRhLnBhdGgsXG4gICAgICAgICAgICAgICAgYmFzZURpcjogZXZlbnQuZGF0YS5iYXNlRGlyLFxuICAgICAgICAgICAgICAgIHJvdXRlUGF0aDogZXZlbnQuZGF0YS5yb3V0ZVBhdGgsXG4gICAgICAgICAgICAgICAgc3RyZWFtTWV0cmljczogY3JlYXRlU3RyZWFtTWV0cmljcyh7XG4gICAgICAgICAgICAgICAgICAuLi5yb3V0ZVJlc3VsdC5tZXRyaWNzLnJzY0Z1bGwuc3RyZWFtTWV0cmljcyxcbiAgICAgICAgICAgICAgICAgIGR1cmF0aW9uOiByc2NGdWxsRW5kVGltZSAtIHJvdXRlUmVzdWx0Lm1ldHJpY3MucnNjRnVsbC5zdHJlYW1NZXRyaWNzLnN0YXJ0VGltZSxcbiAgICAgICAgICAgICAgICAgIGVuZFRpbWU6IHJzY0Z1bGxFbmRUaW1lLFxuICAgICAgICAgICAgICAgIH0pLFxuICAgICAgICAgICAgICB9KTtcblxuICAgICAgICAgICAgICBpZiAob3B0aW9ucy5vbk1ldHJpY3MpIHtcbiAgICAgICAgICAgICAgICBvcHRpb25zLm9uTWV0cmljcyhyc2NGdWxsTWV0cmljcyk7XG4gICAgICAgICAgICAgIH1cbiAgICAgICAgICAgIH1cbiAgICAgICAgICB9IGVsc2UgaWYgKGV2ZW50LmRhdGEuZmlsZVR5cGUgPT09IFwicnNjXCIpIHtcbiAgICAgICAgICAgIGNvbnN0IHJzY0VuZFRpbWUgPSBwZXJmb3JtYW5jZS5ub3coKTtcbiAgICAgICAgICAgIGNvbnN0IHJzY01ldHJpY3MgPSBjcmVhdGVSZW5kZXJNZXRyaWNzKHtcbiAgICAgICAgICAgICAgcm91dGU6IHJvdXRlLFxuICAgICAgICAgICAgICB0eXBlOiByb3V0ZVJlc3VsdC5tZXRyaWNzLnJzY0hlYWRsZXNzLnR5cGUsXG4gICAgICAgICAgICAgIGZyb21NYWluVGhyZWFkOiByb3V0ZVJlc3VsdC5tZXRyaWNzLnJzY0hlYWRsZXNzLmZyb21NYWluVGhyZWFkLFxuICAgICAgICAgICAgICBmcm9tUnNjV29ya2VyOiByb3V0ZVJlc3VsdC5tZXRyaWNzLnJzY0hlYWRsZXNzLmZyb21Sc2NXb3JrZXIsXG4gICAgICAgICAgICAgIGZyb21IdG1sV29ya2VyOiByb3V0ZVJlc3VsdC5tZXRyaWNzLnJzY0hlYWRsZXNzLmZyb21IdG1sV29ya2VyLFxuICAgICAgICAgICAgICBmaWxlU2l6ZTogZXZlbnQuZGF0YS5jb250ZW50Lmxlbmd0aCxcbiAgICAgICAgICAgICAgY2h1bmtzOiBldmVudC5kYXRhLmNodW5rcyB8fCAwLFxuICAgICAgICAgICAgICBwcm9jZXNzaW5nVGltZTogcnNjRW5kVGltZSAtIHJvdXRlUmVzdWx0Lm1ldHJpY3MucnNjSGVhZGxlc3Muc3RyZWFtTWV0cmljcy5zdGFydFRpbWUsXG4gICAgICAgICAgICAgIGNodW5rUmF0ZTogKGV2ZW50LmRhdGEuY2h1bmtzIHx8IDApIC8gKChyc2NFbmRUaW1lIC0gcm91dGVSZXN1bHQubWV0cmljcy5yc2NIZWFkbGVzcy5zdHJlYW1NZXRyaWNzLnN0YXJ0VGltZSkgLyAxMDAwKSxcbiAgICAgICAgICAgICAgZmlsZU5hbWU6IGV2ZW50LmRhdGEuZmlsZU5hbWUsXG4gICAgICAgICAgICAgIG91dHB1dFBhdGg6IGV2ZW50LmRhdGEucGF0aCxcbiAgICAgICAgICAgICAgYmFzZURpcjogZXZlbnQuZGF0YS5iYXNlRGlyLFxuICAgICAgICAgICAgICByb3V0ZVBhdGg6IGV2ZW50LmRhdGEucm91dGVQYXRoLFxuICAgICAgICAgICAgICBzdHJlYW1NZXRyaWNzOiBjcmVhdGVTdHJlYW1NZXRyaWNzKHtcbiAgICAgICAgICAgICAgICAuLi5yb3V0ZVJlc3VsdC5tZXRyaWNzLnJzY0hlYWRsZXNzLnN0cmVhbU1ldHJpY3MsXG4gICAgICAgICAgICAgICAgY2h1bmtzOiBldmVudC5kYXRhLmNodW5rcyB8fCAwLFxuICAgICAgICAgICAgICAgIGJ5dGVzOiBldmVudC5kYXRhLmNvbnRlbnQubGVuZ3RoLFxuICAgICAgICAgICAgICAgIGR1cmF0aW9uOiByc2NFbmRUaW1lIC0gcm91dGVSZXN1bHQubWV0cmljcy5yc2NIZWFkbGVzcy5zdHJlYW1NZXRyaWNzLnN0YXJ0VGltZSxcbiAgICAgICAgICAgICAgICBlbmRUaW1lOiByc2NFbmRUaW1lLFxuICAgICAgICAgICAgICB9KSxcbiAgICAgICAgICAgIH0pO1xuXG4gICAgICAgICAgICBpZiAob3B0aW9ucy5vbk1ldHJpY3MpIHtcbiAgICAgICAgICAgICAgb3B0aW9ucy5vbk1ldHJpY3MocnNjTWV0cmljcyk7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG4gICAgfTtcblxuICAgIGNvbnN0IHJvdXRlSGFuZGxlck9wdGlvbnMgPSB7XG4gICAgICAuLi5vcHRpb25zLFxuICAgICAgbWFuaWZlc3QsXG4gICAgICByb3V0ZSxcbiAgICAgIHBhZ2VQYXRoOiByZXNvbHZlZFBhZ2VQYXRoIGFzIHN0cmluZyxcbiAgICAgIHByb3BzUGF0aDogcmVzb2x2ZWRQcm9wc1BhdGggYXMgc3RyaW5nLFxuICAgICAgcm9vdFBhdGg6IHJlc29sdmVkUm9vdFBhdGggYXMgc3RyaW5nLFxuICAgICAgaHRtbFBhdGg6IHJlc29sdmVkSHRtbFBhdGggYXMgc3RyaW5nLFxuICAgICAgY3NzRmlsZXM6IGNzc0ZpbGVzQnlQYWdlPy5nZXQocm91dGUpID8/IG5ldyBNYXAoKSxcbiAgICAgIGdsb2JhbENzczogb3B0aW9ucy5nbG9iYWxDc3MgPz8gbmV3IE1hcCgpLFxuICAgICAgaWQ6IGAke3JvdXRlfS0ke0RhdGUubm93KCl9LSR7TWF0aC5yYW5kb20oKS50b1N0cmluZygzNikuc3Vic3RyaW5nKDIsIDExKX1gLFxuICAgICAgb25FdmVudDogd3JhcHBlck9uRXZlbnQsXG4gICAgfTtcblxuICAgIGNvbnN0IHBhZ2VSZW5kZXJlciA9IHJlbmRlclBhZ2Uocm91dGVIYW5kbGVyT3B0aW9ucyk7XG4gICAgY29uc3QgcmVzdWx0czogUmVuZGVyUGFnZVJlc3VsdFtdID0gW107XG4gICAgbGV0IHJvdXRlRXJyb3I6IEVycm9yIHwgdW5kZWZpbmVkO1xuXG4gICAgLy8gQ29uc3VtZSBhbGwgeWllbGRzIGZyb20gdGhlIHBhZ2UgcmVuZGVyZXIgYW5kIHdyaXRlIGZpbGVzXG4gICAgZm9yIGF3YWl0IChjb25zdCByZXN1bHQgb2YgcGFnZVJlbmRlcmVyKSB7XG4gICAgICByZXN1bHRzLnB1c2gocmVzdWx0KTtcbiAgICAgIFxuICAgICAgaWYgKHJlc3VsdC50eXBlID09PSBcImVycm9yXCIgJiYgcmVzdWx0LmVycm9yKSB7XG4gICAgICAgIHJvdXRlRXJyb3IgPSByZXN1bHQuZXJyb3IgaW5zdGFuY2VvZiBFcnJvciA/IHJlc3VsdC5lcnJvciA6IG5ldyBFcnJvcihTdHJpbmcocmVzdWx0LmVycm9yKSk7XG4gICAgICB9XG4gICAgICBcbiAgICAgIGlmIChyZXN1bHQudHlwZSA9PT0gXCJzdWNjZXNzXCIgfHwgcmVzdWx0LnR5cGUgPT09IFwic2tpcFwiKSB7XG4gICAgICAgIC8vIFN0b3JlIHJlc3VsdCBmb3IgbWV0cmljcyB0cmFja2luZyAod3JhcHBlck9uRXZlbnQgbmVlZHMgdGhpcylcbiAgICAgICAgcm91dGVSZXN1bHRzLnNldChyb3V0ZSwgcmVzdWx0KTtcblxuICAgICAgICBjb25zdCByc2NXcml0ZVByb21pc2UgPSBmaWxlV3JpdGVyKFxuICAgICAgICAgIHJlc3VsdC5yc2MgYXMgYW55LFxuICAgICAgICAgIFwicnNjXCIsXG4gICAgICAgICAgeyAuLi5vcHRpb25zLCByb3V0ZSwgb25FdmVudDogd3JhcHBlck9uRXZlbnQsIGxvZ2dlcjogb3B0aW9ucy5sb2dnZXIgfSxcbiAgICAgICAgICBvcHRpb25zLnNpZ25hbFxuICAgICAgICApO1xuXG4gICAgICAgIGNvbnN0IGh0bWxXcml0ZVByb21pc2UgPSBmaWxlV3JpdGVyKFxuICAgICAgICAgIHJlc3VsdC5odG1sIGFzIGFueSxcbiAgICAgICAgICBcImh0bWxcIixcbiAgICAgICAgICB7IC4uLm9wdGlvbnMsIHJvdXRlLCBvbkV2ZW50OiB3cmFwcGVyT25FdmVudCwgbG9nZ2VyOiBvcHRpb25zLmxvZ2dlciB9LFxuICAgICAgICAgIG9wdGlvbnMuc2lnbmFsXG4gICAgICAgICk7XG5cbiAgICAgICAgYXdhaXQgUHJvbWlzZS5hbGwoW3JzY1dyaXRlUHJvbWlzZSwgaHRtbFdyaXRlUHJvbWlzZV0pO1xuICAgICAgfVxuICAgIH1cblxuICAgIGlmIChyb3V0ZUVycm9yKSB7XG4gICAgICByZXR1cm4geyByb3V0ZSwgcmVzdWx0cywgZXJyb3I6IHJvdXRlRXJyb3IgfTtcbiAgICB9XG5cbiAgICByZXR1cm4geyByb3V0ZSwgcmVzdWx0cyB9O1xuICB9IGNhdGNoIChlcnJvcikge1xuICAgIHJldHVybiB7IHJvdXRlLCByZXN1bHRzOiBbXSwgZXJyb3I6IGVycm9yIGFzIEVycm9yIH07XG4gIH1cbn1cblxuLyoqXG4gKiBTcGxpdHMgYXJyYXkgaW50byBjaHVua3Mgb2Ygc3BlY2lmaWVkIHNpemVcbiAqL1xuZnVuY3Rpb24gY2h1bms8VD4oYXJyYXk6IFRbXSwgc2l6ZTogbnVtYmVyKTogVFtdW10ge1xuICBjb25zdCBjaHVua3M6IFRbXVtdID0gW107XG4gIGZvciAobGV0IGkgPSAwOyBpIDwgYXJyYXkubGVuZ3RoOyBpICs9IHNpemUpIHtcbiAgICBjaHVua3MucHVzaChhcnJheS5zbGljZShpLCBpICsgc2l6ZSkpO1xuICB9XG4gIHJldHVybiBjaHVua3M7XG59XG5cbi8qKlxuICogQmF0Y2hlZCB2ZXJzaW9uIG9mIHJlbmRlclBhZ2VzIHRoYXQgcmVuZGVycyBwYWdlcyBpbiBwYXJhbGxlbCBiYXRjaGVzXG4gKi9cbmV4cG9ydCBjb25zdCByZW5kZXJQYWdlc0JhdGNoZWQ6IFJlbmRlclBhZ2VzRm4gPSAoXG4gIHJvdXRlcyxcbiAgaGFuZGxlck9wdGlvbnMsXG4gIHJlbmRlclBhZ2VcbikgPT4ge1xuICBjb25zdCB7XG4gICAgYXV0b0Rpc2NvdmVyZWRGaWxlcyxcbiAgICBtYW5pZmVzdCA9IHt9LFxuICAgIC4uLm9wdGlvbnNcbiAgfSA9IGhhbmRsZXJPcHRpb25zO1xuXG4gIGNvbnN0IGJhdGNoU2l6ZSA9IChvcHRpb25zIGFzIGFueSkuYmF0Y2hTaXplID8/IERFRkFVTFRfQkFUQ0hfU0laRTtcbiAgY29uc3QgY29tcGxldGVkUm91dGVzID0gbmV3IFNldDxzdHJpbmc+KCk7XG4gIGNvbnN0IGZhaWxlZFJvdXRlcyA9IG5ldyBNYXA8c3RyaW5nLCB1bmtub3duPigpO1xuICBjb25zdCByZXN1bHRzID0gbmV3IE1hcDxzdHJpbmcsIFJlbmRlclBhZ2VSZXN1bHQ+KCk7XG5cbiAgaWYgKCFhdXRvRGlzY292ZXJlZEZpbGVzPy51cmxNYXApIHtcbiAgICByZXR1cm4gKGFzeW5jIGZ1bmN0aW9uKiBfcmVuZGVyUGFnZXNCYXRjaGVkKCk6IEFzeW5jR2VuZXJhdG9yPFJlbmRlclBhZ2VzUmVzdWx0LCBSZW5kZXJQYWdlc1Jlc3VsdCwgdW5rbm93bj4ge1xuICAgICAgY29uc3QgZXJyb3JSZXN1bHQ6IFJlbmRlclBhZ2VzUmVzdWx0ID0ge1xuICAgICAgICB0eXBlOiBcImVycm9yXCIsXG4gICAgICAgIGVycm9yOiBuZXcgRXJyb3IoXCJObyB1cmxNYXAgcHJvdmlkZWQgdG8gcmVuZGVyUGFnZXNcIiksXG4gICAgICAgIHJvdXRlOiBcIlwiLFxuICAgICAgICBmYWlsZWRSb3V0ZXM6IG5ldyBNYXAoKSxcbiAgICAgICAgY29tcGxldGVkUm91dGVzOiBuZXcgU2V0KCksXG4gICAgICAgIHJlc3VsdHM6IG5ldyBNYXAoKSxcbiAgICAgIH07XG4gICAgICB5aWVsZCBlcnJvclJlc3VsdDtcbiAgICAgIHJldHVybiBlcnJvclJlc3VsdDtcbiAgICB9KSgpO1xuICB9XG5cbiAgcmV0dXJuIChhc3luYyBmdW5jdGlvbiogX3JlbmRlclBhZ2VzQmF0Y2hlZCgpOiBBc3luY0dlbmVyYXRvcjxSZW5kZXJQYWdlc1Jlc3VsdCwgUmVuZGVyUGFnZXNSZXN1bHQsIHVua25vd24+IHtcbiAgICBjb25zdCByb3V0ZUFycmF5ID0gQXJyYXkuZnJvbShyb3V0ZXMpO1xuICAgIGNvbnN0IGJhdGNoZXMgPSBjaHVuayhyb3V0ZUFycmF5LCBiYXRjaFNpemUpO1xuICAgIFxuICAgIGlmIChvcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgIG9wdGlvbnMubG9nZ2VyPy5pbmZvKFxuICAgICAgICBgW3JlbmRlclBhZ2VzQmF0Y2hlZF0gUmVuZGVyaW5nICR7cm91dGVBcnJheS5sZW5ndGh9IHBhZ2VzIGluICR7YmF0Y2hlcy5sZW5ndGh9IGJhdGNoZXMgb2YgJHtiYXRjaFNpemV9YFxuICAgICAgKTtcbiAgICB9XG5cbiAgICBmb3IgKGNvbnN0IGJhdGNoIG9mIGJhdGNoZXMpIHtcbiAgICAgIC8vIENoZWNrIGZvciBhYm9ydCBzaWduYWxcbiAgICAgIGlmIChvcHRpb25zLnNpZ25hbD8uYWJvcnRlZCkge1xuICAgICAgICBjb25zdCBhYm9ydFJlc3VsdDogUmVuZGVyUGFnZXNSZXN1bHQgPSB7XG4gICAgICAgICAgdHlwZTogXCJlcnJvclwiLFxuICAgICAgICAgIGVycm9yOiBvcHRpb25zLnNpZ25hbC5yZWFzb24gfHwgbmV3IEVycm9yKFwiQnVpbGQgYWJvcnRlZFwiKSxcbiAgICAgICAgICByb3V0ZTogYmF0Y2hbMF0gfHwgXCJcIixcbiAgICAgICAgICBmYWlsZWRSb3V0ZXMsXG4gICAgICAgICAgY29tcGxldGVkUm91dGVzLFxuICAgICAgICAgIHJlc3VsdHMsXG4gICAgICAgIH07XG4gICAgICAgIHlpZWxkIGFib3J0UmVzdWx0O1xuICAgICAgICByZXR1cm4gYWJvcnRSZXN1bHQ7XG4gICAgICB9XG5cbiAgICAgIC8vIFJlbmRlciBhbGwgcGFnZXMgaW4gdGhpcyBiYXRjaCBjb25jdXJyZW50bHlcbiAgICAgIGNvbnN0IGJhdGNoUHJvbWlzZXMgPSBiYXRjaC5tYXAocm91dGUgPT4gXG4gICAgICAgIHJlbmRlclNpbmdsZVJvdXRlKHJvdXRlLCBoYW5kbGVyT3B0aW9ucywgcmVuZGVyUGFnZSwgbWFuaWZlc3QsIGZhaWxlZFJvdXRlcylcbiAgICAgICk7XG5cbiAgICAgIGNvbnN0IGJhdGNoUmVzdWx0cyA9IGF3YWl0IFByb21pc2UuYWxsKGJhdGNoUHJvbWlzZXMpO1xuXG4gICAgICAvLyBQcm9jZXNzIHJlc3VsdHMgZnJvbSB0aGlzIGJhdGNoXG4gICAgICBmb3IgKGNvbnN0IHsgcm91dGUsIHJlc3VsdHM6IHBhZ2VSZXN1bHRzLCBlcnJvciB9IG9mIGJhdGNoUmVzdWx0cykge1xuICAgICAgICBpZiAoZXJyb3IpIHtcbiAgICAgICAgICBjb25zdCBwYW5pY0Vycm9yID0gaGFuZGxlRXJyb3Ioe1xuICAgICAgICAgICAgZXJyb3IsXG4gICAgICAgICAgICBsb2dnZXI6IG9wdGlvbnMubG9nZ2VyLFxuICAgICAgICAgICAgcGFuaWNUaHJlc2hvbGQ6IG9wdGlvbnMucGFuaWNUaHJlc2hvbGQsXG4gICAgICAgICAgICBjb250ZXh0OiBgcmVuZGVyUGFnZXNCYXRjaGVkKCR7cm91dGV9KWAsXG4gICAgICAgICAgfSk7XG5cbiAgICAgICAgICBpZiAocGFuaWNFcnJvciAhPSBudWxsKSB7XG4gICAgICAgICAgICBmYWlsZWRSb3V0ZXMuc2V0KHJvdXRlLCBlcnJvcik7XG4gICAgICAgICAgICBvcHRpb25zLmxvZ2dlcj8uZXJyb3IoYFtyZW5kZXJQYWdlc0JhdGNoZWRdIFBhbmljIGVycm9yIGZvciByb3V0ZSAke3JvdXRlfTogJHtlcnJvci5tZXNzYWdlfWApO1xuICAgICAgICAgICAgY29uc3QgZXJyb3JSZXN1bHQ6IFJlbmRlclBhZ2VzUmVzdWx0ID0ge1xuICAgICAgICAgICAgICB0eXBlOiBcImVycm9yXCIsXG4gICAgICAgICAgICAgIGVycm9yLFxuICAgICAgICAgICAgICByb3V0ZSxcbiAgICAgICAgICAgICAgZmFpbGVkUm91dGVzLFxuICAgICAgICAgICAgICBjb21wbGV0ZWRSb3V0ZXMsXG4gICAgICAgICAgICAgIHJlc3VsdHMsXG4gICAgICAgICAgICB9O1xuICAgICAgICAgICAgeWllbGQgZXJyb3JSZXN1bHQ7XG4gICAgICAgICAgICByZXR1cm4gZXJyb3JSZXN1bHQ7XG4gICAgICAgICAgfSBlbHNlIHtcbiAgICAgICAgICAgIG9wdGlvbnMubG9nZ2VyPy53YXJuKGBbcmVuZGVyUGFnZXNCYXRjaGVkXSBOb24tcGFuaWMgZXJyb3IgZm9yIHJvdXRlICR7cm91dGV9OiAke2Vycm9yLm1lc3NhZ2V9YCk7XG4gICAgICAgICAgfVxuICAgICAgICB9IGVsc2Uge1xuICAgICAgICAgIGNvbXBsZXRlZFJvdXRlcy5hZGQocm91dGUpO1xuICAgICAgICAgIFxuICAgICAgICAgIGZvciAoY29uc3QgcmVzdWx0IG9mIHBhZ2VSZXN1bHRzKSB7XG4gICAgICAgICAgICBpZiAocmVzdWx0LnR5cGUgPT09IFwic3VjY2Vzc1wiIHx8IHJlc3VsdC50eXBlID09PSBcInNraXBcIikge1xuICAgICAgICAgICAgICByZXN1bHRzLnNldChyb3V0ZSwgcmVzdWx0KTtcbiAgICAgICAgICAgICAgeWllbGQge1xuICAgICAgICAgICAgICAgIHR5cGU6IFwic3VjY2Vzc1wiLFxuICAgICAgICAgICAgICAgIHJvdXRlLFxuICAgICAgICAgICAgICAgIGZhaWxlZFJvdXRlcyxcbiAgICAgICAgICAgICAgICBjb21wbGV0ZWRSb3V0ZXMsXG4gICAgICAgICAgICAgICAgcmVzdWx0cyxcbiAgICAgICAgICAgICAgfSBzYXRpc2ZpZXMgUmVuZGVyUGFnZXNSZXN1bHQ7XG4gICAgICAgICAgICB9XG4gICAgICAgICAgfVxuICAgICAgICB9XG4gICAgICB9XG5cbiAgICAgIGlmIChvcHRpb25zLnZlcmJvc2UpIHtcbiAgICAgICAgb3B0aW9ucy5sb2dnZXI/LmluZm8oXG4gICAgICAgICAgYFtyZW5kZXJQYWdlc0JhdGNoZWRdIENvbXBsZXRlZCBiYXRjaDogJHtjb21wbGV0ZWRSb3V0ZXMuc2l6ZX0vJHtyb3V0ZUFycmF5Lmxlbmd0aH0gcGFnZXNgXG4gICAgICAgICk7XG4gICAgICB9XG4gICAgfVxuXG4gICAgLy8gRmluYWwgc3VjY2VzcyByZXN1bHRcbiAgICBjb25zdCBmaW5hbFJlc3VsdDogUmVuZGVyUGFnZXNSZXN1bHQgPSB7XG4gICAgICB0eXBlOiBcInN1Y2Nlc3NcIixcbiAgICAgIHJvdXRlOiBcIlwiLFxuICAgICAgZmFpbGVkUm91dGVzLFxuICAgICAgY29tcGxldGVkUm91dGVzLFxuICAgICAgcmVzdWx0cyxcbiAgICB9O1xuXG4gICAgcmV0dXJuIGZpbmFsUmVzdWx0O1xuICB9KSgpO1xufTtcbiJdLCJuYW1lcyI6W10sIm1hcHBpbmdzIjoiOzs7Ozs7Ozs7O0FBZUEsTUFBTSxrQkFBcUIsR0FBQSxDQUFBO0FBRTNCLFNBQVMsdUJBQUEsQ0FBd0Is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