@svelte-vitals/core 0.55.0 → 0.55.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/internal.js CHANGED
@@ -1,4 +1,4 @@
1
- import { $ as SECTIONING_TAGS, $n as formatFailedRuleWarning, $t as valueFromNodes, A as a11yAbbrTitle, An as seoDescriptionLength, At as collectDerivedGuardBindings, B as a11yUseList, Bn as seoOgUrl, Bt as unwrapTs, C as a11yDisallowedElement, Cn as seoHeadingLevelSkip, Cr as summarize, Ct as parseKitModuleFacts, D as a11yDeprecatedElement, Dn as seoHreflang, Dr as defaultConfig, Dt as addBoundNames, E as a11yDeprecatedAttr, En as seoSingleH1, Et as WALK_IGNORED_KEYS, F as isInteractiveContainer, Fn as seoJsonLdRelativeUrl, Ft as matchLifecycleCall, G as a11yInvalidAriaValue, Gn as isPlainObject, Gt as attrText, H as a11yAccessibleName, Hn as seoTwitterCard, Ht as walkEvalScope, I as isInteractiveElement, In as seoJsonLdDeprecatedType, It as parseModuleProgram, J as a11yInvalidRole, Jn as validateRuleSetting, Jt as attrValueOf, K as a11yRequiredAriaProps, Kn as resolveRuleOptions, Kt as attrTextOf, L as literalTabindexValue, Ln as seoJsonLdValidity, Lt as rootObjectName, M as a11yNoAutofocus, Mn as seoJsonLdRequiredProps, Mt as collectProgramBindings, N as a11yNoAccesskey, Nn as seoJsonLdPlaceholder, Nt as collectSuppressions, O as HTML_SPEC, On as seoImageAlt, Or as defaultProject, Ot as collectBrowserGlobalRefs, P as a11yPositiveTabindex, Pn as seoJsonLdDateFormat, Pt as collectSvelteLifecycleImports, Q as NAMING_ATTRS, Qn as compileOverrides, Qt as textFromNodes, R as a11yRequireDatetime, Rn as seoSitemapInRobots, Rt as scopeIntroducedNames, S as a11yPermittedContents, Sn as seoSsrDisabled, Sr as hasFailureAtOrAbove, St as parseInMemoryExports, T as a11yDisallowedAriaProps, Tn as seoDuplicateTitle, Tr as isPenalized, Tt as isRootRelativePath, U as a11yAriaHiddenFocus, Un as seoIndexability, Ut as walkScoped, V as a11yLabelHasControl, Vn as seoOgDescription, Vt as walkEstree, W as a11yInteractiveNesting, Wn as performancePreconnect, Wt as CHILD_NODE_KEYS, X as ASIDE_DEMOTING_TAGS, Xn as applyOverrides, Xt as lineOf, Y as ANCESTRY_DEPENDENT_TAGS, Yn as SEARCH_RESULT_RULES, Yt as findAttr, Z as IDREF_ATTRS, Zn as applyRuleSeverities, Zt as parseSvelte, _ as a11yIdDuplication, _n as correctnessUnmutatedState, _r as seoCanonicalUrl, _t as architectureReservedDirectoryNames, a as formatJsonReport, an as securityJavascriptUrl, ar as performanceLcpImage, at as stripTextDirective, b as a11yDoctype, bn as correctnessEachIndexKey, br as classify, bt as architecturePrivateScopeImport, c as formatGithubReport, cn as correctnessServerBrowserGlobal, cr as performanceResponsiveImage, ct as performanceStateRaw, d as ruleMetaById, dn as correctnessOrphanEffect, dr as seoHtmlLang, dt as performanceMinifyDisabled, en as architecturePropCount, er as selectRules, et as decodeFragmentId, f as severityToSarifLevel, fn as correctnessAutoplayMuted, fr as seoSitemapXml, ft as performanceNamespaceImport, g as a11yNoMissingIdRef, gn as correctnessPropMutation, gr as seoOgImage, gt as architectureReservedNamePlacement, h as a11yUnverifiedIdRef, hn as correctnessStalePropDerivation, hr as seoOgTitle, ht as architectureRouteComponentImport, i as buildJsonReport, in as securityHandlerStateWrite, ir as performanceRenderBlockingScript, it as splitTokens, j as a11yNoDuplicateDt, jn as seoTitleLength, jt as collectNamedImportAliases, k as a11yPatternTitle, kn as seoCharset, kt as collectBrowserGuardImports, l as SEVERITY_RANK, ln as correctnessBasePathNavigation, lr as performanceImageLoadingHint, lt as performanceSequentialAwaits, m as explainRule, mn as correctnessNonreactiveBuiltinState, mr as seoJsonLd, mt as architectureDocLinkTarget, n as mdEscape, nn as securitySharedStateImport, nr as withFailedRulesOff, nt as isTopFragment, o as computeHealth, on as securityRawHtml, or as performanceFontPreloadCrossorigin, ot as resolveRole, p as allRules, pn as correctnessCheckableBindValue, pr as seoRobotsTxt, pt as performanceHeavyImport, q as a11yUnknownAriaAttribute, qn as shouldSkipRangeCheck, qt as attrValue, r as terminalSafe, rn as securityServerModuleState, rr as withIndexableOff, rt as resolveLandmark, s as computeScore, sn as correctnessInstanceBrowserGlobal, sr as performancePreloadMissingAs, st as performanceIframeLoading, t as formatMarkdownReport, tn as architectureComponentSize, tr as settingSeverity, tt as foldOccurrences, u as messageText, un as correctnessOrphanLifecycle, ur as performanceImageDimensions, ut as performanceLoadWaterfall, v as a11yTopLevelLandmark, vn as correctnessEffectAsOnMount, vr as seoDescriptionPresence, vt as architectureDirectoryNaming, w as a11yDeprecatedAria, wn as seoDuplicateDescription, wr as docsUrlFor, wt as resolveRepoLocalPath, x as a11yRequiredElement, xn as correctnessEachKey, xr as effectiveSeverity, xt as collectTopLevelBindings, y as a11yDuplicateLandmark, yn as correctnessEffectAsDerived, yr as seoTitlePresence, yt as architectureUnitEntryFile, z as a11yPlaceholderLabelOption, zn as seoViewport, zt as unwrapExport } from "./markdown-CgcwmqWX.js";
1
+ import { $ as performanceMinifyDisabled, $n as applyRuleSeverities, $t as correctnessOrphanLifecycle, A as a11yAbbrTitle, An as seoImageAlt, Ar as defaultProject, At as walkEstree, B as a11yUseList, Bn as seoSitemapInRobots, Bt as parseSvelte, C as a11yDisallowedElement, Cn as foldOccurrences, Cr as effectiveSeverity, Ct as collectSvelteLifecycleImports, D as a11yDeprecatedElement, Dn as stripTextDirective, Dr as isPenalized, Dt as scopeIntroducedNames, E as a11yDeprecatedAttr, En as splitTokens, Er as docsUrlFor, Et as rootObjectName, F as isInteractiveContainer, Fn as seoJsonLdPlaceholder, Ft as attrTextOf, G as a11yInvalidAriaValue, Gn as seoIndexability, Gt as securitySharedStateImport, H as a11yAccessibleName, Hn as seoOgUrl, Ht as valueFromNodes, I as isInteractiveElement, In as seoJsonLdDateFormat, It as attrValue, J as a11yInvalidRole, Jn as resolveRuleOptions, Jt as securityJavascriptUrl, K as a11yRequiredAriaProps, Kn as performancePreconnect, Kt as securityServerModuleState, L as literalTabindexValue, Ln as seoJsonLdRelativeUrl, Lt as attrValueOf, M as a11yNoAutofocus, Mn as seoDescriptionLength, Mt as walkScoped, N as a11yNoAccesskey, Nn as seoTitleLength, Nt as CHILD_NODE_KEYS, O as HTML_SPEC, On as resolveRole, Ot as unwrapExport, P as a11yPositiveTabindex, Pn as seoJsonLdRequiredProps, Pt as attrText, Q as performanceLoadWaterfall, Qn as applyOverrides, Qt as correctnessBasePathNavigation, R as a11yRequireDatetime, Rn as seoJsonLdDeprecatedType, Rt as findAttr, S as a11yPermittedContents, Sn as decodeFragmentId, Sr as classify, St as collectSuppressions, T as a11yDisallowedAriaProps, Tn as resolveLandmark, Tr as summarize, Tt as parseModuleProgram, U as a11yAriaHiddenFocus, Un as seoOgDescription, Ut as architecturePropCount, V as a11yLabelHasControl, Vn as seoViewport, Vt as textFromNodes, W as a11yInteractiveNesting, Wn as seoTwitterCard, Wt as architectureComponentSize, X as performanceStateRaw, Xn as validateRuleSetting, Xt as correctnessInstanceBrowserGlobal, Y as performanceIframeLoading, Yn as shouldSkipRangeCheck, Yt as securityRawHtml, Z as performanceSequentialAwaits, Zn as SEARCH_RESULT_RULES, Zt as correctnessServerBrowserGlobal, _ as a11yIdDuplication, _n as ANCESTRY_DEPENDENT_TAGS, _r as seoOgTitle, _t as collectBrowserGlobalRefs, a as formatJsonReport, an as correctnessPropMutation, ar as withIndexableOff, at as architectureReservedDirectoryNames, b as a11yDoctype, bn as NAMING_ATTRS, br as seoDescriptionPresence, bt as collectNamedImportAliases, c as formatGithubReport, cn as correctnessEffectAsDerived, cr as performanceFontPreloadCrossorigin, ct as architecturePrivateScopeImport, d as ruleMetaById, dn as seoSsrDisabled, dr as performanceImageLoadingHint, dt as parseInMemoryExports, en as correctnessOrphanEffect, er as compileOverrides, et as performanceNamespaceImport, f as severityToSarifLevel, fn as routeNeverSsr, fr as performanceImageDimensions, ft as parseKitModuleFacts, g as a11yNoMissingIdRef, gn as seoSingleH1, gr as seoJsonLd, gt as addBoundNames, h as a11yUnverifiedIdRef, hn as seoDuplicateTitle, hr as seoRobotsTxt, ht as WALK_IGNORED_KEYS, i as buildJsonReport, in as correctnessStalePropDerivation, ir as withFailedRulesOff, it as architectureReservedNamePlacement, j as a11yNoDuplicateDt, jn as seoCharset, jt as walkEvalScope, k as a11yPatternTitle, kn as seoHreflang, kr as defaultConfig, kt as unwrapTs, l as SEVERITY_RANK, ln as correctnessEachIndexKey, lr as performancePreloadMissingAs, lt as DEFAULT_KIT_ALIASES, m as explainRule, mn as seoDuplicateDescription, mr as seoSitemapXml, mt as isRootRelativePath, n as mdEscape, nn as correctnessCheckableBindValue, nr as selectRules, nt as architectureDocLinkTarget, o as computeHealth, on as correctnessUnmutatedState, or as performanceRenderBlockingScript, ot as architectureDirectoryNaming, p as allRules, pn as seoHeadingLevelSkip, pr as seoHtmlLang, pt as resolveRepoLocalPath, q as a11yUnknownAriaAttribute, qn as isPlainObject, qt as securityHandlerStateWrite, r as terminalSafe, rn as correctnessNonreactiveBuiltinState, rr as settingSeverity, rt as architectureRouteComponentImport, s as computeScore, sn as correctnessEffectAsOnMount, sr as performanceLcpImage, st as architectureUnitEntryFile, t as formatMarkdownReport, tn as correctnessAutoplayMuted, tr as formatFailedRuleWarning, tt as performanceHeavyImport, u as messageText, un as correctnessEachKey, ur as performanceResponsiveImage, ut as collectTopLevelBindings, v as a11yTopLevelLandmark, vn as ASIDE_DEMOTING_TAGS, vr as seoOgImage, vt as collectBrowserGuardImports, w as a11yDeprecatedAria, wn as isTopFragment, wr as hasFailureAtOrAbove, wt as matchLifecycleCall, x as a11yRequiredElement, xn as SECTIONING_TAGS, xr as seoTitlePresence, xt as collectProgramBindings, y as a11yDuplicateLandmark, yn as IDREF_ATTRS, yr as seoCanonicalUrl, yt as collectDerivedGuardBindings, z as a11yPlaceholderLabelOption, zn as seoJsonLdValidity, zt as lineOf } from "./markdown-DgHBAvYl.js";
2
2
  //#region src/head.ts
