payload-live-preview 1.8.0 → 2.0.0-beta.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 +301 -93
- package/dist/adapters/astro/PreviewBoundary.astro +66 -0
- package/dist/adapters/astro/RichText.astro +6 -0
- package/dist/adapters/astro/index.d.ts +165 -134
- 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 +4 -9
- 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 +13 -80
- package/dist/adapters/nextjs/index.js +1 -1
- package/dist/adapters/nextjs/index.js.map +1 -1
- package/dist/adapters/nuxt/index.d.ts +46 -106
- package/dist/adapters/nuxt/index.js +1 -1
- package/dist/adapters/nuxt/index.js.map +1 -1
- package/dist/adapters/sveltekit/index.d.ts +10 -75
- package/dist/adapters/sveltekit/index.js +1 -1
- package/dist/adapters/sveltekit/index.js.map +1 -1
- package/dist/client.cjs +2 -0
- package/dist/client.cjs.map +1 -0
- package/dist/client.d.cts +747 -0
- package/dist/client.d.ts +747 -0
- package/dist/client.js +2 -0
- package/dist/client.js.map +1 -0
- package/dist/codegen-astro.d.ts +5 -27
- package/dist/codegen-astro.js +1 -1
- package/dist/codegen-astro.js.map +1 -1
- package/dist/codegen-cli.d.ts +3 -16
- 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 +37 -124
- package/dist/codegen.d.ts +37 -124
- 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 +647 -1100
- package/dist/core.d.ts +647 -1100
- package/dist/core.js +1 -1
- package/dist/core.js.map +1 -1
- package/dist/doctor-cli.d.ts +3 -28
- package/dist/doctor-cli.js +1 -1
- package/dist/doctor-cli.js.map +1 -1
- package/dist/doctor.d.ts +16 -32
- package/dist/doctor.js +1 -1
- package/dist/doctor.js.map +1 -1
- package/dist/fragment.cjs +2 -0
- package/dist/fragment.cjs.map +1 -0
- package/dist/fragment.d.cts +333 -0
- package/dist/fragment.d.ts +333 -0
- package/dist/fragment.js +2 -0
- package/dist/fragment.js.map +1 -0
- package/dist/index.cjs +1 -1
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +885 -1531
- package/dist/index.d.ts +885 -1531
- package/dist/index.js +1 -1
- package/dist/index.js.map +1 -1
- package/dist/lexical.cjs +2 -0
- package/dist/lexical.cjs.map +1 -0
- package/dist/lexical.d.cts +90 -0
- package/dist/lexical.d.ts +90 -0
- package/dist/lexical.js +2 -0
- package/dist/lexical.js.map +1 -0
- package/dist/middleware-CEPsY1P7.d.ts +40 -0
- package/dist/migrate.d.ts +73 -0
- package/dist/migrate.js +2 -0
- package/dist/migrate.js.map +1 -0
- package/dist/options-CEzzfHJu.d.ts +197 -0
- package/dist/payload.cjs +1 -1
- package/dist/payload.cjs.map +1 -1
- package/dist/payload.d.cts +11 -80
- package/dist/payload.d.ts +11 -80
- package/dist/payload.js +1 -1
- package/dist/payload.js.map +1 -1
- package/dist/plugins.cjs +2 -0
- package/dist/plugins.cjs.map +1 -0
- package/dist/plugins.d.cts +509 -0
- package/dist/plugins.d.ts +509 -0
- package/dist/plugins.js +2 -0
- package/dist/plugins.js.map +1 -0
- package/dist/{probe-tMHdim5y.d.ts → probe-CYtvj_Lm.d.ts} +43 -77
- package/dist/server.cjs +2 -0
- package/dist/server.cjs.map +1 -0
- package/dist/server.d.cts +435 -0
- package/dist/server.d.ts +435 -0
- package/dist/server.js +2 -0
- package/dist/server.js.map +1 -0
- package/dist/structural.cjs +3 -0
- package/dist/structural.cjs.map +1 -0
- package/dist/structural.d.cts +243 -0
- package/dist/structural.d.ts +243 -0
- package/dist/structural.js +3 -0
- package/dist/structural.js.map +1 -0
- package/package.json +86 -7
- package/dist/middleware-DD4Hwomt.d.ts +0 -189
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/** A validated update as events expose it. */
|
|
2
|
+
interface PayloadLivePreviewData {
|
|
3
|
+
readonly fields: Record<string, unknown>;
|
|
4
|
+
readonly schema?: readonly PayloadFieldSchema[];
|
|
5
|
+
readonly globalSlug?: string;
|
|
6
|
+
readonly collectionSlug?: string;
|
|
7
|
+
readonly locale?: string;
|
|
8
|
+
}
|
|
9
|
+
/** The subset of Payload's field schema the runtime reads; extra properties are kept opaquely. */
|
|
10
|
+
interface PayloadFieldSchema {
|
|
11
|
+
readonly name: string;
|
|
12
|
+
readonly type: PayloadFieldType;
|
|
13
|
+
readonly label?: string;
|
|
14
|
+
readonly required?: boolean;
|
|
15
|
+
readonly localized?: boolean;
|
|
16
|
+
readonly fields?: readonly PayloadFieldSchema[];
|
|
17
|
+
readonly blocks?: readonly PayloadBlockSchema[];
|
|
18
|
+
readonly relationTo?: string | readonly string[];
|
|
19
|
+
readonly hasMany?: boolean;
|
|
20
|
+
readonly admin?: {
|
|
21
|
+
readonly condition?: PayloadFieldCondition;
|
|
22
|
+
};
|
|
23
|
+
readonly [extra: string]: unknown;
|
|
24
|
+
}
|
|
25
|
+
interface PayloadBlockSchema {
|
|
26
|
+
readonly slug: string;
|
|
27
|
+
readonly fields: readonly PayloadFieldSchema[];
|
|
28
|
+
readonly [extra: string]: unknown;
|
|
29
|
+
}
|
|
30
|
+
/** Payload's core field types. `tabs` is a structural container; `group` flattens. */
|
|
31
|
+
type PayloadFieldType = 'text' | 'textarea' | 'richText' | 'email' | 'number' | 'checkbox' | 'date' | 'select' | 'radio' | 'array' | 'blocks' | 'group' | 'tabs' | 'row' | 'collapsible' | 'relationship' | 'upload' | 'point' | 'json' | 'code' | 'ui';
|
|
32
|
+
/** `admin.condition` is a function in source and cannot cross `postMessage`; modelled, not consumed. */
|
|
33
|
+
type PayloadFieldCondition = (data: unknown, siblingData: unknown) => boolean;
|
|
34
|
+
|
|
35
|
+
/**
|
|
36
|
+
* How a bound region is brought up to date: the runtime patches it, a server
|
|
37
|
+
* renders a `data-payload-fragment` boundary from the unsaved form state, or
|
|
38
|
+
* the whole route refreshes. Core carries only the seam — which boundaries a
|
|
39
|
+
* strategy owns and what it may do — so a patch-only page pays for nothing
|
|
40
|
+
* more; the orchestration lives in `payload-live-preview/fragment`.
|
|
41
|
+
*/
|
|
42
|
+
|
|
43
|
+
/** What produced an update: the runtime's DOM patching, a server-rendered fragment, or a route refresh. */
|
|
44
|
+
type UpdateSource = 'patch' | 'fragment' | 'route';
|
|
45
|
+
|
|
46
|
+
/** Types shared by the runtime primitives. */
|
|
47
|
+
|
|
48
|
+
/** Payload's field set plus the DOM-binding categories `html`, `url`, `image` and `structural-array`. */
|
|
49
|
+
type FieldType = PayloadFieldType | 'html' | 'url' | 'image' | 'structural-array';
|
|
50
|
+
/** A namespaced project renderer key, so a typo of a built-in type can never become one. */
|
|
51
|
+
type CustomRendererKey = `${string}:${string}`;
|
|
52
|
+
/** What a renderer may be registered under and an element may ask for. */
|
|
53
|
+
type RendererKey = FieldType | CustomRendererKey;
|
|
54
|
+
/**
|
|
55
|
+
* A project rich-text renderer, shared by SSR and preview. Its output goes
|
|
56
|
+
* through the sanitizer; call the same `sanitizeHtml()` server-side for byte equality.
|
|
57
|
+
*/
|
|
58
|
+
type RichTextRenderer = (value: unknown, context: {
|
|
59
|
+
readonly fieldName: string;
|
|
60
|
+
readonly element: Element;
|
|
61
|
+
readonly locale: string | undefined;
|
|
62
|
+
}) => string;
|
|
63
|
+
/** One registered binding. Several may share a field name when it renders in several places. */
|
|
64
|
+
interface CachedElement {
|
|
65
|
+
/** The bound DOM element. */
|
|
66
|
+
readonly element: Element;
|
|
67
|
+
/** Payload field path, e.g., `title` or `hero.subtitle`. */
|
|
68
|
+
readonly fieldName: string;
|
|
69
|
+
/** Resolved from attributes and tag heuristics; the schema may override it unless explicit. */
|
|
70
|
+
readonly fieldType: RendererKey;
|
|
71
|
+
/** Whether `data-payload-type` set the type, in which case the schema must not override it. */
|
|
72
|
+
readonly explicitFieldType?: boolean;
|
|
73
|
+
/** Fields this binding depends on (`data-payload-depends`); a change in any re-applies it under `skipUnchanged`. */
|
|
74
|
+
readonly dependsOn?: readonly string[];
|
|
75
|
+
/** Raw `data-payload-strategy` value. */
|
|
76
|
+
readonly strategy?: string;
|
|
77
|
+
/** How the runtime brings this binding up to date; `'unknown'` for an unrecognised strategy. Resolved by the cache. */
|
|
78
|
+
readonly strategyKind?: UpdateSource | 'unknown';
|
|
79
|
+
/** Nearest enclosing `data-payload-fragment` boundary. Resolved by the cache. */
|
|
80
|
+
readonly fragmentBoundary?: Element;
|
|
81
|
+
/** `data-payload-boundary`: an anchor that hides itself while its field is empty. */
|
|
82
|
+
readonly boundary?: boolean;
|
|
83
|
+
/** Write the value into this attribute instead of the content; policed writes. */
|
|
84
|
+
readonly targetAttribute?: string;
|
|
85
|
+
/** Optional sibling-field path bound to the element's `href` attribute. */
|
|
86
|
+
readonly hrefField?: string;
|
|
87
|
+
/** Optional sibling-field path bound to the element's `src` attribute. */
|
|
88
|
+
readonly srcField?: string;
|
|
89
|
+
/** Optional sibling-field path bound to the element's `alt` attribute. */
|
|
90
|
+
readonly altField?: string;
|
|
91
|
+
/** Optional inline template for array/blocks rendering. */
|
|
92
|
+
readonly arrayTemplate?: string;
|
|
93
|
+
/** Optional separator for primitive-array stringification. */
|
|
94
|
+
readonly arraySeparator?: string;
|
|
95
|
+
/** Optional locale code locked onto this element (overrides the global locale). */
|
|
96
|
+
readonly locale?: string;
|
|
97
|
+
/** The document this binding belongs to, from the nearest `data-payload-owner`. */
|
|
98
|
+
readonly owner?: string;
|
|
99
|
+
}
|
|
100
|
+
/** What a renderer is given; `allFields` lets it resolve a sibling field. */
|
|
101
|
+
interface RenderContext {
|
|
102
|
+
/** Full field map for the current update — used for sibling lookups. */
|
|
103
|
+
readonly allFields: Record<string, unknown>;
|
|
104
|
+
/** Active locale, or `undefined` when none is established. */
|
|
105
|
+
readonly locale: string | undefined;
|
|
106
|
+
/** Optional schema descriptor for the field, when available. */
|
|
107
|
+
readonly schema: PayloadFieldSchema | undefined;
|
|
108
|
+
/** The project's rich-text renderer, when the client was configured with one. */
|
|
109
|
+
readonly renderRichText?: RichTextRenderer;
|
|
110
|
+
}
|
|
111
|
+
/**
|
|
112
|
+
* A renderer writes one value into its element. It must not throw: one bad
|
|
113
|
+
* field may not stop an update. The result stays `void` — the internal
|
|
114
|
+
* no-write sentinel is not part of the contract.
|
|
115
|
+
*/
|
|
116
|
+
interface FieldRenderer {
|
|
117
|
+
readonly name: RendererKey;
|
|
118
|
+
render(target: CachedElement, value: unknown, context: RenderContext): void;
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* `structural-array` renderer (`data-payload-structural`): diffs the previous
|
|
123
|
+
* and next item lists and patches the container through the keyed morph
|
|
124
|
+
* (ADR 0008). All diff memory lives in the closure, one per client.
|
|
125
|
+
*/
|
|
126
|
+
|
|
127
|
+
declare function createStructuralArrayRenderer(): FieldRenderer;
|
|
128
|
+
|
|
129
|
+
/**
|
|
130
|
+
* Structural diff for array and blocks fields. Items with an `id` are keyed
|
|
131
|
+
* (moves are detected); without ids the diff is positional.
|
|
132
|
+
*/
|
|
133
|
+
type ArrayPatch = {
|
|
134
|
+
readonly kind: 'insert';
|
|
135
|
+
readonly index: number;
|
|
136
|
+
readonly value: unknown;
|
|
137
|
+
} | {
|
|
138
|
+
readonly kind: 'remove';
|
|
139
|
+
readonly index: number;
|
|
140
|
+
readonly value: unknown;
|
|
141
|
+
} | {
|
|
142
|
+
readonly kind: 'move';
|
|
143
|
+
readonly from: number;
|
|
144
|
+
readonly to: number;
|
|
145
|
+
readonly value: unknown;
|
|
146
|
+
} | {
|
|
147
|
+
readonly kind: 'update';
|
|
148
|
+
readonly index: number;
|
|
149
|
+
readonly value: unknown;
|
|
150
|
+
} | {
|
|
151
|
+
readonly kind: 'replace';
|
|
152
|
+
readonly index: number;
|
|
153
|
+
readonly oldValue: unknown;
|
|
154
|
+
readonly value: unknown;
|
|
155
|
+
};
|
|
156
|
+
|
|
157
|
+
/**
|
|
158
|
+
* Applies an `ArrayPatch[]` diff to a container as keyed DOM operations
|
|
159
|
+
* instead of rebuilding the list, so consumer state on surviving children is
|
|
160
|
+
* kept. Items are paired by `data-payload-key` (the item `id`); items without
|
|
161
|
+
* one pair by position. Nested arrays reconcile recursively through
|
|
162
|
+
* `data-payload-nested-key` slots. See ADR 0008.
|
|
163
|
+
*/
|
|
164
|
+
|
|
165
|
+
declare const KEY_ATTRIBUTE = "data-payload-key";
|
|
166
|
+
/** Last value seen per item key, per container; owned by the caller so instances never share it. */
|
|
167
|
+
type StructuralStore = WeakMap<Element, Map<string, unknown>>;
|
|
168
|
+
declare function createStructuralStore(): StructuralStore;
|
|
169
|
+
interface StructuralApplyOptions {
|
|
170
|
+
readonly template: string;
|
|
171
|
+
readonly container: Element;
|
|
172
|
+
readonly patches: readonly ArrayPatch[];
|
|
173
|
+
/** The full new array; inserts and replaces render by index from it. */
|
|
174
|
+
readonly nextItems: readonly unknown[];
|
|
175
|
+
/** Pass the same store across renders so nested arrays diff incrementally. */
|
|
176
|
+
readonly store: StructuralStore;
|
|
177
|
+
/** Re-render existing items even when unchanged. */
|
|
178
|
+
readonly forceRender?: boolean;
|
|
179
|
+
/** Edit a changed item in place instead of replacing it. Default `true`. */
|
|
180
|
+
readonly morph?: boolean;
|
|
181
|
+
/** Reported once per container when two items share a key (`LP0405`). */
|
|
182
|
+
readonly onDuplicateKey?: (container: Element, key: string) => void;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* Returns `true` for a DOM mutation, `false` for an already-current tree, and
|
|
186
|
+
* `null` when an item's markup has no sanitized element root — preflighted
|
|
187
|
+
* before any mutation, so the previous DOM and memory stay intact.
|
|
188
|
+
*/
|
|
189
|
+
declare function applyStructuralPatches(options: StructuralApplyOptions): boolean | null;
|
|
190
|
+
|
|
191
|
+
declare const ISLAND_ATTRIBUTE = "data-payload-island";
|
|
192
|
+
|
|
193
|
+
/**
|
|
194
|
+
* Keyed DOM morph: edits a live element toward a freshly rendered one while
|
|
195
|
+
* keeping the live nodes, and with them focus, selection, scroll, playback and
|
|
196
|
+
* listeners. Custom elements, islands, `contenteditable` and
|
|
197
|
+
* `data-payload-owned` subtrees are boundaries the morph never enters.
|
|
198
|
+
* See ADR 0008.
|
|
199
|
+
*/
|
|
200
|
+
|
|
201
|
+
declare const OWNED_ATTRIBUTE = "data-payload-owned";
|
|
202
|
+
interface MorphOptions {
|
|
203
|
+
/** Attributes that key child elements for pairing, tried in order; unkeyed children pair by position. */
|
|
204
|
+
readonly keyAttributes: readonly string[];
|
|
205
|
+
/** Called once per parent when two children share a key; the later ones pair by position. */
|
|
206
|
+
readonly onDuplicateKey?: (parent: Element, key: string) => void;
|
|
207
|
+
/** Elements whose attributes are synchronised but whose children are left alone (nested structural slots). */
|
|
208
|
+
readonly retainChildrenOf?: (live: Element, rendered: Element) => boolean;
|
|
209
|
+
}
|
|
210
|
+
declare function isMorphBoundary(element: Element): boolean;
|
|
211
|
+
/** Whether `live` can be edited toward `rendered` instead of being replaced by it. */
|
|
212
|
+
declare function isMorphCompatible(live: Element, rendered: Element): boolean;
|
|
213
|
+
/**
|
|
214
|
+
* Morph `live` toward `rendered`. Returns `live` when it was retained, or
|
|
215
|
+
* `rendered` when the two are incompatible and the caller must replace.
|
|
216
|
+
* `rendered` is consumed: its children may move into `live`.
|
|
217
|
+
*/
|
|
218
|
+
declare function morphElement(live: Element, rendered: Element, options: MorphOptions): Element;
|
|
219
|
+
|
|
220
|
+
/**
|
|
221
|
+
* One source → dependents map for `skipUnchanged`. Markup declares it the
|
|
222
|
+
* other way round (`data-payload-depends="price"` on the element bound to
|
|
223
|
+
* `priceLabel`) because an author names what a binding needs; the runtime
|
|
224
|
+
* option is keyed by source because the scheduler asks what changed.
|
|
225
|
+
*/
|
|
226
|
+
type DependencyMap = Readonly<Record<string, readonly string[]>>;
|
|
227
|
+
/**
|
|
228
|
+
* Field names from an attribute value. Separators are commas and
|
|
229
|
+
* whitespace; empty entries are dropped; order is kept, duplicates removed.
|
|
230
|
+
*/
|
|
231
|
+
declare function parseDependencyList(value: string | null | undefined): readonly string[];
|
|
232
|
+
/**
|
|
233
|
+
* Merge dependency maps (source → dependents). Later maps add to earlier
|
|
234
|
+
* ones; a dependent is listed once per source.
|
|
235
|
+
*/
|
|
236
|
+
declare function mergeDependencyMaps(...maps: readonly DependencyMap[]): DependencyMap;
|
|
237
|
+
/**
|
|
238
|
+
* The map an element's `data-payload-depends` contributes: every declared
|
|
239
|
+
* source points at this binding's field.
|
|
240
|
+
*/
|
|
241
|
+
declare function dependencyMapFromBinding(fieldName: string, dependsOn: readonly string[]): DependencyMap;
|
|
242
|
+
|
|
243
|
+
export { type ArrayPatch, type CachedElement, type CustomRendererKey, type DependencyMap, type FieldRenderer, type FieldType, ISLAND_ATTRIBUTE, KEY_ATTRIBUTE, type MorphOptions, OWNED_ATTRIBUTE, type PayloadBlockSchema, type PayloadFieldCondition, type PayloadFieldSchema, type PayloadFieldType, type PayloadLivePreviewData, type RenderContext, type RendererKey, type RichTextRenderer, type StructuralApplyOptions, type StructuralStore, type UpdateSource, applyStructuralPatches, createStructuralArrayRenderer, createStructuralStore, dependencyMapFromBinding, isMorphBoundary, isMorphCompatible, mergeDependencyMaps, morphElement, parseDependencyList };
|
|
@@ -0,0 +1,3 @@
|
|
|
1
|
+
var e,t,n=(e=(...e)=>console.warn(...e),(...t)=>{try{("object"==typeof(n=e(...t))&&null!==n||"function"==typeof n)&&"function"==typeof n.then&&Promise.resolve(n).catch(()=>{})}catch{}var n}),o=/* @__PURE__ */new WeakSet;function r(e){return o.add(e),e}function i(e){const n=function(){if(void 0!==t)return t;const e=function(){const e=globalThis.trustedTypes;if("object"==typeof e&&null!==e)return"function"==typeof e.createPolicy?e:void 0}();if(void 0===e)return t=null,null;try{t=e.createPolicy("payload-live-preview",{createHTML:e=>e})}catch{t=null}return t}();return null===n?e:n.createHTML(e)}var a=/* @__PURE__ */new Set(["http:","https:","mailto:","tel:"]),l=/^\s*(?:javascript|data|vbscript|file|blob|about)\s*:/i,s=/^(?:\.{1,2}\/|[a-zA-Z0-9_-]+\/?)/,u=/^[\\/]{2}/,c=/[\t\n\r]/g;function isSafeUrl(e){if("string"!=typeof e||0===e.length)return!1;const t=e.trim().replace(c,"");if(0===t.length)return!1;if(l.test(t))return!1;if(t.startsWith("#")||t.startsWith("?"))return!0;if(u.test(t))return!0;if(t.startsWith("/"))return!0;try{const e=new URL(t);return a.has(e.protocol)}catch{return s.test(t)}}var f=/* @__PURE__ */new Set(["p","br","strong","b","em","i","u","s","strike","mark","small","h1","h2","h3","h4","h5","h6","ul","ol","li","dl","dt","dd","blockquote","code","pre","kbd","samp","var","a","span","div","section","article","aside","header","footer","nav","figure","figcaption","img","picture","source","audio","video","sub","sup","hr","time","abbr","cite","q","table","thead","tbody","tfoot","tr","th","td","caption","colgroup","col"]),d=/* @__PURE__ */new Set(["input","button","textarea","select","option","label"]),p=/* @__PURE__ */new Set(["script","style","iframe","object","embed","link","meta","base","form","input","button","select","textarea","svg","math","template","frame","frameset","noframes","noscript"]),m=/* @__PURE__ */new Set(["id","class","lang","dir","title","role","tabindex"]),h="aria-",v="data-",g={a:/* @__PURE__ */new Set(["href","target","rel","download","hreflang","type"]),img:/* @__PURE__ */new Set(["src","srcset","sizes","alt","width","height","loading","decoding"]),picture:/* @__PURE__ */new Set([]),source:/* @__PURE__ */new Set(["src","srcset","sizes","type","media"]),audio:/* @__PURE__ */new Set(["src","controls","autoplay","loop","muted","preload"]),video:/* @__PURE__ */new Set(["src","poster","controls","autoplay","loop","muted","preload","width","height","playsinline"]),time:/* @__PURE__ */new Set(["datetime"]),abbr:/* @__PURE__ */new Set(["title"]),q:/* @__PURE__ */new Set(["cite"]),blockquote:/* @__PURE__ */new Set(["cite"]),table:/* @__PURE__ */new Set(["summary"]),th:/* @__PURE__ */new Set(["colspan","rowspan","scope","headers","abbr"]),td:/* @__PURE__ */new Set(["colspan","rowspan","headers"]),col:/* @__PURE__ */new Set(["span"]),colgroup:/* @__PURE__ */new Set(["span"]),ol:/* @__PURE__ */new Set(["start","reversed","type"]),li:/* @__PURE__ */new Set(["value"]),code:/* @__PURE__ */new Set(["class"]),pre:/* @__PURE__ */new Set(["class"])},y=/* @__PURE__ */new Set(["href","src","cite","poster"]),b=class extends Error{name="SanitizerEnvironmentError"},w=/* @__PURE__ */new Set(["id","name","data-payload-key","data-payload-nested-key","data-payload-nested-template"]),S="strict";function A(e,t){for(const n of Array.from(e.childNodes))1===n.nodeType?k(n,t):8===n.nodeType&&n.remove()}function k(e,t){const n=e.tagName.toLowerCase();if(!p.has(n)||t.allowFormControls&&d.has(n)){if(!t.allowedTags.has(n)){A(e,t);const n=e.parentNode;if(n){for(;e.firstChild;)n.insertBefore(e.firstChild,e);e.remove()}return}!function(e,t,n){const o=n.attrByTag.get(t);for(const t of Array.from(e.attributes)){const r=t.name.toLowerCase();if(r.startsWith("on")||"style"===r)e.removeAttribute(t.name);else{if("strict"===n.mode){if(n.templateMode&&w.has(r))continue;if("id"===r||"name"===r||r.startsWith("data-payload-")){e.removeAttribute(t.name);continue}if(r.startsWith(v)){n.allowedData.has(r)||e.removeAttribute(t.name);continue}if(m.has(r)||r.startsWith(h))continue}else if(m.has(r)||r.startsWith(h)||r.startsWith(v))continue;o?.has(r)?y.has(r)&&!isSafeUrl(t.value)?e.removeAttribute(t.name):"srcset"!==r||x(t.value)||e.removeAttribute(t.name):e.removeAttribute(t.name)}}}(e,n,t),"a"===n&&function(e){const t=e.getAttribute("href");null!==t&&function isExternalHttpUrl(e){if(!isSafeUrl(e))return!1;const t=e.trim().replace(c,"");return/^https?:\/\//i.test(t)||u.test(t)}(t)&&(e.setAttribute("rel","noopener noreferrer"),e.hasAttribute("target")||e.setAttribute("target","_blank"))}(e),A(e,t)}else e.remove()}function x(e){for(const t of e.split(",")){const e=t.trim();if(0===e.length)continue;const n=e.search(/\s/);if(!isSafeUrl(-1===n?e:e.slice(0,n)))return!1}return!0}var L=Object.freeze({"&":"&","<":"<",">":">",'"':""","'":"'","/":"/","`":"`","=":"="}),E=/[&<>"'/`=]/g;function escapeHtml(e){return""===e?"":e.replace(E,e=>L[e])}var M=/\{\{([\s\S]*?)\}\}/g;function T(e){if(null==e)return"";if("string"==typeof e)return e;if("number"==typeof e||"boolean"==typeof e||"bigint"==typeof e)return String(e);try{return JSON.stringify(e)}catch{return""}}function N(e){if("object"!=typeof e||null===e)return;const t=e.id;return"string"==typeof t||"number"==typeof t?t:void 0}function _(e){if("object"!=typeof e||null===e)return;const t=e.blockType;return"string"==typeof t?t:void 0}function D(e,t){return t.every(e=>void 0!==N(e))?function(e,t){const n=[],o=/* @__PURE__ */new Map;for(let t=0;t<e.length;t+=1){const n=N(e[t]);void 0!==n&&o.set(n,t)}const r=/* @__PURE__ */new Set;for(let i=0;i<t.length;i+=1){const a=t[i],l=N(a);if(void 0===l){n.push({kind:"insert",index:i,value:a});continue}const s=o.get(l);if(void 0===s){n.push({kind:"insert",index:i,value:a});continue}r.add(s);const u=e[s];_(u)===_(a)?(s!==i&&n.push({kind:"move",from:s,to:i,value:a}),C(u,a)||n.push({kind:"update",index:i,value:a})):n.push({kind:"replace",index:i,oldValue:u,value:a})}for(let t=0;t<e.length;t+=1)r.has(t)||n.push({kind:"remove",index:t,value:e[t]});return n}(e,t):function(e,t){const n=[],o=Math.min(e.length,t.length);for(let r=0;r<o;r+=1)C(e[r],t[r])||n.push({kind:"update",index:r,value:t[r]});if(t.length>e.length)for(let o=e.length;o<t.length;o+=1)n.push({kind:"insert",index:o,value:t[o]});if(e.length>t.length)for(let o=t.length;o<e.length;o+=1)n.push({kind:"remove",index:o,value:e[o]});return n}(e,t)}function C(e,t){if(Object.is(e,t))return!0;if("object"!=typeof e||"object"!=typeof t||null===e||null===t)return!1;const n=e,o=t,r=Object.keys(n),i=Object.keys(o);if(r.length!==i.length)return!1;for(const e of r)if(!Object.is(n[e],o[e]))return!1;return!0}var j="data-payload-island",I="data-payload-owned",O=/* @__PURE__ */new Set(["open","value","checked","selected"]);function W(e,t){for(const n of t.keyAttributes){const t=e.getAttribute(n);if(null!==t&&t.length>0)return`${n}=${t}`}}function H(e){if(e.tagName.toLowerCase().includes("-"))return!0;if(e.hasAttribute(j)||e.hasAttribute(I))return!0;const t=e.getAttribute("contenteditable");return null!==t&&"false"!==t}function U(e,t){return e.tagName===t.tagName&&e.namespaceURI===t.namespaceURI&&!H(e)&&!H(t)}function z(e,t,n){if(!U(e,t))return t;const o=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)||O.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 o=function(e,t){const n=/* @__PURE__ */new Map;let o;for(const r of Array.from(e.children)){const e=W(r,t);void 0!==e&&(n.has(e)?o??=e.slice(e.indexOf("=")+1):n.set(e,r))}return void 0!==o&&t.onDuplicateKey?.(e,o),n}(e,n),r=new Set(o.values()),i=Array.from(e.childNodes).filter(e=>!r.has(e)),a=/* @__PURE__ */new Set,l=/* @__PURE__ */new Set,s=Array.from(t.childNodes);let u=e.firstChild,c=0;for(let t=0;t<s.length;t+=1){const r=s[t];let f=null,d=r instanceof Element?W(r,n):void 0;if(void 0!==d&&l.has(d)&&(d=void 0),void 0!==d){l.add(d);const e=o.get(d);if(void 0!==e&&!a.has(e)&&(f=P(e,r,n)===e?e:null,null===f)){e.replaceWith(r),a.add(r),u=r.nextSibling;continue}}else{for(;c<i.length;){const o=i[c];if(c+=1,!a.has(o)){if(R(o,r)){f=P(o,r,n)===o?o:null,null===f&&(e.replaceChild(r,o),a.add(r),u=r.nextSibling);break}if(o instanceof Element){const n=s[t+1];if(!(r instanceof Element)||void 0!==n&&R(o,n)){c-=1;break}e.replaceChild(r,o),a.add(r),u=r.nextSibling;break}if(!(r instanceof Element)){e.replaceChild(r,o),a.add(r),u=r.nextSibling;break}}}if(null===f&&a.has(r))continue}const p=f??r;for(a.add(p);null!==u&&u!==p&&!a.has(u)&&B(u);)u=u.nextSibling;p!==u&&e.insertBefore(p,u),u=p.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,o]=n??[null,null];null!==e&&null!==o&&t.setSelectionRange(e,o)}catch{}}(o),e}function P(e,t,n){return e instanceof Element&&t instanceof Element?H(e)&&H(t)?e:z(e,t,n):(e.nodeValue!==t.nodeValue&&(e.nodeValue=t.nodeValue),e)}function B(e){return e.nodeType===Node.TEXT_NODE&&0===(e.nodeValue??"").trim().length}function R(e,t){return e.nodeType===t.nodeType&&(!(e instanceof Element&&t instanceof Element)||e.tagName===t.tagName&&e.namespaceURI===t.namespaceURI)}var $=["input","textarea","select","option","button","label","details","summary","dialog","video","audio","progress","meter"],q=["type","name","placeholder","open","disabled","readonly","required","checked","selected","value","min","max","step","rows","cols","for","controls","muted","loop","poster","src"],F=/<([a-z][a-z0-9]*(?:-[a-z0-9]+)+)\b/gi,K=/* @__PURE__ */new Map,V="data-payload-key",G="data-payload-nested-key",J="data-payload-nested-template";function X(){/* @__PURE__ */
|
|
2
|
+
return new WeakMap}function Z(e){const{template:t,container:n,patches:o,nextItems:r,store:i,forceRender:a=!1}=e,l=Y(n,t,o,r,a,i);return null===l?null:ee(l,i,{morph:e.morph??!0,onDuplicateKey:e.onDuplicateKey})}function Q(e,t){return t.hasAttribute(G)&&t.hasAttribute(J)}function Y(e,t,n,o,r,i){const a=function(e,t,n,o,r,i,a){const l=Array.from(e.children),s=le(l,V),u=/* @__PURE__ */new Set,c=[];for(let f=0;f<n.length;f+=1){const d=n[f],p=ae(d);let m=void 0===p?l[f]??null:se(s,p)??null;null!==m&&u.has(m)&&(m=null),null!==m&&u.add(m);const h=o.replaces.has(f),v=r||o.renders.has(f)||null===m?ue(e.ownerDocument,t,d,f):void 0;if(null===v)return null;const g=void 0===v?[]:te(h?null:m,v,d,i,a);if(null===g)return null;c.push([f,m,v??void 0,g,h])}return c}(e,t,o,function(e){const t=/* @__PURE__ */new Set,n=/* @__PURE__ */new Set;for(const o of e)"insert"===o.kind||"update"===o.kind?t.add(o.index):"replace"===o.kind&&(t.add(o.index),n.add(o.index));return{renders:t,replaces:n}}(n),r,i.get(e),i);return null===a?null:[e,a,o]}function ee(e,t,n){const[o,r,i]=e,a=/* @__PURE__ */new Set;let l=!1;for(const[e,i,s,u,c]of r){let r=i;if(void 0!==s){const e=!(!n.morph||c||null===i)&&z(i,s,{keyAttributes:[V,G],retainChildrenOf:Q,...void 0!==n.onDuplicateKey?{onDuplicateKey:n.onDuplicateKey}:{}})===i;if(!e)for(const[e,t]of u)null!==e&&(oe(e,t),t.replaceWith(e));for(const[,,e]of u)void 0!==e&&ee(e,t,n);e?l=!0:(null!==i&&(i.replaceWith(s),l=!0),r=s)}if(null===r)continue;const f=o.children[e]??null;r!==f&&(o.insertBefore(r,f),l=!0),a.add(r)}for(const e of Array.from(o.children))a.has(e)||(e.remove(),l=!0);const s=function(e,t){let n=t.get(e);return n||(n=/* @__PURE__ */new Map,t.set(e,n)),n}(o,t);s.clear();for(const e of i)ie(s,e);return l}function te(e,t,n,o,r){const i=le(null===e?[]:ne(e),G),a=ae(n),l=void 0!==a?o?.get(a):void 0,s=[];for(const e of ne(t)){const t=e.getAttribute(G);if(null===t)continue;const o=se(i,t)??null,a=e.getAttribute(J),u=a?o:null,c=u?.getAttribute(J)??null;let f;if(a){const o=re(n,t);if(void 0!==o||null!==u){const n=o??[],i=D(null===u?[]:re(l,t)??[],n),s=null!==u&&c!==a;if((i.length>0||s)&&(f=Y(u??e,a,i,n,s,r)??void 0,void 0===f))return null}}s.push([u,e,f])}return s}function ne(e){return Array.from(e.querySelectorAll(`[${G}]`)).filter(t=>{let n=t.parentElement;for(;null!==n&&n!==e;){if(n.hasAttribute(G))return!1;n=n.parentElement}return n===e})}function oe(e,t){for(const n of Array.from(e.attributes))t.hasAttribute(n.name)||e.removeAttribute(n.name);for(const n of Array.from(t.attributes))e.getAttribute(n.name)!==n.value&&e.setAttribute(n.name,n.value)}function re(e,t){if("object"!=typeof e||null===e)return;const n=e[t];return Array.isArray(n)?n:void 0}function ie(e,t){const n=ae(t);void 0!==n&&e.set(n,t)}function ae(e){if("object"!=typeof e||null===e)return;const t=e.id;return"string"==typeof t||"number"==typeof t?String(t):void 0}function le(e,t){const n=/* @__PURE__ */new Map;for(let o=e.length-1;o>=0;o-=1){const r=e[o];if(void 0===r)continue;const i=r.getAttribute(t);if(null===i)continue;const a=n.get(i);void 0===a?n.set(i,[r]):a.push(r)}return n}function se(e,t){return e.get(t)?.pop()}function ue(e,t,n,o){const r=function sanitizeHtml(e,t){const n=("undefined"==typeof __INLINE_BUILD__||__INLINE_BUILD__,"undefined"==typeof document?void 0:document);if(!n)throw"undefined"!=typeof __INLINE_BUILD__&&__INLINE_BUILD__?new Error("sanitizeHtml needs a DOM"):new b("sanitizeHtml needs a DOM; provide one with setSanitizerDocument() during SSR.");if(""===e)return"";const o=function(e){if(!e){const e=/* @__PURE__ */new Map;for(const[t,n]of Object.entries(g))e.set(t,n);return{allowedTags:f,attrByTag:e,allowFormControls:!1,templateMode:!1,mode:S,allowedData:/* @__PURE__ */new Set}}const t=new Set(f);for(const n of e.additionalAllowedTags??[])t.add(n);if(!0===e.allowFormControls)for(const e of d)t.add(e);const n=/* @__PURE__ */new Map;for(const[e,t]of Object.entries(g))n.set(e,t);for(const[t,o]of Object.entries(e.additionalAllowedAttributes??{})){const e=n.get(t),r=new Set(e??[]);for(const e of o)r.add(e);n.set(t,r)}return{allowedTags:t,attrByTag:n,allowFormControls:!0===e.allowFormControls,templateMode:!0===e.templateMode,mode:e.policy??S,allowedData:new Set((e.allowedDataAttributes??[]).map(e=>e.toLowerCase()))}}(t),r=n.createElement("template");return r.innerHTML=i(e),A(r.content,o),r.innerHTML}(function(e,t,n,o){const r="object"==typeof t&&null!==t?t:null;return e.replace(M,(e,i)=>null!==r&&function(e,t){return Object.prototype.hasOwnProperty.call(e,t)}(r,i)?escapeHtml(o(Reflect.get(r,i))):null===r&&"value"===i?escapeHtml(o(t)):"index"===i?String(n):e)}(t,n,o,T),function(e){const t=K.get(e);if(void 0!==t)return t;const n=new Set($);for(const t of e.matchAll(F)){const e=t[1]?.toLowerCase();void 0!==e&&n.add(e)}const o={};for(const e of n)o[e]=q;const r={additionalAllowedTags:[...n],additionalAllowedAttributes:o,allowFormControls:!0,templateMode:!0};return K.set(e,r),r}(t)),a=e.createElement("template");a.innerHTML=i(r);const l=a.content.firstElementChild;if(!l)return null;const s=ae(n);return void 0!==s&&l.setAttribute(V,s),l}function ce(){const e=/* @__PURE__ */new WeakMap,t=/* @__PURE__ */new WeakSet,o=/* @__PURE__ */new WeakMap,i=X();return{name:"structural-array",render:/* @__PURE__ */r((r,a)=>{const l=function(e){return null==e||""===e}(a)?[]:a;if(!Array.isArray(l))return!1;const s=r.element,u=r.arrayTemplate;if(void 0===u||0===u.length)return function(e,t,o){e.has(t)||(e.add(t),n(`[live-preview] LP0403: Skipping structural update for "${o}": <${t.tagName.toLowerCase()} data-payload-structural> needs data-payload-array-template (for example "<li>{{label}}</li>").`))}(t,s,r.fieldName),!1;const c=e.get(s),f=fe(s),d=D(c?.values??f.map((e,t)=>null===e?{__payloadDomPosition:t}:{id:e}),l),p=function(e,t,n){return void 0===e||e.template!==t||!function(e,t){return e.length===t.length&&e.every((e,n)=>e===t[n])}(e.domSnapshot,n)}(c,u,f);if(0===d.length&&!p)return e.set(s,{values:l.slice(),template:u,domSnapshot:f}),!1;!function(e,t,n,o,r){const i=r.map(de),a=/* @__PURE__ */new Set,l=i.find(e=>!(void 0===e||!a.has(e)&&(a.add(e),1)));if(void 0!==l&&pe(e,t,n,l),i.some(e=>void 0===e)&&me(e,t,"LP0404",`LP0404: an item of "${n}" has no id and pairs by position, so an insert re-renders every row after it. Give items a stable id.`),o?.length===r.length&&r.length>1){const r=new Set(o.map(de).filter(e=>void 0!==e)),a=i.some(e=>void 0!==e&&r.has(e));r.size>0&&!a&&me(e,t,"LP0406",`LP0406: every key of "${n}" changed at once; the source generates ids per message, so no item can be retained across updates.`)}}(o,s,r.fieldName,c?.values,l);const m=Z({template:u,container:s,patches:d,nextItems:l,store:i,forceRender:p,onDuplicateKey:(e,t)=>{pe(o,e,r.fieldName,t)}});return null!==m&&(e.set(s,{values:l.slice(),template:u,domSnapshot:fe(s)}),!!m&&void 0)})}}function fe(e){return Array.from(e.children,e=>e.getAttribute(V))}function de(e){if("object"!=typeof e||null===e)return;const t=e.id;return"string"==typeof t||"number"==typeof t?String(t):void 0}function pe(e,t,n,o){me(e,t,"LP0405",`LP0405: two items of "${n}" share the key "${o}"; later ones pair by position. Make \`id\` unique per item.`)}function me(e,t,o,r){let i=e.get(t);void 0===i&&(i=/* @__PURE__ */new Set,e.set(t,i)),i.has(o)||(i.add(o),n(`[live-preview] ${r}`))}function he(e){if(null==e)return[];const t=/* @__PURE__ */new Set,n=[];for(const o of e.split(/[\s,]+/)){const e=o.trim();0===e.length||t.has(e)||(t.add(e),n.push(e))}return n}function ve(...e){const t=/* @__PURE__ */new Map;for(const n of e)for(const[e,o]of Object.entries(n)){let n=t.get(e);void 0===n&&(n=/* @__PURE__ */new Set,t.set(e,n));for(const e of o)n.add(e)}const n={};for(const[e,o]of t)n[e]=[...o];return n}function ge(e,t){const n={};for(const o of t)o!==e&&(n[o]=[e]);return n}export{j as ISLAND_ATTRIBUTE,V as KEY_ATTRIBUTE,I as OWNED_ATTRIBUTE,Z as applyStructuralPatches,ce as createStructuralArrayRenderer,X as createStructuralStore,ge as dependencyMapFromBinding,H as isMorphBoundary,U as isMorphCompatible,ve as mergeDependencyMaps,z as morphElement,he as parseDependencyList};
|
|
3
|
+
//# sourceMappingURL=structural.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"structural.js","names":["diagnostic","autoPolicy","safeConsoleWarn","args","console","warn","value","then","Promise","resolve","catch","noWriteCallbacks","WeakSet","markNoWriteCallback","callback","add","trustedHtml","html","policy","api","candidate","globalThis","trustedTypes","createPolicy","factory","createHTML","input","resolvePolicy","SAFE_PROTOCOLS","Set","DANGEROUS_PROTOCOL_PATTERN","RELATIVE_PATH","PROTOCOL_RELATIVE","PARSER_IGNORED","isSafeUrl","url","length","trimmed","trim","replace","test","startsWith","parsed","URL","has","protocol","ALLOWED_TAGS","FORM_CONTROLS","REMOVE_COMPLETELY","ATTR_GLOBAL","ATTR_ARIA_PREFIX","ATTR_DATA_PREFIX","ATTR_BY_TAG","a","img","picture","source","audio","video","time","abbr","q","blockquote","table","th","td","col","colgroup","ol","li","code","pre","URL_ATTRIBUTES","SanitizerEnvironmentError","Error","name","TEMPLATE_ATTRIBUTES","defaultMode","sanitizeFragment","node","child","Array","from","childNodes","nodeType","sanitizeElement","remove","element","tag","tagName","toLowerCase","allowFormControls","allowedTags","parent","parentNode","firstChild","insertBefore","tagAttrs","attrByTag","get","attr","attributes","removeAttribute","mode","templateMode","allowedData","isSafeSrcset","sanitizeAttributes","anchor","href","getAttribute","isExternalHttpUrl","setAttribute","hasAttribute","hardenAnchor","split","descriptorStart","search","slice","HTML_ESCAPES","Object","freeze","HTML_ESCAPE_PATTERN","escapeHtml","text","char","PLACEHOLDER_PATTERN","safeStringify","String","JSON","stringify","getId","item","id","getBlockType","blockType","diffArray","prev","next","every","patches","prevIndexById","Map","i","set","consumedFromPrev","to","push","kind","index","prevItem","shallowEqual","oldValue","diffById","min","Math","diffByPosition","b","is","aRec","bRec","aKeys","keys","bKeys","key","ISLAND_ATTRIBUTE","OWNED_ATTRIBUTE","STATE_ATTRIBUTES","keyOf","options","attribute","keyAttributes","isMorphBoundary","includes","editable","isMorphCompatible","live","rendered","namespaceURI","morphElement","focus","active","ownerDocument","activeElement","HTMLElement","contains","selection","HTMLInputElement","HTMLTextAreaElement","selectionStart","selectionEnd","captureFocus","syncAttributes","retainChildrenOf","liveKeyed","keyed","duplicate","children","indexOf","onDuplicateKey","indexKeyed","keyedElements","values","liveUnkeyed","filter","claimed","usedKeys","renderedNodes","cursor","unkeyedIndex","kept","Element","reconcile","replaceWith","nextSibling","sameKind","replaceChild","following","isBlankText","morphChildren","snapshot","isConnected","preventScroll","start","end","setSelectionRange","restoreFocus","nodeValue","Node","TEXT_NODE","TEMPLATE_EXTRA_TAGS","TEMPLATE_EXTRA_ATTRIBUTES","CUSTOM_TAG_PATTERN","optionsByTemplate","KEY_ATTRIBUTE","NESTED_KEY_ATTRIBUTE","NESTED_TEMPLATE_ATTRIBUTE","createStructuralStore","WeakMap","applyStructuralPatches","template","container","nextItems","store","forceRender","plan","prepareStructuralPlan","commitStructuralPlan","morph","isManagedNestedSlot","_live","entries","memory","initialChildren","keyedChildren","indexByAttribute","reserved","readKey","takeIndexedElement","replaces","renders","renderItem","nestedSlots","prepareNestedSlots","prepareReconciliation","patch","createPatchPlan","mutated","retained","liveSlot","renderedSlot","synchronizeAttributes","before","map","getMemory","clear","rememberItem","oldItem","newItem","nextValue","oldSlotsByKey","findDirectNestedSlots","itemKey","prevValue","plans","newSlot","oldSlot","nextTemplate","previousTemplate","nextNested","readNestedArray","resolvedNext","templateChanged","querySelectorAll","slot","ancestor","parentElement","target","nested","isArray","elements","indexed","bucket","pop","safe","sanitizeHtml","doc","__INLINE_BUILD__","document","attrMap","attrs","allowed","additionalAllowedTags","additionalAllowedAttributes","existing","merged","allowedDataAttributes","createElement","innerHTML","content","record","placeholder","prototype","hasOwnProperty","call","hasOwn","Reflect","interpolateArrayTemplate","cached","tags","match","matchAll","templateSanitizeOptions","host","first","firstElementChild","createStructuralArrayRenderer","states","warnedContainers","warnedKeys","render","rawValue","isEmptyValue","arrayTemplate","fieldName","warnMissingTemplate","previousState","domSnapshot","readDomKeySnapshot","position","__payloadDomPosition","previous","current","sameDomKeySnapshot","needsForcedRender","warned","nextKeys","seen","find","warnDuplicateKey","some","warnOnce","previousKeys","stable","size","warnAboutKeys","applied","owner","message","codes","parseDependencyList","names","raw","mergeDependencyMaps","maps","dependents","dependent","result","dependencyMapFromBinding","dependsOn"],"sources":["../src/core/diagnostics.ts","../src/security/trusted-types.ts","../src/core/thenable.ts","../src/core/internal-outcome.ts","../src/security/url-validator.ts","../src/security/sanitizer.ts","../src/security/escape.ts","../src/core/array-template.ts","../src/field-types/utils.ts","../src/schema/diff.ts","../src/core/islands.ts","../src/core/morph.ts","../src/core/template-sanitize.ts","../src/core/structural-applier.ts","../src/field-types/structural-array.ts","../src/core/dependencies.ts"],"sourcesContent":["import { observeThenableResult } from './thenable';\n\n/**\n * Diagnostics are observability, never control flow: a consumer logger may\n * throw or return a rejected thenable, and reporting a failure must not become\n * a second failure. Invocation stays synchronous for ordinary loggers.\n */\nexport function isolateDiagnostic(\n diagnostic: (...args: unknown[]) => unknown,\n): (...args: unknown[]) => void {\n return (...args): void => {\n try {\n observeThenableResult(diagnostic(...args));\n } catch {\n // Diagnostics must not become a second failure boundary.\n }\n };\n}\n\n/** Shared allocation-free default for disabled diagnostic channels. */\nexport function noopDiagnostic(): void {\n // Intentionally empty.\n}\n\n// Access, invocation and thenable inspection all happen inside the wrapper, so\n// a missing or hostile console cannot escape.\nexport const safeConsoleError = isolateDiagnostic((...args) =>\n (console.error as (...values: unknown[]) => unknown)(...args),\n);\n\nexport const safeConsoleWarn = isolateDiagnostic((...args) =>\n (console.warn as (...values: unknown[]) => unknown)(...args),\n);\n\nexport const safeConsoleDebug = isolateDiagnostic((...args) =>\n // eslint-disable-next-line no-console -- best-effort development diagnostics\n (console.debug as (...values: unknown[]) => unknown)(...args),\n);\n","/**\n * Trusted Types: every HTML sink routes through one policy, `payload-live-preview`,\n * whose `createHTML` is the identity — what reaches a sink is already sanitized\n * or escaped. Without the API, strings pass through untouched.\n */\n\n/** The subset of the Trusted Types API this module needs. */\nexport interface TrustedHtmlPolicyLike {\n createHTML(input: string): unknown;\n}\n\ninterface TrustedTypesFactoryLike {\n createPolicy(\n name: string,\n rules: { createHTML: (input: string) => string },\n ): TrustedHtmlPolicyLike;\n}\n\nexport const TRUSTED_TYPES_POLICY_NAME = 'payload-live-preview';\n\nlet policyOverride: TrustedHtmlPolicyLike | null | undefined;\nlet autoPolicy: TrustedHtmlPolicyLike | null | undefined;\n\n/**\n * Use `policy` for every sink, `null` to assign plain strings, `undefined` to\n * return to the auto-created package policy.\n */\nexport function setTrustedTypesPolicy(policy: TrustedHtmlPolicyLike | null | undefined): void {\n policyOverride = policy;\n}\n\nfunction factory(): TrustedTypesFactoryLike | undefined {\n const candidate = (globalThis as { trustedTypes?: unknown }).trustedTypes;\n if (typeof candidate !== 'object' || candidate === null) return undefined;\n const create = (candidate as { createPolicy?: unknown }).createPolicy;\n return typeof create === 'function' ? (candidate as TrustedTypesFactoryLike) : undefined;\n}\n\nfunction resolvePolicy(): TrustedHtmlPolicyLike | null {\n if (policyOverride !== undefined) return policyOverride;\n if (autoPolicy !== undefined) return autoPolicy;\n const api = factory();\n if (api === undefined) {\n autoPolicy = null;\n return null;\n }\n try {\n autoPolicy = api.createPolicy(TRUSTED_TYPES_POLICY_NAME, { createHTML: (input) => input });\n } catch {\n // The site's `trusted-types` directive does not list this name; the\n // sink assignment will surface the enforcement error.\n autoPolicy = null;\n }\n return autoPolicy;\n}\n\n/** `html` as a `TrustedHTML` when a policy exists, else the string. Typed `string` for `innerHTML`. */\nexport function trustedHtml(html: string): string {\n const policy = resolvePolicy();\n if (policy === null) return html;\n return policy.createHTML(html) as string;\n}\n\n/** Test hook: forget the auto-created policy. */\nexport function __resetTrustedTypesForTests(): void {\n policyOverride = undefined;\n autoPolicy = undefined;\n}\n","/**\n * Detect an invalid async result in a synchronous extension point.\n *\n * Rejected native Promises otherwise become unhandled after the caller falls\n * back synchronously. Assimilating the result through a handled Promise keeps\n * that contract violation observable only through the runtime's explicit\n * error channel.\n */\nexport function observeThenableResult(value: unknown): boolean {\n if ((typeof value !== 'object' || value === null) && typeof value !== 'function') return false;\n if (typeof (value as { readonly then?: unknown }).then !== 'function') return false;\n void Promise.resolve(value).catch(() => undefined);\n return true;\n}\n","/**\n * Public renderer callbacks return `void`, but a JavaScript implementation may\n * return anything. Only callbacks marked here may reserve exact `false` as\n * \"no write\", so a custom renderer's incidental boolean cannot change the\n * lifecycle's applied counts.\n */\n\ntype Callback = (...args: never[]) => unknown;\n\nconst noWriteCallbacks = new WeakSet<Callback>();\n\n/** Mark a package-owned callback whose exact `false` return means no write. */\nexport function markNoWriteCallback<T extends Callback>(callback: T): T {\n noWriteCallbacks.add(callback);\n return callback;\n}\n\n/** Whether `callback` owns the internal exact-false sentinel contract. */\nexport function usesNoWriteOutcome(callback: Callback): boolean {\n return noWriteCallbacks.has(callback);\n}\n\n/** Check a renderer object without detaching its public method at the call site. */\nexport function rendererUsesNoWriteOutcome(renderer: { readonly render: Callback }): boolean {\n return noWriteCallbacks.has(renderer.render);\n}\n","/**\n * URL safety: the one scheme allow-list the runtime, the client and the\n * sanitizer share. Empty strings are not safe (`<a href=\"\">` is never emitted).\n */\n\nconst SAFE_PROTOCOLS: ReadonlySet<string> = new Set(['http:', 'https:', 'mailto:', 'tel:']);\n\n// Browsers strip leading whitespace before scheme detection.\nconst DANGEROUS_PROTOCOL_PATTERN = /^\\s*(?:javascript|data|vbscript|file|blob|about)\\s*:/i;\n\nconst RELATIVE_PATH = /^(?:\\.{1,2}\\/|[a-zA-Z0-9_-]+\\/?)/;\n\n// The URL parser treats `\\` as `/` for special schemes, so `/\\evil.com`\n// resolves to another origin rather than to a same-origin path.\nconst PROTOCOL_RELATIVE = /^[\\\\/]{2}/;\n\n/** The URL parser drops these anywhere in the input before it looks at anything. */\nconst PARSER_IGNORED = /[\\t\\n\\r]/g;\n\n/** `true` only for absolute `http`/`https`/`mailto`/`tel` URLs, protocol-relative URLs, paths, `#`/`?` fragments and relative paths. */\nexport function isSafeUrl(url: unknown): boolean {\n if (typeof url !== 'string' || url.length === 0) return false;\n const trimmed = url.trim().replace(PARSER_IGNORED, '');\n if (trimmed.length === 0) return false;\n if (DANGEROUS_PROTOCOL_PATTERN.test(trimmed)) return false;\n if (trimmed.startsWith('#') || trimmed.startsWith('?')) return true;\n if (PROTOCOL_RELATIVE.test(trimmed)) return true;\n if (trimmed.startsWith('/')) return true;\n try {\n const parsed = new URL(trimmed);\n return SAFE_PROTOCOLS.has(parsed.protocol);\n } catch {\n return RELATIVE_PATH.test(trimmed);\n }\n}\n\n/** Whether a safe URL points at another HTTP(S) origin, protocol-relative forms included, and so needs `noopener` hardening. */\nexport function isExternalHttpUrl(url: string): boolean {\n if (!isSafeUrl(url)) return false;\n const trimmed = url.trim().replace(PARSER_IGNORED, '');\n return /^https?:\\/\\//i.test(trimmed) || PROTOCOL_RELATIVE.test(trimmed);\n}\n\n/** The safe scheme set, for tests and introspection. */\nexport const SAFE_URL_PROTOCOLS: ReadonlySet<string> = SAFE_PROTOCOLS;\n","/**\n * HTML sanitizer built on the host parser (`<template>`): allow-listed tags\n * and attributes, validated URLs, hardened external links, no `style`.\n * Needs a DOM; string-only sanitizers are historically brittle.\n */\n\nimport { trustedHtml } from './trusted-types';\nimport { isSafeUrl, isExternalHttpUrl } from './url-validator';\n\ndeclare const __INLINE_BUILD__: boolean | undefined;\n\n/** Tags kept with their content. Others are unwrapped unless in `REMOVE_COMPLETELY`. */\nconst ALLOWED_TAGS: ReadonlySet<string> = new Set([\n 'p',\n 'br',\n 'strong',\n 'b',\n 'em',\n 'i',\n 'u',\n 's',\n 'strike',\n 'mark',\n 'small',\n 'h1',\n 'h2',\n 'h3',\n 'h4',\n 'h5',\n 'h6',\n 'ul',\n 'ol',\n 'li',\n 'dl',\n 'dt',\n 'dd',\n 'blockquote',\n 'code',\n 'pre',\n 'kbd',\n 'samp',\n 'var',\n 'a',\n 'span',\n 'div',\n 'section',\n 'article',\n 'aside',\n 'header',\n 'footer',\n 'nav',\n 'figure',\n 'figcaption',\n 'img',\n 'picture',\n 'source',\n 'audio',\n 'video',\n 'sub',\n 'sup',\n 'hr',\n 'time',\n 'abbr',\n 'cite',\n 'q',\n 'table',\n 'thead',\n 'tbody',\n 'tfoot',\n 'tr',\n 'th',\n 'td',\n 'caption',\n 'colgroup',\n 'col',\n]);\n\n/** Tags `allowFormControls` re-admits for author templates; `form` is deliberately not one. */\nconst FORM_CONTROLS: ReadonlySet<string> = new Set([\n 'input',\n 'button',\n 'textarea',\n 'select',\n 'option',\n 'label',\n]);\n\n/** Removed with their children: the content itself is the hazard. */\nconst REMOVE_COMPLETELY: ReadonlySet<string> = new Set([\n 'script',\n 'style',\n 'iframe',\n 'object',\n 'embed',\n 'link',\n 'meta',\n 'base',\n 'form',\n 'input',\n 'button',\n 'select',\n 'textarea',\n 'svg',\n 'math',\n 'template',\n 'frame',\n 'frameset',\n 'noframes',\n 'noscript',\n]);\n\nconst ATTR_GLOBAL: ReadonlySet<string> = new Set([\n 'id',\n 'class',\n 'lang',\n 'dir',\n 'title',\n 'role',\n 'tabindex',\n]);\n\nconst ATTR_ARIA_PREFIX = 'aria-';\nconst ATTR_DATA_PREFIX = 'data-';\nconst BINDING_DATA_PREFIX = 'data-payload-';\n\nconst ATTR_BY_TAG: Readonly<Record<string, ReadonlySet<string>>> = {\n a: new Set(['href', 'target', 'rel', 'download', 'hreflang', 'type']),\n img: new Set(['src', 'srcset', 'sizes', 'alt', 'width', 'height', 'loading', 'decoding']),\n picture: new Set([]),\n source: new Set(['src', 'srcset', 'sizes', 'type', 'media']),\n audio: new Set(['src', 'controls', 'autoplay', 'loop', 'muted', 'preload']),\n video: new Set([\n 'src',\n 'poster',\n 'controls',\n 'autoplay',\n 'loop',\n 'muted',\n 'preload',\n 'width',\n 'height',\n 'playsinline',\n ]),\n time: new Set(['datetime']),\n abbr: new Set(['title']),\n q: new Set(['cite']),\n blockquote: new Set(['cite']),\n table: new Set(['summary']),\n th: new Set(['colspan', 'rowspan', 'scope', 'headers', 'abbr']),\n td: new Set(['colspan', 'rowspan', 'headers']),\n col: new Set(['span']),\n colgroup: new Set(['span']),\n ol: new Set(['start', 'reversed', 'type']),\n li: new Set(['value']),\n code: new Set(['class']),\n pre: new Set(['class']),\n};\n\nconst URL_ATTRIBUTES: ReadonlySet<string> = new Set(['href', 'src', 'cite', 'poster']);\n\n// Numeric nodeType constants keep an injected SSR document independent of a\n// browser-global `Node` constructor.\nconst ELEMENT_NODE = 1;\nconst COMMENT_NODE = 8;\n\n/** Thrown by `sanitizeHtml()` when no `document` is available (SSR without `setSanitizerDocument()`). */\nexport class SanitizerEnvironmentError extends Error {\n override readonly name = 'SanitizerEnvironmentError';\n}\n\n/**\n * `'strict'` (default) strips `id`, `name` and `data-payload-*` and passes\n * other `data-*` only via `allowedDataAttributes`; `'compat'` keeps them.\n */\nexport type SanitizerPolicyMode = 'compat' | 'strict';\n\nexport interface SanitizeOptions {\n /** Overrides the module default set by `setSanitizerPolicy()`. */\n readonly policy?: SanitizerPolicyMode;\n /** `data-*` attributes (full names) that pass under `'strict'`; `data-payload-*` never does. */\n readonly allowedDataAttributes?: readonly string[];\n /**\n * Keep `input`, `button`, `textarea`, `select`, `option` and `label` — only\n * for markup the page author wrote, never for CMS content. `form`,\n * handlers, `style` and unsafe URLs stay dropped.\n */\n readonly allowFormControls?: boolean;\n /** Extra tags to allow. Lower-case, untrimmed. */\n readonly additionalAllowedTags?: readonly string[];\n /**\n * Extra per-tag attributes, lower-case. Cannot re-admit handlers, `style`,\n * or — under `'strict'` — `id`, `name` and `data-payload-*`.\n */\n readonly additionalAllowedAttributes?: Readonly<Record<string, readonly string[]>>;\n /**\n * The input is a page-author item template, so `'strict'` keeps the\n * applier's reconciliation attributes (`TEMPLATE_ATTRIBUTES`) and nothing\n * else — every other `data-payload-*` is still stripped, so a template can\n * never add a binding.\n */\n readonly templateMode?: boolean;\n}\n\n/** What `templateMode` keeps under `'strict'`. */\nconst TEMPLATE_ATTRIBUTES: ReadonlySet<string> = new Set([\n 'id',\n 'name',\n 'data-payload-key',\n 'data-payload-nested-key',\n 'data-payload-nested-template',\n]);\n\ninterface ResolvedPolicy {\n readonly allowedTags: ReadonlySet<string>;\n readonly allowFormControls: boolean;\n readonly templateMode: boolean;\n readonly mode: SanitizerPolicyMode;\n readonly allowedData: ReadonlySet<string>;\n readonly attrByTag: ReadonlyMap<string, ReadonlySet<string>>;\n}\n\nlet defaultMode: SanitizerPolicyMode = 'strict';\n\n/** Set the policy for calls without an explicit `policy`. The runtime sets it from `sanitizerPolicy`. */\nexport function setSanitizerPolicy(mode: SanitizerPolicyMode): void {\n defaultMode = mode;\n}\n\nfunction resolvePolicy(options: SanitizeOptions | undefined): ResolvedPolicy {\n if (!options) {\n const attrMap = new Map<string, ReadonlySet<string>>();\n for (const [tag, attrs] of Object.entries(ATTR_BY_TAG)) attrMap.set(tag, attrs);\n return {\n allowedTags: ALLOWED_TAGS,\n attrByTag: attrMap,\n allowFormControls: false,\n templateMode: false,\n mode: defaultMode,\n allowedData: new Set(),\n };\n }\n const allowed = new Set(ALLOWED_TAGS);\n for (const tag of options.additionalAllowedTags ?? []) allowed.add(tag);\n if (options.allowFormControls === true) for (const tag of FORM_CONTROLS) allowed.add(tag);\n const attrMap = new Map<string, ReadonlySet<string>>();\n for (const [tag, attrs] of Object.entries(ATTR_BY_TAG)) attrMap.set(tag, attrs);\n for (const [tag, attrs] of Object.entries(options.additionalAllowedAttributes ?? {})) {\n const existing = attrMap.get(tag);\n const merged = new Set(existing ?? []);\n for (const attr of attrs) merged.add(attr);\n attrMap.set(tag, merged);\n }\n return {\n allowedTags: allowed,\n attrByTag: attrMap,\n allowFormControls: options.allowFormControls === true,\n templateMode: options.templateMode === true,\n mode: options.policy ?? defaultMode,\n allowedData: new Set((options.allowedDataAttributes ?? []).map((name) => name.toLowerCase())),\n };\n}\n\n/** The `Document` surface the sanitizer needs; jsdom, linkedom and happy-dom all provide it. */\nexport interface SanitizerDocument {\n createElement: (tagName: string) => {\n innerHTML: string;\n readonly content: ParentNode;\n };\n}\n\nlet documentOverride: SanitizerDocument | undefined;\n\n/** Supply a `Document` for SSR, e.g. linkedom's `parseHTML(...).document`; `null` clears it. */\nexport function setSanitizerDocument(doc: SanitizerDocument | null): void {\n documentOverride = doc ?? undefined;\n}\n\n/**\n * Sanitize `html`; malformed input is recovered by the parser first.\n *\n * @throws {SanitizerEnvironmentError} when no DOM is available.\n */\nexport function sanitizeHtml(html: string, options?: SanitizeOptions): string {\n const doc = resolveDocument();\n if (!doc) throw environmentError();\n if (html === '') return '';\n\n const policy = resolvePolicy(options);\n const template = doc.createElement('template');\n // The sanitizer's own parse is a sink too: under Trusted Types it needs the policy.\n template.innerHTML = trustedHtml(html);\n sanitizeFragment(template.content, policy);\n return template.innerHTML;\n}\n\n// Read the define at each branch rather than through a helper: a bundler\n// folds the substituted literal in place, but will not inline a call, and the\n// SSR-only class and override must not reach the browser runtime.\nfunction environmentError(): Error {\n if (typeof __INLINE_BUILD__ !== 'undefined' && __INLINE_BUILD__) {\n return new Error('sanitizeHtml needs a DOM');\n }\n return new SanitizerEnvironmentError(\n 'sanitizeHtml needs a DOM; provide one with setSanitizerDocument() during SSR.',\n );\n}\n\nfunction resolveDocument(): SanitizerDocument | undefined {\n if (typeof __INLINE_BUILD__ === 'undefined' || !__INLINE_BUILD__) {\n if (documentOverride) return documentOverride;\n }\n if (typeof document === 'undefined') return undefined;\n return document;\n}\n\n/** Whether a DOM is available — the global or an injected one — for callers that treat sanitizing as optional. */\nexport function hasSanitizerDocument(): boolean {\n return resolveDocument() !== undefined;\n}\n\nfunction sanitizeFragment(node: ParentNode, policy: ResolvedPolicy): void {\n // Snapshot: children are mutated during the walk.\n for (const child of Array.from(node.childNodes)) {\n if (child.nodeType === ELEMENT_NODE) {\n sanitizeElement(child as Element, policy);\n } else if (child.nodeType === COMMENT_NODE) {\n child.remove();\n }\n }\n}\n\nfunction sanitizeElement(element: Element, policy: ResolvedPolicy): void {\n const tag = element.tagName.toLowerCase();\n\n if (REMOVE_COMPLETELY.has(tag) && !(policy.allowFormControls && FORM_CONTROLS.has(tag))) {\n element.remove();\n return;\n }\n\n if (!policy.allowedTags.has(tag)) {\n sanitizeFragment(element, policy);\n const parent = element.parentNode;\n if (parent) {\n while (element.firstChild) parent.insertBefore(element.firstChild, element);\n element.remove();\n }\n return;\n }\n\n sanitizeAttributes(element, tag, policy);\n if (tag === 'a') hardenAnchor(element);\n sanitizeFragment(element, policy);\n}\n\nfunction sanitizeAttributes(element: Element, tag: string, policy: ResolvedPolicy): void {\n const tagAttrs = policy.attrByTag.get(tag);\n\n for (const attr of Array.from(element.attributes)) {\n const name = attr.name.toLowerCase();\n if (name.startsWith('on') || name === 'style') {\n element.removeAttribute(attr.name);\n continue;\n }\n if (policy.mode === 'strict') {\n if (policy.templateMode && TEMPLATE_ATTRIBUTES.has(name)) continue;\n // DOM clobbering and binding injection (docs/security.md §5c). Checked\n // before the allow-list so an extension cannot re-admit them.\n if (name === 'id' || name === 'name' || name.startsWith(BINDING_DATA_PREFIX)) {\n element.removeAttribute(attr.name);\n continue;\n }\n if (name.startsWith(ATTR_DATA_PREFIX)) {\n if (!policy.allowedData.has(name)) element.removeAttribute(attr.name);\n continue;\n }\n if (ATTR_GLOBAL.has(name) || name.startsWith(ATTR_ARIA_PREFIX)) continue;\n } else if (\n ATTR_GLOBAL.has(name) ||\n name.startsWith(ATTR_ARIA_PREFIX) ||\n name.startsWith(ATTR_DATA_PREFIX)\n ) {\n continue;\n }\n if (tagAttrs?.has(name)) {\n if (URL_ATTRIBUTES.has(name) && !isSafeUrl(attr.value)) {\n element.removeAttribute(attr.name);\n } else if (name === 'srcset' && !isSafeSrcset(attr.value)) {\n element.removeAttribute(attr.name);\n }\n continue;\n }\n element.removeAttribute(attr.name);\n }\n}\n\n/** Every `srcset` candidate must pass; partial rewriting would silently change what renders. */\nfunction isSafeSrcset(value: string): boolean {\n for (const candidate of value.split(',')) {\n const trimmed = candidate.trim();\n if (trimmed.length === 0) continue;\n const descriptorStart = trimmed.search(/\\s/);\n const url = descriptorStart === -1 ? trimmed : trimmed.slice(0, descriptorStart);\n if (!isSafeUrl(url)) return false;\n }\n return true;\n}\n\nfunction hardenAnchor(anchor: Element): void {\n const href = anchor.getAttribute('href');\n if (href === null || !isExternalHttpUrl(href)) return;\n anchor.setAttribute('rel', 'noopener noreferrer');\n if (!anchor.hasAttribute('target')) anchor.setAttribute('target', '_blank');\n}\n\n/** The built-in allow-lists, for documentation and tests. */\nexport const SANITIZER_POLICY = Object.freeze({\n allowedTags: ALLOWED_TAGS,\n removeCompletely: REMOVE_COMPLETELY,\n globalAttributes: ATTR_GLOBAL,\n attributesByTag: ATTR_BY_TAG,\n urlAttributes: URL_ATTRIBUTES,\n});\n","/** HTML and CSS escaping primitives (OWASP XSS Prevention Cheat Sheet). DOM-free. */\n\nconst HTML_ESCAPES: Readonly<Record<string, string>> = Object.freeze({\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n '/': '/',\n '`': '`',\n '=': '=',\n});\n\nconst HTML_ESCAPE_PATTERN = /[&<>\"'/`=]/g;\n\n/** Escape `text` for an element body or a *quoted* attribute value; strings only, and unquoted attributes are not covered. */\nexport function escapeHtml(text: string): string {\n if (text === '') return '';\n // The character class and the map are coupled: every match is a key.\n // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style\n return text.replace(HTML_ESCAPE_PATTERN, (char) => HTML_ESCAPES[char] as string);\n}\n\n/** Escape a value for a CSS `url(...)` literal; this stops the break-out, not the scheme, so pair it with `isSafeUrl()`. */\nexport function escapeCssUrl(value: string): string {\n return value.replace(/['\"()\\\\]/g, '\\\\$&');\n}\n\nconst ATTR_ESCAPES: Readonly<Record<string, string>> = Object.freeze({\n '&': '&',\n '<': '<',\n '>': '>',\n '\"': '"',\n \"'\": ''',\n});\n\nconst ATTR_ESCAPE_PATTERN = /[&<>\"']/g;\n\n/** Escape a value for a *quoted* HTML attribute, leaving URL characters intact; it validates no scheme, so run `isSafeUrl()` on `href`/`src` first. */\nexport function escapeHtmlAttribute(value: string): string {\n if (value === '') return '';\n // eslint-disable-next-line @typescript-eslint/non-nullable-type-assertion-style\n return value.replace(ATTR_ESCAPE_PATTERN, (char) => ATTR_ESCAPES[char] as string);\n}\n\n/** `escapeHtml()` then newlines to `<br>`; the order is what makes it safe. */\nexport function escapeAndLinebreak(text: string): string {\n return escapeHtml(text).replace(/\\r\\n|\\r|\\n/g, '<br>');\n}\n","/**\n * Interpolate one array-item template in a single pass. A replacement value is\n * data, not template syntax: one `replace()` per key would re-interpret\n * `{{index}}` text that an earlier value introduced, and would apply\n * `String.replace`'s `$` semantics to CMS content.\n */\n\nimport { escapeHtml } from '@security/escape';\n\nconst PLACEHOLDER_PATTERN = /\\{\\{([\\s\\S]*?)\\}\\}/g;\n\nfunction hasOwn(record: object, key: PropertyKey): boolean {\n return Object.prototype.hasOwnProperty.call(record, key);\n}\n\nexport function interpolateArrayTemplate(\n template: string,\n item: unknown,\n index: number,\n stringify: (value: unknown) => string,\n): string {\n const record = typeof item === 'object' && item !== null ? item : null;\n\n return template.replace(PLACEHOLDER_PATTERN, (placeholder, key: string) => {\n // Preserve the established object-field precedence when an object itself\n // has an `index` or `value` property. Otherwise these are reserved tokens.\n if (record !== null && hasOwn(record, key)) {\n return escapeHtml(stringify(Reflect.get(record, key)));\n }\n if (record === null && key === 'value') return escapeHtml(stringify(item));\n if (key === 'index') return String(index);\n return placeholder;\n });\n}\n","/** Value coercion shared by the field renderers. */\n\n/** Display string for any value: primitives as-is, objects as JSON, `null`/`undefined` as `''`. */\nexport function safeStringify(value: unknown): string {\n if (value === null || value === undefined) return '';\n if (typeof value === 'string') return value;\n if (typeof value === 'number' || typeof value === 'boolean' || typeof value === 'bigint') {\n return String(value);\n }\n try {\n return JSON.stringify(value);\n } catch {\n return '';\n }\n}\n\n/** The three values every renderer treats as \"clear\" (docs/renderers.md, value semantics). */\nexport function isEmptyValue(value: unknown): value is null | undefined | '' {\n return value === null || value === undefined || value === '';\n}\n","/**\n * Structural diff for array and blocks fields. Items with an `id` are keyed\n * (moves are detected); without ids the diff is positional.\n */\n\nexport type ArrayPatch =\n | { readonly kind: 'insert'; readonly index: number; readonly value: unknown }\n | { readonly kind: 'remove'; readonly index: number; readonly value: unknown }\n | {\n readonly kind: 'move';\n readonly from: number;\n readonly to: number;\n readonly value: unknown;\n }\n | { readonly kind: 'update'; readonly index: number; readonly value: unknown }\n | {\n readonly kind: 'replace';\n readonly index: number;\n readonly oldValue: unknown;\n readonly value: unknown;\n };\n\nfunction getId(item: unknown): string | number | undefined {\n if (typeof item !== 'object' || item === null) return undefined;\n const id = (item as Record<string, unknown>)['id'];\n if (typeof id === 'string' || typeof id === 'number') return id;\n return undefined;\n}\n\nfunction getBlockType(item: unknown): string | undefined {\n if (typeof item !== 'object' || item === null) return undefined;\n const blockType = (item as Record<string, unknown>)['blockType'];\n return typeof blockType === 'string' ? blockType : undefined;\n}\n\n/** Patches that turn `prev` into `next`; a changed `blockType` is a `replace`, never an `update`. */\nexport function diffArray(\n prev: readonly unknown[],\n next: readonly unknown[],\n): readonly ArrayPatch[] {\n const haveIds = next.every((item) => getId(item) !== undefined);\n if (haveIds) return diffById(prev, next);\n return diffByPosition(prev, next);\n}\n\nfunction diffById(prev: readonly unknown[], next: readonly unknown[]): readonly ArrayPatch[] {\n const patches: ArrayPatch[] = [];\n const prevIndexById = new Map<string | number, number>();\n for (let i = 0; i < prev.length; i += 1) {\n const id = getId(prev[i]);\n if (id !== undefined) prevIndexById.set(id, i);\n }\n\n const consumedFromPrev = new Set<number>();\n for (let to = 0; to < next.length; to += 1) {\n const item = next[to];\n const id = getId(item);\n if (id === undefined) {\n patches.push({ kind: 'insert', index: to, value: item });\n continue;\n }\n const from = prevIndexById.get(id);\n if (from === undefined) {\n patches.push({ kind: 'insert', index: to, value: item });\n continue;\n }\n consumedFromPrev.add(from);\n const prevItem = prev[from];\n if (getBlockType(prevItem) !== getBlockType(item)) {\n patches.push({ kind: 'replace', index: to, oldValue: prevItem, value: item });\n continue;\n }\n if (from !== to) {\n patches.push({ kind: 'move', from, to, value: item });\n }\n if (!shallowEqual(prevItem, item)) {\n patches.push({ kind: 'update', index: to, value: item });\n }\n }\n\n for (let i = 0; i < prev.length; i += 1) {\n if (consumedFromPrev.has(i)) continue;\n patches.push({ kind: 'remove', index: i, value: prev[i] });\n }\n return patches;\n}\n\nfunction diffByPosition(prev: readonly unknown[], next: readonly unknown[]): readonly ArrayPatch[] {\n const patches: ArrayPatch[] = [];\n const min = Math.min(prev.length, next.length);\n for (let i = 0; i < min; i += 1) {\n if (!shallowEqual(prev[i], next[i])) {\n patches.push({ kind: 'update', index: i, value: next[i] });\n }\n }\n if (next.length > prev.length) {\n for (let i = prev.length; i < next.length; i += 1) {\n patches.push({ kind: 'insert', index: i, value: next[i] });\n }\n }\n if (prev.length > next.length) {\n for (let i = next.length; i < prev.length; i += 1) {\n patches.push({ kind: 'remove', index: i, value: prev[i] });\n }\n }\n return patches;\n}\n\n// Shallow on purpose: any nested reference change is an update, and the\n// renderer reconciles deeper differences itself.\nfunction shallowEqual(a: unknown, b: unknown): boolean {\n if (Object.is(a, b)) return true;\n if (typeof a !== 'object' || typeof b !== 'object' || a === null || b === null) return false;\n const aRec = a as Record<string, unknown>;\n const bRec = b as Record<string, unknown>;\n const aKeys = Object.keys(aRec);\n const bKeys = Object.keys(bRec);\n if (aKeys.length !== bKeys.length) return false;\n for (const key of aKeys) {\n if (!Object.is(aRec[key], bRec[key])) return false;\n }\n return true;\n}\n","/**\n * Hydrated islands own their subtree, so the runtime never patches inside one.\n * Instead every flush dispatches `payload-live-preview:update` on each island\n * root with the update in `detail`. `data-payload-island=\"patch\"` opts back in.\n */\n\nexport const ISLAND_EVENT = 'payload-live-preview:update';\nexport const ISLAND_ATTRIBUTE = 'data-payload-island';\nexport const ISLAND_SELECTOR = `astro-island, [${ISLAND_ATTRIBUTE}]`;\n\nexport interface IslandUpdateDetail {\n readonly fields: Readonly<Record<string, unknown>>;\n readonly revision: number;\n readonly receivedAt: number;\n readonly locale: string | undefined;\n}\n\nfunction isIslandRoot(element: Element): boolean {\n return element.tagName.toLowerCase() === 'astro-island' || element.hasAttribute(ISLAND_ATTRIBUTE);\n}\n\nfunction islandAllowsPatching(island: Element): boolean {\n return island.getAttribute(ISLAND_ATTRIBUTE) === 'patch';\n}\n\n/** Whether `element` (or an ancestor) is an island that did not opt into patching. */\nexport function isInsideIsland(element: Element): boolean {\n let current: Element | null = element;\n while (current !== null) {\n if (isIslandRoot(current) && !islandAllowsPatching(current)) return true;\n current = current.parentElement;\n }\n return false;\n}\n\n/** Island roots under `root` that receive update events. */\nexport function collectIslands(root: ParentNode): Element[] {\n const islands: Element[] = [];\n for (const island of root.querySelectorAll(ISLAND_SELECTOR)) {\n if (!islandAllowsPatching(island)) islands.push(island);\n }\n return islands;\n}\n\nexport function dispatchIslandUpdate(\n islands: readonly Element[],\n detail: IslandUpdateDetail,\n): number {\n for (const island of islands) {\n island.dispatchEvent(\n new CustomEvent<IslandUpdateDetail>(ISLAND_EVENT, { detail, bubbles: false }),\n );\n }\n return islands.length;\n}\n","/**\n * Keyed DOM morph: edits a live element toward a freshly rendered one while\n * keeping the live nodes, and with them focus, selection, scroll, playback and\n * listeners. Custom elements, islands, `contenteditable` and\n * `data-payload-owned` subtrees are boundaries the morph never enters.\n * See ADR 0008.\n */\n\nimport { ISLAND_ATTRIBUTE } from './islands';\n\nexport { ISLAND_ATTRIBUTE };\nexport const OWNED_ATTRIBUTE = 'data-payload-owned';\n\n/** Attributes the CMS controls only when the template names them (ADR 0008 §3). */\nconst STATE_ATTRIBUTES: ReadonlySet<string> = new Set(['open', 'value', 'checked', 'selected']);\n\nexport interface MorphOptions {\n /** Attributes that key child elements for pairing, tried in order; unkeyed children pair by position. */\n readonly keyAttributes: readonly string[];\n /** Called once per parent when two children share a key; the later ones pair by position. */\n readonly onDuplicateKey?: (parent: Element, key: string) => void;\n /** Elements whose attributes are synchronised but whose children are left alone (nested structural slots). */\n readonly retainChildrenOf?: (live: Element, rendered: Element) => boolean;\n}\n\n/** Empty attribute values (boolean markers such as `data-payload-island`) are not keys. */\nfunction keyOf(element: Element, options: MorphOptions): string | undefined {\n for (const attribute of options.keyAttributes) {\n const value = element.getAttribute(attribute);\n if (value !== null && value.length > 0) return `${attribute}=${value}`;\n }\n return undefined;\n}\n\nexport function isMorphBoundary(element: Element): boolean {\n if (element.tagName.toLowerCase().includes('-')) return true;\n if (element.hasAttribute(ISLAND_ATTRIBUTE) || element.hasAttribute(OWNED_ATTRIBUTE)) return true;\n const editable = element.getAttribute('contenteditable');\n return editable !== null && editable !== 'false';\n}\n\n/** Whether `live` can be edited toward `rendered` instead of being replaced by it. */\nexport function isMorphCompatible(live: Element, rendered: Element): boolean {\n return (\n live.tagName === rendered.tagName &&\n live.namespaceURI === rendered.namespaceURI &&\n !isMorphBoundary(live) &&\n !isMorphBoundary(rendered)\n );\n}\n\n/**\n * Morph `live` toward `rendered`. Returns `live` when it was retained, or\n * `rendered` when the two are incompatible and the caller must replace.\n * `rendered` is consumed: its children may move into `live`.\n */\nexport function morphElement(live: Element, rendered: Element, options: MorphOptions): Element {\n if (!isMorphCompatible(live, rendered)) return rendered;\n const focus = captureFocus(live);\n syncAttributes(live, rendered);\n if (options.retainChildrenOf?.(live, rendered) !== true) morphChildren(live, rendered, options);\n restoreFocus(focus);\n return live;\n}\n\n/** Match attributes, except that state-bearing ones change only when `rendered` carries them. */\nexport function syncAttributes(live: Element, rendered: Element): void {\n for (const attribute of Array.from(live.attributes)) {\n if (rendered.hasAttribute(attribute.name)) continue;\n if (STATE_ATTRIBUTES.has(attribute.name.toLowerCase())) continue;\n live.removeAttribute(attribute.name);\n }\n for (const attribute of Array.from(rendered.attributes)) {\n if (live.getAttribute(attribute.name) !== attribute.value) {\n live.setAttribute(attribute.name, attribute.value);\n }\n }\n}\n\nfunction morphChildren(live: Element, rendered: Element, options: MorphOptions): void {\n const liveKeyed = indexKeyed(live, options);\n const keyedElements = new Set<Node>(liveKeyed.values());\n const liveUnkeyed = Array.from(live.childNodes).filter((node) => !keyedElements.has(node));\n const claimed = new Set<Node>();\n const usedKeys = new Set<string>();\n const renderedNodes = Array.from(rendered.childNodes);\n let cursor: Node | null = live.firstChild;\n let unkeyedIndex = 0;\n\n for (let i = 0; i < renderedNodes.length; i += 1) {\n const next = renderedNodes[i] as Node;\n let kept: Node | null = null;\n let key = next instanceof Element ? keyOf(next, options) : undefined;\n // A repeated key on the rendered side pairs positionally like a live duplicate.\n if (key !== undefined && usedKeys.has(key)) key = undefined;\n if (key !== undefined) {\n usedKeys.add(key);\n const candidate = liveKeyed.get(key);\n if (candidate !== undefined && !claimed.has(candidate)) {\n kept = reconcile(candidate, next, options) === candidate ? candidate : null;\n if (kept === null) {\n candidate.replaceWith(next);\n claimed.add(next);\n cursor = next.nextSibling;\n continue;\n }\n }\n } else {\n while (unkeyedIndex < liveUnkeyed.length) {\n const candidate = liveUnkeyed[unkeyedIndex] as Node;\n unkeyedIndex += 1;\n if (claimed.has(candidate)) continue;\n if (sameKind(candidate, next)) {\n kept = reconcile(candidate, next, options) === candidate ? candidate : null;\n if (kept === null) {\n live.replaceChild(next, candidate);\n claimed.add(next);\n cursor = next.nextSibling;\n }\n break;\n }\n if (candidate instanceof Element) {\n // `next` is a text/comment, or an element whose kind the following\n // rendered node matches: an insertion, so the live element stays for it.\n const following = renderedNodes[i + 1];\n if (\n !(next instanceof Element) ||\n (following !== undefined && sameKind(candidate, following))\n ) {\n unkeyedIndex -= 1;\n break;\n }\n live.replaceChild(next, candidate);\n claimed.add(next);\n cursor = next.nextSibling;\n break;\n }\n if (!(next instanceof Element)) {\n // Text vs comment: replace rather than rewrite one node type's value into the other.\n live.replaceChild(next, candidate);\n claimed.add(next);\n cursor = next.nextSibling;\n break;\n }\n // A surplus live text/comment before the element `next` needs; removed below.\n }\n if (kept === null && claimed.has(next)) continue;\n }\n\n const node: Node = kept ?? next;\n claimed.add(node);\n // Whitespace-only text the template did not render is surplus. Stepping the\n // cursor over it keeps a retained element where it is: `insertBefore` on a\n // node already in the tree is a remove-and-insert, which blurs a focused input.\n while (cursor !== null && cursor !== node && !claimed.has(cursor) && isBlankText(cursor)) {\n cursor = cursor.nextSibling;\n }\n if (node !== cursor) live.insertBefore(node, cursor);\n cursor = node.nextSibling;\n }\n\n for (const child of Array.from(live.childNodes)) {\n if (!claimed.has(child)) child.remove();\n }\n}\n\n/** Retain `candidate` when it can be edited toward `next`; otherwise report `next`. */\nfunction reconcile(candidate: Node, next: Node, options: MorphOptions): Node {\n if (candidate instanceof Element && next instanceof Element) {\n // A compatible boundary stays exactly as it is (ADR 0008 §4).\n if (isMorphBoundary(candidate) && isMorphBoundary(next)) return candidate;\n return morphElement(candidate, next, options);\n }\n if (candidate.nodeValue !== next.nodeValue) candidate.nodeValue = next.nodeValue;\n return candidate;\n}\n\nfunction isBlankText(node: Node): boolean {\n return node.nodeType === Node.TEXT_NODE && (node.nodeValue ?? '').trim().length === 0;\n}\n\nfunction sameKind(a: Node, b: Node): boolean {\n if (a.nodeType !== b.nodeType) return false;\n if (a instanceof Element && b instanceof Element) {\n return a.tagName === b.tagName && a.namespaceURI === b.namespaceURI;\n }\n return true;\n}\n\n/** First element per key; later duplicates are left as they are and pair positionally. */\nfunction indexKeyed(parent: Element, options: MorphOptions): Map<string, Element> {\n const keyed = new Map<string, Element>();\n let duplicate: string | undefined;\n for (const child of Array.from(parent.children)) {\n const key = keyOf(child, options);\n if (key === undefined) continue;\n if (keyed.has(key)) {\n duplicate ??= key.slice(key.indexOf('=') + 1);\n continue;\n }\n keyed.set(key, child);\n }\n if (duplicate !== undefined) options.onDuplicateKey?.(parent, duplicate);\n return keyed;\n}\n\ninterface FocusSnapshot {\n readonly element: HTMLElement;\n readonly selection: readonly [number | null, number | null] | null;\n}\n\n/** A keyed move is a remove-and-insert, which blurs; remember what had focus. */\nfunction captureFocus(live: Element): FocusSnapshot | null {\n const active = live.ownerDocument.activeElement;\n if (!(active instanceof HTMLElement) || !live.contains(active)) return null;\n const selection =\n active instanceof HTMLInputElement || active instanceof HTMLTextAreaElement\n ? ([active.selectionStart, active.selectionEnd] as const)\n : null;\n return { element: active, selection };\n}\n\nfunction restoreFocus(snapshot: FocusSnapshot | null): void {\n if (snapshot === null) return;\n const { element, selection } = snapshot;\n if (element.ownerDocument.activeElement === element || !element.isConnected) return;\n try {\n element.focus({ preventScroll: true });\n const [start, end] = selection ?? [null, null];\n if (start !== null && end !== null) {\n (element as HTMLInputElement).setSelectionRange(start, end);\n }\n } catch {\n // Not focusable any more; nothing to restore.\n }\n}\n","/**\n * Sanitizer options for item templates (`data-payload-array-template`,\n * nested templates). A template is the page author's markup and every\n * interpolated value is escaped to text before the sanitizer runs, so it may\n * carry form controls and custom elements the rich-text policy refuses.\n * Event handlers, `style` and unsafe URLs are still stripped.\n *\n * Some entries below are already admitted by the sanitizer through another\n * route — `video` and `audio` by the tag allow-list, `select` by\n * `allowFormControls`, `name` by `templateMode`, and `controls`, `muted`,\n * `loop`, `poster` and `src` by the per-tag attribute map. They are kept\n * because this list states what a template may contain, and an allow-list\n * that depends on a second list staying unchanged is the more fragile of the\n * two arrangements. Mutating those entries changes nothing observable, so\n * they survive mutation testing by construction; the behaviour they describe\n * is pinned in `tests/unit/core/template-sanitize.test.ts` instead.\n */\n\nimport type { SanitizeOptions } from '@security/sanitizer';\n\nconst TEMPLATE_EXTRA_TAGS: readonly string[] = [\n 'input',\n 'textarea',\n 'select',\n 'option',\n 'button',\n 'label',\n 'details',\n 'summary',\n 'dialog',\n 'video',\n 'audio',\n 'progress',\n 'meter',\n];\n\nconst TEMPLATE_EXTRA_ATTRIBUTES: readonly string[] = [\n 'type',\n 'name',\n 'placeholder',\n 'open',\n 'disabled',\n 'readonly',\n 'required',\n 'checked',\n 'selected',\n 'value',\n 'min',\n 'max',\n 'step',\n 'rows',\n 'cols',\n 'for',\n 'controls',\n 'muted',\n 'loop',\n 'poster',\n 'src',\n];\n\nconst CUSTOM_TAG_PATTERN = /<([a-z][a-z0-9]*(?:-[a-z0-9]+)+)\\b/gi;\nconst optionsByTemplate = new Map<string, SanitizeOptions>();\n\n/** Options for one template; memoised per template string. */\nexport function templateSanitizeOptions(template: string): SanitizeOptions {\n const cached = optionsByTemplate.get(template);\n if (cached !== undefined) return cached;\n const tags = new Set(TEMPLATE_EXTRA_TAGS);\n for (const match of template.matchAll(CUSTOM_TAG_PATTERN)) {\n const tag = match[1]?.toLowerCase();\n if (tag !== undefined) tags.add(tag);\n }\n const attributes: Record<string, readonly string[]> = {};\n for (const tag of tags) attributes[tag] = TEMPLATE_EXTRA_ATTRIBUTES;\n const options: SanitizeOptions = {\n additionalAllowedTags: [...tags],\n additionalAllowedAttributes: attributes,\n allowFormControls: true,\n templateMode: true,\n };\n optionsByTemplate.set(template, options);\n return options;\n}\n","/**\n * Applies an `ArrayPatch[]` diff to a container as keyed DOM operations\n * instead of rebuilding the list, so consumer state on surviving children is\n * kept. Items are paired by `data-payload-key` (the item `id`); items without\n * one pair by position. Nested arrays reconcile recursively through\n * `data-payload-nested-key` slots. See ADR 0008.\n */\n\nimport { sanitizeHtml } from '@security/sanitizer';\nimport { trustedHtml } from '@security/trusted-types';\nimport { interpolateArrayTemplate } from './array-template';\nimport { safeStringify } from '@field-types/utils';\nimport { diffArray, type ArrayPatch } from '@schema/diff';\nimport { morphElement } from './morph';\nimport { templateSanitizeOptions } from './template-sanitize';\n\nexport const KEY_ATTRIBUTE = 'data-payload-key';\nconst NESTED_KEY_ATTRIBUTE = 'data-payload-nested-key';\nconst NESTED_TEMPLATE_ATTRIBUTE = 'data-payload-nested-template';\n\n/** Last value seen per item key, per container; owned by the caller so instances never share it. */\nexport type StructuralStore = WeakMap<Element, Map<string, unknown>>;\n\nexport function createStructuralStore(): StructuralStore {\n return new WeakMap<Element, Map<string, unknown>>();\n}\n\nexport interface StructuralApplyOptions {\n readonly template: string;\n readonly container: Element;\n readonly patches: readonly ArrayPatch[];\n /** The full new array; inserts and replaces render by index from it. */\n readonly nextItems: readonly unknown[];\n /** Pass the same store across renders so nested arrays diff incrementally. */\n readonly store: StructuralStore;\n /** Re-render existing items even when unchanged. */\n readonly forceRender?: boolean;\n /** Edit a changed item in place instead of replacing it. Default `true`. */\n readonly morph?: boolean;\n /** Reported once per container when two items share a key (`LP0405`). */\n readonly onDuplicateKey?: (container: Element, key: string) => void;\n}\n\n/**\n * Returns `true` for a DOM mutation, `false` for an already-current tree, and\n * `null` when an item's markup has no sanitized element root — preflighted\n * before any mutation, so the previous DOM and memory stay intact.\n */\nexport function applyStructuralPatches(options: StructuralApplyOptions): boolean | null {\n const { template, container, patches, nextItems, store, forceRender = false } = options;\n const plan = prepareStructuralPlan(container, template, patches, nextItems, forceRender, store);\n if (plan === null) return null;\n return commitStructuralPlan(plan, store, {\n morph: options.morph ?? true,\n onDuplicateKey: options.onDuplicateKey,\n });\n}\n\n// Plan records are tuples: many are created per recursive render, and named\n// keys would repeat in the inline bundle.\ntype StructuralPlan = readonly [\n container: Element,\n entries: readonly ReconciliationEntry[],\n nextItems: readonly unknown[],\n];\ntype ReconciliationEntry = readonly [\n index: number,\n live: Element | null,\n rendered: Element | undefined,\n nestedSlots: readonly NestedSlotPlan[],\n /** A `replace` patch: a different item, never morphed toward. */\n replace: boolean,\n];\ntype NestedSlotPlan = readonly [\n live: Element | null,\n rendered: Element,\n children: StructuralPlan | undefined,\n];\n\ninterface CommitOptions {\n readonly morph: boolean;\n readonly onDuplicateKey: ((container: Element, key: string) => void) | undefined;\n}\n\n/** A rendered slot that still carries a nested template keeps its children for its own plan. */\nfunction isManagedNestedSlot(_live: Element, rendered: Element): boolean {\n return (\n rendered.hasAttribute(NESTED_KEY_ATTRIBUTE) && rendered.hasAttribute(NESTED_TEMPLATE_ATTRIBUTE)\n );\n}\n\n/** Materialise the whole recursive replacement tree before touching live DOM. */\nfunction prepareStructuralPlan(\n container: Element,\n template: string,\n patches: readonly ArrayPatch[],\n nextItems: readonly unknown[],\n forceRender: boolean,\n store: StructuralStore,\n): StructuralPlan | null {\n const entries = prepareReconciliation(\n container,\n template,\n nextItems,\n createPatchPlan(patches),\n forceRender,\n store.get(container),\n store,\n );\n return entries === null ? null : [container, entries, nextItems];\n}\n\nfunction commitStructuralPlan(\n plan: StructuralPlan,\n store: StructuralStore,\n options: CommitOptions,\n): boolean {\n const [container, entries, nextItems] = plan;\n const claimed = new Set<Element>();\n let mutated = false;\n for (const [index, live, rendered, nestedSlots, replace] of entries) {\n let node = live;\n if (rendered !== undefined) {\n // Morph a compatible live item in place; otherwise transplant its live\n // nested slots into the rendered item and swap.\n const retained =\n options.morph && !replace && live !== null\n ? morphElement(live, rendered, {\n keyAttributes: [KEY_ATTRIBUTE, NESTED_KEY_ATTRIBUTE],\n retainChildrenOf: isManagedNestedSlot,\n ...(options.onDuplicateKey !== undefined\n ? { onDuplicateKey: options.onDuplicateKey }\n : {}),\n }) === live\n : false;\n if (!retained) {\n for (const [liveSlot, renderedSlot] of nestedSlots) {\n if (liveSlot === null) continue;\n synchronizeAttributes(liveSlot, renderedSlot);\n renderedSlot.replaceWith(liveSlot);\n }\n }\n for (const [, , children] of nestedSlots) {\n if (children !== undefined) commitStructuralPlan(children, store, options);\n }\n if (retained) {\n mutated = true;\n } else {\n if (live !== null) {\n live.replaceWith(rendered);\n mutated = true;\n }\n node = rendered;\n }\n }\n if (node === null) continue;\n const before = container.children[index] ?? null;\n if (node !== before) {\n container.insertBefore(node, before);\n mutated = true;\n }\n claimed.add(node);\n }\n // `nextItems` is the source of truth; this also drops SSR children the first value did not carry.\n for (const child of Array.from(container.children)) {\n if (claimed.has(child)) continue;\n child.remove();\n mutated = true;\n }\n const memory = getMemory(container, store);\n memory.clear();\n for (const value of nextItems) rememberItem(memory, value);\n return mutated;\n}\n\n/**\n * Pair every final item with a live child (by key, else by position) and\n * render what needs rendering. Patch indices describe `next`, live indices\n * move during reconciliation, so keyed nodes are resolved from the DOM first.\n */\nfunction prepareReconciliation(\n container: Element,\n template: string,\n nextItems: readonly unknown[],\n plan: PatchPlan,\n forceRender: boolean,\n memory: ReadonlyMap<string, unknown> | undefined,\n store: StructuralStore,\n): readonly ReconciliationEntry[] | null {\n const initialChildren = Array.from(container.children);\n const keyedChildren = indexByAttribute(initialChildren, KEY_ATTRIBUTE);\n const reserved = new Set<Element>();\n const entries: ReconciliationEntry[] = [];\n for (let index = 0; index < nextItems.length; index += 1) {\n const value = nextItems[index];\n const key = readKey(value);\n let live =\n key === undefined\n ? (initialChildren[index] ?? null)\n : (takeIndexedElement(keyedChildren, key) ?? null);\n if (live !== null && reserved.has(live)) live = null;\n if (live !== null) reserved.add(live);\n const replace = plan.replaces.has(index);\n const needsRender = forceRender || plan.renders.has(index) || live === null;\n const rendered = needsRender\n ? renderItem(container.ownerDocument, template, value, index)\n : undefined;\n if (rendered === null) return null;\n const nestedSlots =\n rendered === undefined\n ? []\n : prepareNestedSlots(replace ? null : live, rendered, value, memory, store);\n if (nestedSlots === null) return null;\n entries.push([index, live, rendered ?? undefined, nestedSlots, replace]);\n }\n return entries;\n}\n\ninterface PatchPlan {\n readonly renders: ReadonlySet<number>;\n readonly replaces: ReadonlySet<number>;\n}\n\nfunction createPatchPlan(patches: readonly ArrayPatch[]): PatchPlan {\n const renders = new Set<number>();\n const replaces = new Set<number>();\n for (const patch of patches) {\n if (patch.kind === 'insert' || patch.kind === 'update') renders.add(patch.index);\n else if (patch.kind === 'replace') {\n renders.add(patch.index);\n replaces.add(patch.index);\n }\n }\n return { renders, replaces };\n}\n\n/** Plan each direct nested slot; a failure at any depth aborts before commit. */\nfunction prepareNestedSlots(\n oldItem: Element | null,\n newItem: Element,\n nextValue: unknown,\n memory: ReadonlyMap<string, unknown> | undefined,\n store: StructuralStore,\n): readonly NestedSlotPlan[] | null {\n const oldSlots = oldItem === null ? [] : findDirectNestedSlots(oldItem);\n const oldSlotsByKey = indexByAttribute(oldSlots, NESTED_KEY_ATTRIBUTE);\n const itemKey = readKey(nextValue);\n const prevValue = itemKey !== undefined ? memory?.get(itemKey) : undefined;\n const plans: NestedSlotPlan[] = [];\n for (const newSlot of findDirectNestedSlots(newItem)) {\n const key = newSlot.getAttribute(NESTED_KEY_ATTRIBUTE);\n if (key === null) continue;\n const oldSlot = takeIndexedElement(oldSlotsByKey, key) ?? null;\n const nextTemplate = newSlot.getAttribute(NESTED_TEMPLATE_ATTRIBUTE);\n // Without a nested template the slot's rendered static content is authoritative.\n const liveSlot = nextTemplate ? oldSlot : null;\n const previousTemplate = liveSlot?.getAttribute(NESTED_TEMPLATE_ATTRIBUTE) ?? null;\n let children: StructuralPlan | undefined;\n if (nextTemplate) {\n const nextNested = readNestedArray(nextValue, key);\n if (nextNested !== undefined || liveSlot !== null) {\n const resolvedNext = nextNested ?? [];\n const prevNested = liveSlot === null ? [] : (readNestedArray(prevValue, key) ?? []);\n const patches = diffArray(prevNested, resolvedNext);\n const templateChanged = liveSlot !== null && previousTemplate !== nextTemplate;\n if (patches.length > 0 || templateChanged) {\n children =\n prepareStructuralPlan(\n liveSlot ?? newSlot,\n nextTemplate,\n patches,\n resolvedNext,\n templateChanged,\n store,\n ) ?? undefined;\n if (children === undefined) return null;\n }\n }\n }\n plans.push([liveSlot, newSlot, children]);\n }\n return plans;\n}\n\n/** Only the outermost nested slots: a transplanted slot owns the recursion below it. */\nfunction findDirectNestedSlots(item: Element): readonly Element[] {\n return Array.from(item.querySelectorAll(`[${NESTED_KEY_ATTRIBUTE}]`)).filter((slot) => {\n let ancestor = slot.parentElement;\n while (ancestor !== null && ancestor !== item) {\n if (ancestor.hasAttribute(NESTED_KEY_ATTRIBUTE)) return false;\n ancestor = ancestor.parentElement;\n }\n return ancestor === item;\n });\n}\n\nfunction synchronizeAttributes(target: Element, source: Element): void {\n for (const attribute of Array.from(target.attributes)) {\n if (!source.hasAttribute(attribute.name)) target.removeAttribute(attribute.name);\n }\n for (const attribute of Array.from(source.attributes)) {\n if (target.getAttribute(attribute.name) !== attribute.value) {\n target.setAttribute(attribute.name, attribute.value);\n }\n }\n}\n\nfunction readNestedArray(value: unknown, key: string): readonly unknown[] | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const nested = (value as Record<string, unknown>)[key];\n return Array.isArray(nested) ? (nested as readonly unknown[]) : undefined;\n}\n\nfunction getMemory(container: Element, store: StructuralStore): Map<string, unknown> {\n let map = store.get(container);\n if (!map) {\n map = new Map();\n store.set(container, map);\n }\n return map;\n}\n\nfunction rememberItem(memory: Map<string, unknown>, value: unknown): void {\n const key = readKey(value);\n if (key !== undefined) memory.set(key, value);\n}\n\nfunction readKey(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const id = (value as Record<string, unknown>)['id'];\n return typeof id === 'string' || typeof id === 'number' ? String(id) : undefined;\n}\n\nfunction indexByAttribute(elements: readonly Element[], attribute: string): Map<string, Element[]> {\n const indexed = new Map<string, Element[]>();\n // Reverse order so pop() yields duplicates in DOM order.\n for (let index = elements.length - 1; index >= 0; index -= 1) {\n const element = elements[index];\n if (element === undefined) continue;\n const key = element.getAttribute(attribute);\n if (key === null) continue;\n const bucket = indexed.get(key);\n if (bucket === undefined) indexed.set(key, [element]);\n else bucket.push(element);\n }\n return indexed;\n}\n\nfunction takeIndexedElement(indexed: Map<string, Element[]>, key: string): Element | undefined {\n return indexed.get(key)?.pop();\n}\n\n/** Render one item; its `id` is stamped as `data-payload-key` so later diffs find it. */\nfunction renderItem(\n ownerDocument: Document,\n template: string,\n value: unknown,\n index: number,\n): Element | null {\n const filled = interpolateArrayTemplate(template, value, index, safeStringify);\n const safe = sanitizeHtml(filled, templateSanitizeOptions(template));\n const host = ownerDocument.createElement('template');\n host.innerHTML = trustedHtml(safe);\n const first = host.content.firstElementChild;\n if (!first) return null;\n const key = readKey(value);\n if (key !== undefined) first.setAttribute(KEY_ATTRIBUTE, key);\n return first;\n}\n","/**\n * `structural-array` renderer (`data-payload-structural`): diffs the previous\n * and next item lists and patches the container through the keyed morph\n * (ADR 0008). All diff memory lives in the closure, one per client.\n */\n\nimport { safeConsoleWarn } from '@core/diagnostics';\nimport { markNoWriteCallback } from '@core/internal-outcome';\nimport {\n applyStructuralPatches,\n createStructuralStore,\n KEY_ATTRIBUTE,\n type StructuralStore,\n} from '@core/structural-applier';\nimport { diffArray } from '@schema/diff';\nimport type { FieldRenderer } from '@core/types';\nimport { isEmptyValue } from './utils';\n\ninterface StructuralRenderState {\n readonly values: readonly unknown[];\n readonly template: string;\n readonly domSnapshot: readonly (string | null)[];\n}\n\ntype WarnedCodes = WeakMap<Element, Set<string>>;\n\nexport function createStructuralArrayRenderer(): FieldRenderer {\n const states = new WeakMap<Element, StructuralRenderState>();\n const warnedContainers = new WeakSet<Element>();\n const warnedKeys: WarnedCodes = new WeakMap();\n const store: StructuralStore = createStructuralStore();\n\n return {\n name: 'structural-array',\n render: /* @__PURE__ */ markNoWriteCallback((target, rawValue) => {\n const value = isEmptyValue(rawValue) ? [] : rawValue;\n if (!Array.isArray(value)) return false;\n const container = target.element;\n const template = target.arrayTemplate;\n if (template === undefined || template.length === 0) {\n warnMissingTemplate(warnedContainers, container, target.fieldName);\n return false;\n }\n const previousState = states.get(container);\n const domSnapshot = readDomKeySnapshot(container);\n const previous = previousState?.values ?? valuesFromDomSnapshot(domSnapshot);\n const patches = diffArray(previous, value);\n const forceRender = needsForcedRender(previousState, template, domSnapshot);\n if (patches.length === 0 && !forceRender) {\n states.set(container, { values: value.slice(), template, domSnapshot });\n return false;\n }\n warnAboutKeys(warnedKeys, container, target.fieldName, previousState?.values, value);\n const applied = applyStructuralPatches({\n template,\n container,\n patches,\n nextItems: value,\n store,\n forceRender,\n onDuplicateKey: (owner, key) => {\n warnDuplicateKey(warnedKeys, owner, target.fieldName, key);\n },\n });\n if (applied === null) return false;\n states.set(container, {\n values: value.slice(),\n template,\n domSnapshot: readDomKeySnapshot(container),\n });\n return applied ? undefined : false;\n }),\n };\n}\n\nfunction needsForcedRender(\n previous: StructuralRenderState | undefined,\n template: string,\n domSnapshot: readonly (string | null)[],\n): boolean {\n if (previous === undefined) return true;\n return previous.template !== template || !sameDomKeySnapshot(previous.domSnapshot, domSnapshot);\n}\n\n// SSR markup exists before any in-memory snapshot; its direct-child keys let\n// the first update reconcile instead of appending a second copy.\nfunction readDomKeySnapshot(container: Element): readonly (string | null)[] {\n return Array.from(container.children, (child) => child.getAttribute(KEY_ATTRIBUTE));\n}\n\nfunction valuesFromDomSnapshot(snapshot: readonly (string | null)[]): readonly unknown[] {\n return snapshot.map((key, position) =>\n key === null ? { __payloadDomPosition: position } : { id: key },\n );\n}\n\nfunction sameDomKeySnapshot(\n previous: readonly (string | null)[],\n current: readonly (string | null)[],\n): boolean {\n if (previous.length !== current.length) return false;\n return previous.every((key, index) => key === current[index]);\n}\n\nfunction warnMissingTemplate(\n warnedContainers: WeakSet<Element>,\n container: Element,\n fieldName: string,\n): void {\n if (warnedContainers.has(container)) return;\n warnedContainers.add(container);\n safeConsoleWarn(\n `[live-preview] LP0403: Skipping structural update for \"${fieldName}\": ` +\n `<${container.tagName.toLowerCase()} data-payload-structural> needs ` +\n `data-payload-array-template (for example \"<li>{{label}}</li>\").`,\n );\n}\n\nfunction itemKey(value: unknown): string | undefined {\n if (typeof value !== 'object' || value === null) return undefined;\n const id = (value as Record<string, unknown>)['id'];\n return typeof id === 'string' || typeof id === 'number' ? String(id) : undefined;\n}\n\n/** Key problems degrade the morph, they do not break it; each is announced once per container (ADR 0008 §5). */\nfunction warnAboutKeys(\n warned: WarnedCodes,\n container: Element,\n fieldName: string,\n previous: readonly unknown[] | undefined,\n next: readonly unknown[],\n): void {\n const nextKeys = next.map(itemKey);\n const seen = new Set<string>();\n const duplicate = nextKeys.find((key) => {\n if (key === undefined) return false;\n if (seen.has(key)) return true;\n seen.add(key);\n return false;\n });\n if (duplicate !== undefined) warnDuplicateKey(warned, container, fieldName, duplicate);\n if (nextKeys.some((key) => key === undefined)) {\n warnOnce(\n warned,\n container,\n 'LP0404',\n `LP0404: an item of \"${fieldName}\" has no id and pairs by ` +\n 'position, so an insert re-renders every row after it. Give items a stable id.',\n );\n }\n if (previous?.length === next.length && next.length > 1) {\n const previousKeys = new Set(previous.map(itemKey).filter((key) => key !== undefined));\n const stable = nextKeys.some((key) => key !== undefined && previousKeys.has(key));\n if (previousKeys.size > 0 && !stable) {\n warnOnce(\n warned,\n container,\n 'LP0406',\n `LP0406: every key of \"${fieldName}\" changed at once; the ` +\n 'source generates ids per message, so no item can be retained across updates.',\n );\n }\n }\n}\n\n// Reached from the pre-diff check and from the morph's nested-slot check; one site, one message.\nfunction warnDuplicateKey(\n warned: WarnedCodes,\n owner: Element,\n fieldName: string,\n key: string,\n): void {\n warnOnce(\n warned,\n owner,\n 'LP0405',\n `LP0405: two items of \"${fieldName}\" share the key \"${key}\"; later ones pair by ` +\n 'position. Make `id` unique per item.',\n );\n}\n\nfunction warnOnce(warned: WarnedCodes, container: Element, code: string, message: string): void {\n let codes = warned.get(container);\n if (codes === undefined) {\n codes = new Set();\n warned.set(container, codes);\n }\n if (codes.has(code)) return;\n codes.add(code);\n safeConsoleWarn(`[live-preview] ${message}`);\n}\n","/**\n * One source → dependents map for `skipUnchanged`. Markup declares it the\n * other way round (`data-payload-depends=\"price\"` on the element bound to\n * `priceLabel`) because an author names what a binding needs; the runtime\n * option is keyed by source because the scheduler asks what changed.\n */\n\nexport type DependencyMap = Readonly<Record<string, readonly string[]>>;\n\n/**\n * Field names from an attribute value. Separators are commas and\n * whitespace; empty entries are dropped; order is kept, duplicates removed.\n */\nexport function parseDependencyList(value: string | null | undefined): readonly string[] {\n if (value === null || value === undefined) return [];\n const seen = new Set<string>();\n const names: string[] = [];\n for (const raw of value.split(/[\\s,]+/)) {\n const name = raw.trim();\n if (name.length === 0 || seen.has(name)) continue;\n seen.add(name);\n names.push(name);\n }\n return names;\n}\n\n/**\n * Merge dependency maps (source → dependents). Later maps add to earlier\n * ones; a dependent is listed once per source.\n */\nexport function mergeDependencyMaps(...maps: readonly DependencyMap[]): DependencyMap {\n const merged = new Map<string, Set<string>>();\n for (const map of maps) {\n for (const [source, dependents] of Object.entries(map)) {\n let bucket = merged.get(source);\n if (bucket === undefined) {\n bucket = new Set();\n merged.set(source, bucket);\n }\n for (const dependent of dependents) bucket.add(dependent);\n }\n }\n const result: Record<string, readonly string[]> = {};\n for (const [source, dependents] of merged) result[source] = [...dependents];\n return result;\n}\n\n/**\n * The map an element's `data-payload-depends` contributes: every declared\n * source points at this binding's field.\n */\nexport function dependencyMapFromBinding(\n fieldName: string,\n dependsOn: readonly string[],\n): DependencyMap {\n const map: Record<string, readonly string[]> = {};\n for (const source of dependsOn) {\n if (source === fieldName) continue;\n map[source] = [fieldName];\n }\n return map;\n}\n"],"mappings":"AA8BO,IAtBLA,ECaEC,EDSSC,GAtBXF,EAsB+C,IAAIG,IAClDC,QAAQC,QAA8CF,GArBhD,IAAIA,KACT,KEFoB,iBADcG,EFIVN,KAAcG,KEHI,OAAVG,GAAoC,mBAAVA,IACD,mBAA/CA,EAAsCC,MAC7CC,QAAQC,QAAQH,GAAOI,MAAM,OFEhC,OAEA,CEPG,IAA+BJ,ICChCK,iBAAA,IAAuBC,QAGtB,SAASC,EAAwCC,GAEtD,OADAH,EAAiBI,IAAID,GACdA,CACT,CF0CO,SAASE,EAAYC,GAC1B,MAAMC,EApBR,WAEE,QAAmB,IAAfjB,EAA0B,OAAOA,EACrC,MAAMkB,EAVR,WACE,MAAMC,EAAaC,WAA0CC,aAC7D,GAAyB,iBAAdF,GAAwC,OAAdA,EAErC,MAAyB,mBADTA,EAAyCG,aAClBH,OAAwC,CACjF,CAKcI,GACZ,QAAY,IAARL,EAEF,OADAlB,EAAa,KACN,KAET,IACEA,EAAakB,EAAII,aA7BoB,uBA6BoB,CAAEE,WAAaC,GAAUA,GACpF,OAGEzB,EAAa,IACf,CACA,OAAOA,CACT,CAIiB0B,GACf,OAAe,OAAXT,EAAwBD,EACrBC,EAAOO,WAAWR,EAC3B,CGxDA,IAAMW,iBAAA,IAA0CC,IAAI,CAAC,QAAS,SAAU,UAAW,SAG7EC,EAA6B,wDAE7BC,EAAgB,mCAIhBC,EAAoB,YAGpBC,EAAiB,YAGhB,SAASC,UAAUC,GACxB,GAAmB,iBAARA,GAAmC,IAAfA,EAAIC,OAAc,OAAO,EACxD,MAAMC,EAAUF,EAAIG,OAAOC,QAAQN,EAAgB,IACnD,GAAuB,IAAnBI,EAAQD,OAAc,OAAO,EACjC,GAAIN,EAA2BU,KAAKH,GAAU,OAAO,EACrD,GAAIA,EAAQI,WAAW,MAAQJ,EAAQI,WAAW,KAAM,OAAO,EAC/D,GAAIT,EAAkBQ,KAAKH,GAAU,OAAO,EAC5C,GAAIA,EAAQI,WAAW,KAAM,OAAO,EACpC,IACE,MAAMC,EAAS,IAAIC,IAAIN,GACvB,OAAOT,EAAegB,IAAIF,EAAOG,SACnC,OACE,OAAOd,EAAcS,KAAKH,EAC5B,CACF,CCtBA,IAAMS,iBAAA,IAAwCjB,IAAI,CAChD,IACA,KACA,SACA,IACA,KACA,IACA,IACA,IACA,SACA,OACA,QACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,KACA,aACA,OACA,MACA,MACA,OACA,MACA,IACA,OACA,MACA,UACA,UACA,QACA,SACA,SACA,MACA,SACA,aACA,MACA,UACA,SACA,QACA,QACA,MACA,MACA,KACA,OACA,OACA,OACA,IACA,QACA,QACA,QACA,QACA,KACA,KACA,KACA,UACA,WACA,QAIIkB,iBAAA,IAAyClB,IAAI,CACjD,QACA,SACA,WACA,SACA,SACA,UAIImB,iBAAA,IAA6CnB,IAAI,CACrD,SACA,QACA,SACA,SACA,QACA,OACA,OACA,OACA,OACA,QACA,SACA,SACA,WACA,MACA,OACA,WACA,QACA,WACA,WACA,aAGIoB,iBAAA,IAAuCpB,IAAI,CAC/C,KACA,QACA,OACA,MACA,QACA,OACA,aAGIqB,EAAmB,QACnBC,EAAmB,QAGnBC,EAA6D,CACjEC,iBAAG,IAAIxB,IAAI,CAAC,OAAQ,SAAU,MAAO,WAAY,WAAY,SAC7DyB,mBAAK,IAAIzB,IAAI,CAAC,MAAO,SAAU,QAAS,MAAO,QAAS,SAAU,UAAW,aAC7E0B,uBAAS,IAAI1B,IAAI,IACjB2B,sBAAA,IAAY3B,IAAI,CAAC,MAAO,SAAU,QAAS,OAAQ,UACnD4B,qBAAO,IAAI5B,IAAI,CAAC,MAAO,WAAY,WAAY,OAAQ,QAAS,YAChE6B,qBAAA,IAAW7B,IAAI,CACb,MACA,SACA,WACA,WACA,OACA,QACA,UACA,QACA,SACA,gBAEF8B,oBAAM,IAAI9B,IAAI,CAAC,aACf+B,oBAAM,IAAI/B,IAAI,CAAC,UACfgC,iBAAG,IAAIhC,IAAI,CAAC,SACZiC,0BAAY,IAAIjC,IAAI,CAAC,SACrBkC,qBAAO,IAAIlC,IAAI,CAAC,YAChBmC,kBAAA,IAAQnC,IAAI,CAAC,UAAW,UAAW,QAAS,UAAW,SACvDoC,kBAAI,IAAIpC,IAAI,CAAC,UAAW,UAAW,YACnCqC,mBAAK,IAAIrC,IAAI,CAAC,SACd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","ignoreList":[]}
|