@absolutejs/absolute 0.19.0-beta.350 → 0.19.0-beta.351
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/angular/index.js +239 -23
- package/dist/angular/index.js.map +4 -4
- package/dist/build.js +2 -2
- package/dist/build.js.map +1 -1
- package/dist/index.js +301 -24
- package/dist/index.js.map +7 -6
- package/dist/react/index.js +239 -23
- package/dist/react/index.js.map +4 -4
- package/dist/src/core/responseEnhancers.d.ts +3 -2
- package/dist/src/utils/index.d.ts +1 -0
- package/dist/src/utils/streamingSlotMetricSink.d.ts +18 -0
- package/dist/src/utils/streamingSlots.d.ts +38 -2
- package/dist/svelte/index.js +239 -23
- package/dist/svelte/index.js.map +4 -4
- package/dist/vue/index.js +239 -23
- package/dist/vue/index.js.map +4 -4
- package/package.json +7 -7
|
@@ -1,9 +1,10 @@
|
|
|
1
|
-
import { type AppendStreamingSlotsOptions, type StreamingSlot } from '../utils/streamingSlots';
|
|
1
|
+
import { type AppendStreamingSlotsOptions, type StreamingSlotPolicy, type StreamingSlot } from '../utils/streamingSlots';
|
|
2
2
|
type ResponseLike = Response | Promise<Response>;
|
|
3
3
|
export type StreamingSlotEnhancerOptions = Omit<AppendStreamingSlotsOptions, 'injectRuntime'> & {
|
|
4
4
|
streamingSlots?: StreamingSlot[];
|
|
5
|
+
policy?: StreamingSlotPolicy;
|
|
5
6
|
};
|
|
6
|
-
export declare const enhanceHtmlResponseWithStreamingSlots: (response: Response, { nonce, onError, streamingSlots }?: StreamingSlotEnhancerOptions) => Response;
|
|
7
|
+
export declare const enhanceHtmlResponseWithStreamingSlots: (response: Response, { nonce, onError, streamingSlots, policy }?: StreamingSlotEnhancerOptions) => Response;
|
|
7
8
|
export declare const withStreamingSlots: (responseLike: ResponseLike, options?: StreamingSlotEnhancerOptions) => Promise<Response>;
|
|
8
9
|
export declare const withRegisteredStreamingSlots: (renderResponse: () => ResponseLike, options?: StreamingSlotEnhancerOptions) => Promise<Response>;
|
|
9
10
|
export {};
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { StreamingSlotMetric, StreamingSlotMetricHandler, StreamingSlotMetricType } from './streamingSlots';
|
|
2
|
+
export type StreamingSlotMetricMetadataValue = string | number | boolean | null;
|
|
3
|
+
export type StreamingSlotMetricMetadata = Record<string, StreamingSlotMetricMetadataValue>;
|
|
4
|
+
export type StreamingSlotMetricSinkEvent = StreamingSlotMetric & {
|
|
5
|
+
at: number;
|
|
6
|
+
route?: string;
|
|
7
|
+
metadata?: StreamingSlotMetricMetadata;
|
|
8
|
+
};
|
|
9
|
+
export type StreamingSlotMetricSinkOptions = {
|
|
10
|
+
onReport?: (metric: StreamingSlotMetricSinkEvent) => void | Promise<void>;
|
|
11
|
+
onError?: (error: unknown, metric: StreamingSlotMetricSinkEvent) => void;
|
|
12
|
+
route?: string;
|
|
13
|
+
metadata?: StreamingSlotMetricMetadata;
|
|
14
|
+
includeTypes?: StreamingSlotMetricType[];
|
|
15
|
+
excludeTypes?: StreamingSlotMetricType[];
|
|
16
|
+
sampleRate?: number;
|
|
17
|
+
};
|
|
18
|
+
export declare const createStreamingSlotMetricSink: ({ excludeTypes, includeTypes, metadata, onReport, onError, route, sampleRate }?: StreamingSlotMetricSinkOptions) => StreamingSlotMetricHandler;
|
|
@@ -1,4 +1,33 @@
|
|
|
1
1
|
type SlotResolver = () => Promise<string> | string;
|
|
2
|
+
type SlotErrorHandler = (error: unknown, slot: StreamingSlot) => void;
|
|
3
|
+
export type StreamingSlotMetricType = 'prepared' | 'dropped' | 'resolved' | 'patched' | 'timeout' | 'size_exceeded' | 'error';
|
|
4
|
+
export type StreamingSlotMetric = {
|
|
5
|
+
type: StreamingSlotMetricType;
|
|
6
|
+
slotId: string;
|
|
7
|
+
durationMs?: number;
|
|
8
|
+
bytes?: number;
|
|
9
|
+
reason?: string;
|
|
10
|
+
error?: unknown;
|
|
11
|
+
};
|
|
12
|
+
export type StreamingSlotMetricHandler = (metric: StreamingSlotMetric) => void;
|
|
13
|
+
export type StreamingSlotPolicy = {
|
|
14
|
+
timeoutMs?: number;
|
|
15
|
+
fallbackHtml?: string;
|
|
16
|
+
errorHtml?: string;
|
|
17
|
+
maxSlotsPerResponse?: number;
|
|
18
|
+
maxSlotHtmlSizeBytes?: number;
|
|
19
|
+
onError?: SlotErrorHandler;
|
|
20
|
+
onSlotMetric?: StreamingSlotMetricHandler;
|
|
21
|
+
};
|
|
22
|
+
type StreamingSlotPolicyValue = {
|
|
23
|
+
timeoutMs: number;
|
|
24
|
+
fallbackHtml: string;
|
|
25
|
+
errorHtml?: string;
|
|
26
|
+
maxSlotsPerResponse: number;
|
|
27
|
+
maxSlotHtmlSizeBytes: number;
|
|
28
|
+
onError?: SlotErrorHandler;
|
|
29
|
+
onSlotMetric?: StreamingSlotMetricHandler;
|
|
30
|
+
};
|
|
2
31
|
export type StreamingSlot = {
|
|
3
32
|
errorHtml?: string;
|
|
4
33
|
fallbackHtml?: string;
|
|
@@ -12,12 +41,16 @@ type DeferredStreamingSlot = Omit<StreamingSlot, 'id'> & {
|
|
|
12
41
|
export type AppendStreamingSlotsOptions = {
|
|
13
42
|
injectRuntime?: boolean;
|
|
14
43
|
nonce?: string;
|
|
44
|
+
policy?: StreamingSlotPolicy;
|
|
45
|
+
onSlotMetric?: StreamingSlotMetricHandler;
|
|
15
46
|
onError?: (error: unknown, slot: StreamingSlot) => void;
|
|
16
47
|
};
|
|
17
48
|
export type StreamOutOfOrderSlotsOptions = {
|
|
18
49
|
footerHtml?: string;
|
|
19
50
|
headerHtml?: string;
|
|
20
51
|
nonce?: string;
|
|
52
|
+
policy?: StreamingSlotPolicy;
|
|
53
|
+
onSlotMetric?: StreamingSlotMetricHandler;
|
|
21
54
|
onError?: (error: unknown, slot: StreamingSlot) => void;
|
|
22
55
|
slots: DeferredStreamingSlot[];
|
|
23
56
|
};
|
|
@@ -27,7 +60,10 @@ export declare const renderStreamingSlotsRuntimeTag: (nonce?: string) => string;
|
|
|
27
60
|
export declare const renderStreamingSlotPlaceholder: (id: string, fallbackHtml?: string) => string;
|
|
28
61
|
export declare const renderStreamingSlotPatchTag: (id: string, html: string, nonce?: string) => string;
|
|
29
62
|
export declare const injectHtmlIntoHead: (html: string, injection: string) => string;
|
|
30
|
-
export declare const
|
|
63
|
+
export declare const getStreamingSlotPolicy: () => StreamingSlotPolicyValue;
|
|
64
|
+
export declare const setStreamingSlotPolicy: (policy?: StreamingSlotPolicy) => void;
|
|
65
|
+
export declare const withStreamingSlotPolicy: <T>(policy: StreamingSlotPolicy, callback: () => Promise<T> | T) => Promise<T>;
|
|
66
|
+
export declare const streamOutOfOrderSlots: ({ footerHtml, headerHtml, nonce, policy, onSlotMetric, onError, slots }: StreamOutOfOrderSlotsOptions) => ReadableStream<Uint8Array<ArrayBufferLike>>;
|
|
31
67
|
export declare const injectStreamingRuntimeIntoStream: (stream: ReadableStream<string | Uint8Array>, nonce?: string) => ReadableStream<Uint8Array<ArrayBufferLike>>;
|
|
32
|
-
export declare const appendStreamingSlotPatchesToStream: (stream: ReadableStream<string | Uint8Array>, slots?:
|
|
68
|
+
export declare const appendStreamingSlotPatchesToStream: (stream: ReadableStream<string | Uint8Array>, slots?: DeferredStreamingSlot[], { injectRuntime, nonce, onError, onSlotMetric, policy }?: AppendStreamingSlotsOptions) => ReadableStream<string | Uint8Array<ArrayBufferLike>>;
|
|
33
69
|
export {};
|
package/dist/svelte/index.js
CHANGED
|
@@ -30881,6 +30881,9 @@ var CLOSING_PAGE_TAG_REGEX = /<\/body>\s*<\/html>\s*$/i;
|
|
|
30881
30881
|
var STREAMING_RUNTIME_GLOBAL = "__ABS_SLOT_ENQUEUE__";
|
|
30882
30882
|
var STREAMING_PENDING_GLOBAL = "__ABS_SLOT_PENDING__";
|
|
30883
30883
|
var STREAM_TAIL_LOOKBEHIND = 128;
|
|
30884
|
+
var STREAMING_SLOT_TIMEOUT_MS = 5000;
|
|
30885
|
+
var STREAMING_SLOT_MAX_PER_RESPONSE = 128;
|
|
30886
|
+
var STREAMING_SLOT_MAX_HTML_BYTES = 64000;
|
|
30884
30887
|
var createSlotPlaceholderId = (id) => `${SLOT_PLACEHOLDER_PREFIX}${id}`;
|
|
30885
30888
|
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)});`;
|
|
30886
30889
|
var createNonceAttr = (nonce) => nonce ? ` nonce="${nonce}"` : "";
|
|
@@ -30897,32 +30900,197 @@ var injectHtmlIntoHead = (html, injection) => {
|
|
|
30897
30900
|
return `${html}${injection}`;
|
|
30898
30901
|
};
|
|
30899
30902
|
var toUint8 = (value, encoder) => encoder.encode(value);
|
|
30900
|
-
var
|
|
30901
|
-
|
|
30902
|
-
|
|
30903
|
+
var currentStreamingSlotPolicy = {
|
|
30904
|
+
timeoutMs: STREAMING_SLOT_TIMEOUT_MS,
|
|
30905
|
+
fallbackHtml: "",
|
|
30906
|
+
errorHtml: undefined,
|
|
30907
|
+
maxSlotsPerResponse: STREAMING_SLOT_MAX_PER_RESPONSE,
|
|
30908
|
+
maxSlotHtmlSizeBytes: STREAMING_SLOT_MAX_HTML_BYTES
|
|
30909
|
+
};
|
|
30910
|
+
var clonePolicy = (policy) => ({
|
|
30911
|
+
...policy
|
|
30912
|
+
});
|
|
30913
|
+
var normalizeSlotBytes = (value, fallback) => {
|
|
30914
|
+
if (typeof value === "number" && Number.isFinite(value) && value >= 0) {
|
|
30915
|
+
return Math.floor(value);
|
|
30916
|
+
}
|
|
30917
|
+
return fallback;
|
|
30918
|
+
};
|
|
30919
|
+
var normalizeSlotText = (value, fallback) => typeof value === "string" ? value : fallback;
|
|
30920
|
+
var normalizeSlotError = (value, fallback) => typeof value === "string" ? value : fallback;
|
|
30921
|
+
var hasPolicyValue = (policy, key) => Object.prototype.hasOwnProperty.call(policy, key);
|
|
30922
|
+
var applyStreamingSlotPolicyOverrides = (base, overridePolicy = {}) => ({
|
|
30923
|
+
timeoutMs: hasPolicyValue(overridePolicy, "timeoutMs") ? normalizeSlotBytes(overridePolicy.timeoutMs, base.timeoutMs) : base.timeoutMs,
|
|
30924
|
+
fallbackHtml: hasPolicyValue(overridePolicy, "fallbackHtml") ? normalizeSlotText(overridePolicy.fallbackHtml, "") : base.fallbackHtml,
|
|
30925
|
+
errorHtml: hasPolicyValue(overridePolicy, "errorHtml") ? normalizeSlotError(overridePolicy.errorHtml) : base.errorHtml,
|
|
30926
|
+
maxSlotsPerResponse: hasPolicyValue(overridePolicy, "maxSlotsPerResponse") ? normalizeSlotBytes(overridePolicy.maxSlotsPerResponse, base.maxSlotsPerResponse) : base.maxSlotsPerResponse,
|
|
30927
|
+
maxSlotHtmlSizeBytes: hasPolicyValue(overridePolicy, "maxSlotHtmlSizeBytes") ? normalizeSlotBytes(overridePolicy.maxSlotHtmlSizeBytes, base.maxSlotHtmlSizeBytes) : base.maxSlotHtmlSizeBytes,
|
|
30928
|
+
onError: hasPolicyValue(overridePolicy, "onError") ? overridePolicy.onError : base.onError,
|
|
30929
|
+
onSlotMetric: hasPolicyValue(overridePolicy, "onSlotMetric") ? overridePolicy.onSlotMetric : base.onSlotMetric
|
|
30930
|
+
});
|
|
30931
|
+
var createCombinedSlotErrorHandler = (policyOnError, enhancerOnError) => {
|
|
30932
|
+
if (!policyOnError && !enhancerOnError)
|
|
30933
|
+
return;
|
|
30934
|
+
return (error, slot) => {
|
|
30935
|
+
policyOnError?.(error, slot);
|
|
30936
|
+
enhancerOnError?.(error, slot);
|
|
30937
|
+
};
|
|
30938
|
+
};
|
|
30939
|
+
var createCombinedSlotMetricHandler = (policyOnSlotMetric, callOnSlotMetric) => {
|
|
30940
|
+
if (!policyOnSlotMetric && !callOnSlotMetric)
|
|
30941
|
+
return;
|
|
30942
|
+
return (metric) => {
|
|
30943
|
+
policyOnSlotMetric?.(metric);
|
|
30944
|
+
callOnSlotMetric?.(metric);
|
|
30945
|
+
};
|
|
30946
|
+
};
|
|
30947
|
+
var resolveStreamingSlotPolicy = (overridePolicy = {}) => {
|
|
30948
|
+
const base = getStreamingSlotPolicy();
|
|
30949
|
+
return applyStreamingSlotPolicyOverrides(base, overridePolicy);
|
|
30950
|
+
};
|
|
30951
|
+
var getStreamingSlotPolicy = () => clonePolicy(currentStreamingSlotPolicy);
|
|
30952
|
+
var setStreamingSlotPolicy = (policy = {}) => {
|
|
30953
|
+
const base = getStreamingSlotPolicy();
|
|
30954
|
+
currentStreamingSlotPolicy = applyStreamingSlotPolicyOverrides(base, policy);
|
|
30955
|
+
};
|
|
30956
|
+
var withStreamingSlotPolicy = async (policy, callback) => {
|
|
30957
|
+
const previous = getStreamingSlotPolicy();
|
|
30958
|
+
setStreamingSlotPolicy(policy);
|
|
30959
|
+
try {
|
|
30960
|
+
return await callback();
|
|
30961
|
+
} finally {
|
|
30962
|
+
currentStreamingSlotPolicy = previous;
|
|
30963
|
+
}
|
|
30964
|
+
};
|
|
30965
|
+
var emitSlotMetric = (metric, onSlotMetric) => {
|
|
30966
|
+
onSlotMetric?.(metric);
|
|
30967
|
+
};
|
|
30968
|
+
var createTimeoutError = (slot, timeoutMs) => {
|
|
30969
|
+
const error = new Error(`Streaming slot "${slot.id}" timed out after ${timeoutMs}ms`);
|
|
30970
|
+
error.__absTimeout = true;
|
|
30971
|
+
return error;
|
|
30972
|
+
};
|
|
30973
|
+
var toStreamingSlot = (slot, policy) => ({
|
|
30974
|
+
errorHtml: slot.errorHtml === undefined ? policy.errorHtml : slot.errorHtml,
|
|
30975
|
+
fallbackHtml: normalizeSlotText(slot.fallbackHtml, policy.fallbackHtml),
|
|
30976
|
+
id: slot.id ?? createStreamingSlotId(),
|
|
30977
|
+
timeoutMs: normalizeSlotBytes(slot.timeoutMs, policy.timeoutMs),
|
|
30978
|
+
resolve: slot.resolve
|
|
30903
30979
|
});
|
|
30904
|
-
var
|
|
30980
|
+
var prepareSlots = ({
|
|
30981
|
+
policy,
|
|
30982
|
+
slots,
|
|
30983
|
+
onError,
|
|
30984
|
+
onSlotMetric
|
|
30985
|
+
}) => {
|
|
30986
|
+
const preparedSlots = slots.map((slot) => toStreamingSlot(slot, policy));
|
|
30987
|
+
const maxSlotsPerResponse = policy.maxSlotsPerResponse;
|
|
30988
|
+
if (maxSlotsPerResponse === 0) {
|
|
30989
|
+
const error = new Error("Streaming slot limit is set to 0");
|
|
30990
|
+
for (const slot of preparedSlots) {
|
|
30991
|
+
onError?.(error, slot);
|
|
30992
|
+
emitSlotMetric({
|
|
30993
|
+
type: "dropped",
|
|
30994
|
+
slotId: slot.id,
|
|
30995
|
+
reason: "maxSlotsPerResponse is 0"
|
|
30996
|
+
}, onSlotMetric);
|
|
30997
|
+
}
|
|
30998
|
+
return [];
|
|
30999
|
+
}
|
|
31000
|
+
if (preparedSlots.length <= maxSlotsPerResponse) {
|
|
31001
|
+
preparedSlots.forEach((slot) => emitSlotMetric({
|
|
31002
|
+
type: "prepared",
|
|
31003
|
+
slotId: slot.id
|
|
31004
|
+
}, onSlotMetric));
|
|
31005
|
+
return preparedSlots;
|
|
31006
|
+
}
|
|
31007
|
+
const keptSlots = preparedSlots.slice(0, maxSlotsPerResponse);
|
|
31008
|
+
const droppedSlots = preparedSlots.slice(maxSlotsPerResponse);
|
|
31009
|
+
droppedSlots.forEach((slot) => {
|
|
31010
|
+
onError?.(new Error(`Streaming slot "${slot.id}" dropped because ${maxSlotsPerResponse} slots is the configured maximum`), slot);
|
|
31011
|
+
emitSlotMetric({
|
|
31012
|
+
type: "dropped",
|
|
31013
|
+
slotId: slot.id,
|
|
31014
|
+
reason: `maxSlotsPerResponse is ${maxSlotsPerResponse}`
|
|
31015
|
+
}, onSlotMetric);
|
|
31016
|
+
});
|
|
31017
|
+
keptSlots.forEach((slot) => emitSlotMetric({
|
|
31018
|
+
type: "prepared",
|
|
31019
|
+
slotId: slot.id
|
|
31020
|
+
}, onSlotMetric));
|
|
31021
|
+
return keptSlots;
|
|
31022
|
+
};
|
|
31023
|
+
var htmlByteLength = (value, encoder) => encoder.encode(value).length;
|
|
31024
|
+
var resolveSlot = async (slot, onError, policy, onSlotMetric) => {
|
|
31025
|
+
const safePolicy = policy ?? getStreamingSlotPolicy();
|
|
31026
|
+
const encoder = new TextEncoder;
|
|
31027
|
+
const start = Date.now();
|
|
30905
31028
|
try {
|
|
30906
|
-
const
|
|
30907
|
-
const
|
|
30908
|
-
|
|
30909
|
-
new Promise((_, reject) => setTimeout(() =>
|
|
30910
|
-
|
|
31029
|
+
const maybeAsyncValue = Promise.resolve(slot.resolve());
|
|
31030
|
+
const resolved = typeof slot.timeoutMs === "number" && slot.timeoutMs > 0 ? await Promise.race([
|
|
31031
|
+
maybeAsyncValue,
|
|
31032
|
+
new Promise((_, reject) => setTimeout(() => {
|
|
31033
|
+
reject(createTimeoutError(slot, slot.timeoutMs ?? 0));
|
|
31034
|
+
}, slot.timeoutMs))
|
|
31035
|
+
]) : await maybeAsyncValue;
|
|
31036
|
+
const html = typeof resolved === "string" ? resolved : `${resolved}`;
|
|
31037
|
+
if (safePolicy.maxSlotHtmlSizeBytes > 0 && htmlByteLength(html, encoder) > safePolicy.maxSlotHtmlSizeBytes) {
|
|
31038
|
+
const bytes2 = htmlByteLength(html, encoder);
|
|
31039
|
+
const error = new Error(`Streaming slot "${slot.id}" exceeded max payload size of ${safePolicy.maxSlotHtmlSizeBytes} bytes`);
|
|
31040
|
+
const durationMs2 = Date.now() - start;
|
|
31041
|
+
onError?.(error, slot);
|
|
31042
|
+
emitSlotMetric({
|
|
31043
|
+
type: "size_exceeded",
|
|
31044
|
+
slotId: slot.id,
|
|
31045
|
+
durationMs: durationMs2,
|
|
31046
|
+
bytes: bytes2,
|
|
31047
|
+
error
|
|
31048
|
+
}, onSlotMetric);
|
|
31049
|
+
const fallbackHtml = typeof slot.errorHtml === "string" ? slot.errorHtml : null;
|
|
31050
|
+
return {
|
|
31051
|
+
html: fallbackHtml,
|
|
31052
|
+
id: slot.id,
|
|
31053
|
+
durationMs: durationMs2,
|
|
31054
|
+
bytes: fallbackHtml === null ? 0 : htmlByteLength(fallbackHtml, encoder)
|
|
31055
|
+
};
|
|
31056
|
+
}
|
|
31057
|
+
const durationMs = Date.now() - start;
|
|
31058
|
+
const bytes = htmlByteLength(html, encoder);
|
|
31059
|
+
emitSlotMetric({
|
|
31060
|
+
type: "resolved",
|
|
31061
|
+
slotId: slot.id,
|
|
31062
|
+
durationMs,
|
|
31063
|
+
bytes
|
|
31064
|
+
}, onSlotMetric);
|
|
30911
31065
|
return {
|
|
30912
31066
|
html,
|
|
30913
|
-
id: slot.id
|
|
31067
|
+
id: slot.id,
|
|
31068
|
+
durationMs,
|
|
31069
|
+
bytes
|
|
30914
31070
|
};
|
|
30915
31071
|
} catch (error) {
|
|
31072
|
+
const durationMs = Date.now() - start;
|
|
30916
31073
|
onError?.(error, slot);
|
|
31074
|
+
emitSlotMetric({
|
|
31075
|
+
type: error?.__absTimeout === true ? "timeout" : "error",
|
|
31076
|
+
slotId: slot.id,
|
|
31077
|
+
durationMs,
|
|
31078
|
+
error
|
|
31079
|
+
}, onSlotMetric);
|
|
30917
31080
|
if (typeof slot.errorHtml === "string") {
|
|
31081
|
+
const html = slot.errorHtml;
|
|
30918
31082
|
return {
|
|
30919
|
-
html
|
|
30920
|
-
id: slot.id
|
|
31083
|
+
html,
|
|
31084
|
+
id: slot.id,
|
|
31085
|
+
durationMs,
|
|
31086
|
+
bytes: htmlByteLength(html, encoder)
|
|
30921
31087
|
};
|
|
30922
31088
|
}
|
|
30923
31089
|
return {
|
|
30924
31090
|
html: null,
|
|
30925
|
-
id: slot.id
|
|
31091
|
+
id: slot.id,
|
|
31092
|
+
durationMs,
|
|
31093
|
+
bytes: 0
|
|
30926
31094
|
};
|
|
30927
31095
|
}
|
|
30928
31096
|
};
|
|
@@ -30938,23 +31106,37 @@ var streamOutOfOrderSlots = ({
|
|
|
30938
31106
|
footerHtml = "",
|
|
30939
31107
|
headerHtml = "",
|
|
30940
31108
|
nonce,
|
|
31109
|
+
policy,
|
|
31110
|
+
onSlotMetric,
|
|
30941
31111
|
onError,
|
|
30942
31112
|
slots
|
|
30943
31113
|
}) => {
|
|
31114
|
+
const resolvedPolicy = resolveStreamingSlotPolicy(policy);
|
|
31115
|
+
const combinedOnError = createCombinedSlotErrorHandler(resolvedPolicy.onError, onError);
|
|
31116
|
+
const combinedOnSlotMetric = createCombinedSlotMetricHandler(resolvedPolicy.onSlotMetric, onSlotMetric);
|
|
31117
|
+
const effectivePolicy = {
|
|
31118
|
+
...resolvedPolicy,
|
|
31119
|
+
onSlotMetric: combinedOnSlotMetric
|
|
31120
|
+
};
|
|
31121
|
+
const preparedSlots = prepareSlots({
|
|
31122
|
+
policy: effectivePolicy,
|
|
31123
|
+
slots,
|
|
31124
|
+
onError: combinedOnError,
|
|
31125
|
+
onSlotMetric: combinedOnSlotMetric
|
|
31126
|
+
});
|
|
30944
31127
|
const encoder = new TextEncoder;
|
|
30945
31128
|
return new ReadableStream({
|
|
30946
31129
|
async start(controller) {
|
|
30947
31130
|
try {
|
|
30948
31131
|
let header = headerHtml;
|
|
30949
|
-
if (!header.includes(STREAMING_RUNTIME_GLOBAL)) {
|
|
31132
|
+
if (preparedSlots.length > 0 && !header.includes(STREAMING_RUNTIME_GLOBAL)) {
|
|
30950
31133
|
header = injectHtmlIntoHead(header, renderStreamingSlotsRuntimeTag(nonce));
|
|
30951
31134
|
}
|
|
30952
31135
|
controller.enqueue(toUint8(header, encoder));
|
|
30953
|
-
const pending =
|
|
30954
|
-
const
|
|
30955
|
-
const fallback = renderStreamingSlotPlaceholder(resolvedSlot.id, resolvedSlot.fallbackHtml ?? "");
|
|
31136
|
+
const pending = preparedSlots.map((slot) => {
|
|
31137
|
+
const fallback = renderStreamingSlotPlaceholder(slot.id, slot.fallbackHtml ?? "");
|
|
30956
31138
|
controller.enqueue(toUint8(fallback, encoder));
|
|
30957
|
-
return resolveSlot(
|
|
31139
|
+
return resolveSlot(slot, combinedOnError, effectivePolicy, combinedOnSlotMetric);
|
|
30958
31140
|
});
|
|
30959
31141
|
while (pending.length > 0) {
|
|
30960
31142
|
const { original, result } = await nextResolvedSlot(pending);
|
|
@@ -30963,6 +31145,12 @@ var streamOutOfOrderSlots = ({
|
|
|
30963
31145
|
pending.splice(index, 1);
|
|
30964
31146
|
if (result.html === null)
|
|
30965
31147
|
continue;
|
|
31148
|
+
emitSlotMetric({
|
|
31149
|
+
type: "patched",
|
|
31150
|
+
slotId: result.id,
|
|
31151
|
+
durationMs: result.durationMs,
|
|
31152
|
+
bytes: result.bytes
|
|
31153
|
+
}, combinedOnSlotMetric);
|
|
30966
31154
|
controller.enqueue(toUint8(renderStreamingSlotPatchTag(result.id, result.html, nonce), encoder));
|
|
30967
31155
|
}
|
|
30968
31156
|
if (footerHtml.length > 0) {
|
|
@@ -31026,12 +31214,33 @@ var injectStreamingRuntimeIntoStream = (stream, nonce) => {
|
|
|
31026
31214
|
}
|
|
31027
31215
|
});
|
|
31028
31216
|
};
|
|
31029
|
-
var appendStreamingSlotPatchesToStream = (stream, slots = [], {
|
|
31217
|
+
var appendStreamingSlotPatchesToStream = (stream, slots = [], {
|
|
31218
|
+
injectRuntime = true,
|
|
31219
|
+
nonce,
|
|
31220
|
+
onError,
|
|
31221
|
+
onSlotMetric,
|
|
31222
|
+
policy
|
|
31223
|
+
} = {}) => {
|
|
31224
|
+
const resolvedPolicy = resolveStreamingSlotPolicy(policy);
|
|
31225
|
+
const combinedOnError = createCombinedSlotErrorHandler(resolvedPolicy.onError, onError);
|
|
31226
|
+
const combinedOnSlotMetric = createCombinedSlotMetricHandler(resolvedPolicy.onSlotMetric, onSlotMetric);
|
|
31227
|
+
const effectivePolicy = {
|
|
31228
|
+
...resolvedPolicy,
|
|
31229
|
+
onSlotMetric: combinedOnSlotMetric
|
|
31230
|
+
};
|
|
31231
|
+
const preparedSlots = prepareSlots({
|
|
31232
|
+
policy: effectivePolicy,
|
|
31233
|
+
slots,
|
|
31234
|
+
onError: combinedOnError,
|
|
31235
|
+
onSlotMetric: combinedOnSlotMetric
|
|
31236
|
+
});
|
|
31237
|
+
if (preparedSlots.length === 0)
|
|
31238
|
+
return stream;
|
|
31030
31239
|
const source = injectRuntime ? injectStreamingRuntimeIntoStream(stream, nonce) : stream;
|
|
31031
31240
|
const encoder = new TextEncoder;
|
|
31032
31241
|
const decoder = new TextDecoder;
|
|
31033
31242
|
const reader = source.getReader();
|
|
31034
|
-
const pending =
|
|
31243
|
+
const pending = preparedSlots.map((slot) => resolveSlot(slot, combinedOnError, effectivePolicy, combinedOnSlotMetric));
|
|
31035
31244
|
return new ReadableStream({
|
|
31036
31245
|
async start(controller) {
|
|
31037
31246
|
let baseDone = false;
|
|
@@ -31088,6 +31297,12 @@ var appendStreamingSlotPatchesToStream = (stream, slots = [], { injectRuntime =
|
|
|
31088
31297
|
pending.splice(index, 1);
|
|
31089
31298
|
if (winner.result.html === null)
|
|
31090
31299
|
continue;
|
|
31300
|
+
emitSlotMetric({
|
|
31301
|
+
type: "patched",
|
|
31302
|
+
slotId: winner.result.id,
|
|
31303
|
+
durationMs: winner.result.durationMs,
|
|
31304
|
+
bytes: winner.result.bytes
|
|
31305
|
+
}, combinedOnSlotMetric);
|
|
31091
31306
|
controller.enqueue(encoder.encode(renderStreamingSlotPatchTag(winner.result.id, winner.result.html, nonce)));
|
|
31092
31307
|
}
|
|
31093
31308
|
if (footer.length > 0)
|
|
@@ -31146,13 +31361,14 @@ var cloneHeaders = (response) => {
|
|
|
31146
31361
|
const headers = new Headers(response.headers);
|
|
31147
31362
|
return headers;
|
|
31148
31363
|
};
|
|
31149
|
-
var enhanceHtmlResponseWithStreamingSlots = (response, { nonce, onError, streamingSlots = [] } = {}) => {
|
|
31364
|
+
var enhanceHtmlResponseWithStreamingSlots = (response, { nonce, onError, streamingSlots = [], policy } = {}) => {
|
|
31150
31365
|
if (!response.body || streamingSlots.length === 0) {
|
|
31151
31366
|
return response;
|
|
31152
31367
|
}
|
|
31153
31368
|
const body = appendStreamingSlotPatchesToStream(response.body, streamingSlots, {
|
|
31154
31369
|
nonce,
|
|
31155
|
-
onError
|
|
31370
|
+
onError,
|
|
31371
|
+
policy
|
|
31156
31372
|
});
|
|
31157
31373
|
return new Response(body, {
|
|
31158
31374
|
headers: cloneHeaders(response),
|
|
@@ -31335,5 +31551,5 @@ export {
|
|
|
31335
31551
|
AwaitSlot_default as AwaitSlot
|
|
31336
31552
|
};
|
|
31337
31553
|
|
|
31338
|
-
//# debugId=
|
|
31554
|
+
//# debugId=CF6826373193F13564756E2164756E21
|
|
31339
31555
|
//# sourceMappingURL=index.js.map
|