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/{types/src/analyze.d.ts → analyze.d.ts} +23 -10
- package/dist/analyze.js +1140 -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/{types/src/parse.d.ts → parse.d.ts} +4 -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 +328 -1
- package/package.json +9 -18
- package/dist/index.cjs +0 -1
- /package/dist/{types/src/ir.d.ts → ir.d.ts} +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { Plugin } from 'vite';
|
|
2
|
-
import { type DevMode } from './engine';
|
|
3
|
-
import { type MonomorphizeOptions } from './mono';
|
|
2
|
+
import { type DevMode } from './engine.js';
|
|
3
|
+
import { type MonomorphizeOptions } from './mono.js';
|
|
4
4
|
export interface ShakerOptions {
|
|
5
5
|
/**
|
|
6
6
|
* Directories (relative to the Vite root) to scan for `.svelte` components.
|
|
@@ -45,6 +45,14 @@ export interface ShakerOptions {
|
|
|
45
45
|
* deterministic across machines (install the peer on every build platform).
|
|
46
46
|
*/
|
|
47
47
|
parser?: 'svelte' | 'rsvelte';
|
|
48
|
+
/**
|
|
49
|
+
* Report how much the shake saved. Default `false`: a single one-line summary
|
|
50
|
+
* of the whole-program byte reduction is always printed after the build crawl.
|
|
51
|
+
* `true` additionally prints a per-file breakdown (original → shaken size and
|
|
52
|
+
* the delta) for every component that actually shrank, so you can see which
|
|
53
|
+
* files were shaken and by how much. Reporting only — it never affects output.
|
|
54
|
+
*/
|
|
55
|
+
verbose?: boolean;
|
|
48
56
|
}
|
|
49
57
|
/**
|
|
50
58
|
* Source-level Svelte tree-shaking as a Vite plugin (docs/ARCHITECTURE.md §6).
|
package/dist/vite.js
CHANGED
|
@@ -1 +1,328 @@
|
|
|
1
|
-
import*as e from"node:fs";import*as t from"node:path";import{parse as n,compile as o}from"svelte/compiler";import{walk as r}from"zimmerframe";import s from"magic-string";import{createRequire as a}from"node:module";function i(e,t){return n(e,{modern:!0,filename:t})}function c(e,t,n,o=i){if(!n)return o(t,e);const r=n.get(e);if(r&&r.code===t)return r.ast;const s=o(t,e);return n.set(e,{code:t,ast:s}),s}function u(e,t,n){r(e,t,n)}const l={known:!1};function f(e,t){if(!e)return l;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)}:l}case"UnaryExpression":{const n=f(e.argument,t);if(!n.known)return l;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 l}}case"LogicalExpression":{const n=f(e.left,t);if(!n.known)return l;switch(e.operator){case"&&":return n.value?f(e.right,t):n;case"||":return n.value?n:f(e.right,t);case"??":return null===n.value||void 0===n.value?f(e.right,t):n;default:return l}}case"BinaryExpression":{const n=f(e.left,t),o=f(e.right,t);if(!n.known||!o.known)return l;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 l}}default:return l}}function d(e,t,n){const o=f(e,t);if(o.known)return o;const r=p(e,t,n);return"unknown"===r?l:{known:!0,value:r}}function p(e,t,n){if(!e)return"unknown";switch(e.type){case"UnaryExpression":return"!"===e.operator?v(p(e.argument,t,n)):"unknown";case"LogicalExpression":{const s=p(e.left,t,n),a=()=>p(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=m(e,o),a=f(t,n);if(s&&a.known)return h(s,a.value,r);const i=m(t,o),c=f(e,n);return i&&c.known?h(i,c.value,r):c.known&&a.known?r?c.value==a.value:c.value===a.value:"unknown"}(e.left,e.right,t,n,r);return"!=="===o||"!="===o?v(s):s}return"unknown"}default:return"unknown"}var o,r}function m(e,t){return"Identifier"===e?.type&&e.name&&t.has(e.name)?t.get(e.name):null}function h(e,t,n){const o=n?e=>e==t:e=>e===t;return!!e.some(o)&&(!!e.every(o)||"unknown")}function v(e){return!0!==e&&(!1===e||"unknown")}function w(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=>d(e.test,t,n)),i=e=>e.known&&Boolean(e.value),c=e=>e.known&&!e.value;let u=!0;for(let e=0;e<o.length;e++){const t=a[e];if(i(t)&&u){const t=o[e].consequent;return{span:s,kept:t,removed:y(s,g(t)),recurse:!1}}c(t)||(u=!1)}const l=a.findIndex(e=>!c(e));if(-1===l)return r?{span:s,kept:r,removed:y(s,g(r)),recurse:!1}:{span:s,kept:void 0,removed:[s],recurse:!1};if(0===l)return{span:s,kept:void 0,removed:k(o,a,l),recurse:!0};const f=o[l].block;return{span:s,kept:void 0,removed:[[s[0],f.start],...k(o,a,l)],recurse:!1,headerRewrite:{from:f.start,to:f.test.start,text:"{#if "}}}function y(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 g(e){const t=e?.nodes??[];return 0===t.length?null:[t[0].start,t[t.length-1].end]}function k(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:x(s.consequent,s.block.end);o.push([s.block.start,i])}return o}function x(e,t){const n=e?.nodes??[];return n.length?n[n.length-1].end:t}function S(e,t){return t.some(([t,n])=>e.start>=t&&e.end<=n)}function b(e,t,n){if(0===t.size&&0===n.size)return[];const o=[];return u(e,null,{IfBlock(e,{next:r}){if(e.elseif||S(e,o))return;const s=w(e,t,n);for(const e of s.removed)o.push(e);s.recurse&&r()}}),o}const I=e=>e.endsWith(".svelte"),M="escapes as value (e.g. <svelte:component this={X}>)";function E(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,R(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(M)&&t.bailReasons.push(M)}let r=C(n,F(n,new Map));for(let e=0;e<10;e++){const e=C(n,F(n,z(n,r)));if($(r,e)){r=e;break}r=e}return{models:n,plans:r}}async function A(e,t,n,o,r){const s=Array.isArray(e)?[...e]:[e],a=[],i=[],u=[...s],l=new Set(u);for(;u.length>0;){const e=u.shift(),s=await n(e);a.push({id:e,code:s});const f=c(e,s,o,r),d=f.instance;if(!d)continue;const p=new Map,m=new Map,h=[];for(const o of H(d)){if("*"===o.imported){m.set(o.local,o.value);continue}if("default"===o.imported&&I(o.value)){const n=await t(o.value,e);n&&(i.push({from:e,local:o.local,to:n,kind:"default-svelte"}),h.push(n));continue}const r=await Y(o.value,o.imported,e,t,n);r&&(i.push({from:e,local:o.local,to:r,kind:"barrel"}),p.set(o.local,r))}const v=[];if(m.size>0)for(const o of W(f)){const r=o.indexOf("."),s=m.get(o.slice(0,r));if(null==s)continue;const a=await Y(s,o.slice(r+1),e,t,n);a&&(i.push({from:e,local:o,to:a,kind:"namespace"}),v.push(a))}const w=j(f,p);for(const e of[...h,...w,...v])l.has(e)||(l.add(e),u.push(e))}return{files:a,edges:i,entries:s}}function F(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&&S(t.node,e)||o(t.childId).sites.push(B(t.node))}return n}function C(e,t){const n=new Map;for(const o of e.values())n.set(o.id,G(o,t.get(o.id)));return n}function $(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(!P(o.constFold,e.constFold))return!1;if(!D(o.narrow,e.narrow))return!1}return!0}function P(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 D(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 z(e,t){const n=new Map;for(const o of e.values()){const e=t.get(o.id);if(e.bail)continue;const r=b(o.ast.fragment,O(e.constFold,o),O(e.narrow,o));r.length>0&&n.set(o.id,r)}return n}function O(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 R(e,t,n){const{id:o,code:r}=e,s=c(o,r,n),a=new Map;for(const e of t)a.set(e.local,e.to);const i=[];u(s.fragment,null,{SvelteOptions(e,{next:t}){for(const t of e.attributes??[])"Attribute"!==t.type||"accessors"!==t.name&&"customElement"!==t.name||i.push(`<svelte:options ${t.name}>`);t()}});let l,f,d=null,p=!1;const m=new Set,h=new Set,v=s.instance;if(v){for(const e of H(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){l=e.declaration,f=e.pattern,e.sharesStatement&&i.push("$props() shares a multi-declarator statement"),d=[];for(const t of e.pattern.properties??[]){if("RestElement"===t.type){p=!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)),d.push({name:e.name,local:r,property:t,defaultExpr:o})}}}const w=function(e,t){const n=[];return u(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}(s,a),{shadowedNames:y,debugNames:g}=function(e,t,n){const o=new Set,r=new Set;t&&u(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??[])L(t,o);t()}});return u(e.fragment,null,{EachBlock(e,{next:t}){L(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??[])L(t,o);t()},AwaitBlock(e,{next:t}){L(e.value,o),L(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??[])L(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}}(s,v,l),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)};u(e.fragment,{parent:null},{_(e,{state:t,next:o}){"Identifier"===e.type&&e.name&&n.has(e.name)&&N(e,t.parent)&&s(e.name),o({parent:e})}}),e.instance&&u(e.instance,{parent:null},{_(e,{state:n,next:r}){"Identifier"===e.type&&e.name&&(t.has(e.name)||o.has(e.name))&&N(e,n.parent)&&!T(n.parent)&&s(e.name),r({parent:e})}});return r}(s,a,m,h);return{id:o,code:r,ast:s,imports:a,props:d,propsDeclaration:l,propsPattern:f,hasRestProp:p,childCalls:w,shadowedNames:y,debugNames:g,escapedComponents:k,bailReasons:i}}function L(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?L(n.argument,t):"Property"===n.type&&L(n.value??n.key,t);return;case"ArrayPattern":for(const n of e.elements??[])L(n,t);return;case"AssignmentPattern":return void L(e.left,t);case"RestElement":return void L(e.argument,t);default:return}}function N(e,t){return!!t&&(!("MemberExpression"===t.type&&t.property===e&&!t.computed)&&(!("Property"===t.type&&t.key===e&&!t.computed&&!0!==t.shorthand)&&!T(t)))}function T(e){return null!=e&&("ImportSpecifier"===e.type||"ImportDefaultSpecifier"===e.type||"ImportNamespaceSpecifier"===e.type||"ExportSpecifier"===e.type)}function j(e,t){const n=new Set;return 0===t.size||u(e.fragment,null,{Component(e,{next:o}){const r=e.name?t.get(e.name):void 0;r&&n.add(r),o()}}),n}function W(e){const t=new Set;return u(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,_(e,n));continue}if("Attribute"!==r.type||!s)continue;const a=q(r.value);o.set(s,a.known?{value:a.value,dynamic:!1,afterLastSpread:e>n}:_(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,_(t.length,n));return{hadSpread:n>=0,explicit:o}}function _(e,t){return{value:void 0,dynamic:!0,afterLastSpread:e>t}}function q(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 V(e,t){return e.shadowedNames.has(t)||e.debugNames.has(t)}function G(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||V(e,t.local))continue;const r=J(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 J(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=U(e.defaultExpr);a.known?s(a.value):o=!0}return{values:n,dynamic:o,top:r}}function U(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*H(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 K(e){return"Identifier"===e?.type&&e.name?e.name:"Literal"===e?.type&&"string"==typeof e.value?e.value:void 0}const Q=8;async function Y(e,t,n,o,r,s=0){if(s>Q)return null;const a=await o(e,n);if(!a)return null;if(I(e)||I(a))return"default"===t||"*"===t?a:null;let c;try{c=await r(a)}catch{return null}const u=function(e,t){try{const n=i(`<script module lang="ts">\n${e}\n<\/script>`,t);return n.module?.content?.body??null}catch{return null}}(c,a);if(!u)return null;for(const e of u)if("ExportNamedDeclaration"===e.type&&e.source?.value){for(const n of e.specifiers??[])if(K(n.exported)===t)return Y(String(e.source.value),K(n.local)??"default",a,o,r,s+1)}else if("ExportNamedDeclaration"!==e.type||e.source){if("ExportAllDeclaration"===e.type&&e.source?.value){const n=await Y(String(e.source.value),t,a,o,r,s+1);if(n)return n}}else for(const n of e.specifiers??[]){if(K(n.exported)!==t)continue;const e=K(n.local);if(!e)continue;const i=Z(u,e);return i?Y(i.value,i.imported,a,o,r,s+1):null}return null}function Z(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 ee=Symbol("unbounded-class-source");function te(e,t,n){if(!0===e)return ee;if(null==e)return new Set;const o=Array.isArray(e)?e:[e];let r=[""];for(const e of o){const o=ne(e,t,n);if(o===ee)return ee;const s=[];for(const e of r)for(const t of o)if(s.push(e+t),s.length>64)return ee;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 ne(e,t,n){return"Text"===e.type?new Set([e.data??e.raw??""]):"ExpressionTag"===e.type?function(e,t,n){if(!e)return ee;if("Identifier"===e.type&&e.name&&n.has(e.name)){const t=new Set;for(const o of n.get(e.name))t.add(oe(o));return t}const o=f(e,t);return o.known?new Set([oe(o.value)]):ee}(e.expression,t,n):ee}function oe(e){return String(e)}function re(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 u(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=te(t.value,r,s);if(e===ee)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&&se(t,r.classes)&&(ae(e.code,t,o.children,n),s+=1);return s}function se(e,t){if(function(e){let t=!1;return u(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 ae(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 ie(e,t){return ue(e,ce(e,t))}function ce(e,t){const n=new Map,o=new Map,r=new Map;for(const a of e.values()){const e=new s(a.code);n.set(a.id,e);const i=t.get(a.id);if(i.bail){o.set(a.id,new Set);continue}const c=me(a,i,e);o.set(a.id,c.dropped),r.set(a.id,c.dead)}for(const t of e.values())Ee(t,o,n.get(t.id),r.get(t.id)??[]);return n}function ue(e,t){const n={};for(const o of e.values())n[o.id]=t.get(o.id).toString();return n}function le(e,t,n,o){const r=ce(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)})),fe(r.code,e.node,o,e.foldedProps,a)}c.length>0&&pe(r,c,a)}}(e,n,o,r),ue(e,r)}function fe(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)&&de(e,n,r)}function de(e,t,n){let o=t.start;" "!==e[o-1]&&"\t"!==e[o-1]||(o-=1),n.remove(o,t.end)}function pe(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 me(e,t,n){const o=[];return{dropped:he(e,t.constFold,t.narrow,t,n,o),dead:o}}function he(e,t,n,o,r,s){if(0===t.size&&0===n.size)return new Set;const a=e.code,i=O(t,e),c=O(n,e),l=[];!function(e,t,n,o,r,s){u(e,{parent:null,preserve:ke(e)},{_(e,{state:a,next:i}){if("IfBlock"!==e.type)return void i({parent:e,preserve:a.preserve||ge(e)});if(e.elseif||S(e,s))return;const c=w(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?"":Se(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 ve([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 ve(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,i,c,a,r,l),function(e,t,n,o,r){if(0===t.size)return;u(e,null,{ConditionalExpression(e,{next:s}){if(S(e,r))return;const a=f(e.test,t);if(!a.known)return void s();const i=a.value?e.consequent:e.alternate;i?(o.overwrite(e.start,e.end,Se(i.start,i.end,[i],t,n)),r.push([e.start,e.end])):s()}})}(e.ast.fragment,i,a,r,l);const d=function(e,t,n){const o=new Map,r=r=>{r&&be(r,t,e.code,(t,r,s)=>{S(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,i,l);for(const[e,t]of i){const n=Ce(t);for(const t of d.get(e)??[])r.overwrite(t.start,t.end,t.head+n+t.tail)}const p=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++;Ie(e.code,r,a,t,n),a=t+1}if(e.propsPattern)for(const o of e.props)t.has(o.name)&&Me(e.propsPattern,o.name,n)}(e,p,r);return re(e,{...o,constFold:i,narrow:c},r),s&&s.push(...l),p}function ve(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&&!S(e,r),a=e[t-1],i=e[t+1],c=s(a)&&we(a,o)?a:void 0,u=s(i)&&we(i,o)?i:void 0,l=c?t-2:t-1,f=u?t+2:t+1,d=l>=0&&ye(e[l],o),p=f<e.length&&ye(e[f],o),m=d&&p&&(!!c||!!u);return!(!!c&&d||!!u&&p)||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 we(e,t){return"Text"===e.type&&/^\s*$/.test(t.slice(e.start,e.end))}function ye(e,t){return"Comment"!==e.type&&!we(e,t)}function ge(e){return"RegularElement"===e.type&&("pre"===e.name||"textarea"===e.name)}function ke(e){let t=!1;return u(e,null,{SvelteOptions(e){for(const n of e.attributes??[])"Attribute"===n.type&&"preserveWhitespace"===n.name&&(t=!xe(n.value))}}),t}function xe(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 Se(e,t,n,o,r){if(0===o.size)return r.slice(e,t);const s=[];for(const e of n)be(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+Ce(o.get(e.name))+e.tail,i=e.end;return a+=r.slice(i,t),a}function be(e,t,n,o){u(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&&Fe(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 Ie(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 l=t[n-1];r.remove(l?l.end:s.start,c)}function Me(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 Ee(e,t,n,o){u(e.ast.fragment,null,{Component(r,{next:s}){if(o.length>0&&S(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)&&Ae(t.value)&&de(e.code,t,n);s()}})}function Ae(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 Fe(e){return" "===e||"\t"===e||"\n"===e||"\r"===e}function Ce(e){return void 0===e?"undefined":JSON.stringify(e)}const $e={enabled:!1,maxVariants:8,minSavings:0};function Pe(e,t,n=$e,r=[]){const s=new Map,a=[];if(!n.enabled)return{variants:s,bindings:a};const i=z(e,t),c=new Map,u=new Set;for(const n of e.values()){const o=i.get(n.id)??[];for(const r of n.childCalls){if(o.length>0&&S(r.node,o))continue;const s=e.get(r.childId),a=t.get(r.childId);if(!s||!a)continue;if(a.bail||!s.props||0===s.props.length){u.add(r.childId);continue}const i=Oe(r.node,s,a);if(0===i.size){u.add(r.childId);continue}const l=Re(s,a,i);if(l===Ne(s,a)){u.add(r.childId);continue}const f=c.get(r.childId);f?f.push({owner:n.id,node:r.node,shape:i,code:l}):c.set(r.childId,[{owner:n.id,node:r.node,shape:i,code:l}])}}const l=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:Ne(o,e))}return n}(e,t),f=new Map;for(const t of e.values())f.set(t.id,ze(l.get(t.id),t));const d=new Set;for(const e of f.values())for(const t of e)d.add(t);const p=(Array.isArray(r)?r:[r]).filter(t=>e.has(t)).filter(e=>!d.has(e)),m=new Map,h=(e,t)=>{const n=m.get(t);if(void 0!==n)return n;let r;try{const{js:n}=o(t,{generate:"client",dev:!1,filename:e});r=n.code.length}catch{r=null}return null!==r&&m.set(t,r),r},v=new Set;for(const e of c.keys())u.has(e)||v.add(e);for(const[t,o]of c){if(u.has(t))continue;if(o.some(e=>e.owner!==t&&v.has(e.owner)))continue;const r=new Map,i=[];let c=!1;for(const e of o){if(r.has(e.code))continue;if(i.length>=n.maxVariants){c=!0;break}const o=`${t}::v${i.length}`;r.set(e.code,o),i.push({id:o,code:e.code})}if(!c&&De(t,i,e,l,f,p,h,n.minSavings)){for(const e of i){const n=o.find(t=>t.code===e.code);s.set(e.id,{id:e.id,childId:t,code:e.code,foldedProps:n.shape})}for(const e of o)a.push({owner:e.owner,childId:t,node:e.node,variantId:r.get(e.code),foldedProps:e.shape})}}return{variants:s,bindings:a}}function De(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,ze(e.code,c));const l=new Set,f=[...s];for(;f.length>0;){const e=f.pop();if(!l.has(e)){l.add(e);for(const t of r.get(e)??[])f.push(t)}}let d=0;for(const e of l){const t=a(e,o.get(e));if(null===t)return!1;d+=t}const p=t.map(e=>e.id),m=new Set,h=new Set,v=t=>t===e?{comps:[],vars:p}:{comps:[t],vars:[]},w=[],y=[];for(const e of s){const t=v(e);w.push(...t.comps),y.push(...t.vars)}for(;w.length>0||y.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),y.push(...e.vars)}continue}const e=y.pop();if(!h.has(e)){h.add(e);for(const t of u.get(e)??[]){const e=v(t);w.push(...e.comps),y.push(...e.vars)}}}let g=0;for(const e of m){const t=a(e,o.get(e));if(null===t)return!1;g+=t}for(const e of h){const n=t.find(t=>t.id===e).code,o=a(e,n);if(null===o)return!1;g+=o}return g<d*(1-i)}function ze(e,t){let n;try{n=i(e,t.id)}catch{return[]}const o=[];return u(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 Oe(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||V(t,o.local)||!a.dynamic&&a.afterLastSpread&&s.set(e,a.value))}return s}function Re(e,t,n){const o=new Map(t.constFold);for(const[e,t]of n)o.set(e,t);const r=new Map;for(const[e,n]of t.narrow)o.has(e)||r.set(e,n);const a=new s(e.code);return he(e,o,r,t,a),a.toString()}const Le=new WeakMap;function Ne(e,t){const n=Le.get(e);if(void 0!==n)return n;const o=new s(e.code);he(e,t.constFold,t.narrow,t,o);const r=o.toString();return Le.set(e,r),r}class Te{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 A([...this.entries],this.resolve,t,n,this.parse),{models:r,plans:s}=E(o,n);return ie(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 je(e,t,n,o){if(!o)return async function(e,t,n){return E(await A(e,t,n))}(e,t,n);const r=new Map;return E(await A(e,t,n,r,o),r)}function We(e,t){for(const[n,o]of Object.entries(t)){const r=e.get(n);if(r&&o!==r.code)try{i(o,n)}catch{t[n]=r.code}}return t}const Be=(e,n)=>e.startsWith(".")?t.resolve(t.dirname(n),e):null;function _e(n){const o=[];let r;try{r=e.readdirSync(n,{withFileTypes:!0})}catch{return o}for(const e of r){if("node_modules"===e.name||e.name.startsWith("."))continue;const r=t.join(n,e.name);e.isDirectory()?o.push(..._e(r)):e.isFile()&&e.name.endsWith(".svelte")&&o.push(r)}return o}const qe=a(import.meta.url);const Ve="shaker_variant";function Ge(n={}){const o=function(e){if(2!==e.level||!e.monomorphize)return $e;const t="object"==typeof e.monomorphize?e.monomorphize:{};return{...$e,enabled:!0,...t}}(n);let r={},s=new Map,a=process.cwd();const i="coarse"===n.dev||"incremental"===n.dev?n.dev:null;let c,u=null,l=!1;const f=()=>{if(l)return c;if(l=!0,"rsvelte"===n.parser&&(c=function(){let e;try{e=qe("@rsvelte/vite-plugin-svelte-native")}catch{return null}const t=e.parse;return"function"!=typeof t?null:e=>JSON.parse(t(e,{skipExpressionLoc:!0}))}()??void 0,!c))throw new Error('[vite-plugin-svelte-shaker] parser: "rsvelte" was requested but the optional peer `@rsvelte/vite-plugin-svelte-native` could not be loaded (not installed, or no prebuilt binary for this platform). Install it on every build platform, or remove `parser: "rsvelte"` to use svelte/compiler.');return c},d=e=>{const t=e.lastIndexOf("::v"),n=e.slice(0,t),o=e.slice(t+3);return`${n}?${Ve}=${o}`};return{name:"vite-plugin-svelte-shaker",enforce:"pre",apply:(e,t)=>null!=i||"build"===t.command,configResolved(e){a=e.root},async configureServer(o){if(!i)return;const s=(n.include??["."]).map(e=>t.resolve(a,e)),c=s.flatMap(_e);u=new Te(c,Be,t=>e.readFileSync(t,"utf-8"),i,f()),r=await u.init();const l=async(e,n)=>{if(!u||!(e=>e.endsWith(".svelte")&&s.some(n=>e===n||e.startsWith(n+t.sep)))(e))return;const a=await u.update({[n]:[e]});for(const[e,t]of Object.entries(a.changed))r[e]=t;for(const e of a.removed)delete r[e];o.moduleGraph.invalidateAll(),o.ws.send({type:"full-reload"})};o.watcher.on("add",e=>{l(e,"added")}),o.watcher.on("unlink",e=>{l(e,"removed")})},async handleHotUpdate(e){if(!u||!e.file.endsWith(".svelte"))return;const t=await u.update({changed:[e.file]});for(const[e,n]of Object.entries(t.changed))r[e]=n;for(const e of t.removed)delete r[e];const n=new Set(e.modules);for(const o of Object.keys(t.changed)){const t=e.server.moduleGraph.getModulesByFile(o);if(t)for(const o of t)e.server.moduleGraph.invalidateModule(o),n.add(o)}return[...n]},async buildStart(){if(u)return;const i=(n.include??["."]).map(e=>t.resolve(a,e)).flatMap(_e);if(0===i.length)return r={},void(s=new Map);const c=t=>e.readFileSync(t,"utf-8"),l=async(e,n)=>{if(e.startsWith(".")||t.isAbsolute(e))return Be(e,n);let o;try{o=await this.resolve(e,n)}catch{return null}return!o||o.external?null:o.id.split("?")[0]};if(!o.enabled)return r=await async function(e,t,n,o){const{models:r,plans:s}=await je(e,t,n,o);return We(r,ie(r,s))}(i,l,c,f()),void(s=new Map);const p=await async function(e,t,n,o=$e,r=e=>e,s){const{models:a,plans:i}=await je(e,t,n,s),c=Pe(a,i,o,e);return{files:We(a,0===c.bindings.length?ie(a,i):le(a,i,c.bindings.map(e=>({owner:e.owner,node:e.node,variantId:e.variantId,foldedProps:e.foldedProps})),r)),mono:c}}(i,l,c,o,d,f());r=p.files,s=new Map;for(const e of p.mono.variants.values())s.set(d(e.id),e.code)},resolveId(e,n){if(!e.includes(`${Ve}=`))return null;const[o,r]=e.split("?");if(!o||!o.endsWith(".svelte"))return null;const s=n?t.dirname(n.split("?")[0]):a;return`${o.startsWith(".")?t.resolve(s,o):o}?${r}`},load:e=>e.includes(`${Ve}=`)?s.get(e)??null:null,transform(e,t){if(t.includes(`${Ve}=`))return null;if(t.includes("svelte&type="))return null;const n=t.split("?")[0];if(!n.endsWith(".svelte"))return null;const o=r[n];return null==o||o===e?null:o}}}export{Ge as shaker};
|
|
1
|
+
import * as fs from 'node:fs';
|
|
2
|
+
import * as path from 'node:path';
|
|
3
|
+
import { compile } from 'svelte/compiler';
|
|
4
|
+
import { svelteShaker, svelteShakerWithMono } from './index.js';
|
|
5
|
+
import { DevShaker } from './engine.js';
|
|
6
|
+
import { collectSvelteFiles, fsResolve } from './scan.js';
|
|
7
|
+
import { DEFAULT_MONO_OPTIONS } from './mono.js';
|
|
8
|
+
import { tryLoadRsvelteParser } from './rsvelte-parse.js';
|
|
9
|
+
/** kB with two decimals, the unit Vite itself uses in its build size report. */
|
|
10
|
+
function formatKB(bytes) {
|
|
11
|
+
return `${(bytes / 1024).toFixed(2)} kB`;
|
|
12
|
+
}
|
|
13
|
+
/**
|
|
14
|
+
* Compiled-output size proxy: the bytes the Svelte compiler emits for `code`
|
|
15
|
+
* (client JS + scoped CSS). This is the number that actually ships, so it
|
|
16
|
+
* captures what the SOURCE-byte total cannot: a dead `{#if}` arm or a removed
|
|
17
|
+
* `<style>` rule shrinks the compiled output far more than its few source bytes
|
|
18
|
+
* suggest. Reporting-only; `null` if the (always valid) source fails to compile,
|
|
19
|
+
* so the caller can skip it without aborting the build.
|
|
20
|
+
*/
|
|
21
|
+
function compiledSize(code, id) {
|
|
22
|
+
try {
|
|
23
|
+
const { js, css } = compile(code, { generate: 'client', dev: false, filename: id });
|
|
24
|
+
return js.code.length + (css?.code.length ?? 0);
|
|
25
|
+
}
|
|
26
|
+
catch {
|
|
27
|
+
return null;
|
|
28
|
+
}
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Print what the shake saved. Always emits a one-line whole-program summary;
|
|
32
|
+
* when `verbose`, also lists each shrunk file (largest saving first). Sizes are
|
|
33
|
+
* UTF-8 byte lengths of the source the engine consumed vs. produced — the honest
|
|
34
|
+
* "how much smaller is the source we hand to the Svelte compiler" number, not the
|
|
35
|
+
* final post-compile/minify bundle size.
|
|
36
|
+
*/
|
|
37
|
+
function reportSizes(shaken, read, root, verbose, log) {
|
|
38
|
+
let totalBefore = 0;
|
|
39
|
+
let totalAfter = 0;
|
|
40
|
+
const rows = [];
|
|
41
|
+
for (const [id, after] of Object.entries(shaken)) {
|
|
42
|
+
const beforeBytes = Buffer.byteLength(read(id));
|
|
43
|
+
const afterBytes = Buffer.byteLength(after);
|
|
44
|
+
totalBefore += beforeBytes;
|
|
45
|
+
totalAfter += afterBytes;
|
|
46
|
+
if (afterBytes < beforeBytes)
|
|
47
|
+
rows.push({ id, before: beforeBytes, after: afterBytes });
|
|
48
|
+
}
|
|
49
|
+
if (totalBefore === 0)
|
|
50
|
+
return;
|
|
51
|
+
const saved = totalBefore - totalAfter;
|
|
52
|
+
const pct = ((saved / totalBefore) * 100).toFixed(1);
|
|
53
|
+
log(`shaken ${rows.length}/${Object.keys(shaken).length} files: ` +
|
|
54
|
+
`${formatKB(totalBefore)} → ${formatKB(totalAfter)} ` +
|
|
55
|
+
`(saved ${formatKB(saved)}, ${pct}%)`);
|
|
56
|
+
if (!verbose)
|
|
57
|
+
return;
|
|
58
|
+
for (const row of rows.sort((a, b) => b.before - b.after - (a.before - a.after))) {
|
|
59
|
+
const rel = path.relative(root, row.id) || row.id;
|
|
60
|
+
const fileSaved = row.before - row.after;
|
|
61
|
+
const filePct = ((fileSaved / row.before) * 100).toFixed(1);
|
|
62
|
+
log(` ${rel}: ${formatKB(row.before)} → ${formatKB(row.after)} (-${filePct}%)`);
|
|
63
|
+
}
|
|
64
|
+
// The source-byte delta UNDER-reports the real win: a folded dead branch or a
|
|
65
|
+
// removed `<style>` rule shrinks the compiled output much more than its source.
|
|
66
|
+
// Compiling is costly, so we only do it for the files that actually shrank, and
|
|
67
|
+
// only under `verbose` — it never affects the build, just the visible number.
|
|
68
|
+
let compiledBefore = 0;
|
|
69
|
+
let compiledAfter = 0;
|
|
70
|
+
for (const row of rows) {
|
|
71
|
+
const before = compiledSize(read(row.id), row.id);
|
|
72
|
+
const after = compiledSize(shaken[row.id], row.id);
|
|
73
|
+
if (before === null || after === null)
|
|
74
|
+
continue; // skip the un-compilable
|
|
75
|
+
compiledBefore += before;
|
|
76
|
+
compiledAfter += after;
|
|
77
|
+
}
|
|
78
|
+
if (compiledBefore > 0) {
|
|
79
|
+
const compiledSaved = compiledBefore - compiledAfter;
|
|
80
|
+
const compiledPct = ((compiledSaved / compiledBefore) * 100).toFixed(1);
|
|
81
|
+
log(`compiled output (js+css) of shaken files: ` +
|
|
82
|
+
`${formatKB(compiledBefore)} → ${formatKB(compiledAfter)} ` +
|
|
83
|
+
`(saved ${formatKB(compiledSaved)}, ${compiledPct}%)`);
|
|
84
|
+
}
|
|
85
|
+
}
|
|
86
|
+
/** Query flag a specialized-variant `.svelte` request carries (see below). */
|
|
87
|
+
const VARIANT_QUERY = 'shaker_variant';
|
|
88
|
+
/**
|
|
89
|
+
* Resolve the {@link MonomorphizeOptions} from the public option surface. L2 is
|
|
90
|
+
* active only when `level: 2` AND `monomorphize` is truthy; anything else leaves
|
|
91
|
+
* it disabled (the default), so existing configs are unaffected.
|
|
92
|
+
*/
|
|
93
|
+
function resolveMono(options) {
|
|
94
|
+
if (options.level !== 2 || !options.monomorphize)
|
|
95
|
+
return DEFAULT_MONO_OPTIONS;
|
|
96
|
+
const overrides = typeof options.monomorphize === 'object' ? options.monomorphize : {};
|
|
97
|
+
return { ...DEFAULT_MONO_OPTIONS, enabled: true, ...overrides };
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Source-level Svelte tree-shaking as a Vite plugin (docs/ARCHITECTURE.md §6).
|
|
101
|
+
*
|
|
102
|
+
* Build-only by default: dev is a pass-through unless `dev` is set (§6.2), so
|
|
103
|
+
* `apply` returns true in build always and in serve only when opted in. When
|
|
104
|
+
* `dev` is enabled, `configureServer` drives a long-lived incremental
|
|
105
|
+
* {@link DevShaker} and `handleHotUpdate` widens the HMR boundary to the children
|
|
106
|
+
* whose residual changed (docs/RUST-MIGRATION.md §3 M2). `enforce: 'pre'` runs
|
|
107
|
+
* us before `@sveltejs/vite-plugin-svelte` in both modes, so we hand it
|
|
108
|
+
* already-slimmed `.svelte` source and stay decoupled from Svelte's codegen.
|
|
109
|
+
*
|
|
110
|
+
* L2 wiring (opt-in, `level: 2`): a specialized variant is exposed as a request
|
|
111
|
+
* for the ORIGINAL child file with a `?shaker_variant=<id>` query. Keeping the
|
|
112
|
+
* real `.svelte` path means the variant's own relative imports (`./Icon.svelte`)
|
|
113
|
+
* resolve exactly as they would in the unspecialized child, and vite-plugin-svelte
|
|
114
|
+
* still compiles it as a normal component; our `transform` swaps in the variant
|
|
115
|
+
* residual for that id. Two call sites with byte-identical residuals share one
|
|
116
|
+
* variant id (dedup), so they share one compiled module.
|
|
117
|
+
*/
|
|
118
|
+
export function shaker(options = {}) {
|
|
119
|
+
const mono = resolveMono(options);
|
|
120
|
+
let shaken = {};
|
|
121
|
+
/** Variant request id (`<childPath>?shaker_variant=<n>`) -> residual source. */
|
|
122
|
+
let variantSources = new Map();
|
|
123
|
+
let root = process.cwd();
|
|
124
|
+
// Vite's logger, captured in `configResolved`; until then fall back to console
|
|
125
|
+
// so the size report still surfaces if `buildStart` somehow runs first.
|
|
126
|
+
let log = (msg) => console.info(`[svelte-shaker] ${msg}`);
|
|
127
|
+
// Dev (serve) shaking is opt-in (docs §6.2); `null` keeps dev a pass-through.
|
|
128
|
+
const devMode = options.dev === 'coarse' || options.dev === 'incremental' ? options.dev : null;
|
|
129
|
+
/** The long-lived incremental engine, created in `configureServer` (serve only). */
|
|
130
|
+
let devShaker = null;
|
|
131
|
+
// Resolve the parser ONCE (lazily, so the optional native package is only loaded
|
|
132
|
+
// when `parser: 'rsvelte'` is actually used). `undefined` means svelte/compiler.
|
|
133
|
+
// An explicit `parser: 'rsvelte'` that can't load THROWS rather than silently
|
|
134
|
+
// falling back to svelte/compiler: a silent fallback would make the same source
|
|
135
|
+
// shake differently depending on whether the optional native binary happens to be
|
|
136
|
+
// installed on this platform — a reproducibility footgun. Failing loudly keeps the
|
|
137
|
+
// chosen parser (and thus the output) deterministic.
|
|
138
|
+
let parseResolved = false;
|
|
139
|
+
let parse;
|
|
140
|
+
const getParse = () => {
|
|
141
|
+
if (parseResolved)
|
|
142
|
+
return parse;
|
|
143
|
+
parseResolved = true;
|
|
144
|
+
if (options.parser === 'rsvelte') {
|
|
145
|
+
parse = tryLoadRsvelteParser() ?? undefined;
|
|
146
|
+
if (!parse)
|
|
147
|
+
throw new Error('[vite-plugin-svelte-shaker] parser: "rsvelte" was requested but the optional ' +
|
|
148
|
+
'peer `@rsvelte/vite-plugin-svelte-native` could not be loaded (not installed, or ' +
|
|
149
|
+
'no prebuilt binary for this platform). Install it on every build platform, or ' +
|
|
150
|
+
'remove `parser: "rsvelte"` to use svelte/compiler.');
|
|
151
|
+
}
|
|
152
|
+
return parse;
|
|
153
|
+
};
|
|
154
|
+
/** The module specifier the rewritten owner imports a given variant from. */
|
|
155
|
+
const variantSpecifier = (variantId) => {
|
|
156
|
+
// `variantId` is `<childPath>::v<n>`; turn it into a query request on the
|
|
157
|
+
// real child path so relative imports inside the residual still resolve.
|
|
158
|
+
const sep = variantId.lastIndexOf('::v');
|
|
159
|
+
const childPath = variantId.slice(0, sep);
|
|
160
|
+
const n = variantId.slice(sep + 3);
|
|
161
|
+
return `${childPath}?${VARIANT_QUERY}=${n}`;
|
|
162
|
+
};
|
|
163
|
+
return {
|
|
164
|
+
name: 'vite-plugin-svelte-shaker',
|
|
165
|
+
enforce: 'pre',
|
|
166
|
+
// Build always; dev (serve) only when opted in via `dev` (docs §6.2).
|
|
167
|
+
apply(_config, env) {
|
|
168
|
+
return devMode != null || env.command === 'build';
|
|
169
|
+
},
|
|
170
|
+
configResolved(config) {
|
|
171
|
+
root = config.root;
|
|
172
|
+
log = (msg) => config.logger.info(`[svelte-shaker] ${msg}`);
|
|
173
|
+
},
|
|
174
|
+
// Dev (serve): drive the long-lived incremental engine instead of the
|
|
175
|
+
// one-shot build crawl. `configureServer` runs before `buildStart`, so
|
|
176
|
+
// setting `devShaker` here makes `buildStart` skip the build path (docs §3 M2).
|
|
177
|
+
async configureServer(server) {
|
|
178
|
+
if (!devMode)
|
|
179
|
+
return;
|
|
180
|
+
const dirs = (options.include ?? ['.']).map((p) => path.resolve(root, p));
|
|
181
|
+
const entries = dirs.flatMap(collectSvelteFiles);
|
|
182
|
+
const read = (id) => fs.readFileSync(id, 'utf-8');
|
|
183
|
+
devShaker = new DevShaker(entries, fsResolve, read, devMode, getParse());
|
|
184
|
+
shaken = await devShaker.init();
|
|
185
|
+
// A `.svelte` add/remove changes the call-site set (a new caller can
|
|
186
|
+
// un-shake a child; a removed one can re-shake it — docs §4). Re-shake and
|
|
187
|
+
// full-reload: over-invalidation is always sound, and add/remove is rare
|
|
188
|
+
// enough that fine-grained HMR for it is not worth the complexity here.
|
|
189
|
+
const isOurs = (file) => file.endsWith('.svelte') && dirs.some((d) => file === d || file.startsWith(d + path.sep));
|
|
190
|
+
const onGraphChange = async (file, kind) => {
|
|
191
|
+
if (!devShaker || !isOurs(file))
|
|
192
|
+
return;
|
|
193
|
+
const result = await devShaker.update({ [kind]: [file] });
|
|
194
|
+
for (const [id, code] of Object.entries(result.changed))
|
|
195
|
+
shaken[id] = code;
|
|
196
|
+
for (const id of result.removed)
|
|
197
|
+
delete shaken[id];
|
|
198
|
+
server.moduleGraph.invalidateAll();
|
|
199
|
+
server.ws.send({ type: 'full-reload' });
|
|
200
|
+
};
|
|
201
|
+
server.watcher.on('add', (file) => void onGraphChange(file, 'added'));
|
|
202
|
+
server.watcher.on('unlink', (file) => void onGraphChange(file, 'removed'));
|
|
203
|
+
},
|
|
204
|
+
// Dev HMR: re-shake the changed file and WIDEN the update set with every
|
|
205
|
+
// component whose slimmed output changed — crucially the un-edited children
|
|
206
|
+
// whose residual shifted because a call site changed (the module-graph
|
|
207
|
+
// divergence, docs §3 M2). Returning a superset is sound; under-reporting
|
|
208
|
+
// would leave stale output in the browser.
|
|
209
|
+
async handleHotUpdate(ctx) {
|
|
210
|
+
if (!devShaker || !ctx.file.endsWith('.svelte'))
|
|
211
|
+
return;
|
|
212
|
+
const result = await devShaker.update({ changed: [ctx.file] });
|
|
213
|
+
for (const [id, code] of Object.entries(result.changed))
|
|
214
|
+
shaken[id] = code;
|
|
215
|
+
for (const id of result.removed)
|
|
216
|
+
delete shaken[id];
|
|
217
|
+
const widened = new Set(ctx.modules);
|
|
218
|
+
for (const id of Object.keys(result.changed)) {
|
|
219
|
+
const mods = ctx.server.moduleGraph.getModulesByFile(id);
|
|
220
|
+
if (!mods)
|
|
221
|
+
continue;
|
|
222
|
+
for (const m of mods) {
|
|
223
|
+
// Invalidate so vite-plugin-svelte re-runs our `transform` (now serving
|
|
224
|
+
// the new `shaken[id]`) and recompiles — including the extracted CSS in
|
|
225
|
+
// the `?svelte&type=style` sub-resource (L1.5 rule removal lives there).
|
|
226
|
+
ctx.server.moduleGraph.invalidateModule(m);
|
|
227
|
+
widened.add(m);
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
return [...widened];
|
|
231
|
+
},
|
|
232
|
+
// Phase 1 (docs §6.1): crawl the whole component graph and compute plans
|
|
233
|
+
// before any file is compiled. Skipped in serve — `configureServer` owns the
|
|
234
|
+
// dev path and has already populated `shaken` via the incremental engine.
|
|
235
|
+
async buildStart() {
|
|
236
|
+
if (devShaker)
|
|
237
|
+
return;
|
|
238
|
+
const dirs = (options.include ?? ['.']).map((p) => path.resolve(root, p));
|
|
239
|
+
const entries = dirs.flatMap(collectSvelteFiles);
|
|
240
|
+
if (entries.length === 0) {
|
|
241
|
+
shaken = {};
|
|
242
|
+
variantSources = new Map();
|
|
243
|
+
return;
|
|
244
|
+
}
|
|
245
|
+
const read = (id) => fs.readFileSync(id, 'utf-8');
|
|
246
|
+
// Resolve relative imports straight off disk (fast, and the id matches what
|
|
247
|
+
// Vite hands `transform`), but send bare specifiers through Vite's resolver
|
|
248
|
+
// so a component library consumed as `@scope/ui` (the design-system shape) is
|
|
249
|
+
// crawled into the program and shaken instead of treated as an opaque
|
|
250
|
+
// external. The arrow keeps `this` bound to the Rollup plugin context.
|
|
251
|
+
const resolve = async (source, importer) => {
|
|
252
|
+
if (source.startsWith('.') || path.isAbsolute(source))
|
|
253
|
+
return fsResolve(source, importer);
|
|
254
|
+
// `this.resolve` THROWS for specifiers some plugin in the chain rejects
|
|
255
|
+
// (a types-only subpath like `svelte/elements`, a virtual id, etc.). A
|
|
256
|
+
// specifier we cannot resolve is simply out of scope — never a build
|
|
257
|
+
// error — so swallow it and leave that barrel branch unfollowed.
|
|
258
|
+
let resolved;
|
|
259
|
+
try {
|
|
260
|
+
resolved = await this.resolve(source, importer);
|
|
261
|
+
}
|
|
262
|
+
catch {
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
if (!resolved || resolved.external)
|
|
266
|
+
return null;
|
|
267
|
+
return resolved.id.split('?')[0];
|
|
268
|
+
};
|
|
269
|
+
if (!mono.enabled) {
|
|
270
|
+
// Default path: byte-for-byte the L0/L1/L1.5 output (no L2 at all).
|
|
271
|
+
shaken = await svelteShaker(entries, resolve, read, getParse());
|
|
272
|
+
variantSources = new Map();
|
|
273
|
+
reportSizes(shaken, read, root, options.verbose === true, log);
|
|
274
|
+
return;
|
|
275
|
+
}
|
|
276
|
+
const result = await svelteShakerWithMono(entries, resolve, read, mono, variantSpecifier, getParse());
|
|
277
|
+
shaken = result.files;
|
|
278
|
+
variantSources = new Map();
|
|
279
|
+
for (const v of result.mono.variants.values())
|
|
280
|
+
variantSources.set(variantSpecifier(v.id), v.code);
|
|
281
|
+
reportSizes(shaken, read, root, options.verbose === true, log);
|
|
282
|
+
},
|
|
283
|
+
// A `?shaker_variant` request resolves to the real child path (so relative
|
|
284
|
+
// imports inside it work); we keep the query so `load`/`transform` can tell
|
|
285
|
+
// the variant apart from the base module. Returning the id verbatim marks it
|
|
286
|
+
// resolved by us.
|
|
287
|
+
resolveId(source, importer) {
|
|
288
|
+
if (!source.includes(`${VARIANT_QUERY}=`))
|
|
289
|
+
return null;
|
|
290
|
+
const [spec, query] = source.split('?');
|
|
291
|
+
if (!spec || !spec.endsWith('.svelte'))
|
|
292
|
+
return null;
|
|
293
|
+
// Resolve the child path relative to the importer (the rewritten owner).
|
|
294
|
+
const base = importer ? path.dirname(importer.split('?')[0]) : root;
|
|
295
|
+
const abs = spec.startsWith('.') ? path.resolve(base, spec) : spec;
|
|
296
|
+
return `${abs}?${query}`;
|
|
297
|
+
},
|
|
298
|
+
load(id) {
|
|
299
|
+
// Vite's default loader reads the file on disk ignoring the query, which
|
|
300
|
+
// would give the UNspecialized child source. Serve the variant residual
|
|
301
|
+
// ourselves so the `?shaker_variant` request gets the specialized code.
|
|
302
|
+
if (!id.includes(`${VARIANT_QUERY}=`))
|
|
303
|
+
return null;
|
|
304
|
+
return variantSources.get(id) ?? null;
|
|
305
|
+
},
|
|
306
|
+
// Phase 2: hand the slimmed source to the Svelte plugin.
|
|
307
|
+
transform(code, id) {
|
|
308
|
+
// A specialized-variant request: its source is already the residual we put
|
|
309
|
+
// there in `load`, so let it flow through to vite-plugin-svelte untouched.
|
|
310
|
+
if (id.includes(`${VARIANT_QUERY}=`))
|
|
311
|
+
return null;
|
|
312
|
+
// Only the *main* `.svelte` module request must be slimmed. vite-plugin-svelte
|
|
313
|
+
// splits a component into sub-resource requests (`Foo.svelte?svelte&type=style&lang.css`,
|
|
314
|
+
// `…&type=script`) whose path still ends in `.svelte`; returning the full
|
|
315
|
+
// slimmed source for those would clobber the extracted CSS/JS with raw
|
|
316
|
+
// component source. Skip anything carrying the Svelte sub-resource marker.
|
|
317
|
+
if (id.includes('svelte&type='))
|
|
318
|
+
return null;
|
|
319
|
+
const file = id.split('?')[0];
|
|
320
|
+
if (!file.endsWith('.svelte'))
|
|
321
|
+
return null;
|
|
322
|
+
const out = shaken[file];
|
|
323
|
+
if (out == null || out === code)
|
|
324
|
+
return null;
|
|
325
|
+
return out;
|
|
326
|
+
},
|
|
327
|
+
};
|
|
328
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "svelte-shaker",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.7.0",
|
|
4
4
|
"description": "Tree shaking for Svelte components",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"dead-code-elimination",
|
|
@@ -22,25 +22,22 @@
|
|
|
22
22
|
"directory": "packages/svelte-shaker"
|
|
23
23
|
},
|
|
24
24
|
"files": [
|
|
25
|
-
"dist
|
|
26
|
-
"dist/*.cjs",
|
|
27
|
-
"dist/types/src"
|
|
25
|
+
"dist"
|
|
28
26
|
],
|
|
29
27
|
"type": "module",
|
|
30
28
|
"main": "./dist/index.js",
|
|
31
|
-
"types": "./dist/
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
32
30
|
"exports": {
|
|
33
31
|
".": {
|
|
34
|
-
"types": "./dist/
|
|
35
|
-
"import": "./dist/index.js"
|
|
36
|
-
"require": "./dist/index.cjs"
|
|
32
|
+
"types": "./dist/index.d.ts",
|
|
33
|
+
"import": "./dist/index.js"
|
|
37
34
|
},
|
|
38
35
|
"./vite": {
|
|
39
|
-
"types": "./dist/
|
|
36
|
+
"types": "./dist/vite.d.ts",
|
|
40
37
|
"import": "./dist/vite.js"
|
|
41
38
|
},
|
|
42
39
|
"./node": {
|
|
43
|
-
"types": "./dist/
|
|
40
|
+
"types": "./dist/scan.d.ts",
|
|
44
41
|
"import": "./dist/scan.js"
|
|
45
42
|
},
|
|
46
43
|
"./package.json": "./package.json"
|
|
@@ -53,16 +50,10 @@
|
|
|
53
50
|
"zimmerframe": "1.1.4"
|
|
54
51
|
},
|
|
55
52
|
"devDependencies": {
|
|
56
|
-
"@rollup/plugin-commonjs": "25.0.8",
|
|
57
|
-
"@rollup/plugin-node-resolve": "15.2.3",
|
|
58
|
-
"@rollup/plugin-terser": "0.4.4",
|
|
59
|
-
"@rollup/plugin-typescript": "11.1.6",
|
|
60
53
|
"@rsvelte/compiler": "0.6.1",
|
|
61
54
|
"@rsvelte/vite-plugin-svelte-native": "0.2.4",
|
|
62
55
|
"@sveltejs/vite-plugin-svelte": "^4",
|
|
63
|
-
"rollup": "4.18.0",
|
|
64
56
|
"svelte": "^5",
|
|
65
|
-
"tslib": "2.6.2",
|
|
66
57
|
"vite": "^5"
|
|
67
58
|
},
|
|
68
59
|
"peerDependencies": {
|
|
@@ -78,9 +69,9 @@
|
|
|
78
69
|
"node": ">=22"
|
|
79
70
|
},
|
|
80
71
|
"scripts": {
|
|
81
|
-
"build": "
|
|
72
|
+
"build": "tsc -p tsconfig.build.json",
|
|
82
73
|
"build:wasm": "wasm-pack build engine-rs --target nodejs --release --out-dir pkg",
|
|
83
|
-
"dev": "
|
|
74
|
+
"dev": "tsc -p tsconfig.build.json -w",
|
|
84
75
|
"test:watch": "vitest",
|
|
85
76
|
"test": "vitest run"
|
|
86
77
|
}
|
package/dist/index.cjs
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
"use strict";var e=require("svelte/compiler"),t=require("zimmerframe"),n=require("magic-string");function o(t,n){return e.parse(t,{modern:!0,filename:n})}function r(e,t,n,r=o){if(!n)return r(t,e);const s=n.get(e);if(s&&s.code===t)return s.ast;const a=r(t,e);return n.set(e,{code:t,ast:a}),a}function s(e,n,o){t.walk(e,n,o)}const a={known:!1};function i(e,t){if(!e)return a;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)}:a}case"UnaryExpression":{const n=i(e.argument,t);if(!n.known)return a;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 a}}case"LogicalExpression":{const n=i(e.left,t);if(!n.known)return a;switch(e.operator){case"&&":return n.value?i(e.right,t):n;case"||":return n.value?n:i(e.right,t);case"??":return null===n.value||void 0===n.value?i(e.right,t):n;default:return a}}case"BinaryExpression":{const n=i(e.left,t),o=i(e.right,t);if(!n.known||!o.known)return a;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 a}}default:return a}}function c(e,t,n){const o=i(e,t);if(o.known)return o;const r=u(e,t,n);return"unknown"===r?a:{known:!0,value:r}}function u(e,t,n){if(!e)return"unknown";switch(e.type){case"UnaryExpression":return"!"===e.operator?p(u(e.argument,t,n)):"unknown";case"LogicalExpression":{const s=u(e.left,t,n),a=()=>u(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=i(t,n);if(s&&a.known)return f(s,a.value,r);const c=l(t,o),u=i(e,n);return c&&u.known?f(c,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?p(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 f(e,t,n){const o=n?e=>e==t:e=>e===t;return!!e.some(o)&&(!!e.every(o)||"unknown")}function p(e){return!0!==e&&(!1===e||"unknown")}function d(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=>c(e.test,t,n)),i=e=>e.known&&Boolean(e.value),u=e=>e.known&&!e.value;let l=!0;for(let e=0;e<o.length;e++){const t=a[e];if(i(t)&&l){const t=o[e].consequent;return{span:s,kept:t,removed:m(s,h(t)),recurse:!1}}u(t)||(l=!1)}const f=a.findIndex(e=>!u(e));if(-1===f)return r?{span:s,kept:r,removed:m(s,h(r)),recurse:!1}:{span:s,kept:void 0,removed:[s],recurse:!1};if(0===f)return{span:s,kept:void 0,removed:v(o,a,f),recurse:!0};const p=o[f].block;return{span:s,kept:void 0,removed:[[s[0],p.start],...v(o,a,f)],recurse:!1,headerRewrite:{from:p.start,to:p.test.start,text:"{#if "}}}function m(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 h(e){const t=e?.nodes??[];return 0===t.length?null:[t[0].start,t[t.length-1].end]}function v(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:w(s.consequent,s.block.end);o.push([s.block.start,i])}return o}function w(e,t){const n=e?.nodes??[];return n.length?n[n.length-1].end:t}function g(e,t){return t.some(([t,n])=>e.start>=t&&e.end<=n)}function y(e,t,n){if(0===t.size&&0===n.size)return[];const o=[];return s(e,null,{IfBlock(e,{next:r}){if(e.elseif||g(e,o))return;const s=d(e,t,n);for(const e of s.removed)o.push(e);s.recurse&&r()}}),o}const k=e=>e.endsWith(".svelte"),x="escapes as value (e.g. <svelte:component this={X}>)";async function S(e,t,n){return b(await I(e,t,n))}function b(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(x)&&t.bailReasons.push(x)}let r=A(n,M(n,new Map));for(let e=0;e<10;e++){const e=A(n,M(n,P(n,r)));if(E(r,e)){r=e;break}r=e}return{models:n,plans:r}}async function I(e,t,n,o,s){const a=Array.isArray(e)?[...e]:[e],i=[],c=[],u=[...a],l=new Set(u);for(;u.length>0;){const e=u.shift(),a=await n(e);i.push({id:e,code:a});const f=r(e,a,o,s),p=f.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&&k(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 H(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 L(f)){const r=o.indexOf("."),s=m.get(o.slice(0,r));if(null==s)continue;const a=await H(s,o.slice(r+1),e,t,n);a&&(c.push({from:e,local:o,to:a,kind:"namespace"}),v.push(a))}const w=R(f,d);for(const e of[...h,...w,...v])l.has(e)||(l.add(e),u.push(e))}return{files:i,edges:c,entries:a}}function M(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&&g(t.node,e)||o(t.childId).sites.push(T(t.node))}return n}function A(e,t){const n=new Map;for(const o of e.values())n.set(o.id,q(o,t.get(o.id)));return n}function E(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(!C(o.constFold,e.constFold))return!1;if(!F(o.narrow,e.narrow))return!1}return!0}function C(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 F(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 P(e,t){const n=new Map;for(const o of e.values()){const e=t.get(o.id);if(e.bail)continue;const r=y(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:a}=e,i=r(o,a,n),c=new Map;for(const e of t)c.set(e.local,e.to);const u=[];s(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 l,f,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){l=e.declaration,f=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 s(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&&s(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??[])$(t,o);t()}});return s(e.fragment,null,{EachBlock(e,{next:t}){$(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??[])$(t,o);t()},AwaitBlock(e,{next:t}){$(e.value,o),$(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??[])$(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,l),k=function(e,t,n,o){const r=new Set,a=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)};s(e.fragment,{parent:null},{_(e,{state:t,next:o}){"Identifier"===e.type&&e.name&&n.has(e.name)&&O(e,t.parent)&&a(e.name),o({parent:e})}}),e.instance&&s(e.instance,{parent:null},{_(e,{state:n,next:r}){"Identifier"===e.type&&e.name&&(t.has(e.name)||o.has(e.name))&&O(e,n.parent)&&!N(n.parent)&&a(e.name),r({parent:e})}});return r}(i,c,m,h);return{id:o,code:a,ast:i,imports:c,props:p,propsDeclaration:l,propsPattern:f,hasRestProp:d,childCalls:w,shadowedNames:g,debugNames:y,escapedComponents:k,bailReasons:u}}function $(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?$(n.argument,t):"Property"===n.type&&$(n.value??n.key,t);return;case"ArrayPattern":for(const n of e.elements??[])$(n,t);return;case"AssignmentPattern":return void $(e.left,t);case"RestElement":return void $(e.argument,t);default:return}}function O(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 R(e,t){const n=new Set;return 0===t.size||s(e.fragment,null,{Component(e,{next:o}){const r=e.name?t.get(e.name):void 0;r&&n.add(r),o()}}),n}function L(e){const t=new Set;return s(e.fragment,null,{Component(e,{next:n}){"string"==typeof e.name&&e.name.includes(".")&&t.add(e.name),n()}}),t}function T(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,_(e,n));continue}if("Attribute"!==r.type||!s)continue;const a=B(r.value);o.set(s,a.known?{value:a.value,dynamic:!1,afterLastSpread:e>n}:_(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,_(t.length,n));return{hadSpread:n>=0,explicit:o}}function _(e,t){return{value:void 0,dynamic:!0,afterLastSpread:e>t}}function B(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 j(e,t){return e.shadowedNames.has(t)||e.debugNames.has(t)}function q(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||j(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=V(e.defaultExpr);a.known?s(a.value):o=!0}return{values:n,dynamic:o,top:r}}function V(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:J(n)??e}))}}}function J(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 X(e){return"Identifier"===e?.type&&e.name?e.name:"Literal"===e?.type&&"string"==typeof e.value?e.value:void 0}const G=8;async function H(e,t,n,r,s,a=0){if(a>G)return null;const i=await r(e,n);if(!i)return null;if(k(e)||k(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=o(`<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(X(n.exported)===t)return H(String(e.source.value),X(n.local)??"default",i,r,s,a+1)}else if("ExportNamedDeclaration"!==e.type||e.source){if("ExportAllDeclaration"===e.type&&e.source?.value){const n=await H(String(e.source.value),t,i,r,s,a+1);if(n)return n}}else for(const n of e.specifiers??[]){if(X(n.exported)!==t)continue;const e=X(n.local);if(!e)continue;const o=K(u,e);return o?H(o.value,o.imported,i,r,s,a+1):null}return null}function K(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:J(o)??t}}}return null}const Q=Symbol("unbounded-class-source");function Y(e,t,n){if(!0===e)return Q;if(null==e)return new Set;const o=Array.isArray(e)?e:[e];let r=[""];for(const e of o){const o=Z(e,t,n);if(o===Q)return Q;const s=[];for(const e of r)for(const t of o)if(s.push(e+t),s.length>64)return Q;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 Z(e,t,n){return"Text"===e.type?new Set([e.data??e.raw??""]):"ExpressionTag"===e.type?function(e,t,n){if(!e)return Q;if("Identifier"===e.type&&e.name&&n.has(e.name)){const t=new Set;for(const o of n.get(e.name))t.add(ee(o));return t}const o=i(e,t);return o.known?new Set([ee(o.value)]):Q}(e.expression,t,n):Q}function ee(e){return String(e)}function te(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,a=t.narrow;return s(e.ast.fragment,null,{_(e,{next:t}){if("RegularElement"===(s=e.type)||"SvelteElement"===s||"Component"===s||"SvelteComponent"===s||"SvelteSelf"===s){var s;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=Y(t.value,r,a);if(e===Q)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 a=0;for(const t of o.children)"Rule"===t.type&&ne(t,r.classes)&&(oe(e.code,t,o.children,n),a+=1);return a}function ne(e,t){if(function(e){let t=!1;return s(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 oe(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 re(e,t){return ae(e,se(e,t))}function se(e,t){const o=new Map,r=new Map,s=new Map;for(const a of e.values()){const e=new n(a.code);o.set(a.id,e);const i=t.get(a.id);if(i.bail){r.set(a.id,new Set);continue}const c=fe(a,i,e);r.set(a.id,c.dropped),s.set(a.id,c.dead)}for(const t of e.values())be(t,r,o.get(t.id),s.get(t.id)??[]);return o}function ae(e,t){const n={};for(const o of e.values())n[o.id]=t.get(o.id).toString();return n}function ie(e,t,n,o){const r=se(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)})),ce(r.code,e.node,o,e.foldedProps,a)}c.length>0&&le(r,c,a)}}(e,n,o,r),ae(e,r)}function ce(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)&&ue(e,n,r)}function ue(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 fe(e,t,n){const o=[];return{dropped:pe(e,t.constFold,t.narrow,t,n,o),dead:o}}function pe(e,t,n,o,r,a){if(0===t.size&&0===n.size)return new Set;const c=e.code,u=D(t,e),l=D(n,e),f=[];!function(e,t,n,o,r,a){s(e,{parent:null,preserve:we(e)},{_(e,{state:s,next:i}){if("IfBlock"!==e.type)return void i({parent:e,preserve:s.preserve||ve(e)});if(e.elseif||g(e,a))return;const c=d(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?"":ye(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 de([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 de(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,a,{parent:s.parent,index:s.parent?.nodes?.indexOf(e)??-1,preserve:s.preserve}),c.recurse&&i({parent:e,preserve:s.preserve})}})}(e.ast.fragment,u,l,c,r,f),function(e,t,n,o,r){if(0===t.size)return;s(e,null,{ConditionalExpression(e,{next:s}){if(g(e,r))return;const a=i(e.test,t);if(!a.known)return void s();const c=a.value?e.consequent:e.alternate;c?(o.overwrite(e.start,e.end,ye(c.start,c.end,[c],t,n)),r.push([e.start,e.end])):s()}})}(e.ast.fragment,u,c,r,f);const p=function(e,t,n){const o=new Map,r=r=>{r&&ke(r,t,e.code,(t,r,s)=>{g(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,f);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 m=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++;xe(e.code,r,a,t,n),a=t+1}if(e.propsPattern)for(const o of e.props)t.has(o.name)&&Se(e.propsPattern,o.name,n)}(e,m,r);return te(e,{...o,constFold:u,narrow:l},r),a&&a.push(...f),m}function de(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&&!g(e,r),a=e[t-1],i=e[t+1],c=s(a)&&me(a,o)?a:void 0,u=s(i)&&me(i,o)?i:void 0,l=c?t-2:t-1,f=u?t+2:t+1,p=l>=0&&he(e[l],o),d=f<e.length&&he(e[f],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 me(e,t){return"Text"===e.type&&/^\s*$/.test(t.slice(e.start,e.end))}function he(e,t){return"Comment"!==e.type&&!me(e,t)}function ve(e){return"RegularElement"===e.type&&("pre"===e.name||"textarea"===e.name)}function we(e){let t=!1;return s(e,null,{SvelteOptions(e){for(const n of e.attributes??[])"Attribute"===n.type&&"preserveWhitespace"===n.name&&(t=!ge(n.value))}}),t}function ge(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 ye(e,t,n,o,r){if(0===o.size)return r.slice(e,t);const s=[];for(const e of n)ke(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 ke(e,t,n,o){s(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&&Me(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 xe(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 l=t[n-1];r.remove(l?l.end:s.start,c)}function Se(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 be(e,t,n,o){s(e.ast.fragment,null,{Component(r,{next:s}){if(o.length>0&&g(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)&&Ie(t.value)&&ue(e.code,t,n);s()}})}function Ie(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 Me(e){return" "===e||"\t"===e||"\n"===e||"\r"===e}function Ae(e){return void 0===e?"undefined":JSON.stringify(e)}const Ee={enabled:!1,maxVariants:8,minSavings:0};function Ce(t,n,o=Ee,r=[]){const s=new Map,a=[];if(!o.enabled)return{variants:s,bindings:a};const i=P(t,n),c=new Map,u=new Set;for(const e of t.values()){const o=i.get(e.id)??[];for(const r of e.childCalls){if(o.length>0&&g(r.node,o))continue;const s=t.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 l=ze(s,a,i);if(l===Oe(s,a)){u.add(r.childId);continue}const f=c.get(r.childId);f?f.push({owner:e.id,node:r.node,shape:i,code:l}):c.set(r.childId,[{owner:e.id,node:r.node,shape:i,code:l}])}}const l=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:Oe(o,e))}return n}(t,n),f=new Map;for(const e of t.values())f.set(e.id,Pe(l.get(e.id),e));const p=new Set;for(const e of f.values())for(const t of e)p.add(t);const d=(Array.isArray(r)?r:[r]).filter(e=>t.has(e)).filter(e=>!p.has(e)),m=new Map,h=(t,n)=>{const o=m.get(n);if(void 0!==o)return o;let r;try{const{js:o}=e.compile(n,{generate:"client",dev:!1,filename:t});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[e,n]of c){if(u.has(e))continue;if(n.some(t=>t.owner!==e&&v.has(t.owner)))continue;const r=new Map,i=[];let c=!1;for(const t of n){if(r.has(t.code))continue;if(i.length>=o.maxVariants){c=!0;break}const n=`${e}::v${i.length}`;r.set(t.code,n),i.push({id:n,code:t.code})}if(!c&&Fe(e,i,t,l,f,d,h,o.minSavings)){for(const t of i){const o=n.find(e=>e.code===t.code);s.set(t.id,{id:t.id,childId:e,code:t.code,foldedProps:o.shape})}for(const t of n)a.push({owner:t.owner,childId:e,node:t.node,variantId:r.get(t.code),foldedProps:t.shape})}}return{variants:s,bindings:a}}function Fe(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,Pe(e.code,c));const l=new Set,f=[...s];for(;f.length>0;){const e=f.pop();if(!l.has(e)){l.add(e);for(const t of r.get(e)??[])f.push(t)}}let p=0;for(const e of l){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 Pe(e,t){let n;try{n=o(e,t.id)}catch{return[]}const r=[];return s(n.fragment,null,{Component(e,{next:n}){const o=e.name?t.imports.get(e.name):void 0;o&&r.push(o),n()}}),r}function De(e,t,n){const o=T(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||j(t,o.local)||!a.dynamic&&a.afterLastSpread&&s.set(e,a.value))}return s}function ze(e,t,o){const r=new Map(t.constFold);for(const[e,t]of o)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 n(e.code);return pe(e,r,s,t,a),a.toString()}const $e=new WeakMap;function Oe(e,t){const o=$e.get(e);if(void 0!==o)return o;const r=new n(e.code);pe(e,t.constFold,t.narrow,t,r);const s=r.toString();return $e.set(e,s),s}async function Ne(e,t,n,o){if(!o)return S(e,t,n);const r=new Map;return b(await I(e,t,n,r,o),r)}function Re(e,t){for(const[n,r]of Object.entries(t)){const s=e.get(n);if(s&&r!==s.code)try{o(r,n)}catch{t[n]=s.code}}return t}exports.DEFAULT_MONO_OPTIONS=Ee,exports.DevShaker=class{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 I([...this.entries],this.resolve,t,n,this.parse),{models:r,plans:s}=b(o,n);return re(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}},exports.analyze=S,exports.analyzeInput=b,exports.buildAnalyzeInput=I,exports.monomorphize=Ce,exports.svelteShaker=async function(e,t,n,o){const{models:r,plans:s}=await Ne(e,t,n,o);return Re(r,re(r,s))},exports.svelteShakerWithMono=async function(e,t,n,o=Ee,r=e=>e,s){const{models:a,plans:i}=await Ne(e,t,n,s),c=Ce(a,i,o,e);return{files:Re(a,0===c.bindings.length?re(a,i):ie(a,i,c.bindings.map(e=>({owner:e.owner,node:e.node,variantId:e.variantId,foldedProps:e.foldedProps})),r)),mono:c}},exports.transformAll=re,exports.transformAllWithMono=ie;
|
|
File without changes
|