@akashjs/vite-plugin 0.1.2 → 0.1.3
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 +9 -126
- package/dist/index.cjs.map +1 -1
- package/dist/index.js +9 -101
- package/dist/index.js.map +1 -1
- package/package.json +2 -2
package/dist/index.cjs
CHANGED
|
@@ -1,51 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
var __defProp = Object.defineProperty;
|
|
3
|
-
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
4
|
-
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
5
|
-
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
6
|
-
var __export = (target, all) => {
|
|
7
|
-
for (var name in all)
|
|
8
|
-
__defProp(target, name, { get: all[name], enumerable: true });
|
|
9
|
-
};
|
|
10
|
-
var __copyProps = (to, from, except, desc) => {
|
|
11
|
-
if (from && typeof from === "object" || typeof from === "function") {
|
|
12
|
-
for (let key of __getOwnPropNames(from))
|
|
13
|
-
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
14
|
-
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
15
|
-
}
|
|
16
|
-
return to;
|
|
17
|
-
};
|
|
18
|
-
var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
|
|
19
|
-
|
|
20
|
-
// src/index.ts
|
|
21
|
-
var index_exports = {};
|
|
22
|
-
__export(index_exports, {
|
|
23
|
-
akash: () => akash,
|
|
24
|
-
default: () => akash
|
|
25
|
-
});
|
|
26
|
-
module.exports = __toCommonJS(index_exports);
|
|
27
|
-
var import_compiler2 = require("@akashjs/compiler");
|
|
28
|
-
|
|
29
|
-
// src/hmr.ts
|
|
30
|
-
var import_compiler = require("@akashjs/compiler");
|
|
31
|
-
function analyzeHmrChange(oldSource, newSource) {
|
|
32
|
-
const oldSfc = (0, import_compiler.parse)(oldSource);
|
|
33
|
-
const newSfc = (0, import_compiler.parse)(newSource);
|
|
34
|
-
const scriptChanged = (oldSfc.script?.content ?? "") !== (newSfc.script?.content ?? "");
|
|
35
|
-
const templateChanged = (oldSfc.template?.content ?? "") !== (newSfc.template?.content ?? "");
|
|
36
|
-
const styleChanged = (oldSfc.style?.content ?? "") !== (newSfc.style?.content ?? "");
|
|
37
|
-
const styleOnly = styleChanged && !scriptChanged && !templateChanged;
|
|
38
|
-
const needsFullReload = scriptChanged;
|
|
39
|
-
return {
|
|
40
|
-
scriptChanged,
|
|
41
|
-
templateChanged,
|
|
42
|
-
styleChanged,
|
|
43
|
-
styleOnly,
|
|
44
|
-
needsFullReload
|
|
45
|
-
};
|
|
46
|
-
}
|
|
47
|
-
function generateHmrCode(id) {
|
|
48
|
-
return `
|
|
1
|
+
'use strict';Object.defineProperty(exports,'__esModule',{value:true});var compiler=require('@akashjs/compiler');function p(l,i){let o=compiler.parse(l),a=compiler.parse(i),e=(o.script?.content??"")!==(a.script?.content??""),n=(o.template?.content??"")!==(a.template?.content??""),s=(o.style?.content??"")!==(a.style?.content??"");return {scriptChanged:e,templateChanged:n,styleChanged:s,styleOnly:s&&!e&&!n,needsFullReload:e}}function u(l){return `
|
|
49
2
|
// HMR
|
|
50
3
|
if (import.meta.hot) {
|
|
51
4
|
import.meta.hot.accept((newModule) => {
|
|
@@ -55,89 +8,19 @@ if (import.meta.hot) {
|
|
|
55
8
|
}
|
|
56
9
|
});
|
|
57
10
|
}
|
|
58
|
-
|
|
59
|
-
}
|
|
60
|
-
function generateStyleHmrCode(styleId) {
|
|
61
|
-
return `
|
|
11
|
+
`}function y(l){return `
|
|
62
12
|
// Style HMR
|
|
63
13
|
if (import.meta.hot) {
|
|
64
14
|
import.meta.hot.accept();
|
|
65
15
|
// Remove old style element and re-inject
|
|
66
|
-
const oldStyle = document.querySelector('[data-akash-style="${
|
|
16
|
+
const oldStyle = document.querySelector('[data-akash-style="${l}"]');
|
|
67
17
|
if (oldStyle) oldStyle.remove();
|
|
68
18
|
}
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
// src/index.ts
|
|
73
|
-
function akash(options = {}) {
|
|
74
|
-
const cssMode = options.css ?? "injected";
|
|
75
|
-
let isProduction = false;
|
|
76
|
-
const sourceCache = /* @__PURE__ */ new Map();
|
|
77
|
-
return {
|
|
78
|
-
name: "akash",
|
|
79
|
-
enforce: "pre",
|
|
80
|
-
configResolved(config) {
|
|
81
|
-
isProduction = config.command === "build";
|
|
82
|
-
},
|
|
83
|
-
transform(code, id) {
|
|
84
|
-
if (!id.endsWith(".akash")) return null;
|
|
85
|
-
const result = (0, import_compiler2.compile)(code, {
|
|
86
|
-
filename: id,
|
|
87
|
-
dev: !isProduction
|
|
88
|
-
});
|
|
89
|
-
let output = result.code;
|
|
90
|
-
if (result.css) {
|
|
91
|
-
if (cssMode === "injected") {
|
|
92
|
-
const cssCode = result.css.replace(/`/g, "\\`").replace(/\\/g, "\\\\");
|
|
93
|
-
const styleId = id.replace(/[^a-zA-Z0-9]/g, "_");
|
|
94
|
-
output += `
|
|
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+=`
|
|
95
20
|
// Injected scoped styles
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
output += `__akash_style.textContent = \`${cssCode}\`;
|
|
102
|
-
`;
|
|
103
|
-
output += `document.head.appendChild(__akash_style);
|
|
104
|
-
`;
|
|
105
|
-
if (!isProduction) {
|
|
106
|
-
output += generateStyleHmrCode(styleId);
|
|
107
|
-
}
|
|
108
|
-
}
|
|
109
|
-
}
|
|
110
|
-
if (!isProduction) {
|
|
111
|
-
output += generateHmrCode(id);
|
|
112
|
-
}
|
|
113
|
-
sourceCache.set(id, code);
|
|
114
|
-
return {
|
|
115
|
-
code: output,
|
|
116
|
-
map: null
|
|
117
|
-
// TODO: integrate SourceMapBuilder
|
|
118
|
-
};
|
|
119
|
-
},
|
|
120
|
-
handleHotUpdate({ file, server, modules, read }) {
|
|
121
|
-
if (!file.endsWith(".akash")) return;
|
|
122
|
-
const oldSource = sourceCache.get(file);
|
|
123
|
-
if (oldSource) {
|
|
124
|
-
read().then((newSource) => {
|
|
125
|
-
const analysis = analyzeHmrChange(oldSource, newSource);
|
|
126
|
-
if (analysis.styleOnly) {
|
|
127
|
-
server.ws.send({
|
|
128
|
-
type: "custom",
|
|
129
|
-
event: "akash:style-update",
|
|
130
|
-
data: { file }
|
|
131
|
-
});
|
|
132
|
-
}
|
|
133
|
-
});
|
|
134
|
-
}
|
|
135
|
-
return modules;
|
|
136
|
-
}
|
|
137
|
-
};
|
|
138
|
-
}
|
|
139
|
-
// Annotate the CommonJS export names for ESM import in node:
|
|
140
|
-
0 && (module.exports = {
|
|
141
|
-
akash
|
|
142
|
-
});
|
|
21
|
+
`,t+=`const __akash_style = document.createElement('style');
|
|
22
|
+
`,t+=`__akash_style.setAttribute('data-akash-style', '${c}');
|
|
23
|
+
`,t+=`__akash_style.textContent = \`${r}\`;
|
|
24
|
+
`,t+=`document.head.appendChild(__akash_style);
|
|
25
|
+
`,o||(t+=y(c));}return o||(t+=u()),a.set(n,e),{code:t,map:null}},handleHotUpdate({file:e,server:n,modules:s,read:t}){if(!e.endsWith(".akash"))return;let r=a.get(e);return r&&t().then(c=>{p(r,c).styleOnly&&n.ws.send({type:"custom",event:"akash:style-update",data:{file:e}});}),s}}}exports.akash=f;exports.default=f;//# sourceMappingURL=index.cjs.map
|
|
143
26
|
//# sourceMappingURL=index.cjs.map
|
package/dist/index.cjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/
|
|
1
|
+
{"version":3,"sources":["../src/hmr.ts","../src/index.ts"],"names":["analyzeHmrChange","oldSource","newSource","oldSfc","parse","newSfc","scriptChanged","templateChanged","styleChanged","generateHmrCode","id","generateStyleHmrCode","styleId","akash","options","cssMode","isProduction","sourceCache","config","code","result","compile","output","cssCode","file","server","modules","read"],"mappings":"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","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\nif (import.meta.hot) {\n import.meta.hot.accept();\n // Remove old style element and re-inject\n const oldStyle = document.querySelector('[data-akash-style=\"${styleId}\"]');\n if (oldStyle) oldStyle.remove();\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 } from '@akashjs/compiler';\nimport type { Plugin } from 'vite';\nimport { analyzeHmrChange, generateHmrCode, generateStyleHmrCode } 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 transform(code, id) {\n if (!id.endsWith('.akash')) return null;\n\n const result = compile(code, {\n filename: id,\n dev: !isProduction,\n });\n\n let output = result.code;\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 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 // Add style HMR in dev mode\n if (!isProduction) {\n output += generateStyleHmrCode(styleId);\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,26 +1,4 @@
|
|
|
1
|
-
|
|
2
|
-
import { compile } from "@akashjs/compiler";
|
|
3
|
-
|
|
4
|
-
// src/hmr.ts
|
|
5
|
-
import { parse } from "@akashjs/compiler";
|
|
6
|
-
function analyzeHmrChange(oldSource, newSource) {
|
|
7
|
-
const oldSfc = parse(oldSource);
|
|
8
|
-
const newSfc = parse(newSource);
|
|
9
|
-
const scriptChanged = (oldSfc.script?.content ?? "") !== (newSfc.script?.content ?? "");
|
|
10
|
-
const templateChanged = (oldSfc.template?.content ?? "") !== (newSfc.template?.content ?? "");
|
|
11
|
-
const styleChanged = (oldSfc.style?.content ?? "") !== (newSfc.style?.content ?? "");
|
|
12
|
-
const styleOnly = styleChanged && !scriptChanged && !templateChanged;
|
|
13
|
-
const needsFullReload = scriptChanged;
|
|
14
|
-
return {
|
|
15
|
-
scriptChanged,
|
|
16
|
-
templateChanged,
|
|
17
|
-
styleChanged,
|
|
18
|
-
styleOnly,
|
|
19
|
-
needsFullReload
|
|
20
|
-
};
|
|
21
|
-
}
|
|
22
|
-
function generateHmrCode(id) {
|
|
23
|
-
return `
|
|
1
|
+
import {compile,parse}from'@akashjs/compiler';function p(l,i){let o=parse(l),a=parse(i),e=(o.script?.content??"")!==(a.script?.content??""),n=(o.template?.content??"")!==(a.template?.content??""),s=(o.style?.content??"")!==(a.style?.content??"");return {scriptChanged:e,templateChanged:n,styleChanged:s,styleOnly:s&&!e&&!n,needsFullReload:e}}function u(l){return `
|
|
24
2
|
// HMR
|
|
25
3
|
if (import.meta.hot) {
|
|
26
4
|
import.meta.hot.accept((newModule) => {
|
|
@@ -30,89 +8,19 @@ if (import.meta.hot) {
|
|
|
30
8
|
}
|
|
31
9
|
});
|
|
32
10
|
}
|
|
33
|
-
|
|
34
|
-
}
|
|
35
|
-
function generateStyleHmrCode(styleId) {
|
|
36
|
-
return `
|
|
11
|
+
`}function y(l){return `
|
|
37
12
|
// Style HMR
|
|
38
13
|
if (import.meta.hot) {
|
|
39
14
|
import.meta.hot.accept();
|
|
40
15
|
// Remove old style element and re-inject
|
|
41
|
-
const oldStyle = document.querySelector('[data-akash-style="${
|
|
16
|
+
const oldStyle = document.querySelector('[data-akash-style="${l}"]');
|
|
42
17
|
if (oldStyle) oldStyle.remove();
|
|
43
18
|
}
|
|
44
|
-
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
// src/index.ts
|
|
48
|
-
function akash(options = {}) {
|
|
49
|
-
const cssMode = options.css ?? "injected";
|
|
50
|
-
let isProduction = false;
|
|
51
|
-
const sourceCache = /* @__PURE__ */ new Map();
|
|
52
|
-
return {
|
|
53
|
-
name: "akash",
|
|
54
|
-
enforce: "pre",
|
|
55
|
-
configResolved(config) {
|
|
56
|
-
isProduction = config.command === "build";
|
|
57
|
-
},
|
|
58
|
-
transform(code, id) {
|
|
59
|
-
if (!id.endsWith(".akash")) return null;
|
|
60
|
-
const result = compile(code, {
|
|
61
|
-
filename: id,
|
|
62
|
-
dev: !isProduction
|
|
63
|
-
});
|
|
64
|
-
let output = result.code;
|
|
65
|
-
if (result.css) {
|
|
66
|
-
if (cssMode === "injected") {
|
|
67
|
-
const cssCode = result.css.replace(/`/g, "\\`").replace(/\\/g, "\\\\");
|
|
68
|
-
const styleId = id.replace(/[^a-zA-Z0-9]/g, "_");
|
|
69
|
-
output += `
|
|
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+=`
|
|
70
20
|
// Injected scoped styles
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
output += `__akash_style.textContent = \`${cssCode}\`;
|
|
77
|
-
`;
|
|
78
|
-
output += `document.head.appendChild(__akash_style);
|
|
79
|
-
`;
|
|
80
|
-
if (!isProduction) {
|
|
81
|
-
output += generateStyleHmrCode(styleId);
|
|
82
|
-
}
|
|
83
|
-
}
|
|
84
|
-
}
|
|
85
|
-
if (!isProduction) {
|
|
86
|
-
output += generateHmrCode(id);
|
|
87
|
-
}
|
|
88
|
-
sourceCache.set(id, code);
|
|
89
|
-
return {
|
|
90
|
-
code: output,
|
|
91
|
-
map: null
|
|
92
|
-
// TODO: integrate SourceMapBuilder
|
|
93
|
-
};
|
|
94
|
-
},
|
|
95
|
-
handleHotUpdate({ file, server, modules, read }) {
|
|
96
|
-
if (!file.endsWith(".akash")) return;
|
|
97
|
-
const oldSource = sourceCache.get(file);
|
|
98
|
-
if (oldSource) {
|
|
99
|
-
read().then((newSource) => {
|
|
100
|
-
const analysis = analyzeHmrChange(oldSource, newSource);
|
|
101
|
-
if (analysis.styleOnly) {
|
|
102
|
-
server.ws.send({
|
|
103
|
-
type: "custom",
|
|
104
|
-
event: "akash:style-update",
|
|
105
|
-
data: { file }
|
|
106
|
-
});
|
|
107
|
-
}
|
|
108
|
-
});
|
|
109
|
-
}
|
|
110
|
-
return modules;
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
}
|
|
114
|
-
export {
|
|
115
|
-
akash,
|
|
116
|
-
akash as default
|
|
117
|
-
};
|
|
21
|
+
`,t+=`const __akash_style = document.createElement('style');
|
|
22
|
+
`,t+=`__akash_style.setAttribute('data-akash-style', '${c}');
|
|
23
|
+
`,t+=`__akash_style.textContent = \`${r}\`;
|
|
24
|
+
`,t+=`document.head.appendChild(__akash_style);
|
|
25
|
+
`,o||(t+=y(c));}return o||(t+=u()),a.set(n,e),{code:t,map:null}},handleHotUpdate({file:e,server:n,modules:s,read:t}){if(!e.endsWith(".akash"))return;let r=a.get(e);return r&&t().then(c=>{p(r,c).styleOnly&&n.ws.send({type:"custom",event:"akash:style-update",data:{file:e}});}),s}}}export{f as akash,f as default};//# sourceMappingURL=index.js.map
|
|
118
26
|
//# sourceMappingURL=index.js.map
|
package/dist/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/
|
|
1
|
+
{"version":3,"sources":["../src/hmr.ts","../src/index.ts"],"names":["analyzeHmrChange","oldSource","newSource","oldSfc","parse","newSfc","scriptChanged","templateChanged","styleChanged","generateHmrCode","id","generateStyleHmrCode","styleId","akash","options","cssMode","isProduction","sourceCache","config","code","result","compile","output","cssCode","file","server","modules","read"],"mappings":"8CA2BO,SAASA,CAAAA,CAAiBC,CAAAA,CAAmBC,CAAAA,CAAgC,CAClF,IAAMC,EAASC,KAAAA,CAAMH,CAAS,CAAA,CACxBI,CAAAA,CAASD,KAAAA,CAAMF,CAAS,CAAA,CAExBI,CAAAA,CAAAA,CAAiBH,EAAO,MAAA,EAAQ,OAAA,EAAW,EAAA,KAASE,CAAAA,CAAO,QAAQ,OAAA,EAAW,EAAA,CAAA,CAC9EE,CAAAA,CAAAA,CAAmBJ,CAAAA,CAAO,UAAU,OAAA,EAAW,EAAA,KAASE,CAAAA,CAAO,QAAA,EAAU,OAAA,EAAW,EAAA,CAAA,CACpFG,CAAAA,CAAAA,CAAgBL,CAAAA,CAAO,OAAO,OAAA,EAAW,EAAA,KAASE,CAAAA,CAAO,KAAA,EAAO,OAAA,EAAW,EAAA,CAAA,CAKjF,OAAO,CACL,cAAAC,CAAAA,CACA,eAAA,CAAAC,CAAAA,CACA,YAAA,CAAAC,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,CAOO,SAASC,CAAAA,CAAqBC,CAAAA,CAAyB,CAC5D,OAAO;AAAA;AAAA;AAAA;AAAA;AAAA,8DAAA,EAKuDA,CAAO,CAAA;AAAA;AAAA;AAAA,CAIvE,CC7De,SAARC,CAAAA,CAAuBC,CAAAA,CAA8B,GAAY,CACtE,IAAMC,CAAAA,CAAUD,CAAAA,CAAQ,KAAO,UAAA,CAC3BE,CAAAA,CAAe,MAGbC,CAAAA,CAAc,IAAI,IAExB,OAAO,CACL,IAAA,CAAM,OAAA,CACN,QAAS,KAAA,CAET,cAAA,CAAeC,EAAQ,CACrBF,CAAAA,CAAeE,EAAO,OAAA,GAAY,QACpC,CAAA,CAEA,SAAA,CAAUC,EAAMT,CAAAA,CAAI,CAClB,GAAI,CAACA,CAAAA,CAAG,SAAS,QAAQ,CAAA,CAAG,OAAO,IAAA,CAEnC,IAAMU,CAAAA,CAASC,OAAAA,CAAQF,CAAAA,CAAM,CAC3B,SAAUT,CAAAA,CACV,GAAA,CAAK,CAACM,CACR,CAAC,CAAA,CAEGM,CAAAA,CAASF,EAAO,IAAA,CAGpB,GAAIA,EAAO,GAAA,EACLL,CAAAA,GAAY,UAAA,CAAY,CAC1B,IAAMQ,CAAAA,CAAUH,CAAAA,CAAO,IAAI,OAAA,CAAQ,IAAA,CAAM,KAAK,CAAA,CAAE,OAAA,CAAQ,KAAA,CAAO,MAAM,EAC/DR,CAAAA,CAAUF,CAAAA,CAAG,QAAQ,eAAA,CAAiB,GAAG,EAC/CY,CAAAA,EAAU;AAAA;AAAA,CAAA,CACVA,CAAAA,EAAU,CAAA;AAAA,CAAA,CACVA,CAAAA,EAAU,mDAAmDV,CAAO,CAAA;AAAA,CAAA,CACpEU,CAAAA,EAAU,iCAAiCC,CAAO,CAAA;AAAA,CAAA,CAClDD,CAAAA,EAAU,CAAA;AAAA,CAAA,CAGLN,IACHM,CAAAA,EAAUX,CAAAA,CAAqBC,CAAO,CAAA,EAE1C,CAIF,OAAKI,CAAAA,GACHM,CAAAA,EAAUb,CAAAA,CAAkB,CAAA,CAAA,CAI9BQ,CAAAA,CAAY,IAAIP,CAAAA,CAAIS,CAAI,EAEjB,CACL,IAAA,CAAMG,CAAAA,CACN,GAAA,CAAK,IACP,CACF,CAAA,CAEA,eAAA,CAAgB,CAAE,KAAAE,CAAAA,CAAM,MAAA,CAAAC,CAAAA,CAAQ,OAAA,CAAAC,EAAS,IAAA,CAAAC,CAAK,EAAG,CAC/C,GAAI,CAACH,CAAAA,CAAK,QAAA,CAAS,QAAQ,CAAA,CAAG,OAE9B,IAAMvB,CAAAA,CAAYgB,CAAAA,CAAY,GAAA,CAAIO,CAAI,CAAA,CAEtC,OAAIvB,CAAAA,EAEF0B,CAAAA,GAAO,IAAA,CAAMzB,CAAAA,EAAc,CACRF,CAAAA,CAAiBC,CAAAA,CAAWC,CAAS,CAAA,CAEzC,SAAA,EAGXuB,CAAAA,CAAO,EAAA,CAAG,KAAK,CACb,IAAA,CAAM,QAAA,CACN,KAAA,CAAO,qBACP,IAAA,CAAM,CAAE,IAAA,CAAAD,CAAK,CACf,CAAC,EAEL,CAAC,CAAA,CAKIE,CACT,CACF,CACF","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\nif (import.meta.hot) {\n import.meta.hot.accept();\n // Remove old style element and re-inject\n const oldStyle = document.querySelector('[data-akash-style=\"${styleId}\"]');\n if (oldStyle) oldStyle.remove();\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 } from '@akashjs/compiler';\nimport type { Plugin } from 'vite';\nimport { analyzeHmrChange, generateHmrCode, generateStyleHmrCode } 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 transform(code, id) {\n if (!id.endsWith('.akash')) return null;\n\n const result = compile(code, {\n filename: id,\n dev: !isProduction,\n });\n\n let output = result.code;\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 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 // Add style HMR in dev mode\n if (!isProduction) {\n output += generateStyleHmrCode(styleId);\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/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@akashjs/vite-plugin",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.3",
|
|
4
4
|
"description": "AkashJS Vite plugin — .akash file transformation and HMR",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"main": "dist/index.cjs",
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
"vite": "^5.0.0"
|
|
24
24
|
},
|
|
25
25
|
"dependencies": {
|
|
26
|
-
"@akashjs/compiler": "^0.1.
|
|
26
|
+
"@akashjs/compiler": "^0.1.3"
|
|
27
27
|
},
|
|
28
28
|
"files": [
|
|
29
29
|
"dist",
|