svelte-shaker 0.5.2 → 0.7.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/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. */