@absolutejs/absolute 0.19.0-beta.350 → 0.19.0-beta.352

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
@@ -361,12 +361,12 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
361
361
  });
362
362
  return { body, styles };
363
363
  }, renderVueError = async (conventionPath, errorProps) => {
364
- const { createSSRApp, h } = await import("vue");
364
+ const { createSSRApp, h: h3 } = await import("vue");
365
365
  const { renderToString } = await import("vue/server-renderer");
366
366
  const mod = await import(conventionPath);
367
367
  const ErrorComponent = mod.default;
368
368
  const app = createSSRApp({
369
- render: () => h(ErrorComponent, errorProps)
369
+ render: () => h3(ErrorComponent, errorProps)
370
370
  });
371
371
  const rawBody = await renderToString(app);
372
372
  const { styles, body } = unescapeVueStyles(rawBody);
@@ -429,12 +429,12 @@ var CONVENTIONS_KEY = "__absoluteConventions", isConventionsMap = (value) => Boo
429
429
  status: 404
430
430
  });
431
431
  }, renderVueNotFound = async (conventionPath) => {
432
- const { createSSRApp, h } = await import("vue");
432
+ const { createSSRApp, h: h3 } = await import("vue");
433
433
  const { renderToString } = await import("vue/server-renderer");
434
434
  const mod = await import(conventionPath);
435
435
  const NotFoundComponent = mod.default;
436
436
  const app = createSSRApp({
437
- render: () => h(NotFoundComponent)
437
+ render: () => h3(NotFoundComponent)
438
438
  });
439
439
  const rawBody = await renderToString(app);
440
440
  const { styles, body } = unescapeVueStyles(rawBody);
@@ -553,10 +553,10 @@ var ssrDirty = false, isRecord = (value) => typeof value === "object" && value !
553
553
  };
554
554
  };
555
555
  const resolvedPage = await resolvePageComponent();
556
- const { createSSRApp, h } = await import("vue");
556
+ const { createSSRApp, h: h3 } = await import("vue");
557
557
  const { renderToWebStream } = await import("vue/server-renderer");
558
558
  const app = createSSRApp({
559
- render: () => h(resolvedPage.component, maybeProps ?? null)
559
+ render: () => h3(resolvedPage.component, maybeProps ?? null)
560
560
  });
561
561
  const bodyStream = renderToWebStream(app);
562
562
  const head = `<!DOCTYPE html><html>${headTag}<body><div id="root">`;
