@akashjs/vite-plugin 0.1.4 → 0.1.6
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/index.cjs +7 -13
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +7 -13
- package/dist/index.js.map +1 -1
- package/package.json +1 -1
package/dist/index.cjs
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var compiler=require('@akashjs/compiler');function
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var compiler=require('@akashjs/compiler'),esbuild=require('esbuild');function y(r,i){let s=compiler.parse(r),l=compiler.parse(i),e=(s.script?.content??"")!==(l.script?.content??""),n=(s.template?.content??"")!==(l.template?.content??""),o=(s.style?.content??"")!==(l.style?.content??"");return {scriptChanged:e,templateChanged:n,styleChanged:o,styleOnly:o&&!e&&!n,needsFullReload:e}}function m(r){return `
|
|
2
2
|
// HMR
|
|
3
3
|
if (import.meta.hot) {
|
|
4
4
|
import.meta.hot.accept((newModule) => {
|
|
@@ -8,19 +8,13 @@ if (import.meta.hot) {
|
|
|
8
8
|
}
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
|
-
`}function
|
|
12
|
-
// Style HMR
|
|
13
|
-
if (import.meta.hot) {
|
|
14
|
-
import.meta.hot.accept();
|
|
15
|
-
// Remove old style element and re-inject
|
|
16
|
-
const oldStyle = document.querySelector('[data-akash-style="${l}"]');
|
|
17
|
-
if (oldStyle) oldStyle.remove();
|
|
18
|
-
}
|
|
19
|
-
`}function f(l={}){let i=l.css??"injected",o=false,a=new Map;return {name:"akash",enforce:"pre",configResolved(e){o=e.command==="build";},transform(e,n){if(!n.endsWith(".akash"))return null;let s=compiler.compile(e,{filename:n,dev:!o}),t=s.code;if(s.css&&i==="injected"){let r=s.css.replace(/`/g,"\\`").replace(/\\/g,"\\\\"),c=n.replace(/[^a-zA-Z0-9]/g,"_");t+=`
|
|
11
|
+
`}function _(r={}){let i=r.css??"injected",s=false,l=new Map;return {name:"akash",enforce:"pre",configResolved(e){s=e.command==="build";},async transform(e,n){if(!n.endsWith(".akash"))return null;let o=compiler.parse(e),c=o.script?.lang==="ts"||o.script?.lang==="typescript",a=compiler.compile(e,{filename:n,dev:!s}),t=a.code;if(c&&(t=(await esbuild.transform(t,{loader:"ts",sourcemap:false})).code),a.css&&i==="injected"){let p=a.css.replace(/`/g,"\\`").replace(/\\/g,"\\\\"),d=n.replace(/[^a-zA-Z0-9]/g,"_");t+=`
|
|
20
12
|
// Injected scoped styles
|
|
13
|
+
`,t+=`const __akash_old_style = document.querySelector('[data-akash-style="${d}"]');
|
|
14
|
+
`,t+=`if (__akash_old_style) __akash_old_style.remove();
|
|
21
15
|
`,t+=`const __akash_style = document.createElement('style');
|
|
22
|
-
`,t+=`__akash_style.setAttribute('data-akash-style', '${
|
|
23
|
-
`,t+=`__akash_style.textContent = \`${
|
|
16
|
+
`,t+=`__akash_style.setAttribute('data-akash-style', '${d}');
|
|
17
|
+
`,t+=`__akash_style.textContent = \`${p}\`;
|
|
24
18
|
`,t+=`document.head.appendChild(__akash_style);
|
|
25
|
-
|
|
19
|
+
`;}return s||(t+=m()),l.set(n,e),{code:t,map:null}},handleHotUpdate({file:e,server:n,modules:o,read:c}){if(!e.endsWith(".akash"))return;let a=l.get(e);return a&&c().then(t=>{y(a,t).styleOnly&&n.ws.send({type:"custom",event:"akash:style-update",data:{file:e}});}),o}}}exports.akash=_;exports.default=_;//# sourceMappingURL=index.cjs.map
|
|
26
20
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hmr.ts","../src/index.ts"],"names":["analyzeHmrChange","oldSource","newSource","oldSfc","parse","newSfc","scriptChanged","templateChanged","styleChanged","generateHmrCode","id","
|
|
1
|
+
{"version":3,"sources":["../src/hmr.ts","../src/index.ts"],"names":["analyzeHmrChange","oldSource","newSource","oldSfc","parse","newSfc","scriptChanged","templateChanged","styleChanged","generateHmrCode","id","akash","options","cssMode","isProduction","sourceCache","config","code","sfc","isTS","result","compile","output","esbuildTransform","cssCode","styleId","file","server","modules","read"],"mappings":"2IA2BO,SAASA,CAAAA,CAAiBC,EAAmBC,CAAAA,CAAgC,CAClF,IAAMC,CAAAA,CAASC,eAAMH,CAAS,CAAA,CACxBI,CAAAA,CAASD,cAAAA,CAAMF,CAAS,CAAA,CAExBI,CAAAA,CAAAA,CAAiBH,CAAAA,CAAO,MAAA,EAAQ,SAAW,EAAA,KAASE,CAAAA,CAAO,MAAA,EAAQ,OAAA,EAAW,IAC9EE,CAAAA,CAAAA,CAAmBJ,CAAAA,CAAO,QAAA,EAAU,OAAA,EAAW,OAASE,CAAAA,CAAO,QAAA,EAAU,OAAA,EAAW,EAAA,CAAA,CACpFG,GAAgBL,CAAAA,CAAO,KAAA,EAAO,OAAA,EAAW,EAAA,KAASE,EAAO,KAAA,EAAO,OAAA,EAAW,EAAA,CAAA,CAKjF,OAAO,CACL,aAAA,CAAAC,CAAAA,CACA,eAAA,CAAAC,CAAAA,CACA,aAAAC,CAAAA,CACA,SAAA,CAPgBA,CAAAA,EAAgB,CAACF,GAAiB,CAACC,CAAAA,CAQnD,eAAA,CAPsBD,CAQxB,CACF,CAMO,SAASG,CAAAA,CAAgBC,CAAAA,CAAoB,CAClD,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA,CAWT,CC3Ce,SAARC,CAAAA,CAAuBC,CAAAA,CAA8B,GAAY,CACtE,IAAMC,CAAAA,CAAUD,CAAAA,CAAQ,GAAA,EAAO,UAAA,CAC3BE,EAAe,KAAA,CAGbC,CAAAA,CAAc,IAAI,GAAA,CAExB,OAAO,CACL,KAAM,OAAA,CACN,OAAA,CAAS,KAAA,CAET,cAAA,CAAeC,CAAAA,CAAQ,CACrBF,EAAeE,CAAAA,CAAO,OAAA,GAAY,QACpC,CAAA,CAEA,MAAM,SAAA,CAAUC,EAAMP,CAAAA,CAAI,CACxB,GAAI,CAACA,CAAAA,CAAG,QAAA,CAAS,QAAQ,CAAA,CAAG,OAAO,IAAA,CAGnC,IAAMQ,CAAAA,CAAMd,cAAAA,CAAMa,CAAI,CAAA,CAChBE,CAAAA,CAAOD,CAAAA,CAAI,MAAA,EAAQ,IAAA,GAAS,IAAA,EAAQA,EAAI,MAAA,EAAQ,IAAA,GAAS,YAAA,CAEzDE,CAAAA,CAASC,gBAAAA,CAAQJ,CAAAA,CAAM,CAC3B,QAAA,CAAUP,CAAAA,CACV,GAAA,CAAK,CAACI,CACR,CAAC,EAEGQ,CAAAA,CAASF,CAAAA,CAAO,IAAA,CAYpB,GATID,CAAAA,GAKFG,CAAAA,CAAAA,CAJiB,MAAMC,iBAAAA,CAAiBD,CAAAA,CAAQ,CAC9C,MAAA,CAAQ,IAAA,CACR,SAAA,CAAW,KACb,CAAC,CAAA,EACiB,IAAA,CAAA,CAIhBF,CAAAA,CAAO,GAAA,EACLP,CAAAA,GAAY,WAAY,CAC1B,IAAMW,CAAAA,CAAUJ,CAAAA,CAAO,GAAA,CAAI,OAAA,CAAQ,KAAM,KAAK,CAAA,CAAE,OAAA,CAAQ,KAAA,CAAO,MAAM,CAAA,CAC/DK,CAAAA,CAAUf,CAAAA,CAAG,OAAA,CAAQ,eAAA,CAAiB,GAAG,CAAA,CAC/CY,CAAAA,EAAU;AAAA;AAAA,CAAA,CAEVA,CAAAA,EAAU,wEAAwEG,CAAO,CAAA;AAAA,CAAA,CACzFH,CAAAA,EAAU,CAAA;AAAA,CAAA,CACVA,CAAAA,EAAU,CAAA;AAAA,CAAA,CACVA,CAAAA,EAAU,mDAAmDG,CAAO,CAAA;AAAA,CAAA,CACpEH,CAAAA,EAAU,iCAAiCE,CAAO,CAAA;AAAA,CAAA,CAClDF,CAAAA,EAAU,CAAA;AAAA,EACZ,CAIF,OAAKR,CAAAA,GACHQ,CAAAA,EAAUb,EAAkB,CAAA,CAAA,CAI9BM,CAAAA,CAAY,GAAA,CAAIL,EAAIO,CAAI,CAAA,CAEjB,CACL,IAAA,CAAMK,EACN,GAAA,CAAK,IACP,CACF,CAAA,CAEA,gBAAgB,CAAE,IAAA,CAAAI,CAAAA,CAAM,MAAA,CAAAC,EAAQ,OAAA,CAAAC,CAAAA,CAAS,IAAA,CAAAC,CAAK,EAAG,CAC/C,GAAI,CAACH,CAAAA,CAAK,SAAS,QAAQ,CAAA,CAAG,OAE9B,IAAMzB,EAAYc,CAAAA,CAAY,GAAA,CAAIW,CAAI,CAAA,CAEtC,OAAIzB,CAAAA,EAEF4B,CAAAA,EAAK,CAAE,IAAA,CAAM3B,GAAc,CACRF,CAAAA,CAAiBC,CAAAA,CAAWC,CAAS,EAEzC,SAAA,EAGXyB,CAAAA,CAAO,EAAA,CAAG,IAAA,CAAK,CACb,IAAA,CAAM,QAAA,CACN,KAAA,CAAO,oBAAA,CACP,KAAM,CAAE,IAAA,CAAAD,CAAK,CACf,CAAC,EAEL,CAAC,CAAA,CAKIE,CACT,CACF,CACF","file":"index.cjs","sourcesContent":["/**\n * HMR handling for .akash files.\n *\n * Determines the type of change (script, template, style) and\n * sends targeted HMR updates. Style-only changes can hot-swap\n * without a full component reload.\n */\n\nimport { parse } from '@akashjs/compiler';\nimport type { HmrContext, ModuleNode } from 'vite';\n\nexport interface HmrAnalysis {\n /** Whether the script block changed */\n scriptChanged: boolean;\n /** Whether the template block changed */\n templateChanged: boolean;\n /** Whether the style block changed */\n styleChanged: boolean;\n /** Whether this is a style-only change (can hot-swap) */\n styleOnly: boolean;\n /** Whether a full reload is needed */\n needsFullReload: boolean;\n}\n\n/**\n * Compare old and new source to determine what changed.\n */\nexport function analyzeHmrChange(oldSource: string, newSource: string): HmrAnalysis {\n const oldSfc = parse(oldSource);\n const newSfc = parse(newSource);\n\n const scriptChanged = (oldSfc.script?.content ?? '') !== (newSfc.script?.content ?? '');\n const templateChanged = (oldSfc.template?.content ?? '') !== (newSfc.template?.content ?? '');\n const styleChanged = (oldSfc.style?.content ?? '') !== (newSfc.style?.content ?? '');\n\n const styleOnly = styleChanged && !scriptChanged && !templateChanged;\n const needsFullReload = scriptChanged;\n\n return {\n scriptChanged,\n templateChanged,\n styleChanged,\n styleOnly,\n needsFullReload,\n };\n}\n\n/**\n * Generate the HMR client code that gets injected into the module.\n * This code is appended to the compiled output in dev mode.\n */\nexport function generateHmrCode(id: string): string {\n return `\n// HMR\nif (import.meta.hot) {\n import.meta.hot.accept((newModule) => {\n if (newModule) {\n // Full module replacement — the new default export\n // replaces the component in the parent's render tree\n }\n });\n}\n`;\n}\n\n/**\n * Generate style-only HMR code.\n * When only styles change, we can hot-swap the <style> element\n * without re-rendering the component.\n */\nexport function generateStyleHmrCode(_styleId: string): string {\n return `\n// Style HMR — accept updates so the module re-evaluates\n// (old style removal happens before new style injection above)\nif (import.meta.hot) {\n import.meta.hot.accept();\n}\n`;\n}\n\n/**\n * Handle hot update for .akash files.\n * Returns the affected modules that need updating.\n */\nexport function handleAkashHotUpdate(\n file: string,\n modules: ModuleNode[],\n oldSource: string | undefined,\n newSource: string,\n): { modules: ModuleNode[]; type: 'full' | 'style-only' } {\n if (!oldSource) {\n return { modules, type: 'full' };\n }\n\n const analysis = analyzeHmrChange(oldSource, newSource);\n\n if (analysis.styleOnly) {\n // Style-only update — can be applied without full reload\n return { modules, type: 'style-only' };\n }\n\n // Script or template changed — need full module invalidation\n return { modules, type: 'full' };\n}\n","/**\n * AkashJS Vite plugin.\n *\n * Transforms .akash single-file components during development\n * and production builds. Handles HMR for style-only and\n * template-only changes.\n */\n\nimport { compile, parse } from '@akashjs/compiler';\nimport { transform as esbuildTransform } from 'esbuild';\nimport type { Plugin } from 'vite';\nimport { analyzeHmrChange, generateHmrCode } from './hmr.js';\n\nexport interface AkashPluginOptions {\n /** Include file patterns (default: .akash files) */\n include?: string[];\n /** CSS injection mode: 'external' extracts CSS, 'injected' inlines it */\n css?: 'external' | 'injected';\n}\n\nexport default function akash(options: AkashPluginOptions = {}): Plugin {\n const cssMode = options.css ?? 'injected';\n let isProduction = false;\n\n // Cache previous source for HMR diffing\n const sourceCache = new Map<string, string>();\n\n return {\n name: 'akash',\n enforce: 'pre',\n\n configResolved(config) {\n isProduction = config.command === 'build';\n },\n\n async transform(code, id) {\n if (!id.endsWith('.akash')) return null;\n\n // Check if the script block uses TypeScript\n const sfc = parse(code);\n const isTS = sfc.script?.lang === 'ts' || sfc.script?.lang === 'typescript';\n\n const result = compile(code, {\n filename: id,\n dev: !isProduction,\n });\n\n let output = result.code;\n\n // Strip TypeScript annotations if the script block uses lang=\"ts\"\n if (isTS) {\n const stripped = await esbuildTransform(output, {\n loader: 'ts',\n sourcemap: false,\n });\n output = stripped.code;\n }\n\n // Inject CSS\n if (result.css) {\n if (cssMode === 'injected') {\n const cssCode = result.css.replace(/`/g, '\\\\`').replace(/\\\\/g, '\\\\\\\\');\n const styleId = id.replace(/[^a-zA-Z0-9]/g, '_');\n output += `\\n// Injected scoped styles\\n`;\n // Remove old style before appending new one (critical for HMR)\n output += `const __akash_old_style = document.querySelector('[data-akash-style=\"${styleId}\"]');\\n`;\n output += `if (__akash_old_style) __akash_old_style.remove();\\n`;\n output += `const __akash_style = document.createElement('style');\\n`;\n output += `__akash_style.setAttribute('data-akash-style', '${styleId}');\\n`;\n output += `__akash_style.textContent = \\`${cssCode}\\`;\\n`;\n output += `document.head.appendChild(__akash_style);\\n`;\n }\n }\n\n // Add HMR support in dev mode\n if (!isProduction) {\n output += generateHmrCode(id);\n }\n\n // Cache source for HMR diffing\n sourceCache.set(id, code);\n\n return {\n code: output,\n map: null, // TODO: integrate SourceMapBuilder\n };\n },\n\n handleHotUpdate({ file, server, modules, read }) {\n if (!file.endsWith('.akash')) return;\n\n const oldSource = sourceCache.get(file);\n\n if (oldSource) {\n // Read new source to analyze what changed\n read().then((newSource) => {\n const analysis = analyzeHmrChange(oldSource, newSource);\n\n if (analysis.styleOnly) {\n // Style-only change — Vite will handle the CSS update\n // via the style HMR code we injected\n server.ws.send({\n type: 'custom',\n event: 'akash:style-update',\n data: { file },\n });\n }\n });\n }\n\n // Always return modules to invalidate — the HMR code in the\n // client handles the actual update strategy\n return modules;\n },\n };\n}\n\nexport { akash };\n"]}
|
package/dist/index.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import {compile
|
|
1
|
+
import {parse,compile}from'@akashjs/compiler';import {transform}from'esbuild';function y(r,i){let s=parse(r),l=parse(i),e=(s.script?.content??"")!==(l.script?.content??""),n=(s.template?.content??"")!==(l.template?.content??""),o=(s.style?.content??"")!==(l.style?.content??"");return {scriptChanged:e,templateChanged:n,styleChanged:o,styleOnly:o&&!e&&!n,needsFullReload:e}}function m(r){return `
|
|
2
2
|
// HMR
|
|
3
3
|
if (import.meta.hot) {
|
|
4
4
|
import.meta.hot.accept((newModule) => {
|
|
@@ -8,19 +8,13 @@ if (import.meta.hot) {
|
|
|
8
8
|
}
|
|
9
9
|
});
|
|
10
10
|
}
|
|
11
|
-
`}function
|
|
12
|
-
// Style HMR
|
|
13
|
-
if (import.meta.hot) {
|
|
14
|
-
import.meta.hot.accept();
|
|
15
|
-
// Remove old style element and re-inject
|
|
16
|
-
const oldStyle = document.querySelector('[data-akash-style="${l}"]');
|
|
17
|
-
if (oldStyle) oldStyle.remove();
|
|
18
|
-
}
|
|
19
|
-
`}function f(l={}){let i=l.css??"injected",o=false,a=new Map;return {name:"akash",enforce:"pre",configResolved(e){o=e.command==="build";},transform(e,n){if(!n.endsWith(".akash"))return null;let s=compile(e,{filename:n,dev:!o}),t=s.code;if(s.css&&i==="injected"){let r=s.css.replace(/`/g,"\\`").replace(/\\/g,"\\\\"),c=n.replace(/[^a-zA-Z0-9]/g,"_");t+=`
|
|
11
|
+
`}function _(r={}){let i=r.css??"injected",s=false,l=new Map;return {name:"akash",enforce:"pre",configResolved(e){s=e.command==="build";},async transform(e,n){if(!n.endsWith(".akash"))return null;let o=parse(e),c=o.script?.lang==="ts"||o.script?.lang==="typescript",a=compile(e,{filename:n,dev:!s}),t=a.code;if(c&&(t=(await transform(t,{loader:"ts",sourcemap:false})).code),a.css&&i==="injected"){let p=a.css.replace(/`/g,"\\`").replace(/\\/g,"\\\\"),d=n.replace(/[^a-zA-Z0-9]/g,"_");t+=`
|
|
20
12
|
// Injected scoped styles
|
|
13
|
+
`,t+=`const __akash_old_style = document.querySelector('[data-akash-style="${d}"]');
|
|
14
|
+
`,t+=`if (__akash_old_style) __akash_old_style.remove();
|
|
21
15
|
`,t+=`const __akash_style = document.createElement('style');
|
|
22
|
-
`,t+=`__akash_style.setAttribute('data-akash-style', '${
|
|
23
|
-
`,t+=`__akash_style.textContent = \`${
|
|
16
|
+
`,t+=`__akash_style.setAttribute('data-akash-style', '${d}');
|
|
17
|
+
`,t+=`__akash_style.textContent = \`${p}\`;
|
|
24
18
|
`,t+=`document.head.appendChild(__akash_style);
|
|
25
|
-
|
|
19
|
+
`;}return s||(t+=m()),l.set(n,e),{code:t,map:null}},handleHotUpdate({file:e,server:n,modules:o,read:c}){if(!e.endsWith(".akash"))return;let a=l.get(e);return a&&c().then(t=>{y(a,t).styleOnly&&n.ws.send({type:"custom",event:"akash:style-update",data:{file:e}});}),o}}}export{_ as akash,_ as default};//# sourceMappingURL=index.js.map
|
|
26
20
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/hmr.ts","../src/index.ts"],"names":["analyzeHmrChange","oldSource","newSource","oldSfc","parse","newSfc","scriptChanged","templateChanged","styleChanged","generateHmrCode","id","
|
|
1
|
+
{"version":3,"sources":["../src/hmr.ts","../src/index.ts"],"names":["analyzeHmrChange","oldSource","newSource","oldSfc","parse","newSfc","scriptChanged","templateChanged","styleChanged","generateHmrCode","id","akash","options","cssMode","isProduction","sourceCache","config","code","sfc","isTS","result","compile","output","esbuildTransform","cssCode","styleId","file","server","modules","read"],"mappings":"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","file":"index.js","sourcesContent":["/**\n * HMR handling for .akash files.\n *\n * Determines the type of change (script, template, style) and\n * sends targeted HMR updates. Style-only changes can hot-swap\n * without a full component reload.\n */\n\nimport { parse } from '@akashjs/compiler';\nimport type { HmrContext, ModuleNode } from 'vite';\n\nexport interface HmrAnalysis {\n /** Whether the script block changed */\n scriptChanged: boolean;\n /** Whether the template block changed */\n templateChanged: boolean;\n /** Whether the style block changed */\n styleChanged: boolean;\n /** Whether this is a style-only change (can hot-swap) */\n styleOnly: boolean;\n /** Whether a full reload is needed */\n needsFullReload: boolean;\n}\n\n/**\n * Compare old and new source to determine what changed.\n */\nexport function analyzeHmrChange(oldSource: string, newSource: string): HmrAnalysis {\n const oldSfc = parse(oldSource);\n const newSfc = parse(newSource);\n\n const scriptChanged = (oldSfc.script?.content ?? '') !== (newSfc.script?.content ?? '');\n const templateChanged = (oldSfc.template?.content ?? '') !== (newSfc.template?.content ?? '');\n const styleChanged = (oldSfc.style?.content ?? '') !== (newSfc.style?.content ?? '');\n\n const styleOnly = styleChanged && !scriptChanged && !templateChanged;\n const needsFullReload = scriptChanged;\n\n return {\n scriptChanged,\n templateChanged,\n styleChanged,\n styleOnly,\n needsFullReload,\n };\n}\n\n/**\n * Generate the HMR client code that gets injected into the module.\n * This code is appended to the compiled output in dev mode.\n */\nexport function generateHmrCode(id: string): string {\n return `\n// HMR\nif (import.meta.hot) {\n import.meta.hot.accept((newModule) => {\n if (newModule) {\n // Full module replacement — the new default export\n // replaces the component in the parent's render tree\n }\n });\n}\n`;\n}\n\n/**\n * Generate style-only HMR code.\n * When only styles change, we can hot-swap the <style> element\n * without re-rendering the component.\n */\nexport function generateStyleHmrCode(_styleId: string): string {\n return `\n// Style HMR — accept updates so the module re-evaluates\n// (old style removal happens before new style injection above)\nif (import.meta.hot) {\n import.meta.hot.accept();\n}\n`;\n}\n\n/**\n * Handle hot update for .akash files.\n * Returns the affected modules that need updating.\n */\nexport function handleAkashHotUpdate(\n file: string,\n modules: ModuleNode[],\n oldSource: string | undefined,\n newSource: string,\n): { modules: ModuleNode[]; type: 'full' | 'style-only' } {\n if (!oldSource) {\n return { modules, type: 'full' };\n }\n\n const analysis = analyzeHmrChange(oldSource, newSource);\n\n if (analysis.styleOnly) {\n // Style-only update — can be applied without full reload\n return { modules, type: 'style-only' };\n }\n\n // Script or template changed — need full module invalidation\n return { modules, type: 'full' };\n}\n","/**\n * AkashJS Vite plugin.\n *\n * Transforms .akash single-file components during development\n * and production builds. Handles HMR for style-only and\n * template-only changes.\n */\n\nimport { compile, parse } from '@akashjs/compiler';\nimport { transform as esbuildTransform } from 'esbuild';\nimport type { Plugin } from 'vite';\nimport { analyzeHmrChange, generateHmrCode } from './hmr.js';\n\nexport interface AkashPluginOptions {\n /** Include file patterns (default: .akash files) */\n include?: string[];\n /** CSS injection mode: 'external' extracts CSS, 'injected' inlines it */\n css?: 'external' | 'injected';\n}\n\nexport default function akash(options: AkashPluginOptions = {}): Plugin {\n const cssMode = options.css ?? 'injected';\n let isProduction = false;\n\n // Cache previous source for HMR diffing\n const sourceCache = new Map<string, string>();\n\n return {\n name: 'akash',\n enforce: 'pre',\n\n configResolved(config) {\n isProduction = config.command === 'build';\n },\n\n async transform(code, id) {\n if (!id.endsWith('.akash')) return null;\n\n // Check if the script block uses TypeScript\n const sfc = parse(code);\n const isTS = sfc.script?.lang === 'ts' || sfc.script?.lang === 'typescript';\n\n const result = compile(code, {\n filename: id,\n dev: !isProduction,\n });\n\n let output = result.code;\n\n // Strip TypeScript annotations if the script block uses lang=\"ts\"\n if (isTS) {\n const stripped = await esbuildTransform(output, {\n loader: 'ts',\n sourcemap: false,\n });\n output = stripped.code;\n }\n\n // Inject CSS\n if (result.css) {\n if (cssMode === 'injected') {\n const cssCode = result.css.replace(/`/g, '\\\\`').replace(/\\\\/g, '\\\\\\\\');\n const styleId = id.replace(/[^a-zA-Z0-9]/g, '_');\n output += `\\n// Injected scoped styles\\n`;\n // Remove old style before appending new one (critical for HMR)\n output += `const __akash_old_style = document.querySelector('[data-akash-style=\"${styleId}\"]');\\n`;\n output += `if (__akash_old_style) __akash_old_style.remove();\\n`;\n output += `const __akash_style = document.createElement('style');\\n`;\n output += `__akash_style.setAttribute('data-akash-style', '${styleId}');\\n`;\n output += `__akash_style.textContent = \\`${cssCode}\\`;\\n`;\n output += `document.head.appendChild(__akash_style);\\n`;\n }\n }\n\n // Add HMR support in dev mode\n if (!isProduction) {\n output += generateHmrCode(id);\n }\n\n // Cache source for HMR diffing\n sourceCache.set(id, code);\n\n return {\n code: output,\n map: null, // TODO: integrate SourceMapBuilder\n };\n },\n\n handleHotUpdate({ file, server, modules, read }) {\n if (!file.endsWith('.akash')) return;\n\n const oldSource = sourceCache.get(file);\n\n if (oldSource) {\n // Read new source to analyze what changed\n read().then((newSource) => {\n const analysis = analyzeHmrChange(oldSource, newSource);\n\n if (analysis.styleOnly) {\n // Style-only change — Vite will handle the CSS update\n // via the style HMR code we injected\n server.ws.send({\n type: 'custom',\n event: 'akash:style-update',\n data: { file },\n });\n }\n });\n }\n\n // Always return modules to invalidate — the HMR code in the\n // client handles the actual update strategy\n return modules;\n },\n };\n}\n\nexport { akash };\n"]}
|