@absolutejs/absolute 0.19.0-beta.367 → 0.19.0-beta.369

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/vue/index.js CHANGED
@@ -78,56 +78,6 @@ var __legacyMetadataTS = (k, v) => {
78
78
  var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
79
79
  var __require = import.meta.require;
80
80
 
81
- // src/core/streamingSlotRegistrar.ts
82
- var registrar = null, setStreamingSlotRegistrar = (nextRegistrar) => {
83
- registrar = nextRegistrar;
84
- }, registerStreamingSlot = (slot) => {
85
- registrar?.(slot);
86
- };
87
-
88
- // src/client/streamSwap.ts
89
- var streamSwapRuntime = () => {
90
- if (window.__ABS_SLOT_RUNTIME__ === true)
91
- return;
92
- window.__ABS_SLOT_RUNTIME__ = true;
93
- window.__ABS_SLOT_PENDING__ = window.__ABS_SLOT_PENDING__ ?? {};
94
- const pending = window.__ABS_SLOT_PENDING__;
95
- const apply = (id, html) => {
96
- const node = document.getElementById(`slot-${id}`);
97
- if (!node) {
98
- pending[id] = html;
99
- return;
100
- }
101
- node.innerHTML = html;
102
- delete pending[id];
103
- };
104
- const flush = () => {
105
- for (const id in pending) {
106
- if (!Object.prototype.hasOwnProperty.call(pending, id))
107
- continue;
108
- apply(id, pending[id] ?? "");
109
- }
110
- };
111
- window.__ABS_SLOT_ENQUEUE__ = (id, html) => {
112
- apply(id, html);
113
- };
114
- if (typeof MutationObserver === "function") {
115
- const observer = new MutationObserver(flush);
116
- const root = document.documentElement ?? document.body ?? document;
117
- observer.observe(root, { childList: true, subtree: true });
118
- }
119
- if (document.readyState === "loading") {
120
- document.addEventListener("DOMContentLoaded", flush, { once: true });
121
- }
122
- flush();
123
- }, stripFunctionWrapper = (value) => {
124
- const start = value.indexOf("{");
125
- const end = value.lastIndexOf("}");
126
- if (start < 0 || end <= start)
127
- return "";
128
- return value.slice(start + 1, end);
129
- }, getStreamSwapRuntimeScript = () => `(function(){${stripFunctionWrapper(streamSwapRuntime.toString())}})();`;
130
-
131
81
  // src/utils/escapeScriptContent.ts
132
82
  var ESCAPE_LOOKUP, ESCAPE_REGEX, escapeScriptContent = (content) => content.replace(ESCAPE_REGEX, (char) => {
133
83
  const escaped = ESCAPE_LOOKUP[char];
@@ -144,253 +94,38 @@ var init_escapeScriptContent = __esm(() => {
144
94
  ESCAPE_REGEX = /[&><\u2028\u2029]/g;
145
95
  });
146
96
 
147
- // src/utils/streamingSlots.ts
148
- var SLOT_ID_PREFIX = "abs-slot-", SLOT_PLACEHOLDER_PREFIX = "slot-", CLOSING_HEAD_TAG = "</head>", CLOSING_HEAD_TAG_LENGTH, CLOSING_PAGE_TAG_REGEX, STREAMING_RUNTIME_GLOBAL = "__ABS_SLOT_ENQUEUE__", STREAMING_PENDING_GLOBAL = "__ABS_SLOT_PENDING__", STREAM_TAIL_LOOKBEHIND = 128, STREAMING_SLOT_TIMEOUT_MS = 5000, STREAMING_SLOT_MAX_PER_RESPONSE = 128, STREAMING_SLOT_MAX_HTML_BYTES = 64000, createSlotPlaceholderId = (id) => `${SLOT_PLACEHOLDER_PREFIX}${id}`, createSlotPatchStatement = (id, html) => `(window.${STREAMING_RUNTIME_GLOBAL}||function(i,h){window.${STREAMING_PENDING_GLOBAL}=window.${STREAMING_PENDING_GLOBAL}||{};window.${STREAMING_PENDING_GLOBAL}[i]=h;})(${JSON.stringify(id)},${JSON.stringify(html)});`, createNonceAttr = (nonce) => nonce ? ` nonce="${nonce}"` : "", createStreamingSlotId = () => `${SLOT_ID_PREFIX}${Math.random().toString(36).slice(2, 10)}`, getStreamingSlotsRuntimeScript = () => getStreamSwapRuntimeScript(), renderStreamingSlotsRuntimeTag = (nonce) => `<script${createNonceAttr(nonce)}>${escapeScriptContent(getStreamingSlotsRuntimeScript())}</script>`, renderStreamingSlotPlaceholder = (id, fallbackHtml = "") => `<div id="${createSlotPlaceholderId(id)}" data-absolute-slot="true">${fallbackHtml}</div>`, renderStreamingSlotPatchTag = (id, html, nonce) => `<script${createNonceAttr(nonce)}>${escapeScriptContent(createSlotPatchStatement(id, html))}</script>`, injectHtmlIntoHead = (html, injection) => {
149
- const closingHeadIndex = html.indexOf(CLOSING_HEAD_TAG);
97
+ // src/constants.ts
98
+ var ANGULAR_INIT_TIMEOUT_MS = 500, ANSI_ESCAPE_LENGTH = 3, ASCII_SPACE = 32, BASE_36_RADIX = 36, BUN_BUILD_WARNING_SUPPRESSION = "wildcard sideEffects are not supported yet", BODY_SLICE_LENGTH = 2000, BYTES_PER_KILOBYTE = 1024, CLI_ARGS_OFFSET = 3, CSS_ERROR_RESOLVE_DELAY_MS = 50, CSS_MAX_CHECK_ATTEMPTS = 10, CSS_MAX_PARSE_TIMEOUT_MS = 500, CSS_SHEET_READY_TIMEOUT_MS = 100, DEFAULT_CHUNK_SIZE = 16384, DEFAULT_DEBOUNCE_MS = 15, DEFAULT_PORT = 3000, DEV_SERVER_RESTART_DEBOUNCE_MS = 100, DOM_UPDATE_DELAY_MS = 50, FILE_PROTOCOL_PREFIX_LENGTH = 7, FOCUS_ID_PREFIX_LENGTH = 3, FOCUS_IDX_PREFIX_LENGTH = 4, FOCUS_NAME_PREFIX_LENGTH = 5, HMR_UPDATE_TIMEOUT_MS = 2000, HOOK_SIGNATURE_LENGTH = 12, EXCLUDE_LAST_OFFSET = -1, HOURS_IN_DAY = 24, HOURS_IN_HALF_DAY = 12, MAX_ERROR_LENGTH = 200, MAX_RECONNECT_ATTEMPTS = 60, MILLISECONDS_IN_A_SECOND = 1000, MINUTES_IN_AN_HOUR = 60, SECONDS_IN_A_MINUTE = 60, MILLISECONDS_IN_A_MINUTE, MILLISECONDS_IN_A_DAY, OVERLAY_FADE_DURATION_MS = 150, PING_INTERVAL_MS = 30000, RAF_BATCH_COUNT = 3, RANDOM_ID_END_INDEX = 11, REBUILD_BATCH_DELAY_MS = 10, REBUILD_RELOAD_DELAY_MS = 200, RECONNECT_INITIAL_DELAY_MS = 500, RECONNECT_POLL_INTERVAL_MS = 300, SIGINT_EXIT_CODE = 130, SIGTERM_EXIT_CODE = 143, SVELTE_CSS_LOAD_TIMEOUT_MS = 500, TIME_PRECISION = 2, TWO_THIRDS, UNFOUND_INDEX = -1, WEBSOCKET_NORMAL_CLOSURE = 1000;
99
+ var init_constants = __esm(() => {
100
+ MILLISECONDS_IN_A_MINUTE = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE;
101
+ MILLISECONDS_IN_A_DAY = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE * MINUTES_IN_AN_HOUR * HOURS_IN_DAY;
102
+ TWO_THIRDS = 2 / 3;
103
+ });
104
+
105
+ // src/core/islandPageContext.ts
106
+ var BOOTSTRAP_MANIFEST_KEY = "BootstrapClient", ISLAND_MARKER = 'data-island="true"', MANIFEST_MARKER = "__ABSOLUTE_MANIFEST__", ISLAND_STATE_MARKER = "__ABS_ISLAND_STATE__", CLOSING_HEAD_TAG2 = "</head>", buildIslandsHeadMarkup = (manifest) => {
107
+ const manifestScript = `<script>window.__ABSOLUTE_MANIFEST__ = ${JSON.stringify(manifest)}</script>`;
108
+ const islandStateScript = `<script>window.__ABS_ISLAND_STATE__ = ${JSON.stringify(globalThis.__ABS_ISLAND_STATE__ ?? {})}</script>`;
109
+ const bootstrapPath = manifest[BOOTSTRAP_MANIFEST_KEY];
110
+ const bootstrapScript = bootstrapPath ? `<script type="module" src="${bootstrapPath}"></script>` : "";
111
+ return `${manifestScript}${islandStateScript}${bootstrapScript}`;
112
+ }, injectHeadMarkup = (html, markup) => {
113
+ const closingHeadIndex = html.indexOf("</head>");
150
114
  if (closingHeadIndex >= 0) {
151
- return `${html.slice(0, closingHeadIndex)}${injection}${html.slice(closingHeadIndex)}`;
152
- }
153
- return `${html}${injection}`;
154
- }, toUint8 = (value, encoder) => encoder.encode(value), currentStreamingSlotPolicy, clonePolicy = (policy) => ({
155
- ...policy
156
- }), normalizeSlotBytes = (value, fallback) => {
157
- if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
158
- return Math.floor(value);
159
- }
160
- return fallback;
161
- }, normalizeSlotText = (value, fallback) => typeof value === "string" ? value : fallback, normalizeSlotError = (value, fallback) => typeof value === "string" ? value : fallback, hasPolicyValue = (policy, key) => Object.prototype.hasOwnProperty.call(policy, key), applyStreamingSlotPolicyOverrides = (base, overridePolicy = {}) => ({
162
- timeoutMs: hasPolicyValue(overridePolicy, "timeoutMs") ? normalizeSlotBytes(overridePolicy.timeoutMs, base.timeoutMs) : base.timeoutMs,
163
- fallbackHtml: hasPolicyValue(overridePolicy, "fallbackHtml") ? normalizeSlotText(overridePolicy.fallbackHtml, "") : base.fallbackHtml,
164
- errorHtml: hasPolicyValue(overridePolicy, "errorHtml") ? normalizeSlotError(overridePolicy.errorHtml) : base.errorHtml,
165
- maxSlotsPerResponse: hasPolicyValue(overridePolicy, "maxSlotsPerResponse") ? normalizeSlotBytes(overridePolicy.maxSlotsPerResponse, base.maxSlotsPerResponse) : base.maxSlotsPerResponse,
166
- maxSlotHtmlSizeBytes: hasPolicyValue(overridePolicy, "maxSlotHtmlSizeBytes") ? normalizeSlotBytes(overridePolicy.maxSlotHtmlSizeBytes, base.maxSlotHtmlSizeBytes) : base.maxSlotHtmlSizeBytes,
167
- onError: hasPolicyValue(overridePolicy, "onError") ? overridePolicy.onError : base.onError,
168
- onSlotMetric: hasPolicyValue(overridePolicy, "onSlotMetric") ? overridePolicy.onSlotMetric : base.onSlotMetric
169
- }), createCombinedSlotErrorHandler = (policyOnError, enhancerOnError) => {
170
- if (!policyOnError && !enhancerOnError)
171
- return;
172
- return (error, slot) => {
173
- policyOnError?.(error, slot);
174
- enhancerOnError?.(error, slot);
175
- };
176
- }, createCombinedSlotMetricHandler = (policyOnSlotMetric, callOnSlotMetric) => {
177
- if (!policyOnSlotMetric && !callOnSlotMetric)
178
- return;
179
- return (metric) => {
180
- policyOnSlotMetric?.(metric);
181
- callOnSlotMetric?.(metric);
182
- };
183
- }, resolveStreamingSlotPolicy = (overridePolicy = {}) => {
184
- const base = getStreamingSlotPolicy();
185
- return applyStreamingSlotPolicyOverrides(base, overridePolicy);
186
- }, getStreamingSlotPolicy = () => clonePolicy(currentStreamingSlotPolicy), setStreamingSlotPolicy = (policy = {}) => {
187
- const base = getStreamingSlotPolicy();
188
- currentStreamingSlotPolicy = applyStreamingSlotPolicyOverrides(base, policy);
189
- }, withStreamingSlotPolicy = async (policy, callback) => {
190
- const previous = getStreamingSlotPolicy();
191
- setStreamingSlotPolicy(policy);
192
- try {
193
- return await callback();
194
- } finally {
195
- currentStreamingSlotPolicy = previous;
196
- }
197
- }, emitSlotMetric = (metric, onSlotMetric) => {
198
- onSlotMetric?.(metric);
199
- }, createTimeoutError = (slot, timeoutMs) => {
200
- const error = new Error(`Streaming slot "${slot.id}" timed out after ${timeoutMs}ms`);
201
- error.__absTimeout = true;
202
- return error;
203
- }, toStreamingSlot = (slot, policy) => ({
204
- errorHtml: slot.errorHtml === undefined ? policy.errorHtml : slot.errorHtml,
205
- fallbackHtml: normalizeSlotText(slot.fallbackHtml, policy.fallbackHtml),
206
- id: slot.id ?? createStreamingSlotId(),
207
- timeoutMs: normalizeSlotBytes(slot.timeoutMs, policy.timeoutMs),
208
- resolve: slot.resolve
209
- }), prepareSlots = ({
210
- policy,
211
- slots,
212
- onError,
213
- onSlotMetric
214
- }) => {
215
- const preparedSlots = slots.map((slot) => toStreamingSlot(slot, policy));
216
- const maxSlotsPerResponse = policy.maxSlotsPerResponse;
217
- if (maxSlotsPerResponse === 0) {
218
- const error = new Error("Streaming slot limit is set to 0");
219
- for (const slot of preparedSlots) {
220
- onError?.(error, slot);
221
- emitSlotMetric({
222
- type: "dropped",
223
- slotId: slot.id,
224
- reason: "maxSlotsPerResponse is 0"
225
- }, onSlotMetric);
226
- }
227
- return [];
228
- }
229
- if (preparedSlots.length <= maxSlotsPerResponse) {
230
- preparedSlots.forEach((slot) => emitSlotMetric({
231
- type: "prepared",
232
- slotId: slot.id
233
- }, onSlotMetric));
234
- return preparedSlots;
115
+ return `${html.slice(0, closingHeadIndex)}${markup}${html.slice(closingHeadIndex)}`;
235
116
  }
236
- const keptSlots = preparedSlots.slice(0, maxSlotsPerResponse);
237
- const droppedSlots = preparedSlots.slice(maxSlotsPerResponse);
238
- droppedSlots.forEach((slot) => {
239
- onError?.(new Error(`Streaming slot "${slot.id}" dropped because ${maxSlotsPerResponse} slots is the configured maximum`), slot);
240
- emitSlotMetric({
241
- type: "dropped",
242
- slotId: slot.id,
243
- reason: `maxSlotsPerResponse is ${maxSlotsPerResponse}`
244
- }, onSlotMetric);
245
- });
246
- keptSlots.forEach((slot) => emitSlotMetric({
247
- type: "prepared",
248
- slotId: slot.id
249
- }, onSlotMetric));
250
- return keptSlots;
251
- }, htmlByteLength = (value, encoder) => encoder.encode(value).length, resolveSlot = async (slot, onError, policy, onSlotMetric) => {
252
- const safePolicy = policy ?? getStreamingSlotPolicy();
253
- const encoder = new TextEncoder;
254
- const start = Date.now();
255
- try {
256
- const maybeAsyncValue = Promise.resolve(slot.resolve());
257
- const resolved = typeof slot.timeoutMs === "number" && slot.timeoutMs > 0 ? await Promise.race([
258
- maybeAsyncValue,
259
- new Promise((_, reject) => setTimeout(() => {
260
- reject(createTimeoutError(slot, slot.timeoutMs ?? 0));
261
- }, slot.timeoutMs))
262
- ]) : await maybeAsyncValue;
263
- const html = typeof resolved === "string" ? resolved : `${resolved}`;
264
- if (safePolicy.maxSlotHtmlSizeBytes > 0 && htmlByteLength(html, encoder) > safePolicy.maxSlotHtmlSizeBytes) {
265
- const bytes2 = htmlByteLength(html, encoder);
266
- const error = new Error(`Streaming slot "${slot.id}" exceeded max payload size of ${safePolicy.maxSlotHtmlSizeBytes} bytes`);
267
- const durationMs2 = Date.now() - start;
268
- onError?.(error, slot);
269
- emitSlotMetric({
270
- type: "size_exceeded",
271
- slotId: slot.id,
272
- durationMs: durationMs2,
273
- bytes: bytes2,
274
- error
275
- }, onSlotMetric);
276
- const fallbackHtml = typeof slot.errorHtml === "string" ? slot.errorHtml : null;
277
- return {
278
- html: fallbackHtml,
279
- id: slot.id,
280
- durationMs: durationMs2,
281
- bytes: fallbackHtml === null ? 0 : htmlByteLength(fallbackHtml, encoder)
282
- };
283
- }
284
- const durationMs = Date.now() - start;
285
- const bytes = htmlByteLength(html, encoder);
286
- emitSlotMetric({
287
- type: "resolved",
288
- slotId: slot.id,
289
- durationMs,
290
- bytes
291
- }, onSlotMetric);
292
- return {
293
- html,
294
- id: slot.id,
295
- durationMs,
296
- bytes
297
- };
298
- } catch (error) {
299
- const durationMs = Date.now() - start;
300
- onError?.(error, slot);
301
- emitSlotMetric({
302
- type: error?.__absTimeout === true ? "timeout" : "error",
303
- slotId: slot.id,
304
- durationMs,
305
- error
306
- }, onSlotMetric);
307
- if (typeof slot.errorHtml === "string") {
308
- const html = slot.errorHtml;
309
- return {
310
- html,
311
- id: slot.id,
312
- durationMs,
313
- bytes: htmlByteLength(html, encoder)
314
- };
117
+ const openingBodyIndex = html.indexOf("<body");
118
+ if (openingBodyIndex >= 0) {
119
+ const bodyStart = html.indexOf(">", openingBodyIndex);
120
+ if (bodyStart >= 0) {
121
+ return `${html.slice(0, openingBodyIndex)}<head>${markup}</head>${html.slice(openingBodyIndex)}`;
315
122
  }
316
- return {
317
- html: null,
318
- id: slot.id,
319
- durationMs,
320
- bytes: 0
321
- };
322
123
  }
323
- }, nextResolvedSlot = async (pending) => {
324
- const wrapped = pending.map((promise) => promise.then((result) => ({
325
- original: promise,
326
- result
327
- })));
328
- return Promise.race(wrapped);
329
- }, streamChunkToString = (value, decoder) => typeof value === "string" ? value : decoder.decode(value, { stream: true }), streamOutOfOrderSlots = ({
330
- footerHtml = "",
331
- headerHtml = "",
332
- nonce,
333
- policy,
334
- onSlotMetric,
335
- onError,
336
- slots
337
- }) => {
338
- const resolvedPolicy = resolveStreamingSlotPolicy(policy);
339
- const combinedOnError = createCombinedSlotErrorHandler(resolvedPolicy.onError, onError);
340
- const combinedOnSlotMetric = createCombinedSlotMetricHandler(resolvedPolicy.onSlotMetric, onSlotMetric);
341
- const effectivePolicy = {
342
- ...resolvedPolicy,
343
- onSlotMetric: combinedOnSlotMetric
344
- };
345
- const preparedSlots = prepareSlots({
346
- policy: effectivePolicy,
347
- slots,
348
- onError: combinedOnError,
349
- onSlotMetric: combinedOnSlotMetric
350
- });
124
+ return `<!DOCTYPE html><html><head>${markup}</head><body>${html}</body></html>`;
125
+ }, streamChunkToString2 = (value, decoder) => typeof value === "string" ? value : decoder.decode(value, { stream: true }), pipeStreamWithHeadInjection = (stream, markup) => {
351
126
  const encoder = new TextEncoder;
352
- return new ReadableStream({
353
- async start(controller) {
354
- try {
355
- let header = headerHtml;
356
- if (preparedSlots.length > 0 && !header.includes(STREAMING_RUNTIME_GLOBAL)) {
357
- header = injectHtmlIntoHead(header, renderStreamingSlotsRuntimeTag(nonce));
358
- }
359
- controller.enqueue(toUint8(header, encoder));
360
- const pending = preparedSlots.map((slot) => {
361
- const fallback = renderStreamingSlotPlaceholder(slot.id, slot.fallbackHtml ?? "");
362
- controller.enqueue(toUint8(fallback, encoder));
363
- return resolveSlot(slot, combinedOnError, effectivePolicy, combinedOnSlotMetric);
364
- });
365
- while (pending.length > 0) {
366
- const { original, result } = await nextResolvedSlot(pending);
367
- const index = pending.indexOf(original);
368
- if (index >= 0)
369
- pending.splice(index, 1);
370
- if (result.html === null)
371
- continue;
372
- emitSlotMetric({
373
- type: "patched",
374
- slotId: result.id,
375
- durationMs: result.durationMs,
376
- bytes: result.bytes
377
- }, combinedOnSlotMetric);
378
- controller.enqueue(toUint8(renderStreamingSlotPatchTag(result.id, result.html, nonce), encoder));
379
- }
380
- if (footerHtml.length > 0) {
381
- controller.enqueue(toUint8(footerHtml, encoder));
382
- }
383
- controller.close();
384
- } catch (error) {
385
- controller.error(error);
386
- }
387
- }
388
- });
389
- }, injectStreamingRuntimeIntoStream = (stream, nonce) => {
390
- const runtimeTag = renderStreamingSlotsRuntimeTag(nonce);
391
- const encoder = new TextEncoder;
392
- const decoder = new TextDecoder;
393
- const lookbehind = CLOSING_HEAD_TAG_LENGTH - 1;
127
+ const decoder = new TextDecoder;
128
+ const lookbehind = CLOSING_HEAD_TAG2.length - 1;
394
129
  return new ReadableStream({
395
130
  async start(controller) {
396
131
  const reader = stream.getReader();
@@ -403,16 +138,16 @@ var SLOT_ID_PREFIX = "abs-slot-", SLOT_PLACEHOLDER_PREFIX = "slot-", CLOSING_HEA
403
138
  break;
404
139
  if (!value)
405
140
  continue;
406
- pending += streamChunkToString(value, decoder);
141
+ pending += streamChunkToString2(value, decoder);
407
142
  if (injected) {
408
143
  controller.enqueue(encoder.encode(pending));
409
144
  pending = "";
410
145
  continue;
411
146
  }
412
- const headIndex = pending.indexOf(CLOSING_HEAD_TAG);
147
+ const headIndex = pending.indexOf(CLOSING_HEAD_TAG2);
413
148
  if (headIndex >= 0) {
414
- const withRuntime = `${pending.slice(0, headIndex)}${runtimeTag}${pending.slice(headIndex)}`;
415
- controller.enqueue(encoder.encode(withRuntime));
149
+ const next = `${pending.slice(0, headIndex)}${markup}${pending.slice(headIndex)}`;
150
+ controller.enqueue(encoder.encode(next));
416
151
  pending = "";
417
152
  injected = true;
418
153
  continue;
@@ -425,7 +160,7 @@ var SLOT_ID_PREFIX = "abs-slot-", SLOT_PLACEHOLDER_PREFIX = "slot-", CLOSING_HEA
425
160
  }
426
161
  pending += decoder.decode();
427
162
  if (!injected) {
428
- pending = injectHtmlIntoHead(pending, runtimeTag);
163
+ pending = injectHeadMarkup(pending, markup);
429
164
  }
430
165
  if (pending.length > 0) {
431
166
  controller.enqueue(encoder.encode(pending));
@@ -436,345 +171,78 @@ var SLOT_ID_PREFIX = "abs-slot-", SLOT_PLACEHOLDER_PREFIX = "slot-", CLOSING_HEA
436
171
  }
437
172
  }
438
173
  });
439
- }, appendStreamingSlotPatchesToStream = (stream, slots = [], {
440
- injectRuntime = true,
441
- nonce,
442
- onError,
443
- onSlotMetric,
444
- policy
445
- } = {}) => {
446
- const resolvedPolicy = resolveStreamingSlotPolicy(policy);
447
- const combinedOnError = createCombinedSlotErrorHandler(resolvedPolicy.onError, onError);
448
- const combinedOnSlotMetric = createCombinedSlotMetricHandler(resolvedPolicy.onSlotMetric, onSlotMetric);
449
- const effectivePolicy = {
450
- ...resolvedPolicy,
451
- onSlotMetric: combinedOnSlotMetric
452
- };
453
- const preparedSlots = prepareSlots({
454
- policy: effectivePolicy,
455
- slots,
456
- onError: combinedOnError,
457
- onSlotMetric: combinedOnSlotMetric
458
- });
459
- if (preparedSlots.length === 0)
460
- return stream;
461
- const source = injectRuntime ? injectStreamingRuntimeIntoStream(stream, nonce) : stream;
174
+ }, pipeStreamWithIslandMarkerDetection = (stream, markup) => {
462
175
  const encoder = new TextEncoder;
463
176
  const decoder = new TextDecoder;
464
- const reader = source.getReader();
465
- const pending = preparedSlots.map((slot) => resolveSlot(slot, combinedOnError, effectivePolicy, combinedOnSlotMetric));
177
+ const lookbehind = Math.max(ISLAND_MARKER.length, 1024);
466
178
  return new ReadableStream({
467
179
  async start(controller) {
468
- let baseDone = false;
469
- let baseRead = reader.read();
470
- let tail = "";
471
- let footer = "";
180
+ const reader = stream.getReader();
181
+ let injected = false;
182
+ let pending = "";
472
183
  try {
473
- while (!baseDone || pending.length > 0) {
474
- const racers = [];
475
- if (!baseDone) {
476
- racers.push(baseRead.then(({ done, value }) => ({
477
- done,
478
- kind: "base",
479
- value
480
- })));
481
- }
482
- if (pending.length > 0) {
483
- racers.push(nextResolvedSlot(pending).then((resolved) => ({
484
- kind: "slot",
485
- ...resolved
486
- })));
487
- }
488
- if (racers.length === 0)
184
+ for (;; ) {
185
+ const { done, value } = await reader.read();
186
+ if (done)
489
187
  break;
490
- const winner = await Promise.race(racers);
491
- if (winner.kind === "base") {
492
- if (winner.done) {
493
- baseDone = true;
494
- tail += decoder.decode();
495
- const footerStart = tail.search(CLOSING_PAGE_TAG_REGEX);
496
- if (footerStart >= 0) {
497
- const content = tail.slice(0, footerStart);
498
- footer = tail.slice(footerStart);
499
- if (content.length > 0) {
500
- controller.enqueue(encoder.encode(content));
501
- }
502
- } else if (tail.length > 0) {
503
- controller.enqueue(encoder.encode(tail));
504
- }
505
- tail = "";
506
- } else if (winner.value) {
507
- tail += streamChunkToString(winner.value, decoder);
508
- if (tail.length > STREAM_TAIL_LOOKBEHIND) {
509
- const content = tail.slice(0, tail.length - STREAM_TAIL_LOOKBEHIND);
510
- controller.enqueue(encoder.encode(content));
511
- tail = tail.slice(-STREAM_TAIL_LOOKBEHIND);
512
- }
513
- baseRead = reader.read();
514
- }
188
+ if (!value)
189
+ continue;
190
+ pending += streamChunkToString2(value, decoder);
191
+ if (injected) {
192
+ controller.enqueue(encoder.encode(pending));
193
+ pending = "";
515
194
  continue;
516
195
  }
517
- const index = pending.indexOf(winner.original);
518
- if (index >= 0)
519
- pending.splice(index, 1);
520
- if (winner.result.html === null)
196
+ const markerIndex = pending.indexOf(ISLAND_MARKER);
197
+ if (markerIndex >= 0) {
198
+ const tagStart = pending.lastIndexOf("<", markerIndex);
199
+ const injectAt = tagStart >= 0 ? tagStart : markerIndex;
200
+ const next = `${pending.slice(0, injectAt)}${markup}${pending.slice(injectAt)}`;
201
+ controller.enqueue(encoder.encode(next));
202
+ pending = "";
203
+ injected = true;
521
204
  continue;
522
- emitSlotMetric({
523
- type: "patched",
524
- slotId: winner.result.id,
525
- durationMs: winner.result.durationMs,
526
- bytes: winner.result.bytes
527
- }, combinedOnSlotMetric);
528
- controller.enqueue(encoder.encode(renderStreamingSlotPatchTag(winner.result.id, winner.result.html, nonce)));
205
+ }
206
+ if (pending.length > lookbehind) {
207
+ const safeText = pending.slice(0, pending.length - lookbehind);
208
+ controller.enqueue(encoder.encode(safeText));
209
+ pending = pending.slice(-lookbehind);
210
+ }
211
+ }
212
+ pending += decoder.decode();
213
+ if (pending.length > 0) {
214
+ controller.enqueue(encoder.encode(pending));
529
215
  }
530
- if (footer.length > 0)
531
- controller.enqueue(encoder.encode(footer));
532
216
  controller.close();
533
217
  } catch (error) {
534
218
  controller.error(error);
535
219
  }
536
220
  }
537
221
  });
538
- };
539
- var init_streamingSlots = __esm(() => {
540
- init_escapeScriptContent();
541
- CLOSING_HEAD_TAG_LENGTH = CLOSING_HEAD_TAG.length;
542
- CLOSING_PAGE_TAG_REGEX = /<\/body>\s*<\/html>\s*$/i;
543
- currentStreamingSlotPolicy = {
544
- timeoutMs: STREAMING_SLOT_TIMEOUT_MS,
545
- fallbackHtml: "",
546
- errorHtml: undefined,
547
- maxSlotsPerResponse: STREAMING_SLOT_MAX_PER_RESPONSE,
548
- maxSlotHtmlSizeBytes: STREAMING_SLOT_MAX_HTML_BYTES
549
- };
550
- });
551
-
552
- // src/core/streamingSlotRegistry.ts
553
- var asyncLocalStorage, isServerRuntime = () => typeof process !== "undefined" && typeof process.versions?.node === "string", ensureAsyncLocalStorage = async () => {
554
- if (typeof asyncLocalStorage !== "undefined")
555
- return asyncLocalStorage;
556
- if (!isServerRuntime()) {
557
- asyncLocalStorage = null;
558
- return asyncLocalStorage;
222
+ }, htmlContainsIslands = (html) => html.includes(ISLAND_MARKER), injectIslandPageContext = (html, options) => {
223
+ const manifest = globalThis.__absoluteManifest;
224
+ const hasIslands = options?.hasIslands ?? htmlContainsIslands(html);
225
+ if (!manifest || !hasIslands) {
226
+ return html;
559
227
  }
560
- const mod = await import("async_hooks");
561
- asyncLocalStorage = new mod.AsyncLocalStorage;
562
- return asyncLocalStorage;
563
- }, registerStreamingSlot2 = (slot) => {
564
- if (!asyncLocalStorage)
565
- return;
566
- const store = asyncLocalStorage.getStore();
567
- if (!store)
568
- return;
569
- store.set(slot.id, slot);
570
- }, runWithStreamingSlotRegistry = async (task) => {
571
- const storage = await ensureAsyncLocalStorage();
572
- if (!storage) {
573
- return {
574
- result: await task(),
575
- slots: []
576
- };
228
+ if (html.includes(MANIFEST_MARKER) || html.includes(ISLAND_STATE_MARKER)) {
229
+ return html;
577
230
  }
578
- return storage.run(new Map, async () => {
579
- const result = await task();
580
- const store = storage.getStore();
581
- return {
582
- result,
583
- slots: store ? [...store.values()] : []
584
- };
585
- });
586
- };
587
- var init_streamingSlotRegistry = __esm(() => {
588
- setStreamingSlotRegistrar(registerStreamingSlot2);
589
- });
590
-
591
- // src/core/responseEnhancers.ts
592
- var toResponse = async (responseLike) => await responseLike, cloneHeaders = (response) => {
593
- const headers = new Headers(response.headers);
594
- return headers;
595
- }, enhanceHtmlResponseWithStreamingSlots = (response, { nonce, onError, streamingSlots = [], policy } = {}) => {
596
- if (!response.body || streamingSlots.length === 0) {
597
- return response;
231
+ return injectHeadMarkup(html, buildIslandsHeadMarkup(manifest));
232
+ }, injectIslandPageContextStream = (stream, options) => {
233
+ const manifest = globalThis.__absoluteManifest;
234
+ if (!manifest)
235
+ return stream;
236
+ const markup = buildIslandsHeadMarkup(manifest);
237
+ if (options?.hasIslands === true) {
238
+ return pipeStreamWithHeadInjection(stream, markup);
598
239
  }
599
- const body = appendStreamingSlotPatchesToStream(response.body, streamingSlots, {
600
- nonce,
601
- onError,
602
- policy
603
- });
604
- return new Response(body, {
605
- headers: cloneHeaders(response),
606
- status: response.status,
607
- statusText: response.statusText
608
- });
609
- }, withStreamingSlots = async (responseLike, options = {}) => enhanceHtmlResponseWithStreamingSlots(await toResponse(responseLike), options), mergeStreamingSlots = (registered, explicit) => {
610
- const merged = new Map;
611
- for (const slot of registered)
612
- merged.set(slot.id, slot);
613
- for (const slot of explicit)
614
- merged.set(slot.id, slot);
615
- return [...merged.values()];
616
- }, withRegisteredStreamingSlots = async (renderResponse, options = {}) => {
617
- const { result, slots } = await runWithStreamingSlotRegistry(renderResponse);
618
- const explicit = options.streamingSlots ?? [];
619
- return withStreamingSlots(result, {
620
- ...options,
621
- streamingSlots: mergeStreamingSlots(slots, explicit)
622
- });
623
- };
624
- var init_responseEnhancers = __esm(() => {
625
- init_streamingSlots();
626
- init_streamingSlotRegistry();
627
- });
628
-
629
- // src/constants.ts
630
- var ANGULAR_INIT_TIMEOUT_MS = 500, ANSI_ESCAPE_LENGTH = 3, ASCII_SPACE = 32, BASE_36_RADIX = 36, BUN_BUILD_WARNING_SUPPRESSION = "wildcard sideEffects are not supported yet", BODY_SLICE_LENGTH = 2000, BYTES_PER_KILOBYTE = 1024, CLI_ARGS_OFFSET = 3, CSS_ERROR_RESOLVE_DELAY_MS = 50, CSS_MAX_CHECK_ATTEMPTS = 10, CSS_MAX_PARSE_TIMEOUT_MS = 500, CSS_SHEET_READY_TIMEOUT_MS = 100, DEFAULT_CHUNK_SIZE = 16384, DEFAULT_DEBOUNCE_MS = 15, DEFAULT_PORT = 3000, DEV_SERVER_RESTART_DEBOUNCE_MS = 100, DOM_UPDATE_DELAY_MS = 50, FILE_PROTOCOL_PREFIX_LENGTH = 7, FOCUS_ID_PREFIX_LENGTH = 3, FOCUS_IDX_PREFIX_LENGTH = 4, FOCUS_NAME_PREFIX_LENGTH = 5, HMR_UPDATE_TIMEOUT_MS = 2000, HOOK_SIGNATURE_LENGTH = 12, EXCLUDE_LAST_OFFSET = -1, HOURS_IN_DAY = 24, HOURS_IN_HALF_DAY = 12, MAX_ERROR_LENGTH = 200, MAX_RECONNECT_ATTEMPTS = 60, MILLISECONDS_IN_A_SECOND = 1000, MINUTES_IN_AN_HOUR = 60, SECONDS_IN_A_MINUTE = 60, MILLISECONDS_IN_A_MINUTE, MILLISECONDS_IN_A_DAY, OVERLAY_FADE_DURATION_MS = 150, PING_INTERVAL_MS = 30000, RAF_BATCH_COUNT = 3, RANDOM_ID_END_INDEX = 11, REBUILD_BATCH_DELAY_MS = 10, REBUILD_RELOAD_DELAY_MS = 200, RECONNECT_INITIAL_DELAY_MS = 500, RECONNECT_POLL_INTERVAL_MS = 300, SIGINT_EXIT_CODE = 130, SIGTERM_EXIT_CODE = 143, SVELTE_CSS_LOAD_TIMEOUT_MS = 500, TIME_PRECISION = 2, TWO_THIRDS, UNFOUND_INDEX = -1, WEBSOCKET_NORMAL_CLOSURE = 1000;
631
- var init_constants = __esm(() => {
632
- MILLISECONDS_IN_A_MINUTE = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE;
633
- MILLISECONDS_IN_A_DAY = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE * MINUTES_IN_AN_HOUR * HOURS_IN_DAY;
634
- TWO_THIRDS = 2 / 3;
635
- });
636
-
637
- // src/core/islandPageContext.ts
638
- var BOOTSTRAP_MANIFEST_KEY = "BootstrapClient", ISLAND_MARKER = 'data-island="true"', MANIFEST_MARKER = "__ABSOLUTE_MANIFEST__", ISLAND_STATE_MARKER = "__ABS_ISLAND_STATE__", CLOSING_HEAD_TAG2 = "</head>", buildIslandsHeadMarkup = (manifest) => {
639
- const manifestScript = `<script>window.__ABSOLUTE_MANIFEST__ = ${JSON.stringify(manifest)}</script>`;
640
- const islandStateScript = `<script>window.__ABS_ISLAND_STATE__ = ${JSON.stringify(globalThis.__ABS_ISLAND_STATE__ ?? {})}</script>`;
641
- const bootstrapPath = manifest[BOOTSTRAP_MANIFEST_KEY];
642
- const bootstrapScript = bootstrapPath ? `<script type="module" src="${bootstrapPath}"></script>` : "";
643
- return `${manifestScript}${islandStateScript}${bootstrapScript}`;
644
- }, injectHeadMarkup = (html, markup) => {
645
- const closingHeadIndex = html.indexOf("</head>");
646
- if (closingHeadIndex >= 0) {
647
- return `${html.slice(0, closingHeadIndex)}${markup}${html.slice(closingHeadIndex)}`;
648
- }
649
- const openingBodyIndex = html.indexOf("<body");
650
- if (openingBodyIndex >= 0) {
651
- const bodyStart = html.indexOf(">", openingBodyIndex);
652
- if (bodyStart >= 0) {
653
- return `${html.slice(0, openingBodyIndex)}<head>${markup}</head>${html.slice(openingBodyIndex)}`;
654
- }
655
- }
656
- return `<!DOCTYPE html><html><head>${markup}</head><body>${html}</body></html>`;
657
- }, streamChunkToString2 = (value, decoder) => typeof value === "string" ? value : decoder.decode(value, { stream: true }), pipeStreamWithHeadInjection = (stream, markup) => {
658
- const encoder = new TextEncoder;
659
- const decoder = new TextDecoder;
660
- const lookbehind = CLOSING_HEAD_TAG2.length - 1;
661
- return new ReadableStream({
662
- async start(controller) {
663
- const reader = stream.getReader();
664
- let injected = false;
665
- let pending = "";
666
- try {
667
- for (;; ) {
668
- const { done, value } = await reader.read();
669
- if (done)
670
- break;
671
- if (!value)
672
- continue;
673
- pending += streamChunkToString2(value, decoder);
674
- if (injected) {
675
- controller.enqueue(encoder.encode(pending));
676
- pending = "";
677
- continue;
678
- }
679
- const headIndex = pending.indexOf(CLOSING_HEAD_TAG2);
680
- if (headIndex >= 0) {
681
- const next = `${pending.slice(0, headIndex)}${markup}${pending.slice(headIndex)}`;
682
- controller.enqueue(encoder.encode(next));
683
- pending = "";
684
- injected = true;
685
- continue;
686
- }
687
- if (pending.length > lookbehind) {
688
- const safeText = pending.slice(0, pending.length - lookbehind);
689
- controller.enqueue(encoder.encode(safeText));
690
- pending = pending.slice(-lookbehind);
691
- }
692
- }
693
- pending += decoder.decode();
694
- if (!injected) {
695
- pending = injectHeadMarkup(pending, markup);
696
- }
697
- if (pending.length > 0) {
698
- controller.enqueue(encoder.encode(pending));
699
- }
700
- controller.close();
701
- } catch (error) {
702
- controller.error(error);
703
- }
704
- }
705
- });
706
- }, pipeStreamWithIslandMarkerDetection = (stream, markup) => {
707
- const encoder = new TextEncoder;
708
- const decoder = new TextDecoder;
709
- const lookbehind = Math.max(ISLAND_MARKER.length, 1024);
710
- return new ReadableStream({
711
- async start(controller) {
712
- const reader = stream.getReader();
713
- let injected = false;
714
- let pending = "";
715
- try {
716
- for (;; ) {
717
- const { done, value } = await reader.read();
718
- if (done)
719
- break;
720
- if (!value)
721
- continue;
722
- pending += streamChunkToString2(value, decoder);
723
- if (injected) {
724
- controller.enqueue(encoder.encode(pending));
725
- pending = "";
726
- continue;
727
- }
728
- const markerIndex = pending.indexOf(ISLAND_MARKER);
729
- if (markerIndex >= 0) {
730
- const tagStart = pending.lastIndexOf("<", markerIndex);
731
- const injectAt = tagStart >= 0 ? tagStart : markerIndex;
732
- const next = `${pending.slice(0, injectAt)}${markup}${pending.slice(injectAt)}`;
733
- controller.enqueue(encoder.encode(next));
734
- pending = "";
735
- injected = true;
736
- continue;
737
- }
738
- if (pending.length > lookbehind) {
739
- const safeText = pending.slice(0, pending.length - lookbehind);
740
- controller.enqueue(encoder.encode(safeText));
741
- pending = pending.slice(-lookbehind);
742
- }
743
- }
744
- pending += decoder.decode();
745
- if (pending.length > 0) {
746
- controller.enqueue(encoder.encode(pending));
747
- }
748
- controller.close();
749
- } catch (error) {
750
- controller.error(error);
751
- }
752
- }
753
- });
754
- }, htmlContainsIslands = (html) => html.includes(ISLAND_MARKER), injectIslandPageContext = (html, options) => {
755
- const manifest = globalThis.__absoluteManifest;
756
- const hasIslands = options?.hasIslands ?? htmlContainsIslands(html);
757
- if (!manifest || !hasIslands) {
758
- return html;
759
- }
760
- if (html.includes(MANIFEST_MARKER) || html.includes(ISLAND_STATE_MARKER)) {
761
- return html;
762
- }
763
- return injectHeadMarkup(html, buildIslandsHeadMarkup(manifest));
764
- }, injectIslandPageContextStream = (stream, options) => {
765
- const manifest = globalThis.__absoluteManifest;
766
- if (!manifest)
767
- return stream;
768
- const markup = buildIslandsHeadMarkup(manifest);
769
- if (options?.hasIslands === true) {
770
- return pipeStreamWithHeadInjection(stream, markup);
771
- }
772
- if (options?.hasIslands === false) {
773
- return stream;
774
- }
775
- return pipeStreamWithIslandMarkerDetection(stream, markup);
776
- }, setCurrentIslandManifest = (manifest) => {
777
- globalThis.__absoluteManifest = manifest;
240
+ if (options?.hasIslands === false) {
241
+ return stream;
242
+ }
243
+ return pipeStreamWithIslandMarkerDetection(stream, markup);
244
+ }, setCurrentIslandManifest = (manifest) => {
245
+ globalThis.__absoluteManifest = manifest;
778
246
  };
779
247
 
780
248
  // src/utils/ssrErrorPage.ts
@@ -2106,6 +1574,18 @@ import { defineComponent as defineComponent2, h as h2 } from "vue";
2106
1574
 
2107
1575
  // src/vue/components/StreamSlot.ts
2108
1576
  import { defineComponent, h } from "vue";
1577
+
1578
+ // src/core/streamingSlotRegistrar.ts
1579
+ var STREAMING_SLOT_REGISTRAR_KEY = Symbol.for("absolutejs.streamingSlotRegistrar");
1580
+ var getRegistrarGlobal = () => globalThis;
1581
+ var setStreamingSlotRegistrar = (nextRegistrar) => {
1582
+ getRegistrarGlobal()[STREAMING_SLOT_REGISTRAR_KEY] = nextRegistrar;
1583
+ };
1584
+ var registerStreamingSlot = (slot) => {
1585
+ getRegistrarGlobal()[STREAMING_SLOT_REGISTRAR_KEY]?.(slot);
1586
+ };
1587
+
1588
+ // src/vue/components/StreamSlot.ts
2109
1589
  var StreamSlot = defineComponent({
2110
1590
  name: "AbsoluteStreamSlot",
2111
1591
  props: {
@@ -2156,8 +1636,576 @@ var SuspenseSlot = defineComponent2({
2156
1636
  return () => h2(StreamSlot, props);
2157
1637
  }
2158
1638
  });
1639
+ // src/client/streamSwap.ts
1640
+ var streamSwapRuntime = () => {
1641
+ if (window.__ABS_SLOT_RUNTIME__ === true)
1642
+ return;
1643
+ window.__ABS_SLOT_RUNTIME__ = true;
1644
+ window.__ABS_SLOT_PENDING__ = window.__ABS_SLOT_PENDING__ ?? {};
1645
+ const pending = window.__ABS_SLOT_PENDING__;
1646
+ const apply = (id, html) => {
1647
+ const node = document.getElementById(`slot-${id}`);
1648
+ if (!node) {
1649
+ pending[id] = html;
1650
+ return;
1651
+ }
1652
+ node.innerHTML = html;
1653
+ delete pending[id];
1654
+ };
1655
+ const flush = () => {
1656
+ for (const id in pending) {
1657
+ if (!Object.prototype.hasOwnProperty.call(pending, id))
1658
+ continue;
1659
+ apply(id, pending[id] ?? "");
1660
+ }
1661
+ };
1662
+ window.__ABS_SLOT_ENQUEUE__ = (id, html) => {
1663
+ apply(id, html);
1664
+ };
1665
+ if (typeof MutationObserver === "function") {
1666
+ const observer = new MutationObserver(flush);
1667
+ const root = document.documentElement ?? document.body ?? document;
1668
+ observer.observe(root, { childList: true, subtree: true });
1669
+ }
1670
+ if (document.readyState === "loading") {
1671
+ document.addEventListener("DOMContentLoaded", flush, { once: true });
1672
+ }
1673
+ flush();
1674
+ };
1675
+ var stripFunctionWrapper = (value) => {
1676
+ const start = value.indexOf("{");
1677
+ const end = value.lastIndexOf("}");
1678
+ if (start < 0 || end <= start)
1679
+ return "";
1680
+ return value.slice(start + 1, end);
1681
+ };
1682
+ var getStreamSwapRuntimeScript = () => `(function(){${stripFunctionWrapper(streamSwapRuntime.toString())}})();`;
1683
+
1684
+ // src/utils/streamingSlots.ts
1685
+ init_escapeScriptContent();
1686
+ var SLOT_ID_PREFIX = "abs-slot-";
1687
+ var SLOT_PLACEHOLDER_PREFIX = "slot-";
1688
+ var CLOSING_HEAD_TAG = "</head>";
1689
+ var CLOSING_HEAD_TAG_LENGTH = CLOSING_HEAD_TAG.length;
1690
+ var CLOSING_PAGE_TAG_REGEX = /<\/body>\s*<\/html>\s*$/i;
1691
+ var STREAMING_RUNTIME_GLOBAL = "__ABS_SLOT_ENQUEUE__";
1692
+ var STREAMING_PENDING_GLOBAL = "__ABS_SLOT_PENDING__";
1693
+ var STREAM_TAIL_LOOKBEHIND = 128;
1694
+ var STREAMING_SLOT_TIMEOUT_MS = 5000;
1695
+ var STREAMING_SLOT_MAX_PER_RESPONSE = 128;
1696
+ var STREAMING_SLOT_MAX_HTML_BYTES = 64000;
1697
+ var createSlotPlaceholderId = (id) => `${SLOT_PLACEHOLDER_PREFIX}${id}`;
1698
+ var createSlotPatchStatement = (id, html) => `(window.${STREAMING_RUNTIME_GLOBAL}||function(i,h){window.${STREAMING_PENDING_GLOBAL}=window.${STREAMING_PENDING_GLOBAL}||{};window.${STREAMING_PENDING_GLOBAL}[i]=h;})(${JSON.stringify(id)},${JSON.stringify(html)});`;
1699
+ var createNonceAttr = (nonce) => nonce ? ` nonce="${nonce}"` : "";
1700
+ var createStreamingSlotId = () => `${SLOT_ID_PREFIX}${Math.random().toString(36).slice(2, 10)}`;
1701
+ var getStreamingSlotsRuntimeScript = () => getStreamSwapRuntimeScript();
1702
+ var renderStreamingSlotsRuntimeTag = (nonce) => `<script${createNonceAttr(nonce)}>${escapeScriptContent(getStreamingSlotsRuntimeScript())}</script>`;
1703
+ var renderStreamingSlotPlaceholder = (id, fallbackHtml = "") => `<div id="${createSlotPlaceholderId(id)}" data-absolute-slot="true">${fallbackHtml}</div>`;
1704
+ var renderStreamingSlotPatchTag = (id, html, nonce) => `<script${createNonceAttr(nonce)}>${escapeScriptContent(createSlotPatchStatement(id, html))}</script>`;
1705
+ var injectHtmlIntoHead = (html, injection) => {
1706
+ const closingHeadIndex = html.indexOf(CLOSING_HEAD_TAG);
1707
+ if (closingHeadIndex >= 0) {
1708
+ return `${html.slice(0, closingHeadIndex)}${injection}${html.slice(closingHeadIndex)}`;
1709
+ }
1710
+ return `${html}${injection}`;
1711
+ };
1712
+ var toUint8 = (value, encoder) => encoder.encode(value);
1713
+ var currentStreamingSlotPolicy = {
1714
+ timeoutMs: STREAMING_SLOT_TIMEOUT_MS,
1715
+ fallbackHtml: "",
1716
+ errorHtml: undefined,
1717
+ maxSlotsPerResponse: STREAMING_SLOT_MAX_PER_RESPONSE,
1718
+ maxSlotHtmlSizeBytes: STREAMING_SLOT_MAX_HTML_BYTES
1719
+ };
1720
+ var clonePolicy = (policy) => ({
1721
+ ...policy
1722
+ });
1723
+ var normalizeSlotBytes = (value, fallback) => {
1724
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
1725
+ return Math.floor(value);
1726
+ }
1727
+ return fallback;
1728
+ };
1729
+ var normalizeSlotText = (value, fallback) => typeof value === "string" ? value : fallback;
1730
+ var normalizeSlotError = (value, fallback) => typeof value === "string" ? value : fallback;
1731
+ var hasPolicyValue = (policy, key) => Object.prototype.hasOwnProperty.call(policy, key);
1732
+ var applyStreamingSlotPolicyOverrides = (base, overridePolicy = {}) => ({
1733
+ timeoutMs: hasPolicyValue(overridePolicy, "timeoutMs") ? normalizeSlotBytes(overridePolicy.timeoutMs, base.timeoutMs) : base.timeoutMs,
1734
+ fallbackHtml: hasPolicyValue(overridePolicy, "fallbackHtml") ? normalizeSlotText(overridePolicy.fallbackHtml, "") : base.fallbackHtml,
1735
+ errorHtml: hasPolicyValue(overridePolicy, "errorHtml") ? normalizeSlotError(overridePolicy.errorHtml) : base.errorHtml,
1736
+ maxSlotsPerResponse: hasPolicyValue(overridePolicy, "maxSlotsPerResponse") ? normalizeSlotBytes(overridePolicy.maxSlotsPerResponse, base.maxSlotsPerResponse) : base.maxSlotsPerResponse,
1737
+ maxSlotHtmlSizeBytes: hasPolicyValue(overridePolicy, "maxSlotHtmlSizeBytes") ? normalizeSlotBytes(overridePolicy.maxSlotHtmlSizeBytes, base.maxSlotHtmlSizeBytes) : base.maxSlotHtmlSizeBytes,
1738
+ onError: hasPolicyValue(overridePolicy, "onError") ? overridePolicy.onError : base.onError,
1739
+ onSlotMetric: hasPolicyValue(overridePolicy, "onSlotMetric") ? overridePolicy.onSlotMetric : base.onSlotMetric
1740
+ });
1741
+ var createCombinedSlotErrorHandler = (policyOnError, enhancerOnError) => {
1742
+ if (!policyOnError && !enhancerOnError)
1743
+ return;
1744
+ return (error, slot) => {
1745
+ policyOnError?.(error, slot);
1746
+ enhancerOnError?.(error, slot);
1747
+ };
1748
+ };
1749
+ var createCombinedSlotMetricHandler = (policyOnSlotMetric, callOnSlotMetric) => {
1750
+ if (!policyOnSlotMetric && !callOnSlotMetric)
1751
+ return;
1752
+ return (metric) => {
1753
+ policyOnSlotMetric?.(metric);
1754
+ callOnSlotMetric?.(metric);
1755
+ };
1756
+ };
1757
+ var resolveStreamingSlotPolicy = (overridePolicy = {}) => {
1758
+ const base = getStreamingSlotPolicy();
1759
+ return applyStreamingSlotPolicyOverrides(base, overridePolicy);
1760
+ };
1761
+ var getStreamingSlotPolicy = () => clonePolicy(currentStreamingSlotPolicy);
1762
+ var setStreamingSlotPolicy = (policy = {}) => {
1763
+ const base = getStreamingSlotPolicy();
1764
+ currentStreamingSlotPolicy = applyStreamingSlotPolicyOverrides(base, policy);
1765
+ };
1766
+ var withStreamingSlotPolicy = async (policy, callback) => {
1767
+ const previous = getStreamingSlotPolicy();
1768
+ setStreamingSlotPolicy(policy);
1769
+ try {
1770
+ return await callback();
1771
+ } finally {
1772
+ currentStreamingSlotPolicy = previous;
1773
+ }
1774
+ };
1775
+ var emitSlotMetric = (metric, onSlotMetric) => {
1776
+ onSlotMetric?.(metric);
1777
+ };
1778
+ var createTimeoutError = (slot, timeoutMs) => {
1779
+ const error = new Error(`Streaming slot "${slot.id}" timed out after ${timeoutMs}ms`);
1780
+ error.__absTimeout = true;
1781
+ return error;
1782
+ };
1783
+ var toStreamingSlot = (slot, policy) => ({
1784
+ errorHtml: slot.errorHtml === undefined ? policy.errorHtml : slot.errorHtml,
1785
+ fallbackHtml: normalizeSlotText(slot.fallbackHtml, policy.fallbackHtml),
1786
+ id: slot.id ?? createStreamingSlotId(),
1787
+ timeoutMs: normalizeSlotBytes(slot.timeoutMs, policy.timeoutMs),
1788
+ resolve: slot.resolve
1789
+ });
1790
+ var prepareSlots = ({
1791
+ policy,
1792
+ slots,
1793
+ onError,
1794
+ onSlotMetric
1795
+ }) => {
1796
+ const preparedSlots = slots.map((slot) => toStreamingSlot(slot, policy));
1797
+ const maxSlotsPerResponse = policy.maxSlotsPerResponse;
1798
+ if (maxSlotsPerResponse === 0) {
1799
+ const error = new Error("Streaming slot limit is set to 0");
1800
+ for (const slot of preparedSlots) {
1801
+ onError?.(error, slot);
1802
+ emitSlotMetric({
1803
+ type: "dropped",
1804
+ slotId: slot.id,
1805
+ reason: "maxSlotsPerResponse is 0"
1806
+ }, onSlotMetric);
1807
+ }
1808
+ return [];
1809
+ }
1810
+ if (preparedSlots.length <= maxSlotsPerResponse) {
1811
+ preparedSlots.forEach((slot) => emitSlotMetric({
1812
+ type: "prepared",
1813
+ slotId: slot.id
1814
+ }, onSlotMetric));
1815
+ return preparedSlots;
1816
+ }
1817
+ const keptSlots = preparedSlots.slice(0, maxSlotsPerResponse);
1818
+ const droppedSlots = preparedSlots.slice(maxSlotsPerResponse);
1819
+ droppedSlots.forEach((slot) => {
1820
+ onError?.(new Error(`Streaming slot "${slot.id}" dropped because ${maxSlotsPerResponse} slots is the configured maximum`), slot);
1821
+ emitSlotMetric({
1822
+ type: "dropped",
1823
+ slotId: slot.id,
1824
+ reason: `maxSlotsPerResponse is ${maxSlotsPerResponse}`
1825
+ }, onSlotMetric);
1826
+ });
1827
+ keptSlots.forEach((slot) => emitSlotMetric({
1828
+ type: "prepared",
1829
+ slotId: slot.id
1830
+ }, onSlotMetric));
1831
+ return keptSlots;
1832
+ };
1833
+ var htmlByteLength = (value, encoder) => encoder.encode(value).length;
1834
+ var resolveSlot = async (slot, onError, policy, onSlotMetric) => {
1835
+ const safePolicy = policy ?? getStreamingSlotPolicy();
1836
+ const encoder = new TextEncoder;
1837
+ const start = Date.now();
1838
+ try {
1839
+ const maybeAsyncValue = Promise.resolve(slot.resolve());
1840
+ const resolved = typeof slot.timeoutMs === "number" && slot.timeoutMs > 0 ? await Promise.race([
1841
+ maybeAsyncValue,
1842
+ new Promise((_, reject) => setTimeout(() => {
1843
+ reject(createTimeoutError(slot, slot.timeoutMs ?? 0));
1844
+ }, slot.timeoutMs))
1845
+ ]) : await maybeAsyncValue;
1846
+ const html = typeof resolved === "string" ? resolved : `${resolved}`;
1847
+ if (safePolicy.maxSlotHtmlSizeBytes > 0 && htmlByteLength(html, encoder) > safePolicy.maxSlotHtmlSizeBytes) {
1848
+ const bytes2 = htmlByteLength(html, encoder);
1849
+ const error = new Error(`Streaming slot "${slot.id}" exceeded max payload size of ${safePolicy.maxSlotHtmlSizeBytes} bytes`);
1850
+ const durationMs2 = Date.now() - start;
1851
+ onError?.(error, slot);
1852
+ emitSlotMetric({
1853
+ type: "size_exceeded",
1854
+ slotId: slot.id,
1855
+ durationMs: durationMs2,
1856
+ bytes: bytes2,
1857
+ error
1858
+ }, onSlotMetric);
1859
+ const fallbackHtml = typeof slot.errorHtml === "string" ? slot.errorHtml : null;
1860
+ return {
1861
+ html: fallbackHtml,
1862
+ id: slot.id,
1863
+ durationMs: durationMs2,
1864
+ bytes: fallbackHtml === null ? 0 : htmlByteLength(fallbackHtml, encoder)
1865
+ };
1866
+ }
1867
+ const durationMs = Date.now() - start;
1868
+ const bytes = htmlByteLength(html, encoder);
1869
+ emitSlotMetric({
1870
+ type: "resolved",
1871
+ slotId: slot.id,
1872
+ durationMs,
1873
+ bytes
1874
+ }, onSlotMetric);
1875
+ return {
1876
+ html,
1877
+ id: slot.id,
1878
+ durationMs,
1879
+ bytes
1880
+ };
1881
+ } catch (error) {
1882
+ const durationMs = Date.now() - start;
1883
+ onError?.(error, slot);
1884
+ emitSlotMetric({
1885
+ type: error?.__absTimeout === true ? "timeout" : "error",
1886
+ slotId: slot.id,
1887
+ durationMs,
1888
+ error
1889
+ }, onSlotMetric);
1890
+ if (typeof slot.errorHtml === "string") {
1891
+ const html = slot.errorHtml;
1892
+ return {
1893
+ html,
1894
+ id: slot.id,
1895
+ durationMs,
1896
+ bytes: htmlByteLength(html, encoder)
1897
+ };
1898
+ }
1899
+ return {
1900
+ html: null,
1901
+ id: slot.id,
1902
+ durationMs,
1903
+ bytes: 0
1904
+ };
1905
+ }
1906
+ };
1907
+ var nextResolvedSlot = async (pending) => {
1908
+ const wrapped = pending.map((promise) => promise.then((result) => ({
1909
+ original: promise,
1910
+ result
1911
+ })));
1912
+ return Promise.race(wrapped);
1913
+ };
1914
+ var streamChunkToString = (value, decoder) => typeof value === "string" ? value : decoder.decode(value, { stream: true });
1915
+ var streamOutOfOrderSlots = ({
1916
+ footerHtml = "",
1917
+ headerHtml = "",
1918
+ nonce,
1919
+ policy,
1920
+ onSlotMetric,
1921
+ onError,
1922
+ slots
1923
+ }) => {
1924
+ const resolvedPolicy = resolveStreamingSlotPolicy(policy);
1925
+ const combinedOnError = createCombinedSlotErrorHandler(resolvedPolicy.onError, onError);
1926
+ const combinedOnSlotMetric = createCombinedSlotMetricHandler(resolvedPolicy.onSlotMetric, onSlotMetric);
1927
+ const effectivePolicy = {
1928
+ ...resolvedPolicy,
1929
+ onSlotMetric: combinedOnSlotMetric
1930
+ };
1931
+ const preparedSlots = prepareSlots({
1932
+ policy: effectivePolicy,
1933
+ slots,
1934
+ onError: combinedOnError,
1935
+ onSlotMetric: combinedOnSlotMetric
1936
+ });
1937
+ const encoder = new TextEncoder;
1938
+ return new ReadableStream({
1939
+ async start(controller) {
1940
+ try {
1941
+ let header = headerHtml;
1942
+ if (preparedSlots.length > 0 && !header.includes(STREAMING_RUNTIME_GLOBAL)) {
1943
+ header = injectHtmlIntoHead(header, renderStreamingSlotsRuntimeTag(nonce));
1944
+ }
1945
+ controller.enqueue(toUint8(header, encoder));
1946
+ const pending = preparedSlots.map((slot) => {
1947
+ const fallback = renderStreamingSlotPlaceholder(slot.id, slot.fallbackHtml ?? "");
1948
+ controller.enqueue(toUint8(fallback, encoder));
1949
+ return resolveSlot(slot, combinedOnError, effectivePolicy, combinedOnSlotMetric);
1950
+ });
1951
+ while (pending.length > 0) {
1952
+ const { original, result } = await nextResolvedSlot(pending);
1953
+ const index = pending.indexOf(original);
1954
+ if (index >= 0)
1955
+ pending.splice(index, 1);
1956
+ if (result.html === null)
1957
+ continue;
1958
+ emitSlotMetric({
1959
+ type: "patched",
1960
+ slotId: result.id,
1961
+ durationMs: result.durationMs,
1962
+ bytes: result.bytes
1963
+ }, combinedOnSlotMetric);
1964
+ controller.enqueue(toUint8(renderStreamingSlotPatchTag(result.id, result.html, nonce), encoder));
1965
+ }
1966
+ if (footerHtml.length > 0) {
1967
+ controller.enqueue(toUint8(footerHtml, encoder));
1968
+ }
1969
+ controller.close();
1970
+ } catch (error) {
1971
+ controller.error(error);
1972
+ }
1973
+ }
1974
+ });
1975
+ };
1976
+ var injectStreamingRuntimeIntoStream = (stream, nonce) => {
1977
+ const runtimeTag = renderStreamingSlotsRuntimeTag(nonce);
1978
+ const encoder = new TextEncoder;
1979
+ const decoder = new TextDecoder;
1980
+ const lookbehind = CLOSING_HEAD_TAG_LENGTH - 1;
1981
+ return new ReadableStream({
1982
+ async start(controller) {
1983
+ const reader = stream.getReader();
1984
+ let injected = false;
1985
+ let pending = "";
1986
+ try {
1987
+ for (;; ) {
1988
+ const { done, value } = await reader.read();
1989
+ if (done)
1990
+ break;
1991
+ if (!value)
1992
+ continue;
1993
+ pending += streamChunkToString(value, decoder);
1994
+ if (injected) {
1995
+ controller.enqueue(encoder.encode(pending));
1996
+ pending = "";
1997
+ continue;
1998
+ }
1999
+ const headIndex = pending.indexOf(CLOSING_HEAD_TAG);
2000
+ if (headIndex >= 0) {
2001
+ const withRuntime = `${pending.slice(0, headIndex)}${runtimeTag}${pending.slice(headIndex)}`;
2002
+ controller.enqueue(encoder.encode(withRuntime));
2003
+ pending = "";
2004
+ injected = true;
2005
+ continue;
2006
+ }
2007
+ if (pending.length > lookbehind) {
2008
+ const safeText = pending.slice(0, pending.length - lookbehind);
2009
+ controller.enqueue(encoder.encode(safeText));
2010
+ pending = pending.slice(-lookbehind);
2011
+ }
2012
+ }
2013
+ pending += decoder.decode();
2014
+ if (!injected) {
2015
+ pending = injectHtmlIntoHead(pending, runtimeTag);
2016
+ }
2017
+ if (pending.length > 0) {
2018
+ controller.enqueue(encoder.encode(pending));
2019
+ }
2020
+ controller.close();
2021
+ } catch (error) {
2022
+ controller.error(error);
2023
+ }
2024
+ }
2025
+ });
2026
+ };
2027
+ var appendStreamingSlotPatchesToStream = (stream, slots = [], {
2028
+ injectRuntime = true,
2029
+ nonce,
2030
+ onError,
2031
+ onSlotMetric,
2032
+ policy
2033
+ } = {}) => {
2034
+ const resolvedPolicy = resolveStreamingSlotPolicy(policy);
2035
+ const combinedOnError = createCombinedSlotErrorHandler(resolvedPolicy.onError, onError);
2036
+ const combinedOnSlotMetric = createCombinedSlotMetricHandler(resolvedPolicy.onSlotMetric, onSlotMetric);
2037
+ const effectivePolicy = {
2038
+ ...resolvedPolicy,
2039
+ onSlotMetric: combinedOnSlotMetric
2040
+ };
2041
+ const preparedSlots = prepareSlots({
2042
+ policy: effectivePolicy,
2043
+ slots,
2044
+ onError: combinedOnError,
2045
+ onSlotMetric: combinedOnSlotMetric
2046
+ });
2047
+ if (preparedSlots.length === 0)
2048
+ return stream;
2049
+ const source = injectRuntime ? injectStreamingRuntimeIntoStream(stream, nonce) : stream;
2050
+ const encoder = new TextEncoder;
2051
+ const decoder = new TextDecoder;
2052
+ const reader = source.getReader();
2053
+ const pending = preparedSlots.map((slot) => resolveSlot(slot, combinedOnError, effectivePolicy, combinedOnSlotMetric));
2054
+ return new ReadableStream({
2055
+ async start(controller) {
2056
+ let baseDone = false;
2057
+ let baseRead = reader.read();
2058
+ let tail = "";
2059
+ let footer = "";
2060
+ try {
2061
+ while (!baseDone || pending.length > 0) {
2062
+ const racers = [];
2063
+ if (!baseDone) {
2064
+ racers.push(baseRead.then(({ done, value }) => ({
2065
+ done,
2066
+ kind: "base",
2067
+ value
2068
+ })));
2069
+ }
2070
+ if (pending.length > 0) {
2071
+ racers.push(nextResolvedSlot(pending).then((resolved) => ({
2072
+ kind: "slot",
2073
+ ...resolved
2074
+ })));
2075
+ }
2076
+ if (racers.length === 0)
2077
+ break;
2078
+ const winner = await Promise.race(racers);
2079
+ if (winner.kind === "base") {
2080
+ if (winner.done) {
2081
+ baseDone = true;
2082
+ tail += decoder.decode();
2083
+ const footerStart = tail.search(CLOSING_PAGE_TAG_REGEX);
2084
+ if (footerStart >= 0) {
2085
+ const content = tail.slice(0, footerStart);
2086
+ footer = tail.slice(footerStart);
2087
+ if (content.length > 0) {
2088
+ controller.enqueue(encoder.encode(content));
2089
+ }
2090
+ } else if (tail.length > 0) {
2091
+ controller.enqueue(encoder.encode(tail));
2092
+ }
2093
+ tail = "";
2094
+ } else if (winner.value) {
2095
+ tail += streamChunkToString(winner.value, decoder);
2096
+ if (tail.length > STREAM_TAIL_LOOKBEHIND) {
2097
+ const content = tail.slice(0, tail.length - STREAM_TAIL_LOOKBEHIND);
2098
+ controller.enqueue(encoder.encode(content));
2099
+ tail = tail.slice(-STREAM_TAIL_LOOKBEHIND);
2100
+ }
2101
+ baseRead = reader.read();
2102
+ }
2103
+ continue;
2104
+ }
2105
+ const index = pending.indexOf(winner.original);
2106
+ if (index >= 0)
2107
+ pending.splice(index, 1);
2108
+ if (winner.result.html === null)
2109
+ continue;
2110
+ emitSlotMetric({
2111
+ type: "patched",
2112
+ slotId: winner.result.id,
2113
+ durationMs: winner.result.durationMs,
2114
+ bytes: winner.result.bytes
2115
+ }, combinedOnSlotMetric);
2116
+ controller.enqueue(encoder.encode(renderStreamingSlotPatchTag(winner.result.id, winner.result.html, nonce)));
2117
+ }
2118
+ if (footer.length > 0)
2119
+ controller.enqueue(encoder.encode(footer));
2120
+ controller.close();
2121
+ } catch (error) {
2122
+ controller.error(error);
2123
+ }
2124
+ }
2125
+ });
2126
+ };
2127
+
2128
+ // src/core/streamingSlotRegistry.ts
2129
+ var asyncLocalStorage;
2130
+ var isServerRuntime = () => typeof process !== "undefined" && typeof process.versions?.node === "string";
2131
+ var ensureAsyncLocalStorage = async () => {
2132
+ if (typeof asyncLocalStorage !== "undefined")
2133
+ return asyncLocalStorage;
2134
+ if (!isServerRuntime()) {
2135
+ asyncLocalStorage = null;
2136
+ return asyncLocalStorage;
2137
+ }
2138
+ const mod = await import("async_hooks");
2139
+ asyncLocalStorage = new mod.AsyncLocalStorage;
2140
+ return asyncLocalStorage;
2141
+ };
2142
+ var registerStreamingSlot2 = (slot) => {
2143
+ if (!asyncLocalStorage)
2144
+ return;
2145
+ const store = asyncLocalStorage.getStore();
2146
+ if (!store)
2147
+ return;
2148
+ store.set(slot.id, slot);
2149
+ };
2150
+ setStreamingSlotRegistrar(registerStreamingSlot2);
2151
+ var runWithStreamingSlotRegistry = async (task) => {
2152
+ const storage = await ensureAsyncLocalStorage();
2153
+ if (!storage) {
2154
+ return {
2155
+ result: await task(),
2156
+ slots: []
2157
+ };
2158
+ }
2159
+ return storage.run(new Map, async () => {
2160
+ const result = await task();
2161
+ const store = storage.getStore();
2162
+ return {
2163
+ result,
2164
+ slots: store ? [...store.values()] : []
2165
+ };
2166
+ });
2167
+ };
2168
+
2169
+ // src/core/responseEnhancers.ts
2170
+ var toResponse = async (responseLike) => await responseLike;
2171
+ var cloneHeaders = (response) => {
2172
+ const headers = new Headers(response.headers);
2173
+ return headers;
2174
+ };
2175
+ var enhanceHtmlResponseWithStreamingSlots = (response, { nonce, onError, streamingSlots = [], policy } = {}) => {
2176
+ if (!response.body || streamingSlots.length === 0) {
2177
+ return response;
2178
+ }
2179
+ const body = appendStreamingSlotPatchesToStream(response.body, streamingSlots, {
2180
+ nonce,
2181
+ onError,
2182
+ policy
2183
+ });
2184
+ return new Response(body, {
2185
+ headers: cloneHeaders(response),
2186
+ status: response.status,
2187
+ statusText: response.statusText
2188
+ });
2189
+ };
2190
+ var withStreamingSlots = async (responseLike, options = {}) => enhanceHtmlResponseWithStreamingSlots(await toResponse(responseLike), options);
2191
+ var mergeStreamingSlots = (registered, explicit) => {
2192
+ const merged = new Map;
2193
+ for (const slot of registered)
2194
+ merged.set(slot.id, slot);
2195
+ for (const slot of explicit)
2196
+ merged.set(slot.id, slot);
2197
+ return [...merged.values()];
2198
+ };
2199
+ var withRegisteredStreamingSlots = async (renderResponse, options = {}) => {
2200
+ const { result, slots } = await runWithStreamingSlotRegistry(renderResponse);
2201
+ const explicit = options.streamingSlots ?? [];
2202
+ return withStreamingSlots(result, {
2203
+ ...options,
2204
+ streamingSlots: mergeStreamingSlots(slots, explicit)
2205
+ });
2206
+ };
2207
+
2159
2208
  // src/core/wrapPageHandlerWithStreamingSlots.ts
2160
- init_responseEnhancers();
2161
2209
  var wrapPageHandlerWithStreamingSlots = (handler) => (...args) => withRegisteredStreamingSlots(() => handler(...args));
2162
2210
 
2163
2211
  // src/vue/index.ts
@@ -2482,5 +2530,5 @@ export {
2482
2530
  Image_default as Image
2483
2531
  };
2484
2532
 
2485
- //# debugId=5177CF90AA9AA8F464756E2164756E21
2533
+ //# debugId=B29486E07F4255F064756E2164756E21
2486
2534
  //# sourceMappingURL=index.js.map