3
3
  const JS_MIME_TYPES = /* @__PURE__ */ new Set([
4
4
  "application/ecmascript",
@@ -32,20 +32,42 @@ function isClassicScriptType(type) {
32
32
  return JS_MIME_TYPES.has(type.replace(ASCII_WHITESPACE_EDGES, "").toLowerCase());
33
33
  }
34
34
  //#endregion
35
+ //#region src/images.ts
36
+ /** A `.svg` path (query and fragment ignored) or an inline `data:image/svg+xml` URI. */
37
+ function isSvgSrc(src) {
38
+ return /^data:image\/svg\+xml[;,]/i.test(src) || /\.svg$/i.test(src.split(/[?#]/, 1)[0]);
39
+ }
40
+ //#endregion
35
41
  //#region src/component-parse.ts
36
42
  const KNOWN_TAGS = new Set(Object.keys(HTML_SPEC.elements).map((k) => k.replace(/^svg:/, "").toLowerCase()));
37
- /** Whether `expr` is a length-only list constructor: `Array(n)` / `new Array(n)` (single argument = length semantics) or `Array.from({ length: n }, …)`. */
43
+ /**
44
+ * Whether `expr` is a length-only list constructor: `Array(n)` / `new Array(n)` (single argument =
45
+ * length semantics), `Array.from({ length: n }, …)`, or `Array.from(<any of these>, …)`, optionally
46
+ * followed by `.fill(x)` (every item the same value) or `.keys()` (the indices themselves).
47
+ */
38
48
  function isLengthOnlyArrayCall(expr) {
39
49
  const e = unwrapTs(expr);
40
50
  if (!e) return false;
51
+ if (e.type === "CallExpression" && e.callee?.type === "MemberExpression" && !e.callee.computed && e.callee.object.type !== "Super" && e.callee.property.type === "Identifier" && (e.callee.property.name === "fill" || e.callee.property.name === "keys")) {
52
+ const receiver = unwrapTs(e.callee.object);
53
+ if (receiver?.type === "ArrayExpression") return receiver.elements.every((el) => el?.type !== "SpreadElement" || isLengthOnlyArrayCall(el.argument));
54
+ return isLengthOnlyArrayCall(e.callee.object);
55
+ }
41
56
  if ((e.type === "CallExpression" || e.type === "NewExpression") && e.callee?.type === "Identifier" && e.callee.name === "Array") return (e.arguments?.length ?? 0) === 1;
42
- if (e.type === "CallExpression" && e.callee?.type === "MemberExpression" && !e.callee.computed && e.callee.object?.type === "Identifier" && e.callee.object.name === "Array" && e.callee.property.type === "Identifier" && e.callee.property.name === "from" && e.arguments?.[0]?.type === "ObjectExpression") return (e.arguments[0].properties ?? []).some((p) => p?.type === "Property" && !p.computed && (p.key?.name === "length" || p.key?.value === "length"));
57
+ if (e.type === "CallExpression" && e.callee?.type === "MemberExpression" && !e.callee.computed && e.callee.object?.type === "Identifier" && e.callee.object.name === "Array" && e.callee.property.type === "Identifier" && e.callee.property.name === "from") {
58
+ const source = e.arguments?.[0];
59
+ if (source?.type === "ObjectExpression") return (source.properties ?? []).some(isLengthProperty);
60
+ return source !== void 0 && source.type !== "SpreadElement" && isLengthOnlyArrayCall(source);
61
+ }
43
62
  return false;
44
63
  }
64
+ function isLengthProperty(p) {
65
+ return p?.type === "Property" && !p.computed && (p.key?.name === "length" || p.key?.value === "length");
66
+ }
45
67
  /**
46
68
  * Whether the each expression yields no item identity to key on: a constant
47
69
  * inline array literal (fixed length, never reorders), a length-only list
48
- * (`Array(n)`, `new Array(n)`, `[...Array(n)]`, `Array.from({ length: n })` —
70
+ * (`Array(n)`, `new Array(n)`, `[...Array(n)]`, `Array.from({ length: n })`, `Array(n).fill(x)`, `{ length: n }` —
49
71
  * placeholder/skeleton lists), or a spread array whose every element spreads a
50
72
  * length-only list. Such blocks are skipped entirely — neither each-key nor
51
73
  * each-index-key can give useful advice on them.
@@ -53,6 +75,7 @@ function isLengthOnlyArrayCall(expr) {
53
75
  function isIdentityFreeEach(node) {
54
76
  const expr = unwrapTs(node.expression);
55
77
  if (expr.type === "ArrayExpression" && Array.isArray(expr.elements)) return expr.elements.every((el) => el?.type !== "SpreadElement" || isLengthOnlyArrayCall(el.argument));
78
+ if (expr.type === "ObjectExpression") return expr.properties.length === 1 && isLengthProperty(expr.properties[0]);
56
79
  return isLengthOnlyArrayCall(expr);
57
80
  }
58
81
  /**
@@ -97,19 +120,152 @@ function isIndexKey(each) {
97
120
  if (typeof each.index !== "string" || each.key == null) return false;
98
121
  return isIndexExpression(each.key, each.index);
99
122
  }
123
+ /**
124
+ * TS nodes that wrap value-space code; every other `TS*` node is a type position. Enums,
125
+ * namespaces and parameter properties are left out: Svelte's own TS support rejects them.
126
+ */
127
+ const TS_VALUE_NODES = /* @__PURE__ */ new Set([
128
+ "TSAsExpression",
129
+ "TSSatisfiesExpression",
130
+ "TSNonNullExpression",
131
+ "TSInstantiationExpression",
132
+ "TSTypeAssertion"
133
+ ]);
134
+ /**
135
+ * Names of `const X = [ … ]` array literals (script top level) that nothing can reorder: every
136
+ * other mention of `X` in the file is a member read, an `{#each X …}`, a `for (… of X)` or a copy into an array literal
137
+ * (`[...X]`). Such a list is the inline
138
+ * literal the each rules already skip, just given a name. Anything else — a mutating call, an
139
+ * assignment through it, passing or spreading `X` — keeps the list keyed. A component's value
140
+ * imports are held to the same uses (`imports`), since the module behind one may be such a list;
141
+ * a module's `export const` is a candidate only with `exported`, because a component's `export`
142
+ * is written by its parent.
143
+ */
144
+ function collectConstantLists(programs, fragment, opts = {}) {
145
+ const candidates = /* @__PURE__ */ new Map();
146
+ const safe = /* @__PURE__ */ new Set();
147
+ const iterated = opts.imports ? eachListRoots(fragment) : void 0;
148
+ for (const program of programs) for (const top of program.body ?? []) {
149
+ if (iterated?.size && top?.type === "ImportDeclaration" && top.importKind !== "type") for (const s of top.specifiers ?? []) {
150
+ if (s?.importKind === "type" || s?.type === "ImportDefaultSpecifier" || !iterated.has(s?.local?.name)) continue;
151
+ const imported = s.type === "ImportNamespaceSpecifier" ? "*" : s.imported?.name ?? s.imported?.value;
152
+ if (typeof imported !== "string") continue;
153
+ opts.imports.set(s.local.name, {
154
+ source: String(top.source.value),
155
+ imported
156
+ });
157
+ candidates.set(s.local.name, s.local);
158
+ safe.add(s.imported);
159
+ }
160
+ if (opts.exported && top?.type === "ExportNamedDeclaration" && !top.source) for (const s of top.specifiers ?? []) safe.add(s.local).add(s.exported);
161
+ const stmt = opts.exported ? unwrapExport(top) : top;
162
+ if (stmt?.type !== "VariableDeclaration" || stmt.kind !== "const") continue;
163
+ for (const d of stmt.declarations ?? []) {
164
+ const init = unwrapTs(d?.init);
165
+ if (d?.id?.type === "Identifier" && init?.type === "ArrayExpression") {
166
+ if (!(init.elements ?? []).some((el) => el?.type === "SpreadElement")) candidates.set(d.id.name, d.id);
167
+ }
168
+ }
169
+ }
170
+ if (candidates.size === 0) return /* @__PURE__ */ new Set();
171
+ for (const node of candidates.values()) safe.add(node);
172
+ const namespaces = new Set([...opts.imports ?? []].filter(([, b]) => b.imported === "*").map(([local]) => local));
173
+ const unsafe = /* @__PURE__ */ new Set();
174
+ const roots = [...programs, fragment];
175
+ const listOf = (n) => n?.type === "Identifier" && candidates.has(n.name) ? n.name : void 0;
176
+ const nsMember = (n) => n?.type === "MemberExpression" && !n.computed && namespaces.has(listOf(n.object)) ? `${n.object.name}.${n.property.name}` : void 0;
177
+ const members = /* @__PURE__ */ new Set();
178
+ for (const root of roots) walkEstree(root, (n) => {
179
+ if (n.type === "EachBlock" && (listOf(n.expression) || nsMember(n.expression))) safe.add(n.expression);
180
+ if (n.type === "ForOfStatement" && (listOf(n.right) || nsMember(n.right))) safe.add(n.right);
181
+ if (n.type === "ArrayExpression") {
182
+ for (const el of n.elements ?? []) if (el?.type === "SpreadElement" && (listOf(el.argument) || nsMember(el.argument))) safe.add(el.argument);
183
+ }
184
+ if (nsMember(n)) members.add(nsMember(n));
185
+ if (n.type === "MemberExpression") {
186
+ if (listOf(n.object) && !(n.computed && namespaces.has(n.object.name))) safe.add(n.object);
187
+ if (nsMember(n.object)) safe.add(n.object);
188
+ if (!n.computed) safe.add(n.property);
189
+ }
190
+ const target = n.type === "AssignmentExpression" ? n.left : n.type === "UpdateExpression" ? n.argument : void 0;
191
+ if (target?.type === "MemberExpression" && listOf(rootObjectNode(target))) unsafe.add(listOf(rootObjectNode(target)));
192
+ const called = n.type === "CallExpression" && n.callee?.type === "MemberExpression" ? n.callee.object : void 0;
193
+ const calledList = listOf(called) ?? nsMember(called);
194
+ if (calledList) {
195
+ const { computed, property } = n.callee;
196
+ const method = !computed ? property?.name : property?.type === "Literal" && typeof property.value === "string" ? property.value : void 0;
197
+ if (computed && method === void 0 || method !== void 0 && MUTATING_METHODS.has(method)) unsafe.add(calledList);
198
+ }
199
+ if (n.type === "BindDirective" && listOf(rootObjectNode(n.expression))) unsafe.add(listOf(rootObjectNode(n.expression)));
200
+ if (n.type === "Property" && !n.computed && !n.shorthand) safe.add(n.key);
201
+ });
202
+ for (const root of roots) walkEvalScope(root, (n) => {
203
+ if (n.type.startsWith("TS") && !TS_VALUE_NODES.has(n.type)) return true;
204
+ const name = listOf(n) ?? nsMember(n);
205
+ if (name && !safe.has(n)) unsafe.add(name);
206
+ return false;
207
+ }, /* @__PURE__ */ new Set(), /* @__PURE__ */ new Set());
208
+ return new Set([...candidates.keys(), ...members].filter((key) => !unsafe.has(key) && !unsafe.has(key.split(".")[0])));
209
+ }
210
+ /**
211
+ * Export names of a module's constant lists — `export const X = [ … ]`, or a local one exported by
212
+ * name — that the module itself never writes (correctness/each-key, correctness/each-index-key).
213
+ */
214
+ function collectConstantListExports(program) {
215
+ const lists = collectConstantLists([program], void 0, { exported: true });
216
+ const out = /* @__PURE__ */ new Set();
217
+ for (const top of program?.body ?? []) {
218
+ if (top?.type !== "ExportNamedDeclaration" || top.exportKind === "type") continue;
219
+ for (const d of top.declaration?.declarations ?? []) if (d?.id?.type === "Identifier" && lists.has(d.id.name)) out.add(d.id.name);
220
+ for (const s of top.source ? [] : top.specifiers ?? []) if (lists.has(s.local.name)) out.add(s.exported.name ?? s.exported.value);
221
+ }
222
+ return out;
223
+ }
224
+ /** The root names `{#each}` blocks iterate: `xs` for both `{#each xs …}` and `{#each xs.ys …}`. */
225
+ function eachListRoots(node, acc = /* @__PURE__ */ new Set()) {
226
+ if (Array.isArray(node)) {
227
+ for (const child of node) eachListRoots(child, acc);
228
+ return acc;
229
+ }
230
+ if (!node || typeof node !== "object") return acc;
231
+ if (node.type === "EachBlock") {
232
+ const expr = node.expression?.type === "MemberExpression" ? node.expression.object : node.expression;
233
+ if (expr?.type === "Identifier") acc.add(expr.name);
234
+ }
235
+ for (const key of CHILD_NODE_KEYS) if (key in node) eachListRoots(node[key], acc);
236
+ return acc;
237
+ }
238
+ /** The innermost object of a member chain (`a` for `a.b[c].d`), or the node itself. */
239
+ function rootObjectNode(n) {
240
+ let cur = n;
241
+ while (cur?.type === "MemberExpression") cur = cur.object;
242
+ return cur;
243
+ }
100
244
  /** Recursively collect every `{#each}` block in the template (correctness/each-key). */
101
- function collectEachBlocks(node, source, acc) {
245
+ function collectEachBlocks(node, source, acc, lists, imports) {
102
246
  if (Array.isArray(node)) {
103
- for (const child of node) collectEachBlocks(child, source, acc);
247
+ for (const child of node) collectEachBlocks(child, source, acc, lists, imports);
104
248
  return;
105
249
  }
106
250
  if (!node || typeof node !== "object") return;
107
- if (node.type === "EachBlock" && node.context != null && !isIdentityFreeEach(node)) acc.push({
108
- hasKey: node.key != null,
109
- line: lineOf(source, node.start),
110
- ...isIndexKey(node) ? { indexKey: true } : {}
111
- });
112
- for (const key of CHILD_NODE_KEYS) if (key in node) collectEachBlocks(node[key], source, acc);
251
+ if (node.type === "EachBlock" && node.context != null && !isIdentityFreeEach(node)) {
252
+ const expr = node.expression;
253
+ const list = expr?.type === "Identifier" ? expr.name : expr?.type === "MemberExpression" && !expr.computed && expr.object?.type === "Identifier" ? `${expr.object.name}.${expr.property.name}` : void 0;
254
+ const constant = list !== void 0 && lists.has(list);
255
+ const [local, member] = list?.split(".") ?? [];
256
+ const binding = constant ? imports.get(local) : void 0;
257
+ const indexKey = isIndexKey(node);
258
+ if (!constant || binding) acc.push({
259
+ hasKey: node.key != null,
260
+ line: lineOf(source, node.start),
261
+ ...indexKey ? { indexKey: true } : {},
262
+ ...binding && (indexKey || node.key == null) ? { importedList: member ? {
263
+ source: binding.source,
264
+ imported: member
265
+ } : binding } : {}
266
+ });
267
+ }
268
+ for (const key of CHILD_NODE_KEYS) if (key in node) collectEachBlocks(node[key], source, acc, lists, imports);
113
269
  }
114
270
  /**
115
271
  * Whether a CallExpression *creates an effect*: `$effect(...)` or `$effect.pre(...)`.
@@ -154,7 +310,7 @@ function isDerivedDeclaration(node) {
154
310
  if (c?.type === "MemberExpression" && c.object?.type === "Identifier" && c.object.name === "$derived") return c.property?.type === "Identifier" && c.property.name === "by";
155
311
  return false;
156
312
  }
157
- function collectStateWrites(root, stateNames, acc, kinds) {
313
+ function collectStateWrites(root, stateNames, acc, kinds, localStates = false) {
158
314
  const record = (name, kind) => {
159
315
  acc.add(name);
160
316
  if (kinds) {
@@ -163,7 +319,7 @@ function collectStateWrites(root, stateNames, acc, kinds) {
163
319
  set.add(kind);
164
320
  }
165
321
  };
166
- walkScoped(root, (n, scope) => {
322
+ const visit = (stateNames) => (n, scope) => {
167
323
  const shadowed = (name) => name === void 0 || scope.has(name);
168
324
  if (n?.type === "AssignmentExpression") {
169
325
  if (n.left?.type === "Identifier" && stateNames.has(n.left.name) && !shadowed(n.left.name)) record(n.left.name, "reassign");
@@ -196,6 +352,17 @@ function collectStateWrites(root, stateNames, acc, kinds) {
196
352
  if (r && stateNames.has(r) && !shadowed(r)) record(r, "escape");
197
353
  }
198
354
  }
355
+ };
356
+ walkScoped(root, visit(stateNames));
357
+ if (!localStates) return;
358
+ walkEstree(root, (n) => {
359
+ if (n.type !== "BlockStatement") return;
360
+ const own = /* @__PURE__ */ new Set();
361
+ for (const stmt of n.body ?? []) {
362
+ if (stmt?.type !== "VariableDeclaration") continue;
363
+ for (const d of stmt.declarations ?? []) if (d?.id?.type === "Identifier" && stateNames.has(d.id.name) && isStateDeclaration(unwrapTs(d.init))) own.add(d.id.name);
364
+ }
365
+ if (own.size > 0) walkScoped(n.body, visit(own));
199
366
  });
200
367
  }
201
368
  /** Function-shaped nodes whose bodies defer evaluation — prop reads inside them stay reactive (compiled to call-time reads). */
@@ -421,16 +588,17 @@ function collectFragmentAliasRefs(node, names, acc, shadowed = /* @__PURE__ */ n
421
588
  }
422
589
  }
423
590
  /**
424
- * Each-context taint (performance/state-raw condition 5): for `{#each candidate as item}`
591
+ * Each-context taint (performance/state-raw condition 5, correctness/unmutated-state): for `{#each candidate as item}`
425
592
  * or `{#each candidate.path as item}`, any mutate/escape of the context binding (or index)
426
593
  * inside the block — member writes, method calls, call arguments, `bind:`, component props —
427
594
  * disqualifies the candidate over the candidate or a member path of it
428
595
  * (`{#each obj.items as item}`): item-level edits stop being reactive under $state.raw.
429
596
  * Pure reassignments of the context name are ignored (they don't touch the list's contents).
597
+ * `includeIndex: false` ignores the index binding, a number that cannot carry a write back to the list.
430
598
  */
431
- function collectEachContextTaint(node, names, acc, shadowed = /* @__PURE__ */ new Set()) {
599
+ function collectEachContextTaint(node, names, acc, shadowed = /* @__PURE__ */ new Set(), includeIndex = true) {
432
600
  if (Array.isArray(node)) {
433
- for (const child of node) collectEachContextTaint(child, names, acc, shadowed);
601
+ for (const child of node) collectEachContextTaint(child, names, acc, shadowed, includeIndex);
434
602
  return;
435
603
  }
436
604
  if (!node || typeof node !== "object" || typeof node.type !== "string") return;
@@ -442,7 +610,7 @@ function collectEachContextTaint(node, names, acc, shadowed = /* @__PURE__ */ ne
442
610
  if (target !== void 0 && names.has(target) && !shadowed.has(target)) {
443
611
  const ctxNames = /* @__PURE__ */ new Set();
444
612
  addBoundNames(node.context, ctxNames);
445
- if (typeof node.index === "string") ctxNames.add(node.index);
613
+ if (includeIndex && typeof node.index === "string") ctxNames.add(node.index);
446
614
  if (ctxNames.size > 0) {
447
615
  const union = /* @__PURE__ */ new Set();
448
616
  const kinds = /* @__PURE__ */ new Map();
@@ -457,7 +625,7 @@ function collectEachContextTaint(node, names, acc, shadowed = /* @__PURE__ */ ne
457
625
  }
458
626
  for (const key of Object.keys(node)) {
459
627
  if (WALK_IGNORED_KEYS.has(key)) continue;
460
- collectEachContextTaint(node[key], names, acc, scope);
628
+ collectEachContextTaint(node[key], names, acc, scope, includeIndex);
461
629
  }
462
630
  }
463
631
  /**
@@ -656,6 +824,30 @@ function collectNewExprLocalNames(program, acc) {
656
824
  });
657
825
  }
658
826
  /**
827
+ * Top-level locals declared as a plain alias of an imported binding or a `new …()` local
828
+ * (`const p = presenter`, `const p = presenter as Presenter`), to a fixed point so alias chains resolve in any order
829
+ * (correctness/effect-as-onmount). Top level only: names match by text, not scope, so a
830
+ * function-local `const id = presenter` would otherwise mark every `id` in the component reactive.
831
+ * Runs before rune names are added: an alias of a `$state` primitive is a non-reactive snapshot.
832
+ */
833
+ function collectAliasLocalNames(program, acc) {
834
+ const declarators = (program?.body ?? []).flatMap((stmt) => {
835
+ const decl = unwrapExport(stmt);
836
+ return decl?.type === "VariableDeclaration" ? decl.declarations : [];
837
+ });
838
+ for (let grew = true; grew;) {
839
+ grew = false;
840
+ for (const d of declarators) {
841
+ if (d.id?.type !== "Identifier" || !d.init || acc.has(d.id.name)) continue;
842
+ const init = unwrapTs(d.init);
843
+ if (init.type === "Identifier" && acc.has(init.name)) {
844
+ acc.add(d.id.name);
845
+ grew = true;
846
+ }
847
+ }
848
+ }
849
+ }
850
+ /**
659
851
  * Whether an $effect callback body reads a reactive value (correctness/effect-as-onmount, conservative):
660
852
  * a reactive name (rune declarator, imported binding, or a local declared with a `new …()`
661
853
  * initializer — see `collectImportedLocalNames`/`collectNewExprLocalNames`), a `$`-prefixed
@@ -851,10 +1043,12 @@ function collectAriaElements(node, source, acc) {
851
1043
  const hasList = tag === "input" && findAttr(node.attributes, "list") !== void 0;
852
1044
  const selectKind = tag === "select" ? selectNativeRole(node.attributes) : void 0;
853
1045
  const hasSpread = node.attributes.some((a) => a?.type === "SpreadAttribute");
1046
+ const hasAction = node.attributes.some((a) => a?.type === "UseDirective");
854
1047
  acc.push({
855
1048
  tag,
856
1049
  line: lineOf(source, node.start),
857
1050
  ...roleAttr ? { role: classifyAttrValue(roleAttr.value) } : {},
1051
+ ...hasAction ? { hasAction: true } : {},
858
1052
  ...inputType !== void 0 ? { inputType: inputType.toLowerCase() } : {},
859
1053
  ...hasList ? { hasList: true } : {},
860
1054
  ...selectKind ? { selectKind } : {},
@@ -989,10 +1183,13 @@ function hasNamingAttr(attributes) {
989
1183
  "title"
990
1184
  ].some((name) => hasNamingValue(attributes, name));
991
1185
  }
992
- /** A tag name with a hyphen is a custom element: it may be form-associated, and its shadow root may
993
- * supply content, neither of which is visible here. Treated as unknowable by both a11y scanners. */
1186
+ /** A custom element may be form-associated and its shadow root may supply content; a namespaced tag
1187
+ * (`<enhanced:img>`) is rewritten by a preprocessor into markup not visible here. Treated as
1188
+ * unknowable by both a11y scanners. */
994
1189
  function isCustomElement(node) {
995
- return node.type === "RegularElement" && typeof node.name === "string" && node.name.includes("-");
1190
+ if (node.type !== "RegularElement" || typeof node.name !== "string") return false;
1191
+ const tag = node.name.toLowerCase();
1192
+ return tag.includes("-") || !KNOWN_TAGS.has(tag);
996
1193
  }
997
1194
  function scanAccessibleNameSubtree(node, skip) {
998
1195
  if (Array.isArray(node)) {
@@ -1591,6 +1788,7 @@ function collectLegacyPropNames(program) {
1591
1788
  const names = /* @__PURE__ */ new Set();
1592
1789
  for (const stmt of program.body ?? []) {
1593
1790
  if (stmt?.type !== "ExportNamedDeclaration" || stmt.declaration?.type !== "VariableDeclaration") continue;
1791
+ if (stmt.declaration.kind === "const") continue;
1594
1792
  for (const d of stmt.declaration.declarations ?? []) if (d?.id?.type === "Identifier") names.add(d.id.name);
1595
1793
  }
1596
1794
  return names;
@@ -1619,9 +1817,27 @@ const MUTATING_METHODS = /* @__PURE__ */ new Set([
1619
1817
  * reassignment for ephemeral state; only mutation is prohibited. Run over the instance
1620
1818
  * program AND the template fragment (inline handlers can mutate props in the template).
1621
1819
  * Scope-aware (issue #140): a local that shadows the prop's name is not flagged.
1820
+ * A `legacy` (export let) prop is flagged only for `delete` and mutating method calls — the legacy
1821
+ * compiler turns a member write or update into an invalidating assignment (`prop(prop().x = …, true)`).
1622
1822
  */
1623
- function collectPropMutations(root, propNames, source, acc) {
1823
+ function collectPropMutations(root, propNames, source, acc, legacy) {
1624
1824
  if (propNames.size === 0) return;
1825
+ const exemptCalls = /* @__PURE__ */ new Set();
1826
+ if (legacy.size > 0) walkEstree(root, (fn) => {
1827
+ if (!isDeferredBody(fn)) return;
1828
+ const assigned = /* @__PURE__ */ new Set();
1829
+ walkScoped(fn.body, (m, scope) => {
1830
+ if (m.type === "AssignmentExpression" && m.left?.type === "Identifier" && !scope.has(m.left.name)) assigned.add(m.left.name);
1831
+ });
1832
+ walkEstree(fn.body, (m) => {
1833
+ const r = m.type === "CallExpression" ? rootObjectName(m.callee?.object) : m.type === "UnaryExpression" && m.operator === "delete" ? rootObjectName(m.argument) : void 0;
1834
+ if (r && legacy.has(r) && assigned.has(r)) exemptCalls.add(m);
1835
+ });
1836
+ });
1837
+ walkEstree(root, (m) => {
1838
+ const call = m.type === "AssignmentExpression" && m.left?.type === "Identifier" ? m.right : void 0;
1839
+ if (call?.type === "CallExpression" && rootObjectName(call.callee?.object) === m.left.name && call.arguments?.length === 1 && call.arguments[0]?.type === "ObjectExpression") exemptCalls.add(call);
1840
+ });
1625
1841
  walkScoped(root, (n, scope) => {
1626
1842
  const flag = (r) => {
1627
1843
  if (r && propNames.has(r) && !scope.has(r)) acc.push({
@@ -1629,9 +1845,14 @@ function collectPropMutations(root, propNames, source, acc) {
1629
1845
  line: lineOf(source, n.start)
1630
1846
  });
1631
1847
  };
1632
- if (n.type === "AssignmentExpression" && n.left?.type === "MemberExpression") flag(rootObjectName(n.left));
1633
- else if (n.type === "UpdateExpression" && n.argument?.type === "MemberExpression") flag(rootObjectName(n.argument));
1634
- else if (n.type === "UnaryExpression" && n.operator === "delete") flag(rootObjectName(n.argument));
1848
+ if (exemptCalls.has(n)) return;
1849
+ if (n.type === "AssignmentExpression" && n.left?.type === "MemberExpression") {
1850
+ const r = rootObjectName(n.left);
1851
+ if (r && !legacy.has(r)) flag(r);
1852
+ } else if (n.type === "UpdateExpression" && n.argument?.type === "MemberExpression") {
1853
+ const r = rootObjectName(n.argument);
1854
+ if (r && !legacy.has(r)) flag(r);
1855
+ } else if (n.type === "UnaryExpression" && n.operator === "delete") flag(rootObjectName(n.argument));
1635
1856
  else if (n.type === "CallExpression" && n.callee?.type === "MemberExpression") {
1636
1857
  const method = n.callee.property?.type === "Identifier" ? n.callee.property.name : void 0;
1637
1858
  if (method && MUTATING_METHODS.has(method)) flag(rootObjectName(n.callee.object));
@@ -1666,13 +1887,18 @@ function isTypeOnlyImport(n) {
1666
1887
  const specs = n.specifiers;
1667
1888
  return Array.isArray(specs) && specs.length > 0 && specs.every((s) => s?.importKind === "type");
1668
1889
  }
1890
+ /** Whether an import declaration binds only named exports — no default, `default as`, or namespace (see `ComponentFacts.importSpans`). */
1891
+ function isNamedOnlyImport(n) {
1892
+ const specs = n.specifiers;
1893
+ return Array.isArray(specs) && specs.length > 0 && specs.every((s) => s?.type === "ImportSpecifier" && (s.imported?.name ?? s.imported?.value) !== "default");
1894
+ }
1669
1895
  /** Module specifiers of every `import`, each with its source line (see `ComponentFacts.importSpans`). */
1670
1896
  function collectImportSources(program, source, acc) {
1671
1897
  walkEstree(program, (n) => {
1672
1898
  if (n.type === "ImportDeclaration" && typeof n.source?.value === "string") acc.push({
1673
1899
  source: n.source.value,
1674
1900
  line: lineOf(source, n.start),
1675
- ...isTypeOnlyImport(n) ? { type: true } : {}
1901
+ ...isTypeOnlyImport(n) ? { type: true } : isNamedOnlyImport(n) ? { named: true } : {}
1676
1902
  });
1677
1903
  });
1678
1904
  }
@@ -1680,13 +1906,45 @@ function collectImportSources(program, source, acc) {
1680
1906
  function isBareSpecifier(s) {
1681
1907
  return !/^[./$#]/.test(s);
1682
1908
  }
1683
- /** Value `import * as X from '<bare pkg>'` namespace imports (type-only excluded) — performance/namespace-import. */
1684
- function collectNamespaceImports(program, source, acc) {
1909
+ /**
1910
+ * Whether `name` is used anywhere in `roots` other than as the object of a static member access
1911
+ * (`X.foo`, `X['foo']`) — passing `X` on, spreading it or indexing it by a variable is what makes
1912
+ * a bundler keep the whole module. `<X.Foo />` in markup is a component name, not an identifier,
1913
+ * so it counts as static. A same-named local (`scopeIntroducedNames`) shadows the namespace.
1914
+ */
1915
+ function namespaceUsedDynamically(name, roots) {
1916
+ const staticOrDeclaring = /* @__PURE__ */ new Set();
1917
+ for (const root of roots) walkEstree(root, (n) => {
1918
+ if (n.type === "MemberExpression") {
1919
+ const literalKey = n.computed && n.property?.type === "Literal" && typeof n.property.value === "string";
1920
+ if (n.object?.type === "Identifier" && n.object.name === name && (!n.computed || literalKey)) staticOrDeclaring.add(n.object);
1921
+ if (!n.computed) staticOrDeclaring.add(n.property);
1922
+ } else if ((n.type === "Property" && !n.shorthand || n.type === "TSPropertySignature" || n.type === "TSMethodSignature") && !n.computed) staticOrDeclaring.add(n.key);
1923
+ else if (n.type === "ImportNamespaceSpecifier") staticOrDeclaring.add(n.local);
1924
+ else if (n.type === "TSQualifiedName" || n.type === "TSTypeQuery") {
1925
+ const id = n.type === "TSQualifiedName" ? n.left : n.exprName;
1926
+ if (id?.type === "Identifier") staticOrDeclaring.add(id);
1927
+ if (n.type === "TSQualifiedName") staticOrDeclaring.add(n.right);
1928
+ }
1929
+ });
1930
+ let dynamic = false;
1931
+ for (const root of roots) walkScoped(root, (n, shadowed) => {
1932
+ if (n.type === "Identifier" && n.name === name && !staticOrDeclaring.has(n) && !shadowed.has(name)) dynamic = true;
1933
+ });
1934
+ return dynamic;
1935
+ }
1936
+ /**
1937
+ * Value `import * as X from '<bare pkg>'` namespace imports (type-only excluded) that `roots` (every
1938
+ * program and template of the file) use dynamically — performance/namespace-import. Static member
1939
+ * accesses tree-shake like named imports, so a namespace used only that way is not reported.
1940
+ */
1941
+ function collectNamespaceImports(program, source, acc, roots) {
1685
1942
  walkEstree(program, (n) => {
1686
1943
  if (n.type !== "ImportDeclaration" || n.importKind === "type") return;
1687
1944
  const spec = n.source?.value;
1688
1945
  if (typeof spec !== "string" || !isBareSpecifier(spec)) return;
1689
- if (Array.isArray(n.specifiers) && n.specifiers.some((s) => s?.type === "ImportNamespaceSpecifier")) acc.push({
1946
+ const ns = (n.specifiers ?? []).find((s) => s?.type === "ImportNamespaceSpecifier");
1947
+ if (ns?.local?.type === "Identifier" && namespaceUsedDynamically(ns.local.name, roots)) acc.push({
1690
1948
  source: spec,
1691
1949
  line: lineOf(source, n.start)
1692
1950
  });
@@ -1931,7 +2189,7 @@ function parseModuleFacts(source, filename) {
1931
2189
  line: shift(s.line)
1932
2190
  });
1933
2191
  const rawNamespaceImports = [];
1934
- collectNamespaceImports(program, wrapped, rawNamespaceImports);
2192
+ collectNamespaceImports(program, wrapped, rawNamespaceImports, [program]);
1935
2193
  for (const n of rawNamespaceImports) namespaceImports.push({
1936
2194
  ...n,
1937
2195
  line: shift(n.line)
@@ -1971,7 +2229,10 @@ function parseComponentFacts(source, filename) {
1971
2229
  if (MODULE_FILE_RE.test(filename)) return parseModuleFacts(source, filename);
1972
2230
  const ast = parseSvelte(source, filename);
1973
2231
  const eachBlocks = [];
1974
- collectEachBlocks(ast.fragment ?? ast, source, eachBlocks);
2232
+ const scriptPrograms = [ast.module?.content, ast.instance?.content].filter(Boolean);
2233
+ const listImports = /* @__PURE__ */ new Map();
2234
+ const lists = collectConstantLists(scriptPrograms, ast.fragment ?? ast, { imports: listImports });
2235
+ collectEachBlocks(ast.fragment ?? ast, source, eachBlocks, lists, listImports);
1975
2236
  const htmlTags = [];
1976
2237
  const javascriptUrls = [];
1977
2238
  collectSecurityFacts(ast.fragment ?? ast, source, htmlTags, javascriptUrls);
@@ -2016,17 +2277,26 @@ function parseComponentFacts(source, filename) {
2016
2277
  const moduleProgram = ast.module?.content;
2017
2278
  const importSpans = [];
2018
2279
  const namespaceImports = [];
2280
+ const usageRoots = [
2281
+ moduleProgram,
2282
+ ast.instance?.content,
2283
+ ast.fragment
2284
+ ].filter(Boolean);
2019
2285
  if (moduleProgram) {
2020
2286
  collectImportSources(moduleProgram, source, importSpans);
2021
- collectNamespaceImports(moduleProgram, source, namespaceImports);
2287
+ collectNamespaceImports(moduleProgram, source, namespaceImports, usageRoots);
2022
2288
  }
2023
2289
  const orphanEffects = moduleProgram ? collectOrphanEffects(moduleProgram, source) : [];
2024
2290
  const orphanLifecycleCalls = moduleProgram ? collectOrphanLifecycleCalls(moduleProgram, source) : [];
2025
2291
  const browserGlobalRefs = [];
2026
- if (moduleProgram) for (const r of collectBrowserGlobalRefs(moduleProgram, source)) browserGlobalRefs.push({
2027
- ...r,
2028
- context: "module"
2029
- });
2292
+ if (moduleProgram) {
2293
+ const hoisted = /* @__PURE__ */ new Set();
2294
+ collectImportedLocalNames(ast.instance?.content, hoisted);
2295
+ for (const r of collectBrowserGlobalRefs(moduleProgram, source, { bound: hoisted })) browserGlobalRefs.push({
2296
+ ...r,
2297
+ context: "module"
2298
+ });
2299
+ }
2030
2300
  const effects = [];
2031
2301
  const constableStates = [];
2032
2302
  const mutatedProps = [];
@@ -2037,13 +2307,14 @@ function parseComponentFacts(source, filename) {
2037
2307
  const program = ast.instance?.content;
2038
2308
  if (program) {
2039
2309
  collectImportSources(program, source, importSpans);
2040
- collectNamespaceImports(program, source, namespaceImports);
2310
+ collectNamespaceImports(program, source, namespaceImports, usageRoots);
2041
2311
  propCount = countProps(program);
2042
2312
  const legacyPropNames = collectLegacyPropNames(program);
2043
2313
  const nonBindableProps = /* @__PURE__ */ new Set([...collectPropNames(program, false), ...legacyPropNames]);
2044
2314
  const rawMutations = [];
2045
- collectPropMutations(program, nonBindableProps, source, rawMutations);
2046
- if (ast.fragment) collectPropMutations(ast.fragment, nonBindableProps, source, rawMutations);
2315
+ collectPropMutations(program, nonBindableProps, source, rawMutations, legacyPropNames);
2316
+ if (ast.fragment) collectPropMutations(ast.fragment, nonBindableProps, source, rawMutations, legacyPropNames);
2317
+ const isLegacy = legacyPropNames.size > 0;
2047
2318
  for (const m of rawMutations) mutatedProps.push(legacyPropNames.has(m.name) ? {
2048
2319
  ...m,
2049
2320
  legacy: true
@@ -2061,7 +2332,6 @@ function parseComponentFacts(source, filename) {
2061
2332
  }
2062
2333
  const referenced = /* @__PURE__ */ new Set();
2063
2334
  if (ast.fragment) collectFragmentRefs(ast.fragment, candidateNames, referenced);
2064
- const isLegacy = legacyPropNames.size > 0;
2065
2335
  for (const c of candidates) if (!disqualified.has(c.name) && referenced.has(c.name)) stalePropDerivations.push(isLegacy ? {
2066
2336
  ...c,
2067
2337
  legacy: true
@@ -2075,7 +2345,9 @@ function parseComponentFacts(source, filename) {
2075
2345
  if (moduleProgram) {
2076
2346
  collectImportedLocalNames(moduleProgram, reactiveNames);
2077
2347
  collectNewExprLocalNames(moduleProgram, reactiveNames);
2348
+ collectAliasLocalNames(moduleProgram, reactiveNames);
2078
2349
  }
2350
+ collectAliasLocalNames(program, reactiveNames);
2079
2351
  const stateDecls = [];
2080
2352
  walkEstree(program, (n) => {
2081
2353
  if (n.type !== "VariableDeclarator" || !n.init) return;
@@ -2100,11 +2372,12 @@ function parseComponentFacts(source, filename) {
2100
2372
  });
2101
2373
  });
2102
2374
  const writtenOrEscaped = /* @__PURE__ */ new Set();
2103
- collectStateWrites(program, stateNames, writtenOrEscaped);
2375
+ collectStateWrites(program, stateNames, writtenOrEscaped, void 0, true);
2104
2376
  if (ast.fragment) {
2105
- collectStateWrites(ast.fragment, stateNames, writtenOrEscaped);
2377
+ collectStateWrites(ast.fragment, stateNames, writtenOrEscaped, void 0, true);
2106
2378
  collectTemplateEscapes(ast.fragment, stateNames, writtenOrEscaped);
2107
2379
  collectDirectiveEscapes(ast.fragment, stateNames, writtenOrEscaped);
2380
+ collectEachContextTaint(ast.fragment, stateNames, writtenOrEscaped, /* @__PURE__ */ new Set(), false);
2108
2381
  }
2109
2382
  for (const d of stateDecls) if (!writtenOrEscaped.has(d.name)) constableStates.push(d);
2110
2383
  const rawableCandidates = [];
@@ -2653,10 +2926,18 @@ function findMinifyDisabled(source) {
2653
2926
  }
2654
2927
  //#endregion
2655
2928
  //#region src/svelte-config-parse.ts
2929
+ /** Whether every branch of a `?:` / `||` / `&&` / `??` tree is the literal `''`. */
2930
+ function alwaysEmptyString(expr) {
2931
+ const e = unwrapTs(expr);
2932
+ if (e.type === "Literal") return e.value === "";
2933
+ if (e.type === "ConditionalExpression") return alwaysEmptyString(e.consequent) && alwaysEmptyString(e.alternate);
2934
+ if (e.type === "LogicalExpression") return alwaysEmptyString(e.left) && alwaysEmptyString(e.right);
2935
+ return false;
2936
+ }
2656
2937
  /**
2657
2938
  * `paths.base` off a resolved Kit-config object: `{ value }` for a non-empty string literal,
2658
2939
  * `{}` for any other expression (base exists, value unknowable — the `dev ? '' : '/repo'`
2659
- * deploy form), and undefined when absent or an explicit empty string.
2940
+ * deploy form), and undefined when absent or when every value it can take is the empty string.
2660
2941
  */
2661
2942
  function basePathOf(kitConfig, bindings) {
2662
2943
  const paths = propOf(kitConfig, "paths");
@@ -2666,7 +2947,7 @@ function basePathOf(kitConfig, bindings) {
2666
2947
  if (!base) return void 0;
2667
2948
  const value = unwrapTs(base.value);
2668
2949
  if (value.type === "Literal") return typeof value.value === "string" && value.value !== "" ? { value: value.value } : void 0;
2669
- return {};
2950
+ return alwaysEmptyString(value) ? void 0 : {};
2670
2951
  }
2671
2952
  /** A property's key when it is a plain (non-computed) string or identifier key. */
2672
2953
  function keyNameOf(p) {
@@ -2674,10 +2955,46 @@ function keyNameOf(p) {
2674
2955
  if (p.key.type === "Identifier") return p.key.name;
2675
2956
  if (p.key.type === "Literal" && typeof p.key.value === "string") return p.key.value;
2676
2957
  }
2677
- /** A property's value when it is a string literal, else undefined. */
2958
+ function stringLiteralOf(expr) {
2959
+ return expr?.type === "Literal" && typeof expr.value === "string" ? expr.value : void 0;
2960
+ }
2961
+ /** `__dirname`, `import.meta.dirname` or `process.cwd()`: the config's directory, which is the project root. */
2962
+ function isRootDir(expr) {
2963
+ if (expr.type === "Identifier") return expr.name === "__dirname";
2964
+ if (expr.type === "MemberExpression" && expr.property.type === "Identifier") return expr.object.type === "MetaProperty" && expr.property.name === "dirname";
2965
+ return expr.type === "CallExpression" && expr.callee.type === "MemberExpression" && expr.callee.object.type === "Identifier" && expr.callee.object.name === "process" && expr.callee.property.type === "Identifier" && expr.callee.property.name === "cwd";
2966
+ }
2967
+ /**
2968
+ * A config path value, relative to the project root: a string literal, `resolve(…)`/`join(…)`
2969
+ * (bare or `path.`-qualified) of string literals led by an optional root directory, or
2970
+ * `fileURLToPath(new URL('<literal>', import.meta.url))`. Anything else is unreadable.
2971
+ */
2972
+ function pathValueOf(value) {
2973
+ const v = unwrapTs(value);
2974
+ if (v.type !== "CallExpression") return stringLiteralOf(v);
2975
+ const callee = v.callee.type === "MemberExpression" && !v.callee.computed ? v.callee.property : v.callee;
2976
+ const name = callee.type === "Identifier" ? callee.name : void 0;
2977
+ const args = v.arguments;
2978
+ if (name === "fileURLToPath") {
2979
+ const url = args[0];
2980
+ if (url?.type !== "NewExpression") return void 0;
2981
+ const [href, base] = url.arguments;
2982
+ return base?.type === "MemberExpression" && base.object.type === "MetaProperty" && base.property.type === "Identifier" && base.property.name === "url" ? stringLiteralOf(href) : void 0;
2983
+ }
2984
+ if (name !== "resolve" && name !== "join") return void 0;
2985
+ const parts = [];
2986
+ for (const [i, arg] of args.entries()) {
2987
+ if (i === 0 && isRootDir(arg)) continue;
2988
+ const part = stringLiteralOf(arg);
2989
+ if (part === void 0) return void 0;
2990
+ if (name === "resolve" && part.startsWith("/")) parts.length = 0;
2991
+ parts.push(part);
2992
+ }
2993
+ return parts.join("/");
2994
+ }
2995
+ /** A property's value as a config path (see `pathValueOf`), else undefined. */
2678
2996
  function stringValueOf(p) {
2679
- const v = unwrapTs(p.value);
2680
- return v.type === "Literal" && typeof v.value === "string" ? v.value : void 0;
2997
+ return pathValueOf(p.value);
2681
2998
  }
2682
2999
  /**
2683
3000
  * `kit.alias`'s entries in source order. Undefined when the key set cannot be known (see
@@ -2745,7 +3062,7 @@ function findKitAliasesInSvelteConfig(source) {
2745
3062
  * same irregularities available to it.
2746
3063
  */
2747
3064
  function normalizeAliasValue(value) {
2748
- const posix = value.replace(/\\/g, "/");
3065
+ const posix = value.replace(/\\/g, "/").replace(/^(\.\/)+/, "");
2749
3066
  return (posix.endsWith("/*") ? posix.slice(0, -2) : posix).replace(/\/+$/, "");
2750
3067
  }
2751
3068
  /**
@@ -2788,6 +3105,57 @@ function resolveKitAliases(viteConfig, svelteConfig) {
2788
3105
  if (!svelteConfig) return void 0;
2789
3106
  return compileKitAliases(findKitAliasesInSvelteConfig(svelteConfig.source));
2790
3107
  }
3108
+ /** Conditions every Vite build of a Svelte app matches; `types`/`require` never apply to an ESM import. */
3109
+ const MATCHED_CONDITIONS = /* @__PURE__ */ new Set([
3110
+ "svelte",
3111
+ "import",
3112
+ "module",
3113
+ "default"
3114
+ ]);
3115
+ const IGNORED_CONDITIONS = /* @__PURE__ */ new Set(["types", "require"]);
3116
+ /**
3117
+ * The target a package `imports` value resolves to, walking conditions in declaration order as Node
3118
+ * does. A condition that depends on the environment (`node`, `browser`, `development`, …) makes the
3119
+ * answer unknowable here, so it resolves to nothing rather than to a branch that may not apply.
3120
+ */
3121
+ function importTarget(value) {
3122
+ if (typeof value === "string") return value;
3123
+ if (!value || typeof value !== "object" || Array.isArray(value)) return void 0;
3124
+ for (const [condition, branch] of Object.entries(value)) {
3125
+ if (IGNORED_CONDITIONS.has(condition)) continue;
3126
+ return MATCHED_CONDITIONS.has(condition) ? importTarget(branch) : void 0;
3127
+ }
3128
+ }
3129
+ /**
3130
+ * `aliases` followed by the project's package.json `imports` entries (`"#lib/*": "./src/lib/*"`),
3131
+ * after Kit's own: Vite's alias plugin resolves before Node-style subpath imports. The entries are
3132
+ * ordered by Node's precedence — exact keys, then patterns by longest prefix — because the alias
3133
+ * resolver takes the first match. Only a project-relative target counts; anything else is skipped,
3134
+ * which leaves the specifier unresolved as before.
3135
+ */
3136
+ function withPackageImports(aliases, packageJsonSource) {
3137
+ let imports;
3138
+ try {
3139
+ imports = JSON.parse(packageJsonSource ?? "").imports;
3140
+ } catch {
3141
+ return aliases;
3142
+ }
3143
+ if (!imports || typeof imports !== "object") return aliases;
3144
+ const entries = [];
3145
+ for (const [key, raw] of Object.entries(imports)) {
3146
+ const target = importTarget(raw);
3147
+ if (target === void 0 || !target.startsWith("./")) continue;
3148
+ const star = key.endsWith("/*");
3149
+ if (star !== target.endsWith("/*") || key.slice(0, star ? -2 : void 0).includes("*")) continue;
3150
+ entries.push({
3151
+ find: star ? key.slice(0, -2) : key,
3152
+ replacement: normalizeAliasValue(target.slice(2)),
3153
+ match: star ? "contents" : "exact"
3154
+ });
3155
+ }
3156
+ entries.sort((a, b) => a.match === b.match ? a.match === "exact" ? 0 : b.find.length - a.find.length : a.match === "exact" ? -1 : 1);
3157
+ return entries.length > 0 ? [...aliases ?? DEFAULT_KIT_ALIASES, ...entries] : aliases;
3158
+ }
2791
3159
  /** Parse a config source to a program, or undefined when it cannot be parsed. */
2792
3160
  function programOf(source, filename) {
2793
3161
  try {
@@ -2868,6 +3236,219 @@ function resolveKitPathsBase(viteConfig, svelteConfig) {
2868
3236
  } : void 0;
2869
3237
  }
2870
3238
  //#endregion
3239
+ //#region src/workspace-packages.ts
3240
+ const DEPENDENCY_FIELDS = [
3241
+ "dependencies",
3242
+ "devDependencies",
3243
+ "peerDependencies"
3244
+ ];
3245
+ /**
3246
+ * The app's dependencies that link a package of the same repository, name → range: a `workspace:`
3247
+ * version range, or a `link:`/`file:` path. A `workspace:` range that renames (`workspace:other@*`)
3248
+ * or names a path is left out, since the specifier would not be the package's own name.
3249
+ */
3250
+ function declaredLocalPackages(packageJsonSource) {
3251
+ const out = /* @__PURE__ */ new Map();
3252
+ let pkg;
3253
+ try {
3254
+ pkg = JSON.parse(packageJsonSource ?? "");
3255
+ } catch {
3256
+ return out;
3257
+ }
3258
+ for (const field of DEPENDENCY_FIELDS) {
3259
+ const deps = pkg?.[field];
3260
+ if (!deps || typeof deps !== "object") continue;
3261
+ for (const [name, range] of Object.entries(deps)) if (typeof range === "string" && /^(?:workspace:(?:[\^~*\d]|$)|link:|file:)/.test(range)) out.set(name, range);
3262
+ }
3263
+ return out;
3264
+ }
3265
+ /** The `packages:` globs of a `pnpm-workspace.yaml`, in block (`- 'apps/*'`) or flow (`[a, b]`) form. */
3266
+ function pnpmWorkspaceGlobs(yaml) {
3267
+ const out = [];
3268
+ const item = (raw) => {
3269
+ const value = raw.trim().replace(/^(['"])(.*)\1$/, "$2");
3270
+ if (value) out.push(value);
3271
+ };
3272
+ let inPackages = false;
3273
+ for (const line of yaml.split(/\r?\n/)) {
3274
+ if (/^\s*(#|$)/.test(line)) continue;
3275
+ const key = /^packages\s*:\s*(.*)$/.exec(line);
3276
+ if (key) {
3277
+ const flow = /^\[(.*)\]/.exec(key[1].replace(/\s+#.*$/, ""));
3278
+ if (flow) flow[1].split(",").forEach(item);
3279
+ inPackages = !flow;
3280
+ continue;
3281
+ }
3282
+ if (!inPackages) continue;
3283
+ if (/^[^\s-]/.test(line)) break;
3284
+ const entry = /^\s*-\s*(.*?)\s*(?:\s#.*)?$/.exec(line);
3285
+ if (entry) item(entry[1]);
3286
+ }
3287
+ return out;
3288
+ }
3289
+ /** A root `package.json`'s `workspaces` globs (an array, or `{ packages }`); undefined when it declares none. */
3290
+ function packageJsonWorkspaceGlobs(source) {
3291
+ let workspaces;
3292
+ try {
3293
+ workspaces = JSON.parse(source ?? "").workspaces;
3294
+ } catch {
3295
+ return;
3296
+ }
3297
+ const list = Array.isArray(workspaces) ? workspaces : workspaces?.packages;
3298
+ return Array.isArray(list) ? list.filter((g) => typeof g === "string") : void 0;
3299
+ }
3300
+ /** A package-relative `svelte` field (`./dist/index.js`, `index.js`); undefined when absent or leaving the package. */
3301
+ function svelteField(manifest) {
3302
+ let field;
3303
+ try {
3304
+ field = JSON.parse(manifest).svelte;
3305
+ } catch {
3306
+ return;
3307
+ }
3308
+ if (typeof field !== "string" || field.startsWith("/") || /^[A-Za-z]:/.test(field)) return void 0;
3309
+ const rel = field.replace(/^\.\//, "");
3310
+ return rel && !rel.split("/").includes("..") ? rel : void 0;
3311
+ }
3312
+ /** `dir/rel`, or `dir` itself for an empty `rel`. */
3313
+ function inDir(dir, rel) {
3314
+ const tail = normalizeAliasValue(rel);
3315
+ return tail ? `${dir}/${tail}` : dir;
3316
+ }
3317
+ /**
3318
+ * One package's entries, as Node resolves a bare specifier against its `exports`: a key without
3319
+ * `*` matches exactly, a `./x/*` key matches the directory's contents (its target may add a suffix
3320
+ * after `*`: `./src/*.js`); exact keys come first, then
3321
+ * patterns by longest prefix. The condition walk is `importTarget`'s, in declaration order over
3322
+ * `svelte`/`import`/`module`/`default`. A target this cannot follow — an environment condition,
3323
+ * a `null` exclusion, a `*` mid-pattern or mid-segment, a path leaving the package — stays as an opaque entry so
3324
+ * a shorter pattern cannot answer in its place. Without `exports`, the bare name resolves through
3325
+ * the `svelte` field and subpaths through the package's file layout.
3326
+ */
3327
+ function entriesOf({ name, dir, manifest }) {
3328
+ let exports;
3329
+ try {
3330
+ exports = JSON.parse(manifest).exports;
3331
+ } catch {
3332
+ return [];
3333
+ }
3334
+ if (exports === void 0) {
3335
+ const field = svelteField(manifest);
3336
+ return [...field === void 0 ? [] : [{
3337
+ find: name,
3338
+ replacement: inDir(dir, field),
3339
+ match: "exact",
3340
+ root: dir
3341
+ }], {
3342
+ find: name,
3343
+ replacement: dir,
3344
+ match: "prefix",
3345
+ root: dir
3346
+ }];
3347
+ }
3348
+ const keys = exports && typeof exports === "object" && !Array.isArray(exports) ? Object.keys(exports) : [];
3349
+ const dotted = keys.filter((k) => k.startsWith(".")).length;
3350
+ if (dotted > 0 && dotted < keys.length) return [{
3351
+ find: name,
3352
+ replacement: null,
3353
+ match: "prefix",
3354
+ root: dir
3355
+ }];
3356
+ const subpaths = dotted > 0 ? exports : { ".": exports };
3357
+ const out = [];
3358
+ for (const [key, value] of Object.entries(subpaths)) {
3359
+ const star = key.indexOf("*");
3360
+ const target = importTarget(value);
3361
+ const local = target?.startsWith("./") && !target.split("/").includes("..") ? target.slice(2) : void 0;
3362
+ if (star < 0) {
3363
+ const replacement = local === void 0 || local.includes("*") ? null : inDir(dir, local);
3364
+ out.push({
3365
+ find: name + key.slice(1),
3366
+ replacement,
3367
+ match: "exact",
3368
+ root: dir
3369
+ });
3370
+ continue;
3371
+ }
3372
+ const head = key.slice(1, star);
3373
+ const trailing = star === key.length - 1 && head.endsWith("/");
3374
+ const at = local?.indexOf("*") ?? -1;
3375
+ const follows = trailing && at > 0 && local[at - 1] === "/" && !local.includes("*", at + 1);
3376
+ const suffix = follows ? local.slice(at + 1) : "";
3377
+ out.push({
3378
+ find: name + head.slice(0, head.lastIndexOf("/")),
3379
+ replacement: follows ? inDir(dir, local.slice(0, at - 1)) : null,
3380
+ match: "contents",
3381
+ root: dir,
3382
+ ...suffix ? { suffix } : {}
3383
+ });
3384
+ }
3385
+ return out.sort((a, b) => a.match === b.match ? a.match === "exact" ? 0 : b.find.length - a.find.length : a.match === "exact" ? -1 : 1);
3386
+ }
3387
+ /**
3388
+ * `aliases` widened with the app's workspace packages, the way the bundler sees them: an alias
3389
+ * whose value points into `node_modules/<package>` names the package's own directory (the link a
3390
+ * workspace install creates, readable whether or not it was installed), and every package's
3391
+ * `exports` follows the aliases, as Vite resolves a bare specifier only after its alias plugin.
3392
+ */
3393
+ function withWorkspacePackages(aliases, packages) {
3394
+ if (packages.length === 0) return aliases;
3395
+ const linked = (entry) => {
3396
+ for (const { name, dir } of packages) {
3397
+ const from = `node_modules/${name}`;
3398
+ const r = entry.replacement;
3399
+ if (r === from || r?.startsWith(`${from}/`)) return {
3400
+ ...entry,
3401
+ replacement: dir + r.slice(from.length),
3402
+ root: dir
3403
+ };
3404
+ }
3405
+ return entry;
3406
+ };
3407
+ return [...(aliases ?? DEFAULT_KIT_ALIASES).map(linked), ...packages.flatMap(entriesOf)];
3408
+ }
3409
+ /**
3410
+ * The app's dependencies that an install puts in `node_modules`: every declared name whose range is
3411
+ * not a local protocol (`workspace:`, `link:`, `file:`, `portal:`). Those are the workspace
3412
+ * resolver's, whose bounds must not be sidestepped through their `node_modules` link.
3413
+ */
3414
+ function declaredInstalledPackages(packageJsonSource) {
3415
+ let pkg;
3416
+ try {
3417
+ pkg = JSON.parse(packageJsonSource ?? "");
3418
+ } catch {
3419
+ return [];
3420
+ }
3421
+ const out = /* @__PURE__ */ new Set();
3422
+ for (const field of DEPENDENCY_FIELDS) {
3423
+ const deps = pkg?.[field];
3424
+ if (!deps || typeof deps !== "object") continue;
3425
+ for (const [name, range] of Object.entries(deps)) if (typeof range === "string" && !/^(?:workspace|link|file|portal):/.test(range)) out.add(name);
3426
+ }
3427
+ return [...out];
3428
+ }
3429
+ function hasSvelteCondition(value) {
3430
+ if (!value || typeof value !== "object") return false;
3431
+ return Object.entries(value).some(([key, branch]) => key === "svelte" || hasSvelteCondition(branch));
3432
+ }
3433
+ /** Whether a manifest publishes Svelte components: a `svelte` field, or a `svelte` condition in `exports`. */
3434
+ function isSveltePackage(manifest) {
3435
+ try {
3436
+ const { svelte, exports } = JSON.parse(manifest);
3437
+ return typeof svelte === "string" || hasSvelteCondition(exports);
3438
+ } catch {
3439
+ return false;
3440
+ }
3441
+ }
3442
+ /**
3443
+ * `aliases` widened with the Svelte packages installed in `node_modules` (`dir` is the textual
3444
+ * `node_modules/<name>` path, relative to the app), compiled like workspace packages. Packages that
3445
+ * publish no Svelte marker get no entries: nothing they export is a component.
3446
+ */
3447
+ function withInstalledPackages(aliases, packages) {
3448
+ const svelte = packages.filter((p) => isSveltePackage(p.manifest));
3449
+ return svelte.length === 0 ? aliases : [...aliases ?? DEFAULT_KIT_ALIASES, ...svelte.flatMap(entriesOf)];
3450
+ }
3451
+ //#endregion
2871
3452
  //#region src/project-paths.ts
2872
3453
  /**
2873
3454
  * Source-file locations that satisfy the project-scope rules, shared by every
@@ -2886,6 +3467,13 @@ const SITEMAP_SOURCE_PATHS = [
2886
3467
  "src/routes/sitemap.xml/+server.ts",
2887
3468
  "src/routes/sitemap.xml/+server.js"
2888
3469
  ];
3470
+ /** The `+server` endpoints above, wherever (group) directories nest them — filter with `servesRootFile`. */
3471
+ const ROOT_FILE_ENDPOINT_GLOB = "src/routes/**/{robots.txt,sitemap.xml}/+server.{ts,js}";
3472
+ /** Whether a `+server` endpoint serves `/<file>`: (group) directories add no URL segment. */
3473
+ function servesRootFile(rel, file) {
3474
+ const segments = rel.split("/");
3475
+ return segments[0] === "src" && segments[1] === "routes" && segments.at(-2) === file && /^\+server\.(ts|js)$/.test(segments.at(-1) ?? "") && segments.slice(2, -2).every((s) => /^\(.+\)$/.test(s));
3476
+ }
2889
3477
  /** Vite's own config resolution order — only the first existing file is the one Vite loads. */
2890
3478
  const VITE_CONFIG_FILES = [
2891
3479
  "vite.config.js",
@@ -3992,4 +4580,4 @@ function formatHtmlReport(results, config, meta) {
3992
4580
  return buildHtmlDocument(buildJsonReport(results, config, meta), meta);
3993
4581
  }
3994
4582
  //#endregion
3995
- export { ANCESTRY_DEPENDENT_TAGS, APP_SCRIPT, ASIDE_DEMOTING_TAGS, CHILD_NODE_KEYS, IDREF_ATTRS, NAMING_ATTRS, ROBOTS_SOURCE_PATHS, SEARCH_RESULT_RULES, SECTIONING_TAGS, SITEMAP_SOURCE_PATHS, SVELTE_CONFIG_FILES, VITE_CONFIG_FILES, a11yAbbrTitle, a11yAccessibleName, a11yAriaHiddenFocus, a11yDeprecatedAria, a11yDeprecatedAttr, a11yDeprecatedElement, a11yDisallowedAriaProps, a11yDisallowedElement, a11yDoctype, a11yDuplicateLandmark, a11yIdDuplication, a11yInteractiveNesting, a11yInvalidAriaValue, a11yInvalidRole, a11yLabelHasControl, a11yNoAccesskey, a11yNoAutofocus, a11yNoDuplicateDt, a11yNoMissingIdRef, a11yPatternTitle, a11yPermittedContents, a11yPlaceholderLabelOption, a11yPositiveTabindex, a11yRequireDatetime, a11yRequiredAriaProps, a11yRequiredElement, a11yTopLevelLandmark, a11yUnknownAriaAttribute, a11yUnverifiedIdRef, a11yUseList, addFactsDirectives, allRules, architectureComponentSize, architectureDirectoryNaming, architectureDocLinkTarget, architecturePrivateScopeImport, architecturePropCount, architectureReservedDirectoryNames, architectureReservedNamePlacement, architectureRouteComponentImport, architectureUnitEntryFile, attrText, attrTextOf, attrValue, attrValueOf, buildHtmlDocument, buildJsonReport, classify, collectComponentFacts, collectKitModuleFacts, collectSourceFiles, collectSuppressions, compileOverrides, computeHealth, computeScore, correctnessAutoplayMuted, correctnessBasePathNavigation, correctnessCheckableBindValue, correctnessEachIndexKey, correctnessEachKey, correctnessEffectAsDerived, correctnessEffectAsOnMount, correctnessInstanceBrowserGlobal, correctnessNonreactiveBuiltinState, correctnessOrphanEffect, correctnessOrphanLifecycle, correctnessPropMutation, correctnessServerBrowserGlobal, correctnessStalePropDerivation, correctnessUnmutatedState, decodeFragmentId, defaultConfig, defaultProject, docsUrlFor, effectiveSeverity, emptyComponentFacts, escapeHtml, explainRule, findAttr, findMinifyDisabled, foldOccurrences, formatAgentReport, formatConsoleReport, formatFailedRuleWarning, formatGithubReport, formatHtmlReport, formatJsonReport, formatMarkdownReport, formatSarifReport, hasFailureAtOrAbove, isClassicScriptType, isPenalized, isPlainObject, isTopFragment, lineOf, noColorPalette, parseComponentFacts, parseSvelte, performanceFontPreloadCrossorigin, performanceHeavyImport, performanceIframeLoading, performanceImageDimensions, performanceImageLoadingHint, performanceLcpImage, performanceLoadWaterfall, performanceMinifyDisabled, performanceNamespaceImport, performancePreconnect, performancePreloadMissingAs, performanceRenderBlockingScript, performanceResponsiveImage, performanceSequentialAwaits, performanceStateRaw, renderAppShell, resolveKitAliases, resolveKitPathsBase, resolveLandmark, resolveRepoLocalPath, resolveRuleOptions, runAnalysis, runRules, safeHref, scoreColor, securityHandlerStateWrite, securityJavascriptUrl, securityRawHtml, securityServerModuleState, securitySharedStateImport, selectRules, seoCanonicalUrl, seoCharset, seoDescriptionLength, seoDescriptionPresence, seoDuplicateDescription, seoDuplicateTitle, seoHeadingLevelSkip, seoHreflang, seoHtmlLang, seoImageAlt, seoIndexability, seoJsonLd, seoJsonLdDateFormat, seoJsonLdDeprecatedType, seoJsonLdPlaceholder, seoJsonLdRelativeUrl, seoJsonLdRequiredProps, seoJsonLdValidity, seoOgDescription, seoOgImage, seoOgTitle, seoOgUrl, seoRobotsTxt, seoSingleH1, seoSitemapInRobots, seoSitemapXml, seoSsrDisabled, seoTitleLength, seoTitlePresence, seoTwitterCard, seoViewport, settingSeverity, shouldSkipRangeCheck, skippedFileWarnings, splitTokens, stripTextDirective, summarize, terminalSafe, textFromNodes, unknownDirectiveIds, validateRuleSetting, valueFromNodes, withFailedRulesOff, withIndexableOff, withReadLimit };
4583
+ export { ANCESTRY_DEPENDENT_TAGS, APP_SCRIPT, ASIDE_DEMOTING_TAGS, CHILD_NODE_KEYS, IDREF_ATTRS, NAMING_ATTRS, ROBOTS_SOURCE_PATHS, ROOT_FILE_ENDPOINT_GLOB, SEARCH_RESULT_RULES, SECTIONING_TAGS, SITEMAP_SOURCE_PATHS, SVELTE_CONFIG_FILES, VITE_CONFIG_FILES, a11yAbbrTitle, a11yAccessibleName, a11yAriaHiddenFocus, a11yDeprecatedAria, a11yDeprecatedAttr, a11yDeprecatedElement, a11yDisallowedAriaProps, a11yDisallowedElement, a11yDoctype, a11yDuplicateLandmark, a11yIdDuplication, a11yInteractiveNesting, a11yInvalidAriaValue, a11yInvalidRole, a11yLabelHasControl, a11yNoAccesskey, a11yNoAutofocus, a11yNoDuplicateDt, a11yNoMissingIdRef, a11yPatternTitle, a11yPermittedContents, a11yPlaceholderLabelOption, a11yPositiveTabindex, a11yRequireDatetime, a11yRequiredAriaProps, a11yRequiredElement, a11yTopLevelLandmark, a11yUnknownAriaAttribute, a11yUnverifiedIdRef, a11yUseList, addFactsDirectives, allRules, architectureComponentSize, architectureDirectoryNaming, architectureDocLinkTarget, architecturePrivateScopeImport, architecturePropCount, architectureReservedDirectoryNames, architectureReservedNamePlacement, architectureRouteComponentImport, architectureUnitEntryFile, attrText, attrTextOf, attrValue, attrValueOf, buildHtmlDocument, buildJsonReport, classify, collectComponentFacts, collectConstantListExports, collectKitModuleFacts, collectSourceFiles, collectSuppressions, compileOverrides, computeHealth, computeScore, correctnessAutoplayMuted, correctnessBasePathNavigation, correctnessCheckableBindValue, correctnessEachIndexKey, correctnessEachKey, correctnessEffectAsDerived, correctnessEffectAsOnMount, correctnessInstanceBrowserGlobal, correctnessNonreactiveBuiltinState, correctnessOrphanEffect, correctnessOrphanLifecycle, correctnessPropMutation, correctnessServerBrowserGlobal, correctnessStalePropDerivation, correctnessUnmutatedState, declaredInstalledPackages, declaredLocalPackages, decodeFragmentId, defaultConfig, defaultProject, docsUrlFor, effectiveSeverity, emptyComponentFacts, escapeHtml, explainRule, findAttr, findMinifyDisabled, foldOccurrences, formatAgentReport, formatConsoleReport, formatFailedRuleWarning, formatGithubReport, formatHtmlReport, formatJsonReport, formatMarkdownReport, formatSarifReport, hasFailureAtOrAbove, isClassicScriptType, isPenalized, isPlainObject, isSvgSrc, isTopFragment, lineOf, noColorPalette, packageJsonWorkspaceGlobs, parseComponentFacts, parseModuleProgram, parseSvelte, performanceFontPreloadCrossorigin, performanceHeavyImport, performanceIframeLoading, performanceImageDimensions, performanceImageLoadingHint, performanceLcpImage, performanceLoadWaterfall, performanceMinifyDisabled, performanceNamespaceImport, performancePreconnect, performancePreloadMissingAs, performanceRenderBlockingScript, performanceResponsiveImage, performanceSequentialAwaits, performanceStateRaw, pnpmWorkspaceGlobs, renderAppShell, resolveKitAliases, resolveKitPathsBase, resolveLandmark, resolveRepoLocalPath, resolveRuleOptions, routeNeverSsr, runAnalysis, runRules, safeHref, scoreColor, securityHandlerStateWrite, securityJavascriptUrl, securityRawHtml, securityServerModuleState, securitySharedStateImport, selectRules, seoCanonicalUrl, seoCharset, seoDescriptionLength, seoDescriptionPresence, seoDuplicateDescription, seoDuplicateTitle, seoHeadingLevelSkip, seoHreflang, seoHtmlLang, seoImageAlt, seoIndexability, seoJsonLd, seoJsonLdDateFormat, seoJsonLdDeprecatedType, seoJsonLdPlaceholder, seoJsonLdRelativeUrl, seoJsonLdRequiredProps, seoJsonLdValidity, seoOgDescription, seoOgImage, seoOgTitle, seoOgUrl, seoRobotsTxt, seoSingleH1, seoSitemapInRobots, seoSitemapXml, seoSsrDisabled, seoTitleLength, seoTitlePresence, seoTwitterCard, seoViewport, servesRootFile, settingSeverity, shouldSkipRangeCheck, skippedFileWarnings, splitTokens, stripTextDirective, summarize, terminalSafe, textFromNodes, unknownDirectiveIds, validateRuleSetting, valueFromNodes, withFailedRulesOff, withIndexableOff, withInstalledPackages, withPackageImports, withReadLimit, withWorkspacePackages };