svelte-shaker 0.5.2 → 0.6.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/dist/{types/src/analyze.d.ts → analyze.d.ts} +3 -3
- package/dist/analyze.js +1072 -0
- package/dist/{types/src/css.d.ts → css.d.ts} +2 -2
- package/dist/css.js +256 -0
- package/dist/{types/src/dead.d.ts → dead.d.ts} +2 -2
- package/dist/dead.js +195 -0
- package/dist/{types/src/engine.d.ts → engine.d.ts} +3 -3
- package/dist/engine.js +109 -0
- package/dist/{types/src/eval.d.ts → eval.d.ts} +2 -2
- package/dist/eval.js +222 -0
- package/dist/{types/src/index.d.ts → index.d.ts} +11 -11
- package/dist/index.js +86 -1
- package/dist/ir.js +15 -0
- package/dist/{types/src/mono.d.ts → mono.d.ts} +3 -3
- package/dist/mono.js +451 -0
- package/dist/parse.js +19 -0
- package/dist/{types/src/rsvelte-parse.d.ts → rsvelte-parse.d.ts} +1 -1
- package/dist/rsvelte-parse.js +31 -0
- package/dist/{types/src/scan.d.ts → scan.d.ts} +2 -2
- package/dist/scan.js +40 -1
- package/dist/{types/src/transform.d.ts → transform.d.ts} +4 -4
- package/dist/transform.js +825 -0
- package/dist/{types/src/vite.d.ts → vite.d.ts} +10 -2
- package/dist/vite.js +289 -1
- package/package.json +9 -18
- package/dist/index.cjs +0 -1
- /package/dist/{types/src/ir.d.ts → ir.d.ts} +0 -0
- /package/dist/{types/src/parse.d.ts → parse.d.ts} +0 -0
package/dist/eval.js
ADDED
|
@@ -0,0 +1,222 @@
|
|
|
1
|
+
const UNKNOWN = { known: false };
|
|
2
|
+
/**
|
|
3
|
+
* A deliberately tiny, total constant evaluator over an ESTree expression,
|
|
4
|
+
* given an environment of statically-known identifiers. It never throws and
|
|
5
|
+
* never guesses: anything it cannot prove is `{ known: false }`.
|
|
6
|
+
*
|
|
7
|
+
* This is the M0 stand-in for the abstract-interpretation engine described in
|
|
8
|
+
* docs/ARCHITECTURE.md §13 — same contract (sound over-approximation, falls to
|
|
9
|
+
* unknown on non-distributive ops), just without the interprocedural lattice.
|
|
10
|
+
*/
|
|
11
|
+
export function evaluate(node, env) {
|
|
12
|
+
if (!node)
|
|
13
|
+
return UNKNOWN;
|
|
14
|
+
switch (node.type) {
|
|
15
|
+
case 'Literal':
|
|
16
|
+
return { known: true, value: node.value };
|
|
17
|
+
case 'Identifier': {
|
|
18
|
+
const name = node.name ?? '';
|
|
19
|
+
if (name === 'undefined')
|
|
20
|
+
return { known: true, value: undefined };
|
|
21
|
+
if (env.has(name))
|
|
22
|
+
return { known: true, value: env.get(name) };
|
|
23
|
+
return UNKNOWN;
|
|
24
|
+
}
|
|
25
|
+
case 'UnaryExpression': {
|
|
26
|
+
const arg = evaluate(node.argument, env);
|
|
27
|
+
if (!arg.known)
|
|
28
|
+
return UNKNOWN;
|
|
29
|
+
const v = arg.value;
|
|
30
|
+
switch (node.operator) {
|
|
31
|
+
case '!':
|
|
32
|
+
return { known: true, value: !v };
|
|
33
|
+
case '-':
|
|
34
|
+
return { known: true, value: -v };
|
|
35
|
+
case '+':
|
|
36
|
+
return { known: true, value: +v };
|
|
37
|
+
case 'typeof':
|
|
38
|
+
return { known: true, value: typeof v };
|
|
39
|
+
case 'void':
|
|
40
|
+
return { known: true, value: undefined };
|
|
41
|
+
default:
|
|
42
|
+
return UNKNOWN;
|
|
43
|
+
}
|
|
44
|
+
}
|
|
45
|
+
case 'LogicalExpression': {
|
|
46
|
+
const left = evaluate(node.left, env);
|
|
47
|
+
if (!left.known)
|
|
48
|
+
return UNKNOWN;
|
|
49
|
+
switch (node.operator) {
|
|
50
|
+
case '&&':
|
|
51
|
+
return left.value ? evaluate(node.right, env) : left;
|
|
52
|
+
case '||':
|
|
53
|
+
return left.value ? left : evaluate(node.right, env);
|
|
54
|
+
case '??':
|
|
55
|
+
return left.value === null || left.value === undefined ? evaluate(node.right, env) : left;
|
|
56
|
+
default:
|
|
57
|
+
return UNKNOWN;
|
|
58
|
+
}
|
|
59
|
+
}
|
|
60
|
+
case 'BinaryExpression': {
|
|
61
|
+
const left = evaluate(node.left, env);
|
|
62
|
+
const right = evaluate(node.right, env);
|
|
63
|
+
if (!left.known || !right.known)
|
|
64
|
+
return UNKNOWN;
|
|
65
|
+
const l = left.value;
|
|
66
|
+
const r = right.value;
|
|
67
|
+
switch (node.operator) {
|
|
68
|
+
case '===':
|
|
69
|
+
return { known: true, value: l === r };
|
|
70
|
+
case '!==':
|
|
71
|
+
return { known: true, value: l !== r };
|
|
72
|
+
case '==':
|
|
73
|
+
return { known: true, value: l == r };
|
|
74
|
+
case '!=':
|
|
75
|
+
return { known: true, value: l != r };
|
|
76
|
+
case '<':
|
|
77
|
+
return { known: true, value: l < r };
|
|
78
|
+
case '>':
|
|
79
|
+
return { known: true, value: l > r };
|
|
80
|
+
case '<=':
|
|
81
|
+
return { known: true, value: l <= r };
|
|
82
|
+
case '>=':
|
|
83
|
+
return { known: true, value: l >= r };
|
|
84
|
+
case '+':
|
|
85
|
+
return { known: true, value: l + r };
|
|
86
|
+
case '-':
|
|
87
|
+
return { known: true, value: l - r };
|
|
88
|
+
case '*':
|
|
89
|
+
return { known: true, value: l * r };
|
|
90
|
+
case '/':
|
|
91
|
+
return { known: true, value: l / r };
|
|
92
|
+
case '%':
|
|
93
|
+
return { known: true, value: l % r };
|
|
94
|
+
default:
|
|
95
|
+
return UNKNOWN;
|
|
96
|
+
}
|
|
97
|
+
}
|
|
98
|
+
default:
|
|
99
|
+
return UNKNOWN;
|
|
100
|
+
}
|
|
101
|
+
}
|
|
102
|
+
/**
|
|
103
|
+
* Sound set-aware predicate. `constEnv` holds props collapsed to a single
|
|
104
|
+
* literal (`constFold`); `setEnv` holds props whose reachable value set is known
|
|
105
|
+
* (`narrow`, >= 2 literals). Returns `{ known:true }` ONLY when the boolean is
|
|
106
|
+
* provable for the whole reachable set — a value reachable through the set keeps
|
|
107
|
+
* the branch. Anything outside the small supported fragment is `{ known:false }`.
|
|
108
|
+
*/
|
|
109
|
+
export function evaluateWithSets(node, constEnv, setEnv) {
|
|
110
|
+
// Constant folding alone may already settle the test (e.g. it only mentions
|
|
111
|
+
// constFold props or literals); prefer that — it can even prove `true`.
|
|
112
|
+
const constOnly = evaluate(node, constEnv);
|
|
113
|
+
if (constOnly.known)
|
|
114
|
+
return constOnly;
|
|
115
|
+
const tri = evalTri(node, constEnv, setEnv);
|
|
116
|
+
return tri === 'unknown' ? UNKNOWN : { known: true, value: tri };
|
|
117
|
+
}
|
|
118
|
+
/** Evaluate a boolean condition to a Kleene truth over the value sets. */
|
|
119
|
+
function evalTri(node, constEnv, setEnv) {
|
|
120
|
+
if (!node)
|
|
121
|
+
return 'unknown';
|
|
122
|
+
switch (node.type) {
|
|
123
|
+
case 'UnaryExpression':
|
|
124
|
+
if (node.operator === '!')
|
|
125
|
+
return notTri(evalTri(node.argument, constEnv, setEnv));
|
|
126
|
+
return 'unknown';
|
|
127
|
+
case 'LogicalExpression': {
|
|
128
|
+
const left = evalTri(node.left, constEnv, setEnv);
|
|
129
|
+
const right = () => evalTri(node.right, constEnv, setEnv);
|
|
130
|
+
// Kleene &&/||: short-circuit on the dominating constant, else combine.
|
|
131
|
+
if (node.operator === '&&') {
|
|
132
|
+
if (left === false)
|
|
133
|
+
return false; // false && _ = false
|
|
134
|
+
return andTri(left, right()); // (true|unknown) && right
|
|
135
|
+
}
|
|
136
|
+
if (node.operator === '||') {
|
|
137
|
+
if (left === true)
|
|
138
|
+
return true; // true || _ = true
|
|
139
|
+
return orTri(left, right()); // (false|unknown) || right
|
|
140
|
+
}
|
|
141
|
+
return 'unknown'; // ?? is value-level, not a boolean we narrow on
|
|
142
|
+
}
|
|
143
|
+
case 'BinaryExpression': {
|
|
144
|
+
const op = node.operator;
|
|
145
|
+
if (op === '===' || op === '==' || op === '!==' || op === '!=') {
|
|
146
|
+
// Strict (`===`/`!==`) compares without coercion; loose (`==`/`!=`) must
|
|
147
|
+
// honor JS type coercion (`0 == false`, `null == undefined`, …) or it
|
|
148
|
+
// would prove a branch dead that actually fires at runtime.
|
|
149
|
+
const loose = op === '==' || op === '!=';
|
|
150
|
+
const eq = equalityTri(node.left, node.right, constEnv, setEnv, loose);
|
|
151
|
+
return op === '!==' || op === '!=' ? notTri(eq) : eq;
|
|
152
|
+
}
|
|
153
|
+
return 'unknown'; // ordering/arithmetic over sets: not supported (sound ⊤)
|
|
154
|
+
}
|
|
155
|
+
default:
|
|
156
|
+
return 'unknown';
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
/**
|
|
160
|
+
* `a === b` over the value sets, sound and three-valued. Only the
|
|
161
|
+
* "set-var vs literal" (and constant-vs-constant) shapes are decided; anything
|
|
162
|
+
* else is `unknown` so the branch survives.
|
|
163
|
+
*/
|
|
164
|
+
function equalityTri(left, right, constEnv, setEnv, loose) {
|
|
165
|
+
// One side a set-var, the other a proven literal -> compare against the set.
|
|
166
|
+
const lset = setVar(left, setEnv);
|
|
167
|
+
const rlit = evaluate(right, constEnv);
|
|
168
|
+
if (lset && rlit.known)
|
|
169
|
+
return matchTri(lset, rlit.value, loose);
|
|
170
|
+
const rset = setVar(right, setEnv);
|
|
171
|
+
const llit = evaluate(left, constEnv);
|
|
172
|
+
if (rset && llit.known)
|
|
173
|
+
return matchTri(rset, llit.value, loose);
|
|
174
|
+
// Both sides constant-foldable -> exact answer (covers literal vs literal),
|
|
175
|
+
// honoring the operator's own equality semantics (strict vs loose).
|
|
176
|
+
if (llit.known && rlit.known)
|
|
177
|
+
return loose ? llit.value == rlit.value : llit.value === rlit.value;
|
|
178
|
+
return 'unknown';
|
|
179
|
+
}
|
|
180
|
+
/** The reachable value set for `node` if it is a bare set-var identifier. */
|
|
181
|
+
function setVar(node, setEnv) {
|
|
182
|
+
if (node?.type === 'Identifier' && node.name && setEnv.has(node.name))
|
|
183
|
+
return setEnv.get(node.name);
|
|
184
|
+
return null;
|
|
185
|
+
}
|
|
186
|
+
/**
|
|
187
|
+
* Is `lit` equal to every / some / no member of the reachable set? `loose`
|
|
188
|
+
* selects JS coercing `==` (e.g. `0 == false`, `null == undefined`) vs strict
|
|
189
|
+
* `===`; using the wrong one would prove a branch dead that actually fires
|
|
190
|
+
* (`{0,1}` with `n == false` really matches `0`). `Object.is` is wrong for both
|
|
191
|
+
* (`-0`/`NaN`), so we use the value operators directly.
|
|
192
|
+
*/
|
|
193
|
+
function matchTri(set, lit, loose) {
|
|
194
|
+
// The loose branch intentionally uses `==` to model JS coercion.
|
|
195
|
+
const eq = loose ? (v) => v == lit : (v) => v === lit;
|
|
196
|
+
if (!set.some(eq))
|
|
197
|
+
return false; // lit ∉ set -> never equal
|
|
198
|
+
if (set.every(eq))
|
|
199
|
+
return true; // set ⊆ {lit} -> always equal
|
|
200
|
+
return 'unknown'; // some equal, some not -> depends on the runtime value
|
|
201
|
+
}
|
|
202
|
+
function notTri(t) {
|
|
203
|
+
if (t === true)
|
|
204
|
+
return false;
|
|
205
|
+
if (t === false)
|
|
206
|
+
return true;
|
|
207
|
+
return 'unknown';
|
|
208
|
+
}
|
|
209
|
+
function andTri(a, b) {
|
|
210
|
+
if (a === false || b === false)
|
|
211
|
+
return false;
|
|
212
|
+
if (a === true && b === true)
|
|
213
|
+
return true;
|
|
214
|
+
return 'unknown';
|
|
215
|
+
}
|
|
216
|
+
function orTri(a, b) {
|
|
217
|
+
if (a === true || b === true)
|
|
218
|
+
return true;
|
|
219
|
+
if (a === false && b === false)
|
|
220
|
+
return false;
|
|
221
|
+
return 'unknown';
|
|
222
|
+
}
|
|
@@ -1,14 +1,14 @@
|
|
|
1
|
-
import { type ReadFile, type Resolve } from './analyze';
|
|
2
|
-
import { type Parse } from './parse';
|
|
3
|
-
import { type MonomorphizeOptions, type MonomorphizeResult } from './mono';
|
|
4
|
-
import type { ComponentId } from './ir';
|
|
5
|
-
export type { ComponentId, AnalyzeInput, InputFile, ResolvedEdge, EdgeKind, EditResult, } from './ir';
|
|
6
|
-
export type { Resolve, ReadFile } from './analyze';
|
|
7
|
-
export type { Parse, Root } from './parse';
|
|
8
|
-
export { analyze, analyzeInput, buildAnalyzeInput } from './analyze';
|
|
9
|
-
export { DevShaker, type DevMode, type DevShakerChange } from './engine';
|
|
10
|
-
export { transformAll, transformAllWithMono } from './transform';
|
|
11
|
-
export { monomorphize, DEFAULT_MONO_OPTIONS, type MonomorphizeOptions, type MonomorphizeResult, type Variant, type CallSiteBinding, } from './mono';
|
|
1
|
+
import { type ReadFile, type Resolve } from './analyze.js';
|
|
2
|
+
import { type Parse } from './parse.js';
|
|
3
|
+
import { type MonomorphizeOptions, type MonomorphizeResult } from './mono.js';
|
|
4
|
+
import type { ComponentId } from './ir.js';
|
|
5
|
+
export type { ComponentId, AnalyzeInput, InputFile, ResolvedEdge, EdgeKind, EditResult, } from './ir.js';
|
|
6
|
+
export type { Resolve, ReadFile } from './analyze.js';
|
|
7
|
+
export type { Parse, Root } from './parse.js';
|
|
8
|
+
export { analyze, analyzeInput, buildAnalyzeInput } from './analyze.js';
|
|
9
|
+
export { DevShaker, type DevMode, type DevShakerChange } from './engine.js';
|
|
10
|
+
export { transformAll, transformAllWithMono } from './transform.js';
|
|
11
|
+
export { monomorphize, DEFAULT_MONO_OPTIONS, type MonomorphizeOptions, type MonomorphizeResult, type Variant, type CallSiteBinding, } from './mono.js';
|
|
12
12
|
/**
|
|
13
13
|
* Whole-program shake: crawl the component graph from `entry`, decide what to
|
|
14
14
|
* fold, and return the shaken source for every reachable `.svelte` file.
|
package/dist/index.js
CHANGED
|
@@ -1 +1,86 @@
|
|
|
1
|
-
import{parse as e,compile as t}from"svelte/compiler";import{walk as n}from"zimmerframe";import o from"magic-string";function r(t,n){return e(t,{modern:!0,filename:n})}function s(e,t,n,o=r){if(!n)return o(t,e);const s=n.get(e);if(s&&s.code===t)return s.ast;const a=o(t,e);return n.set(e,{code:t,ast:a}),a}function a(e,t,o){n(e,t,o)}const i={known:!1};function c(e,t){if(!e)return i;switch(e.type){case"Literal":return{known:!0,value:e.value};case"Identifier":{const n=e.name??"";return"undefined"===n?{known:!0,value:void 0}:t.has(n)?{known:!0,value:t.get(n)}:i}case"UnaryExpression":{const n=c(e.argument,t);if(!n.known)return i;const o=n.value;switch(e.operator){case"!":return{known:!0,value:!o};case"-":return{known:!0,value:-o};case"+":return{known:!0,value:+o};case"typeof":return{known:!0,value:typeof o};case"void":return{known:!0,value:void 0};default:return i}}case"LogicalExpression":{const n=c(e.left,t);if(!n.known)return i;switch(e.operator){case"&&":return n.value?c(e.right,t):n;case"||":return n.value?n:c(e.right,t);case"??":return null===n.value||void 0===n.value?c(e.right,t):n;default:return i}}case"BinaryExpression":{const n=c(e.left,t),o=c(e.right,t);if(!n.known||!o.known)return i;const r=n.value,s=o.value;switch(e.operator){case"===":return{known:!0,value:r===s};case"!==":return{known:!0,value:r!==s};case"==":return{known:!0,value:r==s};case"!=":return{known:!0,value:r!=s};case"<":return{known:!0,value:r<s};case">":return{known:!0,value:r>s};case"<=":return{known:!0,value:r<=s};case">=":return{known:!0,value:r>=s};case"+":return{known:!0,value:r+s};case"-":return{known:!0,value:r-s};case"*":return{known:!0,value:r*s};case"/":return{known:!0,value:r/s};case"%":return{known:!0,value:r%s};default:return i}}default:return i}}function u(e,t,n){const o=c(e,t);if(o.known)return o;const r=f(e,t,n);return"unknown"===r?i:{known:!0,value:r}}function f(e,t,n){if(!e)return"unknown";switch(e.type){case"UnaryExpression":return"!"===e.operator?d(f(e.argument,t,n)):"unknown";case"LogicalExpression":{const s=f(e.left,t,n),a=()=>f(e.right,t,n);return"&&"===e.operator?!1!==s&&(o=s,r=a(),!1!==o&&!1!==r&&(!0===o&&!0===r||"unknown")):"||"===e.operator?!0===s||function(e,t){return!0===e||!0===t||(!1!==e||!1!==t)&&"unknown"}(s,a()):"unknown"}case"BinaryExpression":{const o=e.operator;if("==="===o||"=="===o||"!=="===o||"!="===o){const r="=="===o||"!="===o,s=function(e,t,n,o,r){const s=l(e,o),a=c(t,n);if(s&&a.known)return p(s,a.value,r);const i=l(t,o),u=c(e,n);return i&&u.known?p(i,u.value,r):u.known&&a.known?r?u.value==a.value:u.value===a.value:"unknown"}(e.left,e.right,t,n,r);return"!=="===o||"!="===o?d(s):s}return"unknown"}default:return"unknown"}var o,r}function l(e,t){return"Identifier"===e?.type&&e.name&&t.has(e.name)?t.get(e.name):null}function p(e,t,n){const o=n?e=>e==t:e=>e===t;return!!e.some(o)&&(!!e.every(o)||"unknown")}function d(e){return!0!==e&&(!1===e||"unknown")}function m(e,t,n){const{arms:o,elseFrag:r}=function(e){const t=[];let n,o=e;for(;o;){t.push({block:o,test:o.test,consequent:o.consequent});const e=o.alternate,r="Fragment"===e?.type&&1===e.nodes?.length&&"IfBlock"===e.nodes[0]?.type&&!0===e.nodes[0].elseif?e.nodes[0]:void 0;r?o=r:("Fragment"===e?.type&&(n=e),o=void 0)}return n?{arms:t,elseFrag:n}:{arms:t}}(e),s=[e.start,e.end],a=o.map(e=>u(e.test,t,n)),i=e=>e.known&&Boolean(e.value),c=e=>e.known&&!e.value;let f=!0;for(let e=0;e<o.length;e++){const t=a[e];if(i(t)&&f){const t=o[e].consequent;return{span:s,kept:t,removed:h(s,v(t)),recurse:!1}}c(t)||(f=!1)}const l=a.findIndex(e=>!c(e));if(-1===l)return r?{span:s,kept:r,removed:h(s,v(r)),recurse:!1}:{span:s,kept:void 0,removed:[s],recurse:!1};if(0===l)return{span:s,kept:void 0,removed:w(o,a,l),recurse:!0};const p=o[l].block;return{span:s,kept:void 0,removed:[[s[0],p.start],...w(o,a,l)],recurse:!1,headerRewrite:{from:p.start,to:p.test.start,text:"{#if "}}}function h(e,t){if(!t)return[e];const n=[];return e[0]<t[0]&&n.push([e[0],t[0]]),t[1]<e[1]&&n.push([t[1],e[1]]),n}function v(e){const t=e?.nodes??[];return 0===t.length?null:[t[0].start,t[t.length-1].end]}function w(e,t,n){const o=[];for(let r=n+1;r<e.length;r++){const n=t[r];if(!n.known||n.value)continue;const s=e[r],a=e[r+1]?.block,i=a?a.start:g(s.consequent,s.block.end);o.push([s.block.start,i])}return o}function g(e,t){const n=e?.nodes??[];return n.length?n[n.length-1].end:t}function y(e,t){return t.some(([t,n])=>e.start>=t&&e.end<=n)}function k(e,t,n){if(0===t.size&&0===n.size)return[];const o=[];return a(e,null,{IfBlock(e,{next:r}){if(e.elseif||y(e,o))return;const s=m(e,t,n);for(const e of s.removed)o.push(e);s.recurse&&r()}}),o}const x=e=>e.endsWith(".svelte"),S="escapes as value (e.g. <svelte:component this={X}>)";async function b(e,t,n){return I(await M(e,t,n))}function I(e,t){const n=function(e,t){const n=new Map;for(const t of e.edges){const e=n.get(t.from);e?e.push(t):n.set(t.from,[t])}const o=new Map;for(const r of e.files)o.set(r.id,z(r,n.get(r.id)??[],t));return o}(e,t),o=new Set;for(const e of n.values())for(const t of e.escapedComponents)o.add(t);for(const e of o){const t=n.get(e);t&&!t.bailReasons.includes(S)&&t.bailReasons.push(S)}let r=A(n,E(n,new Map));for(let e=0;e<10;e++){const e=A(n,E(n,$(n,r)));if(C(r,e)){r=e;break}r=e}return{models:n,plans:r}}async function M(e,t,n,o,r){const a=Array.isArray(e)?[...e]:[e],i=[],c=[],u=[...a],f=new Set(u);for(;u.length>0;){const e=u.shift(),a=await n(e);i.push({id:e,code:a});const l=s(e,a,o,r),p=l.instance;if(!p)continue;const d=new Map,m=new Map,h=[];for(const o of U(p)){if("*"===o.imported){m.set(o.local,o.value);continue}if("default"===o.imported&&x(o.value)){const n=await t(o.value,e);n&&(c.push({from:e,local:o.local,to:n,kind:"default-svelte"}),h.push(n));continue}const r=await K(o.value,o.imported,e,t,n);r&&(c.push({from:e,local:o.local,to:r,kind:"barrel"}),d.set(o.local,r))}const v=[];if(m.size>0)for(const o of T(l)){const r=o.indexOf("."),s=m.get(o.slice(0,r));if(null==s)continue;const a=await K(s,o.slice(r+1),e,t,n);a&&(c.push({from:e,local:o,to:a,kind:"namespace"}),v.push(a))}const w=O(l,d);for(const e of[...h,...w,...v])f.has(e)||(f.add(e),u.push(e))}return{files:i,edges:c,entries:a}}function E(e,t){const n=new Map,o=e=>{let t=n.get(e);return t||(t={sites:[]},n.set(e,t)),t};for(const n of e.values()){const e=t.get(n.id)??[];for(const t of n.childCalls)e.length>0&&y(t.node,e)||o(t.childId).sites.push(B(t.node))}return n}function A(e,t){const n=new Map;for(const o of e.values())n.set(o.id,V(o,t.get(o.id)));return n}function C(e,t){if(e.size!==t.size)return!1;for(const[n,o]of e){const e=t.get(n);if(!e)return!1;if(o.bail!==e.bail)return!1;if(!F(o.constFold,e.constFold))return!1;if(!P(o.narrow,e.narrow))return!1}return!0}function F(e,t){if(e.size!==t.size)return!1;for(const[n,o]of e)if(!t.has(n)||!Object.is(t.get(n),o))return!1;return!0}function P(e,t){if(e.size!==t.size)return!1;for(const[n,o]of e){const e=t.get(n);if(!e||o.length!==e.length)return!1;for(let t=0;t<o.length;t++)if(!Object.is(o[t],e[t]))return!1}return!0}function $(e,t){const n=new Map;for(const o of e.values()){const e=t.get(o.id);if(e.bail)continue;const r=k(o.ast.fragment,D(e.constFold,o),D(e.narrow,o));r.length>0&&n.set(o.id,r)}return n}function D(e,t){if(0===e.size)return e;const n=new Map;for(const e of t.props??[])null!==e.local&&n.set(e.name,e.local);const o=new Map;for(const[t,r]of e){const e=n.get(t);void 0!==e&&o.set(e,r)}return o}function z(e,t,n){const{id:o,code:r}=e,i=s(o,r,n),c=new Map;for(const e of t)c.set(e.local,e.to);const u=[];a(i.fragment,null,{SvelteOptions(e,{next:t}){for(const t of e.attributes??[])"Attribute"!==t.type||"accessors"!==t.name&&"customElement"!==t.name||u.push(`<svelte:options ${t.name}>`);t()}});let f,l,p=null,d=!1;const m=new Set,h=new Set,v=i.instance;if(v){for(const e of U(v))m.add(e.local),"*"===e.imported&&h.add(e.local);const e=function(e){const t=e.content;for(const e of t?.body??[])if("VariableDeclaration"===e.type)for(const t of e.declarations??[]){const n=t.init,o=t.id;if("CallExpression"===n?.type&&"Identifier"===n.callee?.type&&"$props"===n.callee.name&&"ObjectPattern"===o?.type)return{declaration:e,pattern:o,sharesStatement:(e.declarations?.length??1)>1}}return null}(v);if(e){f=e.declaration,l=e.pattern,e.sharesStatement&&u.push("$props() shares a multi-declarator statement"),p=[];for(const t of e.pattern.properties??[]){if("RestElement"===t.type){d=!0;continue}if("Property"!==t.type)continue;const e=t.key;if("Identifier"!==e?.type||!e.name)continue;const n=t.value;let o,r=null;"Identifier"===n?.type?r=n.name??null:"AssignmentPattern"===n?.type&&(o=n.right,"Identifier"===n.left?.type&&(r=n.left.name??null)),p.push({name:e.name,local:r,property:t,defaultExpr:o})}}}const w=function(e,t){const n=[];return a(e.fragment,null,{Component(e,{next:o}){const r=e.name?t.get(e.name):void 0;r&&n.push({childId:r,node:e}),o()}}),n}(i,c),{shadowedNames:g,debugNames:y}=function(e,t,n){const o=new Set,r=new Set;t&&a(t,null,{_(e,{next:t}){if("VariableDeclarator"!==e.type&&"FunctionDeclaration"!==e.type||e===n||"Identifier"!==e.id?.type||!e.id.name||o.add(e.id.name),"FunctionDeclaration"===e.type||"FunctionExpression"===e.type||"ArrowFunctionExpression"===e.type)for(const t of e.params??[])R(t,o);t()}});return a(e.fragment,null,{EachBlock(e,{next:t}){R(e.context,o),"string"==typeof e.index&&o.add(e.index),t()},SnippetBlock(e,{next:t}){"Identifier"===e.expression?.type&&e.expression.name&&o.add(e.expression.name);for(const t of e.parameters??[])R(t,o);t()},AwaitBlock(e,{next:t}){R(e.value,o),R(e.error,o),t()},LetDirective(e,{next:t}){e.name&&o.add(e.name),t()},ConstTag(e,{next:t}){for(const t of e.declaration?.declarations??[])R(t.id,o);t()},DebugTag(e,{next:t}){for(const t of e.identifiers??[])"Identifier"===t.type&&t.name&&r.add(t.name);t()}}),{shadowedNames:o,debugNames:r}}(i,v,f),k=function(e,t,n,o){const r=new Set,s=e=>{if(!e)return;const n=t.get(e);if(n&&r.add(n),o.has(e))for(const[n,o]of t)n.startsWith(`${e}.`)&&r.add(o)};a(e.fragment,{parent:null},{_(e,{state:t,next:o}){"Identifier"===e.type&&e.name&&n.has(e.name)&&L(e,t.parent)&&s(e.name),o({parent:e})}}),e.instance&&a(e.instance,{parent:null},{_(e,{state:n,next:r}){"Identifier"===e.type&&e.name&&(t.has(e.name)||o.has(e.name))&&L(e,n.parent)&&!N(n.parent)&&s(e.name),r({parent:e})}});return r}(i,c,m,h);return{id:o,code:r,ast:i,imports:c,props:p,propsDeclaration:f,propsPattern:l,hasRestProp:d,childCalls:w,shadowedNames:g,debugNames:y,escapedComponents:k,bailReasons:u}}function R(e,t){if(e)switch(e.type){case"Identifier":return void(e.name&&t.add(e.name));case"ObjectPattern":for(const n of e.properties??[])"RestElement"===n.type?R(n.argument,t):"Property"===n.type&&R(n.value??n.key,t);return;case"ArrayPattern":for(const n of e.elements??[])R(n,t);return;case"AssignmentPattern":return void R(e.left,t);case"RestElement":return void R(e.argument,t);default:return}}function L(e,t){return!!t&&(!("MemberExpression"===t.type&&t.property===e&&!t.computed)&&(!("Property"===t.type&&t.key===e&&!t.computed&&!0!==t.shorthand)&&!N(t)))}function N(e){return null!=e&&("ImportSpecifier"===e.type||"ImportDefaultSpecifier"===e.type||"ImportNamespaceSpecifier"===e.type||"ExportSpecifier"===e.type)}function O(e,t){const n=new Set;return 0===t.size||a(e.fragment,null,{Component(e,{next:o}){const r=e.name?t.get(e.name):void 0;r&&n.add(r),o()}}),n}function T(e){const t=new Set;return a(e.fragment,null,{Component(e,{next:n}){"string"==typeof e.name&&e.name.includes(".")&&t.add(e.name),n()}}),t}function B(e){const t=e.attributes??[];let n=-1;for(let e=0;e<t.length;e++)"SpreadAttribute"===t[e].type&&(n=e);const o=new Map;for(let e=0;e<t.length;e++){const r=t[e],s=r.name;if("BindDirective"===r.type){s&&o.set(s,j(e,n));continue}if("Attribute"!==r.type||!s)continue;const a=_(r.value);o.set(s,a.known?{value:a.value,dynamic:!1,afterLastSpread:e>n}:j(e,n))}for(const r of function(e){const t=e.fragment?.nodes??[],n=[];let o=!1;for(const e of t)if("SnippetBlock"!==e.type){if("Comment"!==e.type){if("Text"===e.type){if(""===(e.data??e.raw??"").trim())continue}o=!0}}else"Identifier"===e.expression?.type&&e.expression.name&&n.push(e.expression.name);o&&n.push("children");return n}(e))o.set(r,j(t.length,n));return{hadSpread:n>=0,explicit:o}}function j(e,t){return{value:void 0,dynamic:!0,afterLastSpread:e>t}}function _(e){if(!0===e)return{known:!0,value:!0};if(null==e)return{known:!1};const t=Array.isArray(e)?e:[e];if(1===t.length){const e=t[0];return"Text"===e.type?{known:!0,value:e.data??e.raw??""}:"ExpressionTag"===e.type&&"Literal"===e.expression?.type?{known:!0,value:e.expression.value}:{known:!1}}let n="";for(const e of t){if("Text"!==e.type)return{known:!1};n+=e.data??e.raw??""}return{known:!0,value:n}}function q(e,t){return e.shadowedNames.has(t)||e.debugNames.has(t)}function V(e,t){const n={id:e.id,bail:!1,reasons:[],constFold:new Map,narrow:new Map,valueSets:new Map};if(e.bailReasons.length>0)return n.bail=!0,n.reasons.push(...e.bailReasons),n;if(!e.props||0===e.props.length)return n;const o=t?.sites??[];if(0===o.length)return n;for(const t of e.props){if(null===t.local||q(e,t.local))continue;const r=W(t,o);n.valueSets.set(t.name,r),r.top||r.dynamic||(1!==r.values.length?r.values.length>=2&&n.narrow.set(t.name,r.values):n.constFold.set(t.name,r.values[0]))}return n}function W(e,t){const n=[];let o=!1,r=!1;const s=e=>{n.some(t=>Object.is(t,e))||n.push(e)};for(const n of t){const t=n.explicit.get(e.name);if(t?.afterLastSpread){t.dynamic?o=!0:s(t.value);continue}if(n.hadSpread){r=!0;continue}const a=J(e.defaultExpr);a.known?s(a.value):o=!0}return{values:n,dynamic:o,top:r}}function J(e){return e?"Literal"===e.type?{known:!0,value:e.value}:"Identifier"===e.type&&"undefined"===e.name?{known:!0,value:void 0}:{known:!1}:{known:!0,value:void 0}}function*U(e){const t=e.content;for(const e of t?.body??[]){if("ImportDeclaration"!==e.type)continue;const t=e.source?.value;if("string"==typeof t)for(const n of e.specifiers??[]){const e=n.local?.name;e&&("ImportDefaultSpecifier"===n.type?yield{value:t,local:e,imported:"default"}:"ImportNamespaceSpecifier"===n.type?yield{value:t,local:e,imported:"*"}:"ImportSpecifier"===n.type&&(yield{value:t,local:e,imported:X(n)??e}))}}}function X(e){const t=e.imported;return"Identifier"===t?.type&&t.name?t.name:"Literal"===t?.type&&"string"==typeof t.value?t.value:void 0}function G(e){return"Identifier"===e?.type&&e.name?e.name:"Literal"===e?.type&&"string"==typeof e.value?e.value:void 0}const H=8;async function K(e,t,n,o,s,a=0){if(a>H)return null;const i=await o(e,n);if(!i)return null;if(x(e)||x(i))return"default"===t||"*"===t?i:null;let c;try{c=await s(i)}catch{return null}const u=function(e,t){try{const n=r(`<script module lang="ts">\n${e}\n<\/script>`,t);return n.module?.content?.body??null}catch{return null}}(c,i);if(!u)return null;for(const e of u)if("ExportNamedDeclaration"===e.type&&e.source?.value){for(const n of e.specifiers??[])if(G(n.exported)===t)return K(String(e.source.value),G(n.local)??"default",i,o,s,a+1)}else if("ExportNamedDeclaration"!==e.type||e.source){if("ExportAllDeclaration"===e.type&&e.source?.value){const n=await K(String(e.source.value),t,i,o,s,a+1);if(n)return n}}else for(const n of e.specifiers??[]){if(G(n.exported)!==t)continue;const e=G(n.local);if(!e)continue;const r=Q(u,e);return r?K(r.value,r.imported,i,o,s,a+1):null}return null}function Q(e,t){for(const n of e){if("ImportDeclaration"!==n.type)continue;const e=n.source?.value;if("string"==typeof e)for(const o of n.specifiers??[])if(o.local?.name===t){if("ImportDefaultSpecifier"===o.type)return{value:e,imported:"default"};if("ImportNamespaceSpecifier"===o.type)return{value:e,imported:"*"};if("ImportSpecifier"===o.type)return{value:e,imported:X(o)??t}}}return null}const Y=Symbol("unbounded-class-source");function Z(e,t,n){if(!0===e)return Y;if(null==e)return new Set;const o=Array.isArray(e)?e:[e];let r=[""];for(const e of o){const o=ee(e,t,n);if(o===Y)return Y;const s=[];for(const e of r)for(const t of o)if(s.push(e+t),s.length>64)return Y;r=s}const s=new Set;for(const e of r)for(const t of e.split(/\s+/))t&&s.add(t);return s}function ee(e,t,n){return"Text"===e.type?new Set([e.data??e.raw??""]):"ExpressionTag"===e.type?function(e,t,n){if(!e)return Y;if("Identifier"===e.type&&e.name&&n.has(e.name)){const t=new Set;for(const o of n.get(e.name))t.add(te(o));return t}const o=c(e,t);return o.known?new Set([te(o.value)]):Y}(e.expression,t,n):Y}function te(e){return String(e)}function ne(e,t,n){const o=e.ast.css;if(!o||!o.children)return 0;const r=function(e,t){const n=new Set;let o=!1;const r=t.constFold,s=t.narrow;return a(e.ast.fragment,null,{_(e,{next:t}){if("RegularElement"===(a=e.type)||"SvelteElement"===a||"Component"===a||"SvelteComponent"===a||"SvelteSelf"===a){var a;for(const t of e.attributes??[]){if("SpreadAttribute"===t.type){o=!0;continue}if("ClassDirective"===t.type){t.name&&n.add(t.name);continue}if("Attribute"!==t.type||"class"!==t.name)continue;const e=Z(t.value,r,s);if(e===Y)o=!0;else for(const t of e)n.add(t)}t()}else t()}}),{classes:n,unbounded:o}}(e,t);if(r.unbounded)return 0;let s=0;for(const t of o.children)"Rule"===t.type&&oe(t,r.classes)&&(re(e.code,t,o.children,n),s+=1);return s}function oe(e,t){if(function(e){let t=!1;return a(e,null,{_(e,{next:n}){"PseudoClassSelector"===e.type&&"global"===e.name&&(t=!0),n()}}),t}(e))return!1;const n=e.prelude?.children??[];return 0!==n.length&&n.every(e=>function(e,t){let n=!1;for(const o of e.children??[])for(const e of o.selectors??[])"ClassSelector"===e.type&&e.name&&!t.has(e.name)&&(n=!0);return n}(e,t))}function re(e,t,n,o){const r=n.indexOf(t),s=n[r-1];let a=t.start;const i=s?s.end:0;for(;a>i&&/\s/.test(e[a-1]);)a-=1;o.remove(a,t.end)}function se(e,t){return ie(e,ae(e,t))}function ae(e,t){const n=new Map,r=new Map,s=new Map;for(const a of e.values()){const e=new o(a.code);n.set(a.id,e);const i=t.get(a.id);if(i.bail){r.set(a.id,new Set);continue}const c=pe(a,i,e);r.set(a.id,c.dropped),s.set(a.id,c.dead)}for(const t of e.values())Ie(t,r,n.get(t.id),s.get(t.id)??[]);return n}function ie(e,t){const n={};for(const o of e.values())n[o.id]=t.get(o.id).toString();return n}function ce(e,t,n,o){const r=ae(e,t);return function(e,t,n,o){const r=new Map;for(const e of t){const t=r.get(e.owner);t?t.push(e):r.set(e.owner,[e])}for(const[t,s]of r){const r=e.get(t),a=o.get(t);if(!r||!a)continue;const i=new Map,c=[];let u=0;for(const e of s){const t=e.node.name??"Cmp";let o=i.get(e.variantId);void 0===o&&(o=`${t}__shaker_v${u++}`,i.set(e.variantId,o),c.push({local:o,spec:n(e.variantId)})),ue(r.code,e.node,o,e.foldedProps,a)}c.length>0&&le(r,c,a)}}(e,n,o,r),ie(e,r)}function ue(e,t,n,o,r){const s=t.name;if(!s)return;const a=t.start+1;e.slice(a,a+s.length)===s&&r.overwrite(a,a+s.length,n);const i=`</${s}`,c=e.lastIndexOf(i,t.end);if(c>=t.start){const e=c+2;r.overwrite(e,e+s.length,n)}for(const n of t.attributes??[])"Attribute"===n.type&&n.name&&o.has(n.name)&&fe(e,n,r)}function fe(e,t,n){let o=t.start;" "!==e[o-1]&&"\t"!==e[o-1]||(o-=1),n.remove(o,t.end)}function le(e,t,n){const o=t.map(e=>` import ${e.local} from ${JSON.stringify(e.spec)};`).join("\n"),r=e.ast.instance,s=r?.content?.body??[];if(r&&s.length>0){const e=s[s.length-1];return void n.appendLeft(e.end,`\n${o}`)}r&&r.content?n.appendLeft(r.content.start,`\n${o}\n`):n.prepend(`<script>\n${o}\n<\/script>\n`)}function pe(e,t,n){const o=[];return{dropped:de(e,t.constFold,t.narrow,t,n,o),dead:o}}function de(e,t,n,o,r,s){if(0===t.size&&0===n.size)return new Set;const i=e.code,u=D(t,e),f=D(n,e),l=[];!function(e,t,n,o,r,s){a(e,{parent:null,preserve:ge(e)},{_(e,{state:a,next:i}){if("IfBlock"!==e.type)return void i({parent:e,preserve:a.preserve||we(e)});if(e.elseif||y(e,s))return;const c=m(e,t,n);!function(e,t,n,o,r,s){if(e.kept){let a=function(e,t,n){const o=e?.nodes??[];return 0===o.length?"":ke(o[0].start,o[o.length-1].end,o,t,n)}(e.kept,t,n);return s.preserve||(a=a.replace(/^\s+|\s+$/g,"")),""!==a||s.preserve?(o.overwrite(e.span[0],e.span[1],a),void r.push(e.span)):void me([e.span],e.span,n,o,r,s)}if(function(e){return void 0===e.kept&&1===e.removed.length&&e.removed[0][0]===e.span[0]&&e.removed[0][1]===e.span[1]}(e))return void me(e.removed,e.span,n,o,r,s);for(const[t,n]of e.removed)o.remove(t,n),r.push([t,n]);if(e.headerRewrite){const{from:t,to:n,text:r}=e.headerRewrite;o.overwrite(t,n,r)}}(c,t,o,r,s,{parent:a.parent,index:a.parent?.nodes?.indexOf(e)??-1,preserve:a.preserve}),c.recurse&&i({parent:e,preserve:a.preserve})}})}(e.ast.fragment,u,f,i,r,l),function(e,t,n,o,r){if(0===t.size)return;a(e,null,{ConditionalExpression(e,{next:s}){if(y(e,r))return;const a=c(e.test,t);if(!a.known)return void s();const i=a.value?e.consequent:e.alternate;i?(o.overwrite(e.start,e.end,ke(i.start,i.end,[i],t,n)),r.push([e.start,e.end])):s()}})}(e.ast.fragment,u,i,r,l);const p=function(e,t,n){const o=new Map,r=r=>{r&&xe(r,t,e.code,(t,r,s)=>{y(s,n)||s===e.propsPattern||(o.get(t)??function(e,t){const n=[];return e.set(t,n),n}(o,t)).push(r)})};return r(e.ast.instance),r(e.ast.fragment),o}(e,u,l);for(const[e,t]of u){const n=Ae(t);for(const t of p.get(e)??[])r.overwrite(t.start,t.end,t.head+n+t.tail)}const d=new Set(t.keys());!function(e,t,n){if(!e.props||0===t.size)return;const o=e.props.filter(e=>!t.has(e.name));if(0===o.length&&!e.hasRestProp&&e.propsDeclaration)return void function(e,t,n){let o=t.start;for(;o>0&&"\n"!==e[o-1];)o-=1;let r=t.end;for(;r<e.length&&"\n"!==e[r];)r+=1;const s=e.slice(o,t.start),a=e.slice(t.end,r);/^\s*$/.test(s)&&/^\s*;?\s*$/.test(a)?n.remove(o,r<e.length?r+1:r):n.remove(t.start,";"===e[t.end]?t.end+1:t.end)}(e.code,e.propsDeclaration,n);const r=e.propsPattern?.properties??[],s=new Set(e.props.filter(e=>t.has(e.name)).map(e=>e.property));let a=0;for(;a<r.length;){if(!s.has(r[a])){a++;continue}let t=a;for(;t+1<r.length&&s.has(r[t+1]);)t++;Se(e.code,r,a,t,n),a=t+1}if(e.propsPattern)for(const o of e.props)t.has(o.name)&&be(e.propsPattern,o.name,n)}(e,d,r);return ne(e,{...o,constFold:u,narrow:f},r),s&&s.push(...l),d}function me(e,t,n,o,r,s){if(!s.preserve&&s.parent?.nodes&&s.index>=0){const e=function(e,t,n,o,r){const s=e=>!!e&&!y(e,r),a=e[t-1],i=e[t+1],c=s(a)&&he(a,o)?a:void 0,u=s(i)&&he(i,o)?i:void 0,f=c?t-2:t-1,l=u?t+2:t+1,p=f>=0&&ve(e[f],o),d=l<e.length&&ve(e[l],o),m=p&&d&&(!!c||!!u);return!(!!c&&p||!!u&&d)||m?void 0:[c?c.start:n[0],u?u.end:n[1]]}(s.parent.nodes,s.index,t,n,r);if(e)return o.overwrite(e[0],e[1],'{" "}'),void r.push(e)}for(const[t,n]of e)o.remove(t,n),r.push([t,n])}function he(e,t){return"Text"===e.type&&/^\s*$/.test(t.slice(e.start,e.end))}function ve(e,t){return"Comment"!==e.type&&!he(e,t)}function we(e){return"RegularElement"===e.type&&("pre"===e.name||"textarea"===e.name)}function ge(e){let t=!1;return a(e,null,{SvelteOptions(e){for(const n of e.attributes??[])"Attribute"===n.type&&"preserveWhitespace"===n.name&&(t=!ye(n.value))}}),t}function ye(e){if(!1===e)return!0;return(Array.isArray(e)?e:[e]).some(e=>"ExpressionTag"===e?.type&&"Literal"===e.expression?.type&&!1===e.expression.value)}function ke(e,t,n,o,r){if(0===o.size)return r.slice(e,t);const s=[];for(const e of n)xe(e,o,r,(e,t)=>s.push({...t,name:e}));if(0===s.length)return r.slice(e,t);s.sort((e,t)=>e.start-t.start);let a="",i=e;for(const e of s)a+=r.slice(i,e.start),a+=e.head+Ae(o.get(e.name))+e.tail,i=e.end;return a+=r.slice(i,t),a}function xe(e,t,n,o){a(e,{parent:null,grandparent:null},{_(e,{state:r,next:s}){if("StyleDirective"===e.type&&!0===e.value&&e.name&&t.has(e.name)){let t=e.end;for(;t>e.start&&Ee(n[t-1]);)t-=1;const r=n.slice(e.start,t);o(e.name,{start:e.start,end:t,head:`${r}={`,tail:"}"},e)}else"Identifier"===e.type&&e.name&&t.has(e.name)&&!function(e,t){return!!t&&("MemberExpression"===t.type&&t.property===e&&!t.computed||("Property"===t.type&&t.key===e&&!t.computed&&!0!==t.shorthand||(!("TSPropertySignature"!==t.type&&"TSMethodSignature"!==t.type||t.key!==e||t.computed)||("ImportSpecifier"===t.type||"ImportDefaultSpecifier"===t.type||"ImportNamespaceSpecifier"===t.type||"ExportSpecifier"===t.type))))}(e,r.parent)&&o(e.name,function(e,t,n,o){if("ClassDirective"===t?.type&&t.expression===e&&":"===o[e.start-1]){const t=o.slice(e.start,e.end);return{start:e.start,end:e.end,head:`${t}={`,tail:"}"}}if("ExpressionTag"===t?.type&&"Attribute"===n?.type&&n.name&&"{"===o[n.start])return{start:n.start,end:n.end,head:`${n.name}={`,tail:"}"};if("Property"===t?.type&&!0===t.shorthand&&t.value===e){const t=o.slice(e.start,e.end);return{start:e.start,end:e.end,head:`${t}: `,tail:""}}return{start:e.start,end:e.end,head:"",tail:""}}(e,r.parent,r.grandparent,n),e);s({parent:e,grandparent:r.parent})}})}function Se(e,t,n,o,r){const s=t[n],a=t[o],i=t[o+1];if(i)return void r.remove(s.start,i.start);let c=a.end,u=c;for(;u<e.length&&/\s/.test(e[u]);)u++;","===e[u]&&(c=u+1);const f=t[n-1];r.remove(f?f.end:s.start,c)}function be(e,t,n){const o=e.typeAnnotation?.typeAnnotation?.members??[],r=o.findIndex(e=>"Identifier"===e.key?.type&&e.key.name===t);if(-1===r)return;const s=o[r],a=o[r+1],i=o[r-1];a?n.remove(s.start,a.start):i?n.remove(i.end,s.end):n.remove(s.start,s.end)}function Ie(e,t,n,o){a(e.ast.fragment,null,{Component(r,{next:s}){if(o.length>0&&y(r,o))return;const a=r.name?e.imports.get(r.name):void 0,i=a?t.get(a):void 0;if(i&&i.size>0)for(const t of r.attributes??[])"Attribute"===t.type&&t.name&&i.has(t.name)&&Me(t.value)&&fe(e.code,t,n);s()}})}function Me(e){if(!0===e||null==e)return!0;return(Array.isArray(e)?e:[e]).every(e=>"Text"===e.type||"ExpressionTag"===e.type&&"Literal"===e.expression?.type)}function Ee(e){return" "===e||"\t"===e||"\n"===e||"\r"===e}function Ae(e){return void 0===e?"undefined":JSON.stringify(e)}const Ce={enabled:!1,maxVariants:8,minSavings:0};function Fe(e,n,o=Ce,r=[]){const s=new Map,a=[];if(!o.enabled)return{variants:s,bindings:a};const i=$(e,n),c=new Map,u=new Set;for(const t of e.values()){const o=i.get(t.id)??[];for(const r of t.childCalls){if(o.length>0&&y(r.node,o))continue;const s=e.get(r.childId),a=n.get(r.childId);if(!s||!a)continue;if(a.bail||!s.props||0===s.props.length){u.add(r.childId);continue}const i=De(r.node,s,a);if(0===i.size){u.add(r.childId);continue}const f=ze(s,a,i);if(f===Le(s,a)){u.add(r.childId);continue}const l=c.get(r.childId);l?l.push({owner:t.id,node:r.node,shape:i,code:f}):c.set(r.childId,[{owner:t.id,node:r.node,shape:i,code:f}])}}const f=function(e,t){const n=new Map;for(const o of e.values()){const e=t.get(o.id);n.set(o.id,e.bail?o.code:Le(o,e))}return n}(e,n),l=new Map;for(const t of e.values())l.set(t.id,$e(f.get(t.id),t));const p=new Set;for(const e of l.values())for(const t of e)p.add(t);const d=(Array.isArray(r)?r:[r]).filter(t=>e.has(t)).filter(e=>!p.has(e)),m=new Map,h=(e,n)=>{const o=m.get(n);if(void 0!==o)return o;let r;try{const{js:o}=t(n,{generate:"client",dev:!1,filename:e});r=o.code.length}catch{r=null}return null!==r&&m.set(n,r),r},v=new Set;for(const e of c.keys())u.has(e)||v.add(e);for(const[t,n]of c){if(u.has(t))continue;if(n.some(e=>e.owner!==t&&v.has(e.owner)))continue;const r=new Map,i=[];let c=!1;for(const e of n){if(r.has(e.code))continue;if(i.length>=o.maxVariants){c=!0;break}const n=`${t}::v${i.length}`;r.set(e.code,n),i.push({id:n,code:e.code})}if(!c&&Pe(t,i,e,f,l,d,h,o.minSavings)){for(const e of i){const o=n.find(t=>t.code===e.code);s.set(e.id,{id:e.id,childId:t,code:e.code,foldedProps:o.shape})}for(const e of n)a.push({owner:e.owner,childId:t,node:e.node,variantId:r.get(e.code),foldedProps:e.shape})}}return{variants:s,bindings:a}}function Pe(e,t,n,o,r,s,a,i){const c=n.get(e),u=new Map;for(const e of t)u.set(e.id,$e(e.code,c));const f=new Set,l=[...s];for(;l.length>0;){const e=l.pop();if(!f.has(e)){f.add(e);for(const t of r.get(e)??[])l.push(t)}}let p=0;for(const e of f){const t=a(e,o.get(e));if(null===t)return!1;p+=t}const d=t.map(e=>e.id),m=new Set,h=new Set,v=t=>t===e?{comps:[],vars:d}:{comps:[t],vars:[]},w=[],g=[];for(const e of s){const t=v(e);w.push(...t.comps),g.push(...t.vars)}for(;w.length>0||g.length>0;){if(w.length>0){const e=w.pop();if(m.has(e))continue;m.add(e);for(const t of r.get(e)??[]){const e=v(t);w.push(...e.comps),g.push(...e.vars)}continue}const e=g.pop();if(!h.has(e)){h.add(e);for(const t of u.get(e)??[]){const e=v(t);w.push(...e.comps),g.push(...e.vars)}}}let y=0;for(const e of m){const t=a(e,o.get(e));if(null===t)return!1;y+=t}for(const e of h){const n=t.find(t=>t.id===e).code,o=a(e,n);if(null===o)return!1;y+=o}return y<p*(1-i)}function $e(e,t){let n;try{n=r(e,t.id)}catch{return[]}const o=[];return a(n.fragment,null,{Component(e,{next:n}){const r=e.name?t.imports.get(e.name):void 0;r&&o.push(r),n()}}),o}function De(e,t,n){const o=B(e),r=new Map;for(const e of t.props??[])r.set(e.name,e);const s=new Map;for(const[e,a]of o.explicit){const o=r.get(e);o&&(n.constFold.has(e)||null===o.local||q(t,o.local)||!a.dynamic&&a.afterLastSpread&&s.set(e,a.value))}return s}function ze(e,t,n){const r=new Map(t.constFold);for(const[e,t]of n)r.set(e,t);const s=new Map;for(const[e,n]of t.narrow)r.has(e)||s.set(e,n);const a=new o(e.code);return de(e,r,s,t,a),a.toString()}const Re=new WeakMap;function Le(e,t){const n=Re.get(e);if(void 0!==n)return n;const r=new o(e.code);de(e,t.constFold,t.narrow,t,r);const s=r.toString();return Re.set(e,s),s}class Ne{entries=new Set;resolve;readFile;mode;parse;parseCache=new Map;codeCache=new Map;output={};constructor(e,t,n,o="incremental",r){for(const t of Array.isArray(e)?e:[e])this.entries.add(t);this.resolve=t,this.readFile=n,this.mode=o,this.parse=r}async init(){return this.output=await this.shake(),this.output}get(e){return this.output[e]}snapshot(){return{...this.output}}async update(e){const t="incremental"===this.mode;for(const t of e.removed??[])this.entries.delete(t),this.codeCache.delete(t),this.parseCache.delete(t);for(const n of e.added??[])this.entries.add(n),t&&this.codeCache.set(n,await this.readFile(n));for(const n of e.changed??[])t&&this.codeCache.set(n,await this.readFile(n));const n=this.output,o=await this.shake();this.output=o;const r={};for(const e of Object.keys(o))n[e]!==o[e]&&(r[e]=o[e]);return{changed:r,removed:Object.keys(n).filter(e=>!(e in o))}}async shake(){const e="incremental"===this.mode,t=e?this.cachedReadFile:this.readFile,n=e?this.parseCache:this.parse?new Map:void 0,o=await M([...this.entries],this.resolve,t,n,this.parse),{models:r,plans:s}=I(o,n);return se(r,s)}cachedReadFile=async e=>{const t=this.codeCache.get(e);if(void 0!==t)return t;const n=await this.readFile(e);return this.codeCache.set(e,n),n}}async function Oe(e,t,n,o){const{models:r,plans:s}=await Te(e,t,n,o);return Be(r,se(r,s))}async function Te(e,t,n,o){if(!o)return b(e,t,n);const r=new Map;return I(await M(e,t,n,r,o),r)}function Be(e,t){for(const[n,o]of Object.entries(t)){const s=e.get(n);if(s&&o!==s.code)try{r(o,n)}catch{t[n]=s.code}}return t}async function je(e,t,n,o=Ce,r=e=>e,s){const{models:a,plans:i}=await Te(e,t,n,s),c=Fe(a,i,o,e);return{files:Be(a,0===c.bindings.length?se(a,i):ce(a,i,c.bindings.map(e=>({owner:e.owner,node:e.node,variantId:e.variantId,foldedProps:e.foldedProps})),r)),mono:c}}export{Ce as DEFAULT_MONO_OPTIONS,Ne as DevShaker,b as analyze,I as analyzeInput,M as buildAnalyzeInput,Fe as monomorphize,Oe as svelteShaker,je as svelteShakerWithMono,se as transformAll,ce as transformAllWithMono};
|
|
1
|
+
import { analyze, analyzeInput, buildAnalyzeInput, } from './analyze.js';
|
|
2
|
+
import { parseSvelte } from './parse.js';
|
|
3
|
+
import { transformAll, transformAllWithMono } from './transform.js';
|
|
4
|
+
import { monomorphize, DEFAULT_MONO_OPTIONS, } from './mono.js';
|
|
5
|
+
export { analyze, analyzeInput, buildAnalyzeInput } from './analyze.js';
|
|
6
|
+
export { DevShaker } from './engine.js';
|
|
7
|
+
export { transformAll, transformAllWithMono } from './transform.js';
|
|
8
|
+
export { monomorphize, DEFAULT_MONO_OPTIONS, } from './mono.js';
|
|
9
|
+
/**
|
|
10
|
+
* Whole-program shake: crawl the component graph from `entry`, decide what to
|
|
11
|
+
* fold, and return the shaken source for every reachable `.svelte` file.
|
|
12
|
+
*
|
|
13
|
+
* `resolve` / `readFile` are injected so the engine stays environment-free —
|
|
14
|
+
* it has NO `node:*` imports, so it runs unchanged in the browser (the
|
|
15
|
+
* playground passes an in-memory file map). A Vite plugin passes `this.resolve`;
|
|
16
|
+
* Node callers use `fsResolve` / `fs.readFileSync` from `svelte-shaker/node`.
|
|
17
|
+
* See docs/ARCHITECTURE.md §5 — this is the Engine; the Shell owns resolution.
|
|
18
|
+
*/
|
|
19
|
+
export async function svelteShaker(entries, resolve, readFile, parse) {
|
|
20
|
+
const { models, plans } = await analyzeWith(entries, resolve, readFile, parse);
|
|
21
|
+
return revertUnparseable(models, transformAll(models, plans));
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Crawl + analyze with an optional non-default parser ({@link Parse}). When
|
|
25
|
+
* `parse` is given (the Vite plugin's `parser: 'rsvelte'` path), each file is
|
|
26
|
+
* parsed ONCE into a shared cache during the crawl and that cache is reused by the
|
|
27
|
+
* analysis — so the alternate parser drives the whole engine with no second parse.
|
|
28
|
+
* When omitted, this is exactly `analyze(entries, resolve, readFile)` (the default
|
|
29
|
+
* svelte/compiler path, byte-for-byte unchanged).
|
|
30
|
+
*/
|
|
31
|
+
async function analyzeWith(entries, resolve, readFile, parse) {
|
|
32
|
+
if (!parse)
|
|
33
|
+
return analyze(entries, resolve, readFile);
|
|
34
|
+
const cache = new Map();
|
|
35
|
+
const input = await buildAnalyzeInput(entries, resolve, readFile, cache, parse);
|
|
36
|
+
return analyzeInput(input, cache);
|
|
37
|
+
}
|
|
38
|
+
/**
|
|
39
|
+
* Self-check the shaken output: if a component's slimmed source does not re-parse
|
|
40
|
+
* as valid Svelte, leave that file UNTOUCHED (revert to its original). The engine
|
|
41
|
+
* aims to only ever emit valid, behavior-preserving source, so a parse failure is a
|
|
42
|
+
* transform bug — but this last line of defense keeps a single mishandled component
|
|
43
|
+
* shape from breaking the whole build, and reverting one file is always sound (it is
|
|
44
|
+
* just "did not shake this component"). Unchanged files are skipped (cheap).
|
|
45
|
+
*/
|
|
46
|
+
function revertUnparseable(models, out) {
|
|
47
|
+
for (const [id, code] of Object.entries(out)) {
|
|
48
|
+
const model = models.get(id);
|
|
49
|
+
if (!model || code === model.code)
|
|
50
|
+
continue;
|
|
51
|
+
try {
|
|
52
|
+
parseSvelte(code, id);
|
|
53
|
+
}
|
|
54
|
+
catch {
|
|
55
|
+
out[id] = model.code;
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
return out;
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* Whole-program shake WITH optional L2 monomorphization (docs §3 "L2").
|
|
62
|
+
*
|
|
63
|
+
* `mono` carries the specialized variants (id -> residual source) and the call
|
|
64
|
+
* sites bound to them; `files` is the wired owner source. The Shell resolves
|
|
65
|
+
* `variantSpecifier(id)` to a virtual module whose source is
|
|
66
|
+
* `mono.variants.get(id)!.code`. With `mono.enabled` false (default) nothing is
|
|
67
|
+
* specialized and `files` equals the L0/L1/L1.5 output exactly — a strict
|
|
68
|
+
* superset of the default behavior, so existing consumers are unaffected.
|
|
69
|
+
*/
|
|
70
|
+
export async function svelteShakerWithMono(entries, resolve, readFile, mono = DEFAULT_MONO_OPTIONS, variantSpecifier = (id) => id, parse) {
|
|
71
|
+
const { models, plans } = await analyzeWith(entries, resolve, readFile, parse);
|
|
72
|
+
// Thread the shake entries through so the net-win gate can compute module
|
|
73
|
+
// reachability from them (docs §3 L2, §13.2).
|
|
74
|
+
const result = monomorphize(models, plans, mono, entries);
|
|
75
|
+
// With no bindings the wired pass and the base pass are identical, so reuse
|
|
76
|
+
// the plain transform to keep the default path byte-for-byte unchanged.
|
|
77
|
+
const files = result.bindings.length === 0
|
|
78
|
+
? transformAll(models, plans)
|
|
79
|
+
: transformAllWithMono(models, plans, result.bindings.map((b) => ({
|
|
80
|
+
owner: b.owner,
|
|
81
|
+
node: b.node,
|
|
82
|
+
variantId: b.variantId,
|
|
83
|
+
foldedProps: b.foldedProps,
|
|
84
|
+
})), variantSpecifier);
|
|
85
|
+
return { files: revertUnparseable(models, files), mono: result };
|
|
86
|
+
}
|
package/dist/ir.js
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
// ----------------------------------------------------------------------
|
|
2
|
+
// IR / data contract between the analysis and the transform.
|
|
3
|
+
// See docs/ARCHITECTURE.md §5.1. This is the M0 (walking-skeleton) subset:
|
|
4
|
+
// only the pieces basic1 exercises, but shaped so later levels slot in.
|
|
5
|
+
// ----------------------------------------------------------------------
|
|
6
|
+
export function emptyPlan(id) {
|
|
7
|
+
return {
|
|
8
|
+
id,
|
|
9
|
+
bail: false,
|
|
10
|
+
reasons: [],
|
|
11
|
+
constFold: new Map(),
|
|
12
|
+
narrow: new Map(),
|
|
13
|
+
valueSets: new Map(),
|
|
14
|
+
};
|
|
15
|
+
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { type FileModel } from './analyze';
|
|
2
|
-
import { type AnyNode } from './parse';
|
|
3
|
-
import type { ComponentId, ComponentPlan, Literal } from './ir';
|
|
1
|
+
import { type FileModel } from './analyze.js';
|
|
2
|
+
import { type AnyNode } from './parse.js';
|
|
3
|
+
import type { ComponentId, ComponentPlan, Literal } from './ir.js';
|
|
4
4
|
/** Tuning knobs for L2 (docs §8.1, §13.2). All have sound defaults. */
|
|
5
5
|
export interface MonomorphizeOptions {
|
|
6
6
|
/** Master switch. Default OFF — every existing behavior is unchanged. */
|