@@ -1681,7 +1681,7 @@ function sha1(str) {
1681
1681
  words32[len >> 5] |= 128 << 24 - len % 32;
1682
1682
  words32[(len + 64 >> 9 << 4) + 15] = len;
1683
1683
  for (let i = 0;i < words32.length; i += 16) {
1684
- const h0 = a, h1 = b, h2 = c, h3 = d, h4 = e;
1684
+ const h0 = a, h1 = b, h22 = c, h3 = d, h4 = e;
1685
1685
  for (let j = 0;j < 80; j++) {
1686
1686
  if (j < 16) {
1687
1687
  w[j] = words32[i + j];
@@ -1700,7 +1700,7 @@ function sha1(str) {
1700
1700
  }
1701
1701
  a = add32(a, h0);
1702
1702
  b = add32(b, h1);
1703
- c = add32(c, h2);
1703
+ c = add32(c, h22);
1704
1704
  d = add32(d, h3);
1705
1705
  e = add32(e, h4);
1706
1706
  }
@@ -30398,14 +30398,14 @@ var init_islands2 = __esm(() => {
30398
30398
  import { createElement } from "react";
30399
30399
  import { renderToStaticMarkup } from "react-dom/server";
30400
30400
  import { render as renderSvelte } from "svelte/server";
30401
- import { createSSRApp, h } from "vue";
30401
+ import { createSSRApp, h as h3 } from "vue";
30402
30402
  import { renderToString as renderVueToString } from "vue/server-renderer";
30403
30403
  var renderReactIslandToHtml = (component, props) => renderToStaticMarkup(createElement(component, props)), renderSvelteIslandToHtml = (component, props) => {
30404
30404
  const { body } = renderSvelte(component, { props });
30405
30405
  return body;
30406
30406
  }, renderVueIslandToHtml = (component, props) => {
30407
30407
  const app = createSSRApp({
30408
- render: () => h(component, props)
30408
+ render: () => h3(component, props)
30409
30409
  });
30410
30410
  return renderVueToString(app);
30411
30411
  };
@@ -30782,6 +30782,105 @@ var init_renderIslandMarkup = __esm(() => {
30782
30782
  resolvedServerBuildComponentCache = new Map;
30783
30783
  });
30784
30784
 
30785
+ // src/vue/components/Image.vue
30786
+ var Image_default = "../Image-0pe96k20.vue";
30787
+ // src/vue/components/SuspenseSlot.ts
30788
+ import { defineComponent as defineComponent2, h as h2 } from "vue";
30789
+
30790
+ // src/vue/components/StreamSlot.ts
30791
+ import { defineComponent, h } from "vue";
30792
+
30793
+ // src/core/streamingSlotRegistry.ts
30794
+ var asyncLocalStorage;
30795
+ var isServerRuntime = () => typeof process !== "undefined" && typeof process.versions?.node === "string";
30796
+ var ensureAsyncLocalStorage = async () => {
30797
+ if (typeof asyncLocalStorage !== "undefined")
30798
+ return asyncLocalStorage;
30799
+ if (!isServerRuntime()) {
30800
+ asyncLocalStorage = null;
30801
+ return asyncLocalStorage;
30802
+ }
30803
+ const mod = await import("async_hooks");
30804
+ asyncLocalStorage = new mod.AsyncLocalStorage;
30805
+ return asyncLocalStorage;
30806
+ };
30807
+ var registerStreamingSlot = (slot) => {
30808
+ if (!asyncLocalStorage)
30809
+ return;
30810
+ const store = asyncLocalStorage.getStore();
30811
+ if (!store)
30812
+ return;
30813
+ store.set(slot.id, slot);
30814
+ };
30815
+ var runWithStreamingSlotRegistry = async (task) => {
30816
+ const storage = await ensureAsyncLocalStorage();
30817
+ if (!storage) {
30818
+ return {
30819
+ result: await task(),
30820
+ slots: []
30821
+ };
30822
+ }
30823
+ return storage.run(new Map, async () => {
30824
+ const result = await task();
30825
+ const store = storage.getStore();
30826
+ return {
30827
+ result,
30828
+ slots: store ? [...store.values()] : []
30829
+ };
30830
+ });
30831
+ };
30832
+
30833
+ // src/vue/components/StreamSlot.ts
30834
+ var StreamSlot = defineComponent({
30835
+ name: "AbsoluteStreamSlot",
30836
+ props: {
30837
+ className: { default: undefined, type: String },
30838
+ errorHtml: { default: undefined, type: String },
30839
+ fallbackHtml: { default: "", type: String },
30840
+ id: { required: true, type: String },
30841
+ resolve: {
30842
+ required: true,
30843
+ type: Function
30844
+ },
30845
+ timeoutMs: { default: undefined, type: Number }
30846
+ },
30847
+ setup(props) {
30848
+ if (typeof window === "undefined") {
30849
+ registerStreamingSlot({
30850
+ errorHtml: props.errorHtml,
30851
+ fallbackHtml: props.fallbackHtml,
30852
+ id: props.id,
30853
+ resolve: props.resolve,
30854
+ timeoutMs: props.timeoutMs
30855
+ });
30856
+ }
30857
+ return () => h("div", {
30858
+ class: props.className,
30859
+ "data-absolute-slot": "true",
30860
+ id: `slot-${props.id}`,
30861
+ innerHTML: props.fallbackHtml
30862
+ });
30863
+ }
30864
+ });
30865
+
30866
+ // src/vue/components/SuspenseSlot.ts
30867
+ var SuspenseSlot = defineComponent2({
30868
+ name: "AbsoluteSuspenseSlot",
30869
+ props: {
30870
+ className: { default: undefined, type: String },
30871
+ errorHtml: { default: undefined, type: String },
30872
+ fallbackHtml: { default: "", type: String },
30873
+ id: { required: true, type: String },
30874
+ resolve: {
30875
+ required: true,
30876
+ type: Function
30877
+ },
30878
+ timeoutMs: { default: undefined, type: Number }
30879
+ },
30880
+ setup(props) {
30881
+ return () => h2(StreamSlot, props);
30882
+ }
30883
+ });
30785
30884
  // src/client/streamSwap.ts
30786
30885
  var streamSwapRuntime = () => {
30787
30886
  if (window.__ABS_SLOT_RUNTIME__ === true)
@@ -30837,6 +30936,9 @@ var CLOSING_PAGE_TAG_REGEX = /<\/body>\s*<\/html>\s*$/i;
30837
30936
  var STREAMING_RUNTIME_GLOBAL = "__ABS_SLOT_ENQUEUE__";
30838
30937
  var STREAMING_PENDING_GLOBAL = "__ABS_SLOT_PENDING__";
30839
30938
  var STREAM_TAIL_LOOKBEHIND = 128;
30939
+ var STREAMING_SLOT_TIMEOUT_MS = 5000;
30940
+ var STREAMING_SLOT_MAX_PER_RESPONSE = 128;
30941
+ var STREAMING_SLOT_MAX_HTML_BYTES = 64000;
30840
30942
  var createSlotPlaceholderId = (id) => `${SLOT_PLACEHOLDER_PREFIX}${id}`;
30841
30943
  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)});`;
30842
30944
  var createNonceAttr = (nonce) => nonce ? ` nonce="${nonce}"` : "";
@@ -30853,32 +30955,197 @@ var injectHtmlIntoHead = (html, injection) => {
30853
30955
  return `${html}${injection}`;
30854
30956
  };
30855
30957
  var toUint8 = (value, encoder) => encoder.encode(value);
30856
- var toStreamingSlot = (slot) => ({
30857
- ...slot,
30858
- id: slot.id ?? createStreamingSlotId()
30958
+ var currentStreamingSlotPolicy = {
30959
+ timeoutMs: STREAMING_SLOT_TIMEOUT_MS,
30960
+ fallbackHtml: "",
30961
+ errorHtml: undefined,
30962
+ maxSlotsPerResponse: STREAMING_SLOT_MAX_PER_RESPONSE,
30963
+ maxSlotHtmlSizeBytes: STREAMING_SLOT_MAX_HTML_BYTES
30964
+ };
30965
+ var clonePolicy = (policy) => ({
30966
+ ...policy
30859
30967
  });
30860
- var resolveSlot = async (slot, onError) => {
30968
+ var normalizeSlotBytes = (value, fallback) => {
30969
+ if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
30970
+ return Math.floor(value);
30971
+ }
30972
+ return fallback;
30973
+ };
30974
+ var normalizeSlotText = (value, fallback) => typeof value === "string" ? value : fallback;
30975
+ var normalizeSlotError = (value, fallback) => typeof value === "string" ? value : fallback;
30976
+ var hasPolicyValue = (policy, key) => Object.prototype.hasOwnProperty.call(policy, key);
30977
+ var applyStreamingSlotPolicyOverrides = (base, overridePolicy = {}) => ({
30978
+ timeoutMs: hasPolicyValue(overridePolicy, "timeoutMs") ? normalizeSlotBytes(overridePolicy.timeoutMs, base.timeoutMs) : base.timeoutMs,
30979
+ fallbackHtml: hasPolicyValue(overridePolicy, "fallbackHtml") ? normalizeSlotText(overridePolicy.fallbackHtml, "") : base.fallbackHtml,
30980
+ errorHtml: hasPolicyValue(overridePolicy, "errorHtml") ? normalizeSlotError(overridePolicy.errorHtml) : base.errorHtml,
30981
+ maxSlotsPerResponse: hasPolicyValue(overridePolicy, "maxSlotsPerResponse") ? normalizeSlotBytes(overridePolicy.maxSlotsPerResponse, base.maxSlotsPerResponse) : base.maxSlotsPerResponse,
30982
+ maxSlotHtmlSizeBytes: hasPolicyValue(overridePolicy, "maxSlotHtmlSizeBytes") ? normalizeSlotBytes(overridePolicy.maxSlotHtmlSizeBytes, base.maxSlotHtmlSizeBytes) : base.maxSlotHtmlSizeBytes,
30983
+ onError: hasPolicyValue(overridePolicy, "onError") ? overridePolicy.onError : base.onError,
30984
+ onSlotMetric: hasPolicyValue(overridePolicy, "onSlotMetric") ? overridePolicy.onSlotMetric : base.onSlotMetric
30985
+ });
30986
+ var createCombinedSlotErrorHandler = (policyOnError, enhancerOnError) => {
30987
+ if (!policyOnError && !enhancerOnError)
30988
+ return;
30989
+ return (error, slot) => {
30990
+ policyOnError?.(error, slot);
30991
+ enhancerOnError?.(error, slot);
30992
+ };
30993
+ };
30994
+ var createCombinedSlotMetricHandler = (policyOnSlotMetric, callOnSlotMetric) => {
30995
+ if (!policyOnSlotMetric && !callOnSlotMetric)
30996
+ return;
30997
+ return (metric) => {
30998
+ policyOnSlotMetric?.(metric);
30999
+ callOnSlotMetric?.(metric);
31000
+ };
31001
+ };
31002
+ var resolveStreamingSlotPolicy = (overridePolicy = {}) => {
31003
+ const base = getStreamingSlotPolicy();
31004
+ return applyStreamingSlotPolicyOverrides(base, overridePolicy);
31005
+ };
31006
+ var getStreamingSlotPolicy = () => clonePolicy(currentStreamingSlotPolicy);
31007
+ var setStreamingSlotPolicy = (policy = {}) => {
31008
+ const base = getStreamingSlotPolicy();
31009
+ currentStreamingSlotPolicy = applyStreamingSlotPolicyOverrides(base, policy);
31010
+ };
31011
+ var withStreamingSlotPolicy = async (policy, callback) => {
31012
+ const previous = getStreamingSlotPolicy();
31013
+ setStreamingSlotPolicy(policy);
30861
31014
  try {
30862
- const resolved = slot.resolve();
30863
- const html = typeof slot.timeoutMs === "number" && slot.timeoutMs > 0 ? await Promise.race([
30864
- Promise.resolve(resolved),
30865
- new Promise((_, reject) => setTimeout(() => reject(new Error(`Streaming slot "${slot.id}" timed out after ${slot.timeoutMs}ms`)), slot.timeoutMs))
30866
- ]) : await resolved;
31015
+ return await callback();
31016
+ } finally {
31017
+ currentStreamingSlotPolicy = previous;
31018
+ }
31019
+ };
31020
+ var emitSlotMetric = (metric, onSlotMetric) => {
31021
+ onSlotMetric?.(metric);
31022
+ };
31023
+ var createTimeoutError = (slot, timeoutMs) => {
31024
+ const error = new Error(`Streaming slot "${slot.id}" timed out after ${timeoutMs}ms`);
31025
+ error.__absTimeout = true;
31026
+ return error;
31027
+ };
31028
+ var toStreamingSlot = (slot, policy) => ({
31029
+ errorHtml: slot.errorHtml === undefined ? policy.errorHtml : slot.errorHtml,
31030
+ fallbackHtml: normalizeSlotText(slot.fallbackHtml, policy.fallbackHtml),
31031
+ id: slot.id ?? createStreamingSlotId(),
31032
+ timeoutMs: normalizeSlotBytes(slot.timeoutMs, policy.timeoutMs),
31033
+ resolve: slot.resolve
31034
+ });
31035
+ var prepareSlots = ({
31036
+ policy,
31037
+ slots,
31038
+ onError,
31039
+ onSlotMetric
31040
+ }) => {
31041
+ const preparedSlots = slots.map((slot) => toStreamingSlot(slot, policy));
31042
+ const maxSlotsPerResponse = policy.maxSlotsPerResponse;
31043
+ if (maxSlotsPerResponse === 0) {
31044
+ const error = new Error("Streaming slot limit is set to 0");
31045
+ for (const slot of preparedSlots) {
31046
+ onError?.(error, slot);
31047
+ emitSlotMetric({
31048
+ type: "dropped",
31049
+ slotId: slot.id,
31050
+ reason: "maxSlotsPerResponse is 0"
31051
+ }, onSlotMetric);
31052
+ }
31053
+ return [];
31054
+ }
31055
+ if (preparedSlots.length <= maxSlotsPerResponse) {
31056
+ preparedSlots.forEach((slot) => emitSlotMetric({
31057
+ type: "prepared",
31058
+ slotId: slot.id
31059
+ }, onSlotMetric));
31060
+ return preparedSlots;
31061
+ }
31062
+ const keptSlots = preparedSlots.slice(0, maxSlotsPerResponse);
31063
+ const droppedSlots = preparedSlots.slice(maxSlotsPerResponse);
31064
+ droppedSlots.forEach((slot) => {
31065
+ onError?.(new Error(`Streaming slot "${slot.id}" dropped because ${maxSlotsPerResponse} slots is the configured maximum`), slot);
31066
+ emitSlotMetric({
31067
+ type: "dropped",
31068
+ slotId: slot.id,
31069
+ reason: `maxSlotsPerResponse is ${maxSlotsPerResponse}`
31070
+ }, onSlotMetric);
31071
+ });
31072
+ keptSlots.forEach((slot) => emitSlotMetric({
31073
+ type: "prepared",
31074
+ slotId: slot.id
31075
+ }, onSlotMetric));
31076
+ return keptSlots;
31077
+ };
31078
+ var htmlByteLength = (value, encoder) => encoder.encode(value).length;
31079
+ var resolveSlot = async (slot, onError, policy, onSlotMetric) => {
31080
+ const safePolicy = policy ?? getStreamingSlotPolicy();
31081
+ const encoder = new TextEncoder;
31082
+ const start = Date.now();
31083
+ try {
31084
+ const maybeAsyncValue = Promise.resolve(slot.resolve());
31085
+ const resolved = typeof slot.timeoutMs === "number" && slot.timeoutMs > 0 ? await Promise.race([
31086
+ maybeAsyncValue,
31087
+ new Promise((_, reject) => setTimeout(() => {
31088
+ reject(createTimeoutError(slot, slot.timeoutMs ?? 0));
31089
+ }, slot.timeoutMs))
31090
+ ]) : await maybeAsyncValue;
31091
+ const html = typeof resolved === "string" ? resolved : `${resolved}`;
31092
+ if (safePolicy.maxSlotHtmlSizeBytes > 0 && htmlByteLength(html, encoder) > safePolicy.maxSlotHtmlSizeBytes) {
31093
+ const bytes2 = htmlByteLength(html, encoder);
31094
+ const error = new Error(`Streaming slot "${slot.id}" exceeded max payload size of ${safePolicy.maxSlotHtmlSizeBytes} bytes`);
31095
+ const durationMs2 = Date.now() - start;
31096
+ onError?.(error, slot);
31097
+ emitSlotMetric({
31098
+ type: "size_exceeded",
31099
+ slotId: slot.id,
31100
+ durationMs: durationMs2,
31101
+ bytes: bytes2,
31102
+ error
31103
+ }, onSlotMetric);
31104
+ const fallbackHtml = typeof slot.errorHtml === "string" ? slot.errorHtml : null;
31105
+ return {
31106
+ html: fallbackHtml,
31107
+ id: slot.id,
31108
+ durationMs: durationMs2,
31109
+ bytes: fallbackHtml === null ? 0 : htmlByteLength(fallbackHtml, encoder)
31110
+ };
31111
+ }
31112
+ const durationMs = Date.now() - start;
31113
+ const bytes = htmlByteLength(html, encoder);
31114
+ emitSlotMetric({
31115
+ type: "resolved",
31116
+ slotId: slot.id,
31117
+ durationMs,
31118
+ bytes
31119
+ }, onSlotMetric);
30867
31120
  return {
30868
31121
  html,
30869
- id: slot.id
31122
+ id: slot.id,
31123
+ durationMs,
31124
+ bytes
30870
31125
  };
30871
31126
  } catch (error) {
31127
+ const durationMs = Date.now() - start;
30872
31128
  onError?.(error, slot);
31129
+ emitSlotMetric({
31130
+ type: error?.__absTimeout === true ? "timeout" : "error",
31131
+ slotId: slot.id,
31132
+ durationMs,
31133
+ error
31134
+ }, onSlotMetric);
30873
31135
  if (typeof slot.errorHtml === "string") {
31136
+ const html = slot.errorHtml;
30874
31137
  return {
30875
- html: slot.errorHtml,
30876
- id: slot.id
31138
+ html,
31139
+ id: slot.id,
31140
+ durationMs,
31141
+ bytes: htmlByteLength(html, encoder)
30877
31142
  };
30878
31143
  }
30879
31144
  return {
30880
31145
  html: null,
30881
- id: slot.id
31146
+ id: slot.id,
31147
+ durationMs,
31148
+ bytes: 0
30882
31149
  };
30883
31150
  }
30884
31151
  };
@@ -30894,23 +31161,37 @@ var streamOutOfOrderSlots = ({
30894
31161
  footerHtml = "",
30895
31162
  headerHtml = "",
30896
31163
  nonce,
31164
+ policy,
31165
+ onSlotMetric,
30897
31166
  onError,
30898
31167
  slots
30899
31168
  }) => {
31169
+ const resolvedPolicy = resolveStreamingSlotPolicy(policy);
31170
+ const combinedOnError = createCombinedSlotErrorHandler(resolvedPolicy.onError, onError);
31171
+ const combinedOnSlotMetric = createCombinedSlotMetricHandler(resolvedPolicy.onSlotMetric, onSlotMetric);
31172
+ const effectivePolicy = {
31173
+ ...resolvedPolicy,
31174
+ onSlotMetric: combinedOnSlotMetric
31175
+ };
31176
+ const preparedSlots = prepareSlots({
31177
+ policy: effectivePolicy,
31178
+ slots,
31179
+ onError: combinedOnError,
31180
+ onSlotMetric: combinedOnSlotMetric
31181
+ });
30900
31182
  const encoder = new TextEncoder;
30901
31183
  return new ReadableStream({
30902
31184
  async start(controller) {
30903
31185
  try {
30904
31186
  let header = headerHtml;
30905
- if (!header.includes(STREAMING_RUNTIME_GLOBAL)) {
31187
+ if (preparedSlots.length > 0 && !header.includes(STREAMING_RUNTIME_GLOBAL)) {
30906
31188
  header = injectHtmlIntoHead(header, renderStreamingSlotsRuntimeTag(nonce));
30907
31189
  }
30908
31190
  controller.enqueue(toUint8(header, encoder));
30909
- const pending = slots.map((slot) => {
30910
- const resolvedSlot = toStreamingSlot(slot);
30911
- const fallback = renderStreamingSlotPlaceholder(resolvedSlot.id, resolvedSlot.fallbackHtml ?? "");
31191
+ const pending = preparedSlots.map((slot) => {
31192
+ const fallback = renderStreamingSlotPlaceholder(slot.id, slot.fallbackHtml ?? "");
30912
31193
  controller.enqueue(toUint8(fallback, encoder));
30913
- return resolveSlot(resolvedSlot, onError);
31194
+ return resolveSlot(slot, combinedOnError, effectivePolicy, combinedOnSlotMetric);
30914
31195
  });
30915
31196
  while (pending.length > 0) {
30916
31197
  const { original, result } = await nextResolvedSlot(pending);
@@ -30919,6 +31200,12 @@ var streamOutOfOrderSlots = ({
30919
31200
  pending.splice(index, 1);
30920
31201
  if (result.html === null)
30921
31202
  continue;
31203
+ emitSlotMetric({
31204
+ type: "patched",
31205
+ slotId: result.id,
31206
+ durationMs: result.durationMs,
31207
+ bytes: result.bytes
31208
+ }, combinedOnSlotMetric);
30922
31209
  controller.enqueue(toUint8(renderStreamingSlotPatchTag(result.id, result.html, nonce), encoder));
30923
31210
  }
30924
31211
  if (footerHtml.length > 0) {
@@ -30982,12 +31269,33 @@ var injectStreamingRuntimeIntoStream = (stream, nonce) => {
30982
31269
  }
30983
31270
  });
30984
31271
  };
30985
- var appendStreamingSlotPatchesToStream = (stream, slots = [], { injectRuntime = true, nonce, onError } = {}) => {
31272
+ var appendStreamingSlotPatchesToStream = (stream, slots = [], {
31273
+ injectRuntime = true,
31274
+ nonce,
31275
+ onError,
31276
+ onSlotMetric,
31277
+ policy
31278
+ } = {}) => {
31279
+ const resolvedPolicy = resolveStreamingSlotPolicy(policy);
31280
+ const combinedOnError = createCombinedSlotErrorHandler(resolvedPolicy.onError, onError);
31281
+ const combinedOnSlotMetric = createCombinedSlotMetricHandler(resolvedPolicy.onSlotMetric, onSlotMetric);
31282
+ const effectivePolicy = {
31283
+ ...resolvedPolicy,
31284
+ onSlotMetric: combinedOnSlotMetric
31285
+ };
31286
+ const preparedSlots = prepareSlots({
31287
+ policy: effectivePolicy,
31288
+ slots,
31289
+ onError: combinedOnError,
31290
+ onSlotMetric: combinedOnSlotMetric
31291
+ });
31292
+ if (preparedSlots.length === 0)
31293
+ return stream;
30986
31294
  const source = injectRuntime ? injectStreamingRuntimeIntoStream(stream, nonce) : stream;
30987
31295
  const encoder = new TextEncoder;
30988
31296
  const decoder = new TextDecoder;
30989
31297
  const reader = source.getReader();
30990
- const pending = slots.map((slot) => resolveSlot(slot, onError));
31298
+ const pending = preparedSlots.map((slot) => resolveSlot(slot, combinedOnError, effectivePolicy, combinedOnSlotMetric));
30991
31299
  return new ReadableStream({
30992
31300
  async start(controller) {
30993
31301
  let baseDone = false;
@@ -31044,6 +31352,12 @@ var appendStreamingSlotPatchesToStream = (stream, slots = [], { injectRuntime =
31044
31352
  pending.splice(index, 1);
31045
31353
  if (winner.result.html === null)
31046
31354
  continue;
31355
+ emitSlotMetric({
31356
+ type: "patched",
31357
+ slotId: winner.result.id,
31358
+ durationMs: winner.result.durationMs,
31359
+ bytes: winner.result.bytes
31360
+ }, combinedOnSlotMetric);
31047
31361
  controller.enqueue(encoder.encode(renderStreamingSlotPatchTag(winner.result.id, winner.result.html, nonce)));
31048
31362
  }
31049
31363
  if (footer.length > 0)
@@ -31056,59 +31370,20 @@ var appendStreamingSlotPatchesToStream = (stream, slots = [], { injectRuntime =
31056
31370
  });
31057
31371
  };
31058
31372
 
31059
- // src/core/streamingSlotRegistry.ts
31060
- var asyncLocalStorage;
31061
- var isServerRuntime = () => typeof process !== "undefined" && typeof process.versions?.node === "string";
31062
- var ensureAsyncLocalStorage = async () => {
31063
- if (typeof asyncLocalStorage !== "undefined")
31064
- return asyncLocalStorage;
31065
- if (!isServerRuntime()) {
31066
- asyncLocalStorage = null;
31067
- return asyncLocalStorage;
31068
- }
31069
- const mod = await import("async_hooks");
31070
- asyncLocalStorage = new mod.AsyncLocalStorage;
31071
- return asyncLocalStorage;
31072
- };
31073
- var registerStreamingSlot = (slot) => {
31074
- if (!asyncLocalStorage)
31075
- return;
31076
- const store = asyncLocalStorage.getStore();
31077
- if (!store)
31078
- return;
31079
- store.set(slot.id, slot);
31080
- };
31081
- var runWithStreamingSlotRegistry = async (task) => {
31082
- const storage = await ensureAsyncLocalStorage();
31083
- if (!storage) {
31084
- return {
31085
- result: await task(),
31086
- slots: []
31087
- };
31088
- }
31089
- return storage.run(new Map, async () => {
31090
- const result = await task();
31091
- const store = storage.getStore();
31092
- return {
31093
- result,
31094
- slots: store ? [...store.values()] : []
31095
- };
31096
- });
31097
- };
31098
-
31099
31373
  // src/core/responseEnhancers.ts
31100
31374
  var toResponse = async (responseLike) => await responseLike;
31101
31375
  var cloneHeaders = (response) => {
31102
31376
  const headers = new Headers(response.headers);
31103
31377
  return headers;
31104
31378
  };
31105
- var enhanceHtmlResponseWithStreamingSlots = (response, { nonce, onError, streamingSlots = [] } = {}) => {
31379
+ var enhanceHtmlResponseWithStreamingSlots = (response, { nonce, onError, streamingSlots = [], policy } = {}) => {
31106
31380
  if (!response.body || streamingSlots.length === 0) {
31107
31381
  return response;
31108
31382
  }
31109
31383
  const body = appendStreamingSlotPatchesToStream(response.body, streamingSlots, {
31110
31384
  nonce,
31111
- onError
31385
+ onError,
31386
+ policy
31112
31387
  });
31113
31388
  return new Response(body, {
31114
31389
  headers: cloneHeaders(response),
@@ -31141,7 +31416,7 @@ var wrapPageHandlerWithStreamingSlots = (handler) => (...args) => withRegistered
31141
31416
  init_pageHandler();
31142
31417
 
31143
31418
  // src/vue/Island.ts
31144
- import { defineComponent, h as h2, onServerPrefetch } from "vue";
31419
+ import { defineComponent as defineComponent3, h as h4, onServerPrefetch } from "vue";
31145
31420
 
31146
31421
  // src/client/preserveIslandMarkup.ts
31147
31422
  init_islandMarkupAttributes();
@@ -31229,7 +31504,7 @@ var preserveIslandMarkup = (props) => {
31229
31504
  // src/vue/Island.ts
31230
31505
  init_islandMarkupAttributes();
31231
31506
  init_renderIslandMarkup();
31232
- var defineRuntimeIslandComponent = (setup) => defineComponent({
31507
+ var defineRuntimeIslandComponent = (setup) => defineComponent3({
31233
31508
  name: "AbsoluteIsland",
31234
31509
  props: {
31235
31510
  component: {
@@ -31261,7 +31536,7 @@ var Island = defineRuntimeIslandComponent((props) => {
31261
31536
  });
31262
31537
  return () => {
31263
31538
  const preserved = isBrowser ? preserveIslandMarkup(props) : null;
31264
- return h2("div", {
31539
+ return h4("div", {
31265
31540
  ...preserved?.attributes ?? markerAttributes,
31266
31541
  "data-allow-mismatch": "",
31267
31542
  innerHTML: isBrowser ? preserved?.innerHTML : html
@@ -31271,8 +31546,8 @@ var Island = defineRuntimeIslandComponent((props) => {
31271
31546
  // src/vue/createIsland.ts
31272
31547
  init_islandMarkupAttributes();
31273
31548
  init_renderIslandMarkup();
31274
- import { defineComponent as defineComponent2, h as h3, onServerPrefetch as onServerPrefetch2 } from "vue";
31275
- var defineRuntimeIslandComponent2 = (setup) => defineComponent2({
31549
+ import { defineComponent as defineComponent4, h as h5, onServerPrefetch as onServerPrefetch2 } from "vue";
31550
+ var defineRuntimeIslandComponent2 = (setup) => defineComponent4({
31276
31551
  name: "AbsoluteIsland",
31277
31552
  props: {
31278
31553
  component: {
@@ -31302,7 +31577,7 @@ var createTypedIsland = (registry) => defineRuntimeIslandComponent2((props) => {
31302
31577
  const result = await renderIslandResult(registry, props);
31303
31578
  ({ attributes: markerAttributes, html } = result);
31304
31579
  });
31305
- return () => h3("div", {
31580
+ return () => h5("div", {
31306
31581
  ...markerAttributes,
31307
31582
  "data-allow-mismatch": "",
31308
31583
  innerHTML: isBrowser ? undefined : html
@@ -31453,8 +31728,11 @@ export {
31453
31728
  useIslandStore,
31454
31729
  handleVuePageRequest2 as handleVuePageRequest,
31455
31730
  createTypedIsland,
31456
- Island
31731
+ SuspenseSlot,
31732
+ StreamSlot,
31733
+ Island,
31734
+ Image_default as Image
31457
31735
  };
31458
31736
 
31459
- //# debugId=DC8489D31EE81ABA64756E2164756E21
31737
+ //# debugId=5FAE5FAF19D8DFBB64756E2164756E21
31460
31738
  //# sourceMappingURL=index.js.map