payload-live-preview 2.0.0-beta.0 → 2.0.0
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/README.md +60 -775
- package/dist/adapters/astro/PreviewBoundary.astro +2 -2
- package/dist/adapters/astro/index.d.ts +28 -154
- package/dist/adapters/astro/index.js +1 -1
- package/dist/adapters/astro/index.js.map +1 -1
- package/dist/adapters/astro/middleware-entry.d.ts +3 -2
- package/dist/adapters/astro/middleware-entry.js +1 -1
- package/dist/adapters/astro/middleware-entry.js.map +1 -1
- package/dist/adapters/nextjs/index.d.ts +247 -6
- package/dist/adapters/nextjs/index.js +1 -1
- package/dist/adapters/nextjs/index.js.map +1 -1
- package/dist/adapters/nuxt/index.d.ts +58 -3
- package/dist/adapters/nuxt/index.js +1 -1
- package/dist/adapters/nuxt/index.js.map +1 -1
- package/dist/adapters/nuxt/module.d.ts +82 -0
- package/dist/adapters/nuxt/module.js +2 -0
- package/dist/adapters/nuxt/module.js.map +1 -0
- package/dist/adapters/react/index.d.ts +110 -0
- package/dist/adapters/react/index.js +3 -0
- package/dist/adapters/react/index.js.map +1 -0
- package/dist/adapters/sveltekit/index.d.ts +65 -7
- package/dist/adapters/sveltekit/index.js +1 -1
- package/dist/adapters/sveltekit/index.js.map +1 -1
- package/dist/adapters/vue/index.d.ts +56 -0
- package/dist/adapters/vue/index.js +2 -0
- package/dist/adapters/vue/index.js.map +1 -0
- package/dist/annotate.d.ts +161 -0
- package/dist/annotate.js +2 -0
- package/dist/annotate.js.map +1 -0
- package/dist/client.cjs +1 -1
- package/dist/client.cjs.map +1 -1
- package/dist/client.d.cts +182 -9
- package/dist/client.d.ts +182 -9
- package/dist/client.js +1 -1
- package/dist/client.js.map +1 -1
- package/dist/codegen-astro.js +1 -1
- package/dist/codegen-astro.js.map +1 -1
- package/dist/codegen-cli.js +1 -1
- package/dist/codegen-cli.js.map +1 -1
- package/dist/codegen.cjs +1 -1
- package/dist/codegen.cjs.map +1 -1
- package/dist/codegen.d.cts +129 -4
- package/dist/codegen.d.ts +129 -4
- package/dist/codegen.js +1 -1
- package/dist/codegen.js.map +1 -1
- package/dist/core.cjs +1 -1
- package/dist/core.cjs.map +1 -1
- package/dist/core.d.cts +264 -73
- package/dist/core.d.ts +264 -73
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/doctor-cli.d.ts +1 -1
- package/dist/doctor-cli.js +1 -1
- package/dist/doctor-cli.js.map +1 -1
- package/dist/doctor.d.ts +7 -6
- package/dist/doctor.js +1 -1
- package/dist/doctor.js.map +1 -1
- package/dist/document-session-BfBfLVpg.d.ts +53 -0
- package/dist/fragment-endpoint-3Mlz7GDz.d.ts +189 -0
- package/dist/fragment.cjs +1 -1
- package/dist/fragment.cjs.map +1 -1
- package/dist/fragment.d.cts +64 -18
- package/dist/fragment.d.ts +64 -18
- package/dist/fragment.js +1 -1
- package/dist/fragment.js.map +1 -1
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +422 -83
- package/dist/index.d.ts +422 -83
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lean.cjs +2 -0
- package/dist/lean.cjs.map +1 -0
- package/dist/lean.d.cts +44 -0
- package/dist/lean.d.ts +44 -0
- package/dist/lean.js +2 -0
- package/dist/lean.js.map +1 -0
- package/dist/lexical.cjs +1 -1
- package/dist/lexical.cjs.map +1 -1
- package/dist/lexical.d.cts +19 -1
- package/dist/lexical.d.ts +19 -1
- package/dist/lexical.js +1 -1
- package/dist/lexical.js.map +1 -1
- package/dist/locals-DBXDMxOA.d.ts +45 -0
- package/dist/{middleware-CEPsY1P7.d.ts → middleware-Bx9I7PXW.d.ts} +14 -14
- package/dist/migrate.d.ts +4 -3
- package/dist/migrate.js +1 -1
- package/dist/migrate.js.map +1 -1
- package/dist/{options-CEzzfHJu.d.ts → options-BW1eqXvc.d.ts} +90 -2
- package/dist/plugins.cjs +1 -1
- package/dist/plugins.cjs.map +1 -1
- package/dist/plugins.d.cts +111 -6
- package/dist/plugins.d.ts +111 -6
- package/dist/plugins.js +1 -1
- package/dist/plugins.js.map +1 -1
- package/dist/{probe-CYtvj_Lm.d.ts → probe-CELeUciC.d.ts} +26 -4
- package/dist/server.cjs +1 -1
- package/dist/server.cjs.map +1 -1
- package/dist/server.d.cts +67 -13
- package/dist/server.d.ts +67 -13
- package/dist/server.js +1 -1
- package/dist/server.js.map +1 -1
- package/dist/structural.cjs +2 -2
- package/dist/structural.cjs.map +1 -1
- package/dist/structural.d.cts +47 -4
- package/dist/structural.d.ts +47 -4
- package/dist/structural.js +2 -2
- package/dist/structural.js.map +1 -1
- package/package.json +77 -9
package/dist/fragment.d.cts
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Browser-side reporting sites write the literal (`code: 'LP0603'`) rather than
|
|
7
7
|
* reading it from this record: the frozen table would then ship in the inline
|
|
8
|
-
* runtime for the sake of six characters
|
|
8
|
+
* runtime for the sake of six characters — it did, 1 287 B in every page, for
|
|
9
|
+
* the one read Z6 left in the strategy runner, and `diagnostic-codes.test.ts`
|
|
10
|
+
* now holds the artifact free of it. Server-side tools may import it.
|
|
9
11
|
*/
|
|
10
12
|
/**
|
|
11
13
|
* Every diagnostic code the runtime can report, by name.
|
|
@@ -23,6 +25,8 @@ declare const DIAGNOSTIC_CODES: Readonly<{
|
|
|
23
25
|
readonly ReferrerOnlyTrust: "LP0102";
|
|
24
26
|
/** A plugin declares a runtime range this runtime does not satisfy; it was refused. */
|
|
25
27
|
readonly PluginIncompatible: "LP0103";
|
|
28
|
+
/** The page carries the lean runtime and needs a feature that profile leaves out. */
|
|
29
|
+
readonly ProfileFeatureOmitted: "LP0104";
|
|
26
30
|
/** An update named a field with no binding anchor on the page. */
|
|
27
31
|
readonly OrphanField: "LP0201";
|
|
28
32
|
/** Owner scoping is on and the update names no document it could belong to. */
|
|
@@ -43,10 +47,24 @@ declare const DIAGNOSTIC_CODES: Readonly<{
|
|
|
43
47
|
readonly StructuralUnstableKeys: "LP0406";
|
|
44
48
|
/** A binding asks for a delivery strategy this release does not have; it is left unchanged. */
|
|
45
49
|
readonly UnsupportedStrategy: "LP0407";
|
|
50
|
+
/** `data-payload-format` names a format the vocabulary does not contain; the default formatting was used instead. */
|
|
51
|
+
readonly UnknownValueFormat: "LP0408";
|
|
52
|
+
/** The strict sanitizer removed an attribute the 1.x `'compat'` policy kept. */
|
|
53
|
+
readonly SanitizerDroppedAttribute: "LP0409";
|
|
54
|
+
/** A Lexical block has no renderer; the markup the server rendered for it is kept instead. */
|
|
55
|
+
readonly UnrenderedBlockKept: "LP0410";
|
|
56
|
+
/** A patch cannot reach what the server would have drawn; `onUnfaithfulPatch` decided what happens next. */
|
|
57
|
+
readonly UnfaithfulPatch: "LP0411";
|
|
58
|
+
/** The first write to a date, number or checkbox binding replaced a different reading of the same value. */
|
|
59
|
+
readonly ServerFormatReplaced: "LP0412";
|
|
60
|
+
/** A Lexical block has no renderer, and the write could not keep the markup the server rendered for it; it is gone. */
|
|
61
|
+
readonly UnrenderedBlockLost: "LP0413";
|
|
46
62
|
/** A message was rejected before it reached the update pipeline. */
|
|
47
63
|
readonly MessageRejected: "LP0501";
|
|
48
64
|
/** A preview token was rejected. */
|
|
49
65
|
readonly TokenRejected: "LP0502";
|
|
66
|
+
/** A trusted origin sent a message this protocol version does not recognise. */
|
|
67
|
+
readonly ProtocolShapeUnknown: "LP0503";
|
|
50
68
|
/** A consumer event handler threw. */
|
|
51
69
|
readonly HandlerThrew: "LP0601";
|
|
52
70
|
/** A consumer transform threw; the original value was kept. */
|
|
@@ -57,11 +75,13 @@ declare const DIAGNOSTIC_CODES: Readonly<{
|
|
|
57
75
|
readonly StartupFailed: "LP0605";
|
|
58
76
|
/** Sending the ready handshake failed. */
|
|
59
77
|
readonly ReadyFailed: "LP0606";
|
|
78
|
+
/** The page declared hydration, but no React commit or Vue mount came within the cap; the runtime started without waiting. */
|
|
79
|
+
readonly HydrationWaitTimedOut: "LP0607";
|
|
60
80
|
/** The audit found no runtime in a response that carried preview intent. */
|
|
61
81
|
readonly AuditRuntimeMissing: "LP0701";
|
|
62
82
|
/** The preview response declares no `frame-ancestors`. */
|
|
63
83
|
readonly AuditNoFrameAncestors: "LP0702";
|
|
64
|
-
/** `X-Frame-Options` forbids framing, which no CSP can undo. */
|
|
84
|
+
/** `X-Frame-Options` forbids framing, which no CSP can undo; `SAMEORIGIN` forbids it from another origin only. */
|
|
65
85
|
readonly AuditFrameOptionsBlocks: "LP0703";
|
|
66
86
|
/** Binding attributes are served to anonymous visitors. */
|
|
67
87
|
readonly AuditBindingsExposed: "LP0704";
|
|
@@ -81,10 +101,12 @@ declare const DIAGNOSTIC_CODES: Readonly<{
|
|
|
81
101
|
readonly FragmentUnauthorized: "LP0803";
|
|
82
102
|
/** A fragment response arrived for a revision that was already superseded and was discarded. */
|
|
83
103
|
readonly FragmentSuperseded: "LP0804";
|
|
84
|
-
/** A route refresh was
|
|
104
|
+
/** A route refresh was refused: the loop guard, or the strategy's minimum interval. */
|
|
85
105
|
readonly RouteRefreshLoop: "LP0805";
|
|
86
106
|
/** A boundary asks for the fragment strategy but no fragment handler is configured; it is patched. */
|
|
87
107
|
readonly FragmentStrategyUnavailable: "LP0806";
|
|
108
|
+
/** A revision changed a field with no binding; `onUnfaithfulPatch` refreshed the route. */
|
|
109
|
+
readonly UnboundChangeRefresh: "LP0807";
|
|
88
110
|
/** A readiness row is not yet at its 2.0 value; `pll doctor --v2` reports it. */
|
|
89
111
|
readonly V2ReadinessGap: "LP0709";
|
|
90
112
|
/** The preview runtime is served to anonymous visitors, not only inside the admin frame. */
|
|
@@ -103,7 +125,7 @@ type DiagnosticCode = (typeof DIAGNOSTIC_CODES)[keyof typeof DIAGNOSTIC_CODES];
|
|
|
103
125
|
|
|
104
126
|
/** What produced an update: the runtime's DOM patching, a server-rendered fragment, or a route refresh. */
|
|
105
127
|
type UpdateSource = 'patch' | 'fragment' | 'route';
|
|
106
|
-
/** Marks a server-rendered boundary; the value is the registry id the server may render. */
|
|
128
|
+
/** Marks a server-rendered boundary; the value is the registry id the server may render. @internal */
|
|
107
129
|
declare const FRAGMENT_ATTRIBUTE = "data-payload-fragment";
|
|
108
130
|
/** One revision, as a strategy sees it, with the runtime capabilities it may use. */
|
|
109
131
|
interface FragmentContext {
|
|
@@ -149,7 +171,21 @@ interface RouteContext {
|
|
|
149
171
|
readonly signal: AbortSignal;
|
|
150
172
|
readonly isCurrent: () => boolean;
|
|
151
173
|
readonly log: (code: DiagnosticCode, detail: string) => void;
|
|
174
|
+
/**
|
|
175
|
+
* Ask to be run again in `delayMs`, once. A strategy that refuses a refresh
|
|
176
|
+
* because it is rate-limiting itself uses this: the window is a rate limit
|
|
177
|
+
* and not a filter, so what falls inside it still has to reach the preview.
|
|
178
|
+
* The runtime runs at most one such request, and only while the revision that
|
|
179
|
+
* asked is still the current one.
|
|
180
|
+
*/
|
|
181
|
+
readonly retryAfter?: (delayMs: number) => void;
|
|
152
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* What one refresh did. `refused` is the strategy's own brake and not a
|
|
185
|
+
* failure — it is counted separately, because a number that mixes a planned
|
|
186
|
+
* pause with a broken request cannot be read.
|
|
187
|
+
*/
|
|
188
|
+
type RouteOutcome = 'refreshed' | 'failed' | 'refused' | 'superseded';
|
|
153
189
|
/**
|
|
154
190
|
* Whether a revision needs the whole route re-rendered, and how. After a
|
|
155
191
|
* refresh the runtime rescans and re-applies the revision, so the unsaved
|
|
@@ -157,7 +193,7 @@ interface RouteContext {
|
|
|
157
193
|
*/
|
|
158
194
|
interface RouteStrategy {
|
|
159
195
|
readonly plan: (root: ParentNode, changedFields: ReadonlySet<string>) => boolean;
|
|
160
|
-
readonly refresh: (context: RouteContext) => Promise<
|
|
196
|
+
readonly refresh: (context: RouteContext) => Promise<RouteOutcome>;
|
|
161
197
|
}
|
|
162
198
|
interface StrategyHandlers {
|
|
163
199
|
readonly fragment?: FragmentStrategy;
|
|
@@ -167,13 +203,15 @@ interface StrategyHandlers {
|
|
|
167
203
|
* Explicit `data-payload-strategy` wins; otherwise a binding inside a fragment
|
|
168
204
|
* boundary belongs to the fragment, one in `<head>` to the route, the rest is
|
|
169
205
|
* patched. An unknown explicit value resolves to `undefined` (LP0407).
|
|
206
|
+
* @internal
|
|
170
207
|
*/
|
|
171
208
|
declare function resolveStrategy(element: Element): UpdateSource | undefined;
|
|
172
209
|
|
|
173
210
|
/** Fragment boundaries: how a `data-payload-fragment` element is read and which ones an update touches. */
|
|
174
211
|
|
|
175
|
-
/** Distinguishes several boundaries of one registry id; unique among siblings. */
|
|
212
|
+
/** Distinguishes several boundaries of one registry id; unique among siblings. @internal */
|
|
176
213
|
declare const FRAGMENT_KEY_ATTRIBUTE = "data-payload-fragment-key";
|
|
214
|
+
/** @internal */
|
|
177
215
|
interface FragmentBoundary {
|
|
178
216
|
readonly element: Element;
|
|
179
217
|
/** Registry id — never a path, module or function name. */
|
|
@@ -182,7 +220,7 @@ interface FragmentBoundary {
|
|
|
182
220
|
/** Fields whose change re-renders the boundary; empty means any field. */
|
|
183
221
|
readonly dependsOn: readonly string[];
|
|
184
222
|
}
|
|
185
|
-
/** One revision's request to a per-boundary handler. */
|
|
223
|
+
/** One revision's request to a per-boundary handler. @internal */
|
|
186
224
|
interface StrategyRequest {
|
|
187
225
|
readonly revision: number;
|
|
188
226
|
readonly receivedAt: number;
|
|
@@ -193,6 +231,7 @@ interface StrategyRequest {
|
|
|
193
231
|
/** Aborted when a newer revision arrives or the runtime stops. */
|
|
194
232
|
readonly signal: AbortSignal;
|
|
195
233
|
}
|
|
234
|
+
/** @internal */
|
|
196
235
|
type FragmentOutcome = {
|
|
197
236
|
readonly status: 'rendered';
|
|
198
237
|
/** The boundary's new inner HTML. */
|
|
@@ -205,10 +244,11 @@ type FragmentOutcome = {
|
|
|
205
244
|
} | {
|
|
206
245
|
readonly status: 'superseded';
|
|
207
246
|
};
|
|
208
|
-
/** Renders one boundary for one revision. Must honour `request.signal`. */
|
|
247
|
+
/** Renders one boundary for one revision. Must honour `request.signal`. @internal */
|
|
209
248
|
type FragmentHandler = (request: StrategyRequest, boundary: FragmentBoundary) => Promise<FragmentOutcome>;
|
|
249
|
+
/** @internal */
|
|
210
250
|
declare function describeBoundary(element: Element): FragmentBoundary | null;
|
|
211
|
-
/** The boundaries under `root` that `changedFields` touch; one inside an island is the island's business. */
|
|
251
|
+
/** The boundaries under `root` that `changedFields` touch; one inside an island is the island's business. @internal */
|
|
212
252
|
declare function collectFragmentBoundaries(root: ParentNode, changedFields: ReadonlySet<string>): readonly FragmentBoundary[];
|
|
213
253
|
|
|
214
254
|
/**
|
|
@@ -236,22 +276,24 @@ interface FragmentStrategyOptions {
|
|
|
236
276
|
readonly search: string;
|
|
237
277
|
};
|
|
238
278
|
}
|
|
279
|
+
/** @internal */
|
|
239
280
|
declare function createFragmentHandler(options: FragmentStrategyOptions): FragmentHandler;
|
|
240
281
|
|
|
241
282
|
/**
|
|
242
283
|
* The route strategy: when a revision touches what no smaller strategy can
|
|
243
|
-
* render,
|
|
244
|
-
* `minIntervalMs` is refused as
|
|
284
|
+
* render, ask the host's own router to re-render it, or else fetch the route
|
|
285
|
+
* again and morph it in place. A refresh inside `minIntervalMs` is refused as
|
|
286
|
+
* LP0805 and handed back for a trailing run. See ADR 0011.
|
|
245
287
|
*/
|
|
246
288
|
|
|
247
|
-
/** Sent with every refresh so a server can tell a preview refresh from navigation. */
|
|
289
|
+
/** Sent with every refresh so a server can tell a preview refresh from navigation. @internal */
|
|
248
290
|
declare const ROUTE_REFRESH_HEADER = "x-payload-live-preview";
|
|
249
291
|
interface RouteStrategyOptions {
|
|
250
292
|
/** `fetch` to use; defaults to the global one. */
|
|
251
293
|
readonly fetch?: (url: string, init?: RequestInit) => Promise<Response>;
|
|
252
294
|
/** Per-refresh timeout. Default 8000 ms. */
|
|
253
295
|
readonly timeoutMs?: number;
|
|
254
|
-
/** Shortest gap between two refreshes; one inside it is refused with LP0805. Default 1000 ms. */
|
|
296
|
+
/** Shortest gap between two refreshes; one inside it is refused with LP0805 and run when the gap closes. Default 1000 ms. */
|
|
255
297
|
readonly minIntervalMs?: number;
|
|
256
298
|
/** The document to refresh; defaults to `document`. */
|
|
257
299
|
readonly document?: Document;
|
|
@@ -266,7 +308,7 @@ interface RouteStrategyOptions {
|
|
|
266
308
|
readonly scrollTo: (x: number, y: number) => void;
|
|
267
309
|
};
|
|
268
310
|
}
|
|
269
|
-
/** An explicit `data-payload-strategy="route"`, or a binding in `<head>`. */
|
|
311
|
+
/** An explicit `data-payload-strategy="route"`, or a binding in `<head>`. @internal */
|
|
270
312
|
declare function isRouteBound(element: Element): boolean;
|
|
271
313
|
declare function createRouteStrategy(options?: RouteStrategyOptions): RouteStrategy;
|
|
272
314
|
|
|
@@ -275,9 +317,11 @@ declare function createRouteStrategy(options?: RouteStrategyOptions): RouteStrat
|
|
|
275
317
|
* and what it answers. Both sides validate the shape; nothing on the wire
|
|
276
318
|
* names code, paths or templates. See ADR 0011.
|
|
277
319
|
*/
|
|
278
|
-
/** Bumped when the request or response shape changes incompatibly. */
|
|
320
|
+
/** Bumped when the request or response shape changes incompatibly. @internal */
|
|
279
321
|
declare const FRAGMENT_PROTOCOL_VERSION = 1;
|
|
322
|
+
/** @internal */
|
|
280
323
|
declare const FRAGMENT_VERSION_HEADER = "x-payload-fragment-version";
|
|
324
|
+
/** @internal */
|
|
281
325
|
interface FragmentRequestBody {
|
|
282
326
|
/** Registry id of the boundary (`data-payload-fragment`). */
|
|
283
327
|
readonly fragment: string;
|
|
@@ -294,6 +338,7 @@ interface FragmentRequestBody {
|
|
|
294
338
|
/** The unsaved form state as the admin posted it, after the runtime's merge. */
|
|
295
339
|
readonly fields: Readonly<Record<string, unknown>>;
|
|
296
340
|
}
|
|
341
|
+
/** @internal */
|
|
297
342
|
interface FragmentResponseBody {
|
|
298
343
|
/** The boundary's new inner HTML. */
|
|
299
344
|
readonly html: string;
|
|
@@ -310,9 +355,9 @@ interface FragmentResponseBody {
|
|
|
310
355
|
readonly durationMs?: number;
|
|
311
356
|
};
|
|
312
357
|
}
|
|
313
|
-
/** Shape check for a request body; `null` when it is not one. */
|
|
358
|
+
/** Shape check for a request body; `null` when it is not one. @internal */
|
|
314
359
|
declare function parseFragmentRequest(value: unknown): FragmentRequestBody | null;
|
|
315
|
-
/** Shape check for a response body; `null` when it is not one. */
|
|
360
|
+
/** Shape check for a response body; `null` when it is not one. @internal */
|
|
316
361
|
declare function parseFragmentResponse(value: unknown): FragmentResponseBody | null;
|
|
317
362
|
|
|
318
363
|
/**
|
|
@@ -325,9 +370,10 @@ declare function parseFragmentResponse(value: unknown): FragmentResponseBody | n
|
|
|
325
370
|
* The strategy the runtime drives, built on a per-boundary handler: plan the
|
|
326
371
|
* boundaries, render each, morph a success, patch a failure. A late or
|
|
327
372
|
* aborted render is dropped, never applied.
|
|
373
|
+
* @internal
|
|
328
374
|
*/
|
|
329
375
|
declare function fragmentStrategyFrom(handler: FragmentHandler): FragmentStrategy;
|
|
330
376
|
/** The strategy for a fragment endpoint: hand it to the runtime as `strategies.fragment`. */
|
|
331
377
|
declare function createFragmentStrategy(options: FragmentStrategyOptions): FragmentStrategy;
|
|
332
378
|
|
|
333
|
-
export { DIAGNOSTIC_CODES, type DiagnosticCode, FRAGMENT_ATTRIBUTE, FRAGMENT_KEY_ATTRIBUTE, FRAGMENT_PROTOCOL_VERSION, FRAGMENT_VERSION_HEADER, type FragmentBoundary, type FragmentContext, type FragmentHandler, type FragmentOutcome, type FragmentReport, type FragmentRequestBody, type FragmentResponseBody, type FragmentStrategy, type FragmentStrategyOptions, ROUTE_REFRESH_HEADER, type RouteContext, type RouteStrategy, type RouteStrategyOptions, type StrategyHandlers, type StrategyRequest, type UpdateSource, collectFragmentBoundaries, createFragmentHandler, createFragmentStrategy, createRouteStrategy, describeBoundary, fragmentStrategyFrom, isRouteBound, parseFragmentRequest, parseFragmentResponse, resolveStrategy };
|
|
379
|
+
export { DIAGNOSTIC_CODES, type DiagnosticCode, FRAGMENT_ATTRIBUTE, FRAGMENT_KEY_ATTRIBUTE, FRAGMENT_PROTOCOL_VERSION, FRAGMENT_VERSION_HEADER, type FragmentBoundary, type FragmentContext, type FragmentHandler, type FragmentOutcome, type FragmentReport, type FragmentRequestBody, type FragmentResponseBody, type FragmentStrategy, type FragmentStrategyOptions, ROUTE_REFRESH_HEADER, type RouteContext, type RouteOutcome, type RouteStrategy, type RouteStrategyOptions, type StrategyHandlers, type StrategyRequest, type UpdateSource, collectFragmentBoundaries, createFragmentHandler, createFragmentStrategy, createRouteStrategy, describeBoundary, fragmentStrategyFrom, isRouteBound, parseFragmentRequest, parseFragmentResponse, resolveStrategy };
|
package/dist/fragment.d.ts
CHANGED
|
@@ -5,7 +5,9 @@
|
|
|
5
5
|
*
|
|
6
6
|
* Browser-side reporting sites write the literal (`code: 'LP0603'`) rather than
|
|
7
7
|
* reading it from this record: the frozen table would then ship in the inline
|
|
8
|
-
* runtime for the sake of six characters
|
|
8
|
+
* runtime for the sake of six characters — it did, 1 287 B in every page, for
|
|
9
|
+
* the one read Z6 left in the strategy runner, and `diagnostic-codes.test.ts`
|
|
10
|
+
* now holds the artifact free of it. Server-side tools may import it.
|
|
9
11
|
*/
|
|
10
12
|
/**
|
|
11
13
|
* Every diagnostic code the runtime can report, by name.
|
|
@@ -23,6 +25,8 @@ declare const DIAGNOSTIC_CODES: Readonly<{
|
|
|
23
25
|
readonly ReferrerOnlyTrust: "LP0102";
|
|
24
26
|
/** A plugin declares a runtime range this runtime does not satisfy; it was refused. */
|
|
25
27
|
readonly PluginIncompatible: "LP0103";
|
|
28
|
+
/** The page carries the lean runtime and needs a feature that profile leaves out. */
|
|
29
|
+
readonly ProfileFeatureOmitted: "LP0104";
|
|
26
30
|
/** An update named a field with no binding anchor on the page. */
|
|
27
31
|
readonly OrphanField: "LP0201";
|
|
28
32
|
/** Owner scoping is on and the update names no document it could belong to. */
|
|
@@ -43,10 +47,24 @@ declare const DIAGNOSTIC_CODES: Readonly<{
|
|
|
43
47
|
readonly StructuralUnstableKeys: "LP0406";
|
|
44
48
|
/** A binding asks for a delivery strategy this release does not have; it is left unchanged. */
|
|
45
49
|
readonly UnsupportedStrategy: "LP0407";
|
|
50
|
+
/** `data-payload-format` names a format the vocabulary does not contain; the default formatting was used instead. */
|
|
51
|
+
readonly UnknownValueFormat: "LP0408";
|
|
52
|
+
/** The strict sanitizer removed an attribute the 1.x `'compat'` policy kept. */
|
|
53
|
+
readonly SanitizerDroppedAttribute: "LP0409";
|
|
54
|
+
/** A Lexical block has no renderer; the markup the server rendered for it is kept instead. */
|
|
55
|
+
readonly UnrenderedBlockKept: "LP0410";
|
|
56
|
+
/** A patch cannot reach what the server would have drawn; `onUnfaithfulPatch` decided what happens next. */
|
|
57
|
+
readonly UnfaithfulPatch: "LP0411";
|
|
58
|
+
/** The first write to a date, number or checkbox binding replaced a different reading of the same value. */
|
|
59
|
+
readonly ServerFormatReplaced: "LP0412";
|
|
60
|
+
/** A Lexical block has no renderer, and the write could not keep the markup the server rendered for it; it is gone. */
|
|
61
|
+
readonly UnrenderedBlockLost: "LP0413";
|
|
46
62
|
/** A message was rejected before it reached the update pipeline. */
|
|
47
63
|
readonly MessageRejected: "LP0501";
|
|
48
64
|
/** A preview token was rejected. */
|
|
49
65
|
readonly TokenRejected: "LP0502";
|
|
66
|
+
/** A trusted origin sent a message this protocol version does not recognise. */
|
|
67
|
+
readonly ProtocolShapeUnknown: "LP0503";
|
|
50
68
|
/** A consumer event handler threw. */
|
|
51
69
|
readonly HandlerThrew: "LP0601";
|
|
52
70
|
/** A consumer transform threw; the original value was kept. */
|
|
@@ -57,11 +75,13 @@ declare const DIAGNOSTIC_CODES: Readonly<{
|
|
|
57
75
|
readonly StartupFailed: "LP0605";
|
|
58
76
|
/** Sending the ready handshake failed. */
|
|
59
77
|
readonly ReadyFailed: "LP0606";
|
|
78
|
+
/** The page declared hydration, but no React commit or Vue mount came within the cap; the runtime started without waiting. */
|
|
79
|
+
readonly HydrationWaitTimedOut: "LP0607";
|
|
60
80
|
/** The audit found no runtime in a response that carried preview intent. */
|
|
61
81
|
readonly AuditRuntimeMissing: "LP0701";
|
|
62
82
|
/** The preview response declares no `frame-ancestors`. */
|
|
63
83
|
readonly AuditNoFrameAncestors: "LP0702";
|
|
64
|
-
/** `X-Frame-Options` forbids framing, which no CSP can undo. */
|
|
84
|
+
/** `X-Frame-Options` forbids framing, which no CSP can undo; `SAMEORIGIN` forbids it from another origin only. */
|
|
65
85
|
readonly AuditFrameOptionsBlocks: "LP0703";
|
|
66
86
|
/** Binding attributes are served to anonymous visitors. */
|
|
67
87
|
readonly AuditBindingsExposed: "LP0704";
|
|
@@ -81,10 +101,12 @@ declare const DIAGNOSTIC_CODES: Readonly<{
|
|
|
81
101
|
readonly FragmentUnauthorized: "LP0803";
|
|
82
102
|
/** A fragment response arrived for a revision that was already superseded and was discarded. */
|
|
83
103
|
readonly FragmentSuperseded: "LP0804";
|
|
84
|
-
/** A route refresh was
|
|
104
|
+
/** A route refresh was refused: the loop guard, or the strategy's minimum interval. */
|
|
85
105
|
readonly RouteRefreshLoop: "LP0805";
|
|
86
106
|
/** A boundary asks for the fragment strategy but no fragment handler is configured; it is patched. */
|
|
87
107
|
readonly FragmentStrategyUnavailable: "LP0806";
|
|
108
|
+
/** A revision changed a field with no binding; `onUnfaithfulPatch` refreshed the route. */
|
|
109
|
+
readonly UnboundChangeRefresh: "LP0807";
|
|
88
110
|
/** A readiness row is not yet at its 2.0 value; `pll doctor --v2` reports it. */
|
|
89
111
|
readonly V2ReadinessGap: "LP0709";
|
|
90
112
|
/** The preview runtime is served to anonymous visitors, not only inside the admin frame. */
|
|
@@ -103,7 +125,7 @@ type DiagnosticCode = (typeof DIAGNOSTIC_CODES)[keyof typeof DIAGNOSTIC_CODES];
|
|
|
103
125
|
|
|
104
126
|
/** What produced an update: the runtime's DOM patching, a server-rendered fragment, or a route refresh. */
|
|
105
127
|
type UpdateSource = 'patch' | 'fragment' | 'route';
|
|
106
|
-
/** Marks a server-rendered boundary; the value is the registry id the server may render. */
|
|
128
|
+
/** Marks a server-rendered boundary; the value is the registry id the server may render. @internal */
|
|
107
129
|
declare const FRAGMENT_ATTRIBUTE = "data-payload-fragment";
|
|
108
130
|
/** One revision, as a strategy sees it, with the runtime capabilities it may use. */
|
|
109
131
|
interface FragmentContext {
|
|
@@ -149,7 +171,21 @@ interface RouteContext {
|
|
|
149
171
|
readonly signal: AbortSignal;
|
|
150
172
|
readonly isCurrent: () => boolean;
|
|
151
173
|
readonly log: (code: DiagnosticCode, detail: string) => void;
|
|
174
|
+
/**
|
|
175
|
+
* Ask to be run again in `delayMs`, once. A strategy that refuses a refresh
|
|
176
|
+
* because it is rate-limiting itself uses this: the window is a rate limit
|
|
177
|
+
* and not a filter, so what falls inside it still has to reach the preview.
|
|
178
|
+
* The runtime runs at most one such request, and only while the revision that
|
|
179
|
+
* asked is still the current one.
|
|
180
|
+
*/
|
|
181
|
+
readonly retryAfter?: (delayMs: number) => void;
|
|
152
182
|
}
|
|
183
|
+
/**
|
|
184
|
+
* What one refresh did. `refused` is the strategy's own brake and not a
|
|
185
|
+
* failure — it is counted separately, because a number that mixes a planned
|
|
186
|
+
* pause with a broken request cannot be read.
|
|
187
|
+
*/
|
|
188
|
+
type RouteOutcome = 'refreshed' | 'failed' | 'refused' | 'superseded';
|
|
153
189
|
/**
|
|
154
190
|
* Whether a revision needs the whole route re-rendered, and how. After a
|
|
155
191
|
* refresh the runtime rescans and re-applies the revision, so the unsaved
|
|
@@ -157,7 +193,7 @@ interface RouteContext {
|
|
|
157
193
|
*/
|
|
158
194
|
interface RouteStrategy {
|
|
159
195
|
readonly plan: (root: ParentNode, changedFields: ReadonlySet<string>) => boolean;
|
|
160
|
-
readonly refresh: (context: RouteContext) => Promise<
|
|
196
|
+
readonly refresh: (context: RouteContext) => Promise<RouteOutcome>;
|
|
161
197
|
}
|
|
162
198
|
interface StrategyHandlers {
|
|
163
199
|
readonly fragment?: FragmentStrategy;
|
|
@@ -167,13 +203,15 @@ interface StrategyHandlers {
|
|
|
167
203
|
* Explicit `data-payload-strategy` wins; otherwise a binding inside a fragment
|
|
168
204
|
* boundary belongs to the fragment, one in `<head>` to the route, the rest is
|
|
169
205
|
* patched. An unknown explicit value resolves to `undefined` (LP0407).
|
|
206
|
+
* @internal
|
|
170
207
|
*/
|
|
171
208
|
declare function resolveStrategy(element: Element): UpdateSource | undefined;
|
|
172
209
|
|
|
173
210
|
/** Fragment boundaries: how a `data-payload-fragment` element is read and which ones an update touches. */
|
|
174
211
|
|
|
175
|
-
/** Distinguishes several boundaries of one registry id; unique among siblings. */
|
|
212
|
+
/** Distinguishes several boundaries of one registry id; unique among siblings. @internal */
|
|
176
213
|
declare const FRAGMENT_KEY_ATTRIBUTE = "data-payload-fragment-key";
|
|
214
|
+
/** @internal */
|
|
177
215
|
interface FragmentBoundary {
|
|
178
216
|
readonly element: Element;
|
|
179
217
|
/** Registry id — never a path, module or function name. */
|
|
@@ -182,7 +220,7 @@ interface FragmentBoundary {
|
|
|
182
220
|
/** Fields whose change re-renders the boundary; empty means any field. */
|
|
183
221
|
readonly dependsOn: readonly string[];
|
|
184
222
|
}
|
|
185
|
-
/** One revision's request to a per-boundary handler. */
|
|
223
|
+
/** One revision's request to a per-boundary handler. @internal */
|
|
186
224
|
interface StrategyRequest {
|
|
187
225
|
readonly revision: number;
|
|
188
226
|
readonly receivedAt: number;
|
|
@@ -193,6 +231,7 @@ interface StrategyRequest {
|
|
|
193
231
|
/** Aborted when a newer revision arrives or the runtime stops. */
|
|
194
232
|
readonly signal: AbortSignal;
|
|
195
233
|
}
|
|
234
|
+
/** @internal */
|
|
196
235
|
type FragmentOutcome = {
|
|
197
236
|
readonly status: 'rendered';
|
|
198
237
|
/** The boundary's new inner HTML. */
|
|
@@ -205,10 +244,11 @@ type FragmentOutcome = {
|
|
|
205
244
|
} | {
|
|
206
245
|
readonly status: 'superseded';
|
|
207
246
|
};
|
|
208
|
-
/** Renders one boundary for one revision. Must honour `request.signal`. */
|
|
247
|
+
/** Renders one boundary for one revision. Must honour `request.signal`. @internal */
|
|
209
248
|
type FragmentHandler = (request: StrategyRequest, boundary: FragmentBoundary) => Promise<FragmentOutcome>;
|
|
249
|
+
/** @internal */
|
|
210
250
|
declare function describeBoundary(element: Element): FragmentBoundary | null;
|
|
211
|
-
/** The boundaries under `root` that `changedFields` touch; one inside an island is the island's business. */
|
|
251
|
+
/** The boundaries under `root` that `changedFields` touch; one inside an island is the island's business. @internal */
|
|
212
252
|
declare function collectFragmentBoundaries(root: ParentNode, changedFields: ReadonlySet<string>): readonly FragmentBoundary[];
|
|
213
253
|
|
|
214
254
|
/**
|
|
@@ -236,22 +276,24 @@ interface FragmentStrategyOptions {
|
|
|
236
276
|
readonly search: string;
|
|
237
277
|
};
|
|
238
278
|
}
|
|
279
|
+
/** @internal */
|
|
239
280
|
declare function createFragmentHandler(options: FragmentStrategyOptions): FragmentHandler;
|
|
240
281
|
|
|
241
282
|
/**
|
|
242
283
|
* The route strategy: when a revision touches what no smaller strategy can
|
|
243
|
-
* render,
|
|
244
|
-
* `minIntervalMs` is refused as
|
|
284
|
+
* render, ask the host's own router to re-render it, or else fetch the route
|
|
285
|
+
* again and morph it in place. A refresh inside `minIntervalMs` is refused as
|
|
286
|
+
* LP0805 and handed back for a trailing run. See ADR 0011.
|
|
245
287
|
*/
|
|
246
288
|
|
|
247
|
-
/** Sent with every refresh so a server can tell a preview refresh from navigation. */
|
|
289
|
+
/** Sent with every refresh so a server can tell a preview refresh from navigation. @internal */
|
|
248
290
|
declare const ROUTE_REFRESH_HEADER = "x-payload-live-preview";
|
|
249
291
|
interface RouteStrategyOptions {
|
|
250
292
|
/** `fetch` to use; defaults to the global one. */
|
|
251
293
|
readonly fetch?: (url: string, init?: RequestInit) => Promise<Response>;
|
|
252
294
|
/** Per-refresh timeout. Default 8000 ms. */
|
|
253
295
|
readonly timeoutMs?: number;
|
|
254
|
-
/** Shortest gap between two refreshes; one inside it is refused with LP0805. Default 1000 ms. */
|
|
296
|
+
/** Shortest gap between two refreshes; one inside it is refused with LP0805 and run when the gap closes. Default 1000 ms. */
|
|
255
297
|
readonly minIntervalMs?: number;
|
|
256
298
|
/** The document to refresh; defaults to `document`. */
|
|
257
299
|
readonly document?: Document;
|
|
@@ -266,7 +308,7 @@ interface RouteStrategyOptions {
|
|
|
266
308
|
readonly scrollTo: (x: number, y: number) => void;
|
|
267
309
|
};
|
|
268
310
|
}
|
|
269
|
-
/** An explicit `data-payload-strategy="route"`, or a binding in `<head>`. */
|
|
311
|
+
/** An explicit `data-payload-strategy="route"`, or a binding in `<head>`. @internal */
|
|
270
312
|
declare function isRouteBound(element: Element): boolean;
|
|
271
313
|
declare function createRouteStrategy(options?: RouteStrategyOptions): RouteStrategy;
|
|
272
314
|
|
|
@@ -275,9 +317,11 @@ declare function createRouteStrategy(options?: RouteStrategyOptions): RouteStrat
|
|
|
275
317
|
* and what it answers. Both sides validate the shape; nothing on the wire
|
|
276
318
|
* names code, paths or templates. See ADR 0011.
|
|
277
319
|
*/
|
|
278
|
-
/** Bumped when the request or response shape changes incompatibly. */
|
|
320
|
+
/** Bumped when the request or response shape changes incompatibly. @internal */
|
|
279
321
|
declare const FRAGMENT_PROTOCOL_VERSION = 1;
|
|
322
|
+
/** @internal */
|
|
280
323
|
declare const FRAGMENT_VERSION_HEADER = "x-payload-fragment-version";
|
|
324
|
+
/** @internal */
|
|
281
325
|
interface FragmentRequestBody {
|
|
282
326
|
/** Registry id of the boundary (`data-payload-fragment`). */
|
|
283
327
|
readonly fragment: string;
|
|
@@ -294,6 +338,7 @@ interface FragmentRequestBody {
|
|
|
294
338
|
/** The unsaved form state as the admin posted it, after the runtime's merge. */
|
|
295
339
|
readonly fields: Readonly<Record<string, unknown>>;
|
|
296
340
|
}
|
|
341
|
+
/** @internal */
|
|
297
342
|
interface FragmentResponseBody {
|
|
298
343
|
/** The boundary's new inner HTML. */
|
|
299
344
|
readonly html: string;
|
|
@@ -310,9 +355,9 @@ interface FragmentResponseBody {
|
|
|
310
355
|
readonly durationMs?: number;
|
|
311
356
|
};
|
|
312
357
|
}
|
|
313
|
-
/** Shape check for a request body; `null` when it is not one. */
|
|
358
|
+
/** Shape check for a request body; `null` when it is not one. @internal */
|
|
314
359
|
declare function parseFragmentRequest(value: unknown): FragmentRequestBody | null;
|
|
315
|
-
/** Shape check for a response body; `null` when it is not one. */
|
|
360
|
+
/** Shape check for a response body; `null` when it is not one. @internal */
|
|
316
361
|
declare function parseFragmentResponse(value: unknown): FragmentResponseBody | null;
|
|
317
362
|
|
|
318
363
|
/**
|
|
@@ -325,9 +370,10 @@ declare function parseFragmentResponse(value: unknown): FragmentResponseBody | n
|
|
|
325
370
|
* The strategy the runtime drives, built on a per-boundary handler: plan the
|
|
326
371
|
* boundaries, render each, morph a success, patch a failure. A late or
|
|
327
372
|
* aborted render is dropped, never applied.
|
|
373
|
+
* @internal
|
|
328
374
|
*/
|
|
329
375
|
declare function fragmentStrategyFrom(handler: FragmentHandler): FragmentStrategy;
|
|
330
376
|
/** The strategy for a fragment endpoint: hand it to the runtime as `strategies.fragment`. */
|
|
331
377
|
declare function createFragmentStrategy(options: FragmentStrategyOptions): FragmentStrategy;
|
|
332
378
|
|
|
333
|
-
export { DIAGNOSTIC_CODES, type DiagnosticCode, FRAGMENT_ATTRIBUTE, FRAGMENT_KEY_ATTRIBUTE, FRAGMENT_PROTOCOL_VERSION, FRAGMENT_VERSION_HEADER, type FragmentBoundary, type FragmentContext, type FragmentHandler, type FragmentOutcome, type FragmentReport, type FragmentRequestBody, type FragmentResponseBody, type FragmentStrategy, type FragmentStrategyOptions, ROUTE_REFRESH_HEADER, type RouteContext, type RouteStrategy, type RouteStrategyOptions, type StrategyHandlers, type StrategyRequest, type UpdateSource, collectFragmentBoundaries, createFragmentHandler, createFragmentStrategy, createRouteStrategy, describeBoundary, fragmentStrategyFrom, isRouteBound, parseFragmentRequest, parseFragmentResponse, resolveStrategy };
|
|
379
|
+
export { DIAGNOSTIC_CODES, type DiagnosticCode, FRAGMENT_ATTRIBUTE, FRAGMENT_KEY_ATTRIBUTE, FRAGMENT_PROTOCOL_VERSION, FRAGMENT_VERSION_HEADER, type FragmentBoundary, type FragmentContext, type FragmentHandler, type FragmentOutcome, type FragmentReport, type FragmentRequestBody, type FragmentResponseBody, type FragmentStrategy, type FragmentStrategyOptions, ROUTE_REFRESH_HEADER, type RouteContext, type RouteOutcome, type RouteStrategy, type RouteStrategyOptions, type StrategyHandlers, type StrategyRequest, type UpdateSource, collectFragmentBoundaries, createFragmentHandler, createFragmentStrategy, createRouteStrategy, describeBoundary, fragmentStrategyFrom, isRouteBound, parseFragmentRequest, parseFragmentResponse, resolveStrategy };
|
package/dist/fragment.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
var e="data-payload-island";function t(t){return"astro-island"===t.tagName.toLowerCase()||t.hasAttribute(e)}function n(t){return"patch"===t.getAttribute(e)}function isInsideIsland(e){let r=e;for(;null!==r;){if(t(r)&&!n(r))return!0;r=r.parentElement}return!1}function r(e){if(null==e)return[];const t=/* @__PURE__ */new Set,n=[];for(const r of e.split(/[\s,]+/)){const e=r.trim();0===e.length||t.has(e)||(t.add(e),n.push(e))}return n}var o="data-payload-fragment";function i(e){const t=e.getAttribute("data-payload-strategy");return null!==t&&t.length>0?"patch"===t||"fragment"===t||"route"===t?t:void 0:null!==function(e){return e.closest(`[${o}]`)}(e)?"fragment":null!==e.closest("head")?"route":"patch"}var a="data-payload-fragment-key";function s(e){const t=e.getAttribute(o);if(null===t||0===t.length)return null;const n=e.getAttribute(a);return{element:e,id:t,key:null===n||0===n.length?void 0:n,dependsOn:r(e.getAttribute("data-payload-depends"))}}function l(e,t){const n=[];for(const r of e.querySelectorAll(`[${o}]`)){const e=s(r);null===e||isInsideIsland(r)||e.dependsOn.length>0&&!e.dependsOn.some(e=>t.has(e))||n.push(e)}return n}var u=1,c="x-payload-fragment-version";function d(e,t){if(t>12||"object"!=typeof e||null===e)return t;let n=t;for(const r of Object.values(e))if(n=Math.max(n,d(r,t+1)),n>12)break;return n}function f(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function g(e){if(!f(e))return null;const t=e.fragment;if("string"!=typeof t||!/^[a-z][a-z0-9-]{0,63}$/iu.test(t))return null;const n=e.key;if(void 0!==n&&("string"!=typeof n||n.length>128))return null;const r=e.route;if("string"!=typeof r||!r.startsWith("/")||r.length>2048)return null;const o=e.search;if("string"!=typeof o||o.length>4096||""!==o&&!o.startsWith("?"))return null;const i=e.revision;if("number"!=typeof i||!Number.isInteger(i)||i<0)return null;const a=[];for(const t of["locale","collectionSlug","globalSlug"]){const n=e[t];if(void 0!==n){if("string"!=typeof n||n.length>128)return null;a.push(n)}else a.push(void 0)}const[s,l,u]=a,c=e.fields;return!f(c)||d(c,0)>12?null:{fragment:t,..."string"==typeof n?{key:n}:{},route:r,search:o,revision:i,...void 0!==s?{locale:s}:{},...void 0!==l?{collectionSlug:l}:{},...void 0!==u?{globalSlug:u}:{},fields:c}}function m(e){if(!f(e))return null;const{html:t,boundary:n,revision:r,metadata:o}=e;return"string"!=typeof t?null:f(n)&&"string"==typeof n.id?void 0!==n.key&&"string"!=typeof n.key||"number"!=typeof r?null:f(o)&&"string"==typeof o.renderedAt&&"string"==typeof o.renderer?e:null:null}var h={status:"superseded"};function p(e,t){return{status:"failed",code:e,reason:t}}function y(e){const t=function(e){const t=()=>{throw new TypeError('createFragmentStrategy: endpoint must be a same-origin path starting with "/"')};if(("string"!=typeof e||!e.startsWith("/")||e.startsWith("//")||e.includes("\\"))&&t(),"undefined"!=typeof location){let n;try{n=new URL(e,location.href)}catch{n=void 0}n?.origin!==location.origin&&t()}return e}(e.endpoint),n=e.timeoutMs??5e3,r=e.maxResponseBytes??524288,o=function(e){let t=0;const n=[];return async r=>{t<e?t+=1:await new Promise(e=>{n.push(e)});try{return await r()}finally{(()=>{const e=n.shift();void 0===e?t-=1:e()})()}}}(Math.max(1,e.maxConcurrent??4)),i=/* @__PURE__ */new Map;return(a,s)=>{const l=`${s.id} ${s.key??""} ${String(a.revision)}`,u=i.get(l);if(void 0!==u)return u;const d=o(()=>async function(o,i){const a=()=>o.signal.aborted;if(a())return h;const s=e.location??location,l=function(e){const t={};for(const[n,r]of Object.entries(e))void 0!==r&&(t[n]=r);return t}({fragment:i.id,key:i.key,route:s.pathname,search:s.search,revision:o.revision,locale:o.locale,collectionSlug:o.collectionSlug,globalSlug:o.globalSlug,fields:o.fields}),u=new AbortController,d=()=>{u.abort()};o.signal.addEventListener("abort",d,{once:!0});const f={timedOut:!1},g=setTimeout(()=>{f.timedOut=!0,u.abort()},n),y=e=>a()?h:f.timedOut?p("LP0801",`timeout after ${String(n)} ms`):p("LP0801",function(e){return e instanceof Error?e.message:String(e)}(e));try{let s;try{s=await(e.fetch??fetch)(t,{method:"POST",credentials:"same-origin",headers:{...e.headers,accept:"application/json","content-type":"application/json",[c]:String(1)},body:JSON.stringify(l),signal:u.signal})}catch(e){return y(e)}if(a())return h;if(401===s.status||403===s.status)return p("LP0803",`endpoint refused the preview (${String(s.status)})`);if(!s.ok)return p("LP0801",`endpoint answered ${String(s.status)}`);const d=s.headers.get("content-type")??"";if(!d.toLowerCase().startsWith("application/json"))return p("LP0802",`unexpected content type "${d}"`);if(Number(s.headers.get("content-length")??"0")>r)return p("LP0802","response exceeds the size limit");let g,b;try{g=await async function(e,t,n){const r=e.body;if("object"!=typeof(o=r)||null===o||"function"!=typeof o.getReader){const n=await e.text();return(new TextEncoder).encode(n).byteLength>t?null:n}var o;const i=r.getReader(),a=()=>{i.cancel().catch(()=>{})};n.addEventListener("abort",a,{once:!0});const s=new TextDecoder;let l="",u=0;try{for(;;){const{done:e,value:n}=await i.read();if(e)break;if(u+=n.byteLength,u>t)return a(),null;l+=s.decode(n,{stream:!0})}}finally{n.removeEventListener("abort",a)}return l+s.decode()}(s,r,u.signal)}catch(e){return y(e)}if(a())return h;if(f.timedOut)return p("LP0801",`timeout after ${String(n)} ms`);if(null===g)return p("LP0802","response exceeds the size limit");try{b=JSON.parse(g)}catch{return p("LP0802","response is not JSON")}const v=m(b);return null===v?p("LP0802","response has the wrong shape"):v.boundary.id!==i.id?p("LP0802","response is for another boundary"):v.revision!==o.revision?h:{status:"rendered",html:v.html,metadata:v.metadata}}finally{clearTimeout(g),o.signal.removeEventListener("abort",d)}}(a,s));i.set(l,d);const f=()=>{i.get(l)===d&&i.delete(l)};return d.then(f,f),d}}var b=Object.freeze({NoTrustedOrigin:"LP0101",ReferrerOnlyTrust:"LP0102",PluginIncompatible:"LP0103",OrphanField:"LP0201",UnattributableUpdate:"LP0202",VisibilityGateDeferred:"LP0301",UnsafeAttributeWrite:"LP0401",TextTargetHasChildren:"LP0402",MissingArrayTemplate:"LP0403",StructuralItemUnkeyed:"LP0404",StructuralDuplicateKey:"LP0405",StructuralUnstableKeys:"LP0406",UnsupportedStrategy:"LP0407",MessageRejected:"LP0501",TokenRejected:"LP0502",HandlerThrew:"LP0601",TransformThrew:"LP0602",RendererThrew:"LP0603",StartupFailed:"LP0605",ReadyFailed:"LP0606",AuditRuntimeMissing:"LP0701",AuditNoFrameAncestors:"LP0702",AuditFrameOptionsBlocks:"LP0703",AuditBindingsExposed:"LP0704",AuditGateThresholdExceeded:"LP0705",AuditUnownedBindings:"LP0706",AuditNoBindings:"LP0707",AuditNotAPage:"LP0708",FragmentRequestFailed:"LP0801",FragmentResponseInvalid:"LP0802",FragmentUnauthorized:"LP0803",FragmentSuperseded:"LP0804",RouteRefreshLoop:"LP0805",FragmentStrategyUnavailable:"LP0806",V2ReadinessGap:"LP0709",RuntimeOnPublicPage:"LP0710"}),v="data-payload-owned",L=/* @__PURE__ */new Set(["open","value","checked","selected"]);function P(e,t){for(const n of t.keyAttributes){const t=e.getAttribute(n);if(null!==t&&t.length>0)return`${n}=${t}`}}function A(t){if(t.tagName.toLowerCase().includes("-"))return!0;if(t.hasAttribute(e)||t.hasAttribute(v))return!0;const n=t.getAttribute("contenteditable");return null!==n&&"false"!==n}function S(e,t,n){if(!function(e,t){return e.tagName===t.tagName&&e.namespaceURI===t.namespaceURI&&!A(e)&&!A(t)}(e,t))return t;const r=function(e){const t=e.ownerDocument.activeElement;if(!(t instanceof HTMLElement&&e.contains(t)))return null;return{element:t,selection:t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement?[t.selectionStart,t.selectionEnd]:null}}(e);return function(e,t){for(const n of Array.from(e.attributes))t.hasAttribute(n.name)||L.has(n.name.toLowerCase())||e.removeAttribute(n.name);for(const n of Array.from(t.attributes))e.getAttribute(n.name)!==n.value&&e.setAttribute(n.name,n.value)}(e,t),!0!==n.retainChildrenOf?.(e,t)&&function(e,t,n){const r=function(e,t){const n=/* @__PURE__ */new Map;let r;for(const o of Array.from(e.children)){const e=P(o,t);void 0!==e&&(n.has(e)?r??=e.slice(e.indexOf("=")+1):n.set(e,o))}return void 0!==r&&t.onDuplicateKey?.(e,r),n}(e,n),o=new Set(r.values()),i=Array.from(e.childNodes).filter(e=>!o.has(e)),a=/* @__PURE__ */new Set,s=/* @__PURE__ */new Set,l=Array.from(t.childNodes);let u=e.firstChild,c=0;for(let t=0;t<l.length;t+=1){const o=l[t];let d=null,f=o instanceof Element?P(o,n):void 0;if(void 0!==f&&s.has(f)&&(f=void 0),void 0!==f){s.add(f);const e=r.get(f);if(void 0!==e&&!a.has(e)&&(d=w(e,o,n)===e?e:null,null===d)){e.replaceWith(o),a.add(o),u=o.nextSibling;continue}}else{for(;c<i.length;){const r=i[c];if(c+=1,!a.has(r)){if(T(r,o)){d=w(r,o,n)===r?r:null,null===d&&(e.replaceChild(o,r),a.add(o),u=o.nextSibling);break}if(r instanceof Element){const n=l[t+1];if(!(o instanceof Element)||void 0!==n&&T(r,n)){c-=1;break}e.replaceChild(o,r),a.add(o),u=o.nextSibling;break}if(!(o instanceof Element)){e.replaceChild(o,r),a.add(o),u=o.nextSibling;break}}}if(null===d&&a.has(o))continue}const g=d??o;for(a.add(g);null!==u&&u!==g&&!a.has(u)&&E(u);)u=u.nextSibling;g!==u&&e.insertBefore(g,u),u=g.nextSibling}for(const t of Array.from(e.childNodes))a.has(t)||t.remove()}(e,t,n),function(e){if(null===e)return;const{element:t,selection:n}=e;if(t.ownerDocument.activeElement!==t&&t.isConnected)try{t.focus({preventScroll:!0});const[e,r]=n??[null,null];null!==e&&null!==r&&t.setSelectionRange(e,r)}catch{}}(r),e}function w(e,t,n){return e instanceof Element&&t instanceof Element?A(e)&&A(t)?e:S(e,t,n):(e.nodeValue!==t.nodeValue&&(e.nodeValue=t.nodeValue),e)}function E(e){return e.nodeType===Node.TEXT_NODE&&0===(e.nodeValue??"").trim().length}function T(e,t){return e.nodeType===t.nodeType&&(!(e instanceof Element&&t instanceof Element)||e.tagName===t.tagName&&e.namespaceURI===t.namespaceURI)}var k="data-payload-strategy",x="data-payload-field",N="x-payload-live-preview";function O(e){const t=e.getAttribute(k);return null!==t?"route"===t:null!==e.closest("head")}function $(e){const t=e.getAttribute(x),n=r(e.getAttribute("data-payload-depends"));return null===t||0===t.length?n:[t,...n]}function R(e){if("META"===e.tagName){const t=e.getAttribute("name")??e.getAttribute("property");return null===t?null:`meta:${t}`}return"LINK"===e.tagName&&"canonical"===e.getAttribute("rel")?"link:canonical":null}function C(e={}){const t=e.timeoutMs??8e3,n=e.minIntervalMs??1e3;let r=-1/0;return{plan(e,t){for(const n of e.querySelectorAll(`[${x}], [${k}="route"]`)){if(!O(n))continue;const e=$(n);if(0===e.length||e.some(e=>t.has(e)))return!0}return!1},async refresh(i){const s=Date.now();if(s-r<n)return i.log("LP0805",`route refresh for revision ${String(i.revision)} refused: the previous one was ${String(s-r)} ms ago`),"failed";r=s;const l=e.document??document,u=e.location??location,c=e.window??window,d=new AbortController,f=()=>{d.abort()};i.signal.addEventListener("abort",f,{once:!0});const g=setTimeout(()=>{d.abort()},t),m=e=>i.signal.aborted?"superseded":(i.log("LP0801",e instanceof Error?e.message:String(e)),"failed");try{let t;try{t=await(e.fetch??fetch)(u.href,{method:"GET",credentials:"same-origin",cache:"no-store",headers:{accept:"text/html",[N]:"route"},signal:d.signal})}catch(e){return m(e)}if(i.signal.aborted)return"superseded";if(!t.ok||!(t.headers.get("content-type")??"").includes("text/html"))return i.log("LP0802",`route answered ${String(t.status)} ${t.headers.get("content-type")??""}`),"failed";try{const e=await t.text();if(!i.isCurrent())return"superseded";const n=(new DOMParser).parseFromString(e,"text/html"),r=c.scrollX,s=c.scrollY;return function(e,t){t.title!==e.title&&(e.title=t.title);const n=/* @__PURE__ */new Map;for(const t of e.head.querySelectorAll("meta, link")){const e=R(t);null===e||n.has(e)||n.set(e,t)}const r=/* @__PURE__ */new Set;for(const o of t.head.querySelectorAll("meta, link")){const t=R(o);if(null===t)continue;r.add(t);const i=n.get(t);if(void 0!==i){if(!i.hasAttribute(v))for(const e of Array.from(o.attributes))i.getAttribute(e.name)!==e.value&&i.setAttribute(e.name,e.value)}else e.head.append(e.importNode(o,!0))}for(const[e,t]of n)r.has(e)||t.hasAttribute(v)||t.remove()}(l,n),S(l.body,n.body,{keyAttributes:["data-payload-key",a,o],retainChildrenOf:e=>e.hasAttribute(o)}),c.scrollTo(r,s),"refreshed"}catch(e){return m(e)}}finally{clearTimeout(g),i.signal.removeEventListener("abort",f)}}}}function M(e){return{plan:(e,t)=>l(e,t).map(e=>e.element),async render(t,n){const r={rendered:0,failed:0,superseded:0},o={revision:t.revision,receivedAt:t.receivedAt,fields:t.fields,locale:t.locale,collectionSlug:t.collectionSlug,globalSlug:t.globalSlug,signal:t.signal};return await Promise.all(n.map(async n=>{const i=s(n);if(null===i)return;let a;try{a=await e(o,i)}catch(e){a={status:"failed",code:"LP0801",reason:e instanceof Error?e.message:String(e)}}return t.isCurrent()&&"superseded"!==a.status?"rendered"===a.status?(t.morph(n,a.html),t.rendered(n,i.id,i.key),void(r.rendered+=1)):(t.failed(n,i.id,i.key,a.code,a.reason),t.isCurrent()&&t.patch(n),void(r.failed+=1)):(r.superseded+=1,void t.log("LP0804",`fragment "${i.id}" for revision ${String(o.revision)} discarded as superseded`))})),r}}}function I(e){return M(y(e))}export{b as DIAGNOSTIC_CODES,o as FRAGMENT_ATTRIBUTE,a as FRAGMENT_KEY_ATTRIBUTE,u as FRAGMENT_PROTOCOL_VERSION,c as FRAGMENT_VERSION_HEADER,N as ROUTE_REFRESH_HEADER,l as collectFragmentBoundaries,y as createFragmentHandler,I as createFragmentStrategy,C as createRouteStrategy,s as describeBoundary,M as fragmentStrategyFrom,O as isRouteBound,g as parseFragmentRequest,m as parseFragmentResponse,i as resolveStrategy};
|
|
1
|
+
function e(e,t){const n=new AbortController;let r=!1;const o=()=>{n.abort()};e.addEventListener("abort",o,{once:!0});const i=setTimeout(()=>{r=!0,n.abort()},t);return{signal:n.signal,timedOut:()=>r,dispose:()=>{clearTimeout(i),e.removeEventListener("abort",o)}}}function t(e){return e instanceof Error?e.message:String(e)}var n="data-payload-island";function r(e){return function(e){return"astro-island"===e.tagName.toLowerCase()||e.hasAttribute(n)}(e)&&!("patch"===e.getAttribute(n))}function isInsideIsland(e){let t=e;for(;null!==t;){if(r(t))return!0;t=t.parentElement}return!1}function o(e){if(null==e)return[];const t=/* @__PURE__ */new Set,n=[];for(const r of e.split(/[\s,]+/)){const e=r.trim();0===e.length||t.has(e)||(t.add(e),n.push(e))}return n}var i="data-payload-fragment";function a(e){const t=e.getAttribute("data-payload-strategy");return null!==t&&t.length>0?"patch"===t||"fragment"===t||"route"===t?t:void 0:null!==function(e){return e.closest(`[${i}]`)}(e)?"fragment":null!==e.closest("head")?"route":"patch"}var s="data-payload-fragment-key";function l(e){const t=e.getAttribute(i);if(null===t||0===t.length)return null;const n=e.getAttribute(s);return{element:e,id:t,key:null===n||0===n.length?void 0:n,dependsOn:o(e.getAttribute("data-payload-depends"))}}function u(e,t){const n=[];for(const r of e.querySelectorAll(`[${i}]`)){const e=l(r);null===e||isInsideIsland(r)||e.dependsOn.length>0&&!e.dependsOn.some(e=>t.has(e))||n.push(e)}return n}var c=1,d="x-payload-fragment-version";function f(e,t){if(t>12||"object"!=typeof e||null===e)return t;let n=t;for(const r of Object.values(e))if(n=Math.max(n,f(r,t+1)),n>12)break;return n}function g(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function h(e){if(!g(e))return null;const t=e.fragment;if("string"!=typeof t||!/^[a-z][a-z0-9-]{0,63}$/iu.test(t))return null;const n=e.key;if(void 0!==n&&("string"!=typeof n||n.length>128))return null;const r=e.route;if("string"!=typeof r||!r.startsWith("/")||r.length>2048)return null;const o=e.search;if("string"!=typeof o||o.length>4096||""!==o&&!o.startsWith("?"))return null;const i=e.revision;if("number"!=typeof i||!Number.isInteger(i)||i<0)return null;const a=[];for(const t of["locale","collectionSlug","globalSlug"]){const n=e[t];if(void 0!==n){if("string"!=typeof n||n.length>128)return null;a.push(n)}else a.push(void 0)}const[s,l,u]=a,c=e.fields;return!g(c)||f(c,0)>12?null:{fragment:t,..."string"==typeof n?{key:n}:{},route:r,search:o,revision:i,...void 0!==s?{locale:s}:{},...void 0!==l?{collectionSlug:l}:{},...void 0!==u?{globalSlug:u}:{},fields:c}}function p(e){if(!g(e))return null;const{html:t,boundary:n,revision:r,metadata:o}=e;return"string"!=typeof t?null:g(n)&&"string"==typeof n.id?void 0!==n.key&&"string"!=typeof n.key||"number"!=typeof r?null:g(o)&&"string"==typeof o.renderedAt&&"string"==typeof o.renderer?e:null:null}var m={status:"superseded"};function y(e,t){return{status:"failed",code:e,reason:t}}function b(n){const r=function(e){const t=()=>{throw new TypeError('createFragmentStrategy: endpoint must be a same-origin path starting with "/"')};if(("string"!=typeof e||!e.startsWith("/")||e.startsWith("//")||e.includes("\\"))&&t(),"undefined"!=typeof location){let n;try{n=new URL(e,location.href)}catch{n=void 0}n?.origin!==location.origin&&t()}return e}(n.endpoint),o=n.timeoutMs??5e3,i=n.maxResponseBytes??524288,a=function(e){let t=0;const n=[];return async r=>{t<e?t+=1:await new Promise(e=>{n.push(e)});try{return await r()}finally{(()=>{const e=n.shift();void 0===e?t-=1:e()})()}}}(Math.max(1,n.maxConcurrent??4)),s=/* @__PURE__ */new Map;return(l,u)=>{const c=`${u.id} ${u.key??""} ${String(l.revision)}`,f=s.get(c);if(void 0!==f)return f;const g=a(()=>async function(a,s){const l=()=>a.signal.aborted;if(l())return m;const u=n.location??location,c=function(e){const t={};for(const[n,r]of Object.entries(e))void 0!==r&&(t[n]=r);return t}({fragment:s.id,key:s.key,route:u.pathname,search:u.search,revision:a.revision,locale:a.locale,collectionSlug:a.collectionSlug,globalSlug:a.globalSlug,fields:a.fields}),f=e(a.signal,o),g=e=>l()?m:f.timedOut()?y("LP0801",`timeout after ${String(o)} ms`):y("LP0801",t(e));try{let e;try{e=await(n.fetch??fetch)(r,{method:"POST",credentials:"same-origin",headers:{...n.headers,accept:"application/json","content-type":"application/json",[d]:String(1)},body:JSON.stringify(c),signal:f.signal})}catch(e){return g(e)}if(l())return m;if(401===e.status||403===e.status)return y("LP0803",`endpoint refused the preview (${String(e.status)})`);if(!e.ok)return y("LP0801",`endpoint answered ${String(e.status)}`);const t=e.headers.get("content-type")??"";if(!t.toLowerCase().startsWith("application/json"))return y("LP0802",`unexpected content type "${t}"`);if(Number(e.headers.get("content-length")??"0")>i)return y("LP0802","response exceeds the size limit");let u,h;try{u=await async function(e,t,n){const r=e.body;if("object"!=typeof(o=r)||null===o||"function"!=typeof o.getReader){const n=await e.text();return(new TextEncoder).encode(n).byteLength>t?null:n}var o;const i=r.getReader(),a=()=>{i.cancel().catch(()=>{})};n.addEventListener("abort",a,{once:!0});const s=new TextDecoder;let l="",u=0;try{for(;;){const{done:e,value:n}=await i.read();if(e)break;if(u+=n.byteLength,u>t)return a(),null;l+=s.decode(n,{stream:!0})}}finally{n.removeEventListener("abort",a)}return l+s.decode()}(e,i,f.signal)}catch(e){return g(e)}if(l())return m;if(f.timedOut())return y("LP0801",`timeout after ${String(o)} ms`);if(null===u)return y("LP0802","response exceeds the size limit");try{h=JSON.parse(u)}catch{return y("LP0802","response is not JSON")}const b=p(h);return null===b?y("LP0802","response has the wrong shape"):b.boundary.id!==s.id?y("LP0802","response is for another boundary"):b.revision!==a.revision?m:{status:"rendered",html:b.html,metadata:b.metadata}}finally{f.dispose()}}(l,u));s.set(c,g);const h=()=>{s.get(c)===g&&s.delete(c)};return g.then(h,h),g}}var v=Object.freeze({NoTrustedOrigin:"LP0101",ReferrerOnlyTrust:"LP0102",PluginIncompatible:"LP0103",ProfileFeatureOmitted:"LP0104",OrphanField:"LP0201",UnattributableUpdate:"LP0202",VisibilityGateDeferred:"LP0301",UnsafeAttributeWrite:"LP0401",TextTargetHasChildren:"LP0402",MissingArrayTemplate:"LP0403",StructuralItemUnkeyed:"LP0404",StructuralDuplicateKey:"LP0405",StructuralUnstableKeys:"LP0406",UnsupportedStrategy:"LP0407",UnknownValueFormat:"LP0408",SanitizerDroppedAttribute:"LP0409",UnrenderedBlockKept:"LP0410",UnfaithfulPatch:"LP0411",ServerFormatReplaced:"LP0412",UnrenderedBlockLost:"LP0413",MessageRejected:"LP0501",TokenRejected:"LP0502",ProtocolShapeUnknown:"LP0503",HandlerThrew:"LP0601",TransformThrew:"LP0602",RendererThrew:"LP0603",StartupFailed:"LP0605",ReadyFailed:"LP0606",HydrationWaitTimedOut:"LP0607",AuditRuntimeMissing:"LP0701",AuditNoFrameAncestors:"LP0702",AuditFrameOptionsBlocks:"LP0703",AuditBindingsExposed:"LP0704",AuditGateThresholdExceeded:"LP0705",AuditUnownedBindings:"LP0706",AuditNoBindings:"LP0707",AuditNotAPage:"LP0708",FragmentRequestFailed:"LP0801",FragmentResponseInvalid:"LP0802",FragmentUnauthorized:"LP0803",FragmentSuperseded:"LP0804",RouteRefreshLoop:"LP0805",FragmentStrategyUnavailable:"LP0806",UnboundChangeRefresh:"LP0807",V2ReadinessGap:"LP0709",RuntimeOnPublicPage:"LP0710"}),L="data-payload-owned",P=/* @__PURE__ */new Set(["open","value","checked","selected"]);function A(e,t){for(const n of t.keyAttributes){const t=e.getAttribute(n);if(null!==t&&t.length>0)return`${n}=${t}`}}function S(e){if(e.tagName.toLowerCase().includes("-"))return!0;if(e.hasAttribute(n)||e.hasAttribute(L))return!0;const t=e.getAttribute("contenteditable");return null!==t&&"false"!==t}function w(e,t,n){if(!function(e,t){return e.tagName===t.tagName&&e.namespaceURI===t.namespaceURI&&!S(e)&&!S(t)}(e,t))return t;const r=function(e){const t=e.ownerDocument.activeElement;if(!(t instanceof HTMLElement&&e.contains(t)))return null;return{element:t,selection:t instanceof HTMLInputElement||t instanceof HTMLTextAreaElement?[t.selectionStart,t.selectionEnd]:null}}(e);return function(e,t){for(const n of Array.from(e.attributes))t.hasAttribute(n.name)||P.has(n.name.toLowerCase())||e.removeAttribute(n.name);for(const n of Array.from(t.attributes))e.getAttribute(n.name)!==n.value&&e.setAttribute(n.name,n.value)}(e,t),!0!==n.retainChildrenOf?.(e,t)&&function(e,t,n){const r=function(e,t){const n=/* @__PURE__ */new Map;let r;for(const o of Array.from(e.children)){const e=A(o,t);void 0!==e&&(n.has(e)?r??=e.slice(e.indexOf("=")+1):n.set(e,o))}return void 0!==r&&t.onDuplicateKey?.(e,r),n}(e,n),o=new Set(r.values()),i=Array.from(e.childNodes).filter(e=>!o.has(e)),a=/* @__PURE__ */new Set,s=/* @__PURE__ */new Set,l=Array.from(t.childNodes);let u=e.firstChild,c=0;for(let t=0;t<l.length;t+=1){const o=l[t];let d=null,f=o instanceof Element?A(o,n):void 0;if(void 0!==f&&s.has(f)&&(f=void 0),void 0!==f){s.add(f);const e=r.get(f);if(void 0!==e&&!a.has(e)&&(d=k(e,o,n)===e?e:null,null===d)){e.replaceWith(o),a.add(o),u=o.nextSibling;continue}}else{for(;c<i.length;){const r=i[c];if(c+=1,!a.has(r)){if(x(r,o)){d=k(r,o,n)===r?r:null,null===d&&(e.replaceChild(o,r),a.add(o),u=o.nextSibling);break}if(r instanceof Element){const n=l[t+1];if(!(o instanceof Element)||void 0!==n&&x(r,n)){c-=1;break}e.replaceChild(o,r),a.add(o),u=o.nextSibling;break}if(!(o instanceof Element)){e.replaceChild(o,r),a.add(o),u=o.nextSibling;break}}}if(null===d&&a.has(o))continue}const g=d??o;for(a.add(g);null!==u&&u!==g&&!a.has(u)&&T(u);)u=u.nextSibling;g!==u&&e.insertBefore(g,u),u=g.nextSibling}for(const t of Array.from(e.childNodes))a.has(t)||t.remove()}(e,t,n),function(e){if(null===e)return;const{element:t,selection:n}=e;if(t.ownerDocument.activeElement!==t&&t.isConnected)try{t.focus({preventScroll:!0});const[e,r]=n??[null,null];null!==e&&null!==r&&t.setSelectionRange(e,r)}catch{}}(r),e}function k(e,t,n){return e instanceof Element&&t instanceof Element?S(e)&&S(t)?e:w(e,t,n):(e.nodeValue!==t.nodeValue&&(e.nodeValue=t.nodeValue),e)}function T(e){return e.nodeType===Node.TEXT_NODE&&0===(e.nodeValue??"").trim().length}function x(e,t){return e.nodeType===t.nodeType&&(!(e instanceof Element&&t instanceof Element)||e.tagName===t.tagName&&e.namespaceURI===t.namespaceURI)}var E="data-payload-strategy",O="data-payload-field",R="x-payload-live-preview";function N(e){const t=e.getAttribute(E);return null!==t?"route"===t:null!==e.closest("head")}function $(e){const t=e.getAttribute(O),n=o(e.getAttribute("data-payload-depends"));return null===t||0===t.length?n:[t,...n]}function U(e){if("META"===e.tagName){const t=e.getAttribute("name")??e.getAttribute("property");return null===t?null:`meta:${t}`}return"LINK"===e.tagName&&"canonical"===e.getAttribute("rel")?"link:canonical":null}function C(n={}){const r=n.timeoutMs??8e3,o=n.minIntervalMs??1e3;let a=-1/0;return{plan(e,t){for(const n of e.querySelectorAll(`[${O}], [${E}="route"]`)){if(!N(n))continue;const e=$(n);if(0===e.length||e.some(e=>t.has(e)))return!0}return!1},async refresh(l){const u=Date.now(),c=o-(u-a);if(c>0)return l.retryAfter?.(c),l.log("LP0805",`route refresh for revision ${String(l.revision)} refused: the previous one was ${String(u-a)} ms ago`),"refused";a=u;const d=n.document??document,f=n.location??location,g=n.window??window,h=e(l.signal,r),p=e=>{if(l.signal.aborted)return"superseded";const n=h.timedOut()?`route refresh timed out after ${String(r)} ms`:t(e);return l.log("LP0801",n),"failed"};try{const e=("undefined"==typeof window?void 0:window)?.__livePreviewRouteRefresh;if(void 0!==e){try{await e()}catch(e){return p(e)}return l.isCurrent()?"refreshed":"superseded"}let t;try{t=await(n.fetch??fetch)(f.href,{method:"GET",credentials:"same-origin",cache:"no-store",headers:{accept:"text/html",[R]:"route"},signal:h.signal})}catch(e){return p(e)}if(l.signal.aborted)return"superseded";if(!t.ok||!(t.headers.get("content-type")??"").includes("text/html"))return l.log("LP0802",`route answered ${String(t.status)} ${t.headers.get("content-type")??""}`),"failed";try{const e=await t.text();if(!l.isCurrent())return"superseded";const n=(new DOMParser).parseFromString(e,"text/html"),r=g.scrollX,o=g.scrollY;return function(e,t){t.title!==e.title&&(e.title=t.title);const n=/* @__PURE__ */new Map;for(const t of e.head.querySelectorAll("meta, link")){const e=U(t);null===e||n.has(e)||n.set(e,t)}const r=/* @__PURE__ */new Set;for(const o of t.head.querySelectorAll("meta, link")){const t=U(o);if(null===t)continue;r.add(t);const i=n.get(t);if(void 0!==i){if(!i.hasAttribute(L))for(const e of Array.from(o.attributes))i.getAttribute(e.name)!==e.value&&i.setAttribute(e.name,e.value)}else e.head.append(e.importNode(o,!0))}for(const[e,t]of n)r.has(e)||t.hasAttribute(L)||t.remove()}(d,n),w(d.body,n.body,{keyAttributes:["data-payload-key",s,i],retainChildrenOf:e=>e.hasAttribute(i)}),g.scrollTo(r,o),"refreshed"}catch(e){return p(e)}}finally{h.dispose()}}}}function F(e){return{plan:(e,t)=>u(e,t).map(e=>e.element),async render(n,r){const o={rendered:0,failed:0,superseded:0},i={revision:n.revision,receivedAt:n.receivedAt,fields:n.fields,locale:n.locale,collectionSlug:n.collectionSlug,globalSlug:n.globalSlug,signal:n.signal};return await Promise.all(r.map(async r=>{const a=l(r);if(null===a)return;let s;try{s=await e(i,a)}catch(e){s={status:"failed",code:"LP0801",reason:t(e)}}return n.isCurrent()&&"superseded"!==s.status?"rendered"===s.status?(n.morph(r,s.html),n.rendered(r,a.id,a.key),void(o.rendered+=1)):(n.failed(r,a.id,a.key,s.code,s.reason),n.isCurrent()&&n.patch(r),void(o.failed+=1)):(o.superseded+=1,void n.log("LP0804",`fragment "${a.id}" for revision ${String(i.revision)} discarded as superseded`))})),o}}}function M(e){return F(b(e))}export{v as DIAGNOSTIC_CODES,i as FRAGMENT_ATTRIBUTE,s as FRAGMENT_KEY_ATTRIBUTE,c as FRAGMENT_PROTOCOL_VERSION,d as FRAGMENT_VERSION_HEADER,R as ROUTE_REFRESH_HEADER,u as collectFragmentBoundaries,b as createFragmentHandler,M as createFragmentStrategy,C as createRouteStrategy,l as describeBoundary,F as fragmentStrategyFrom,N as isRouteBound,h as parseFragmentRequest,p as parseFragmentResponse,a as resolveStrategy};
|
|
2
2
|
//# sourceMappingURL=fragment.js.map
|