@abs-test/absolutejs-test 0.1.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.
Files changed (107) hide show
  1. package/.claude/settings.local.json +10 -0
  2. package/.hmr-temp/App.3e3a3834.js +65 -0
  3. package/.hmr-temp/App.462a6bf2.js +65 -0
  4. package/.hmr-temp/App.9d060aa8.js +65 -0
  5. package/.hmr-temp/Dropdown.4cb79868.js +43 -0
  6. package/.hmr-temp/Head.92c96724.js +51 -0
  7. package/.hmr-temp/ReactExample.031ea6c9.js +28 -0
  8. package/.hmr-temp/ReactExample.3ad8f8c9.js +29 -0
  9. package/.hmr-temp/ReactExample.b28ebc93.js +27 -0
  10. package/.hmr-temp/ReactExample.c4bbd06e.js +27 -0
  11. package/.hmr-temp/ReactExample.dcc8d0d4.js +27 -0
  12. package/CLAUDE.md +65 -0
  13. package/LICENSE +80 -0
  14. package/README.md +163 -0
  15. package/THIRD_PARTY_NOTICES.md +61 -0
  16. package/abs-test-absolutejs-test-0.1.0.tgz +0 -0
  17. package/absolutejs-absolute-0.15.12.tgz +0 -0
  18. package/dist/cli/index.js +98 -0
  19. package/dist/dev/client/cssUtils.ts +288 -0
  20. package/dist/dev/client/domDiff.ts +261 -0
  21. package/dist/dev/client/domState.ts +271 -0
  22. package/dist/dev/client/errorOverlay.ts +168 -0
  23. package/dist/dev/client/frameworkDetect.ts +63 -0
  24. package/dist/dev/client/handlers/html.ts +415 -0
  25. package/dist/dev/client/handlers/htmx.ts +248 -0
  26. package/dist/dev/client/handlers/react.ts +86 -0
  27. package/dist/dev/client/handlers/rebuild.ts +153 -0
  28. package/dist/dev/client/handlers/svelte.ts +129 -0
  29. package/dist/dev/client/handlers/vue.ts +254 -0
  30. package/dist/dev/client/headPatch.ts +213 -0
  31. package/dist/dev/client/hmrClient.ts +237 -0
  32. package/dist/dev/client/moduleVersions.ts +57 -0
  33. package/dist/dev/client/reactRefreshSetup.ts +21 -0
  34. package/dist/index.js +3667 -0
  35. package/dist/index.js.map +65 -0
  36. package/dist/src/build/buildReactVendor.d.ts +8 -0
  37. package/dist/src/build/compileSvelte.d.ts +11 -0
  38. package/dist/src/build/compileVue.d.ts +33 -0
  39. package/dist/src/build/generateManifest.d.ts +2 -0
  40. package/dist/src/build/generateReactIndexes.d.ts +1 -0
  41. package/dist/src/build/htmlScriptHMRPlugin.d.ts +13 -0
  42. package/dist/src/build/outputLogs.d.ts +1 -0
  43. package/dist/src/build/rewriteReactImports.d.ts +8 -0
  44. package/dist/src/build/scanEntryPoints.d.ts +1 -0
  45. package/dist/src/build/updateAssetPaths.d.ts +1 -0
  46. package/dist/src/build/wrapHTMLScript.d.ts +24 -0
  47. package/dist/src/cli/index.d.ts +2 -0
  48. package/dist/src/constants.d.ts +12 -0
  49. package/dist/src/core/build.d.ts +2 -0
  50. package/dist/src/core/devBuild.d.ts +6 -0
  51. package/dist/src/core/devVendorPaths.d.ts +7 -0
  52. package/dist/src/core/index.d.ts +4 -0
  53. package/dist/src/core/lookup.d.ts +3 -0
  54. package/dist/src/core/pageHandlers.d.ts +15 -0
  55. package/dist/src/dev/assetStore.d.ts +12 -0
  56. package/dist/src/dev/buildHMRClient.d.ts +1 -0
  57. package/dist/src/dev/clientManager.d.ts +26 -0
  58. package/dist/src/dev/configResolver.d.ts +13 -0
  59. package/dist/src/dev/dependencyGraph.d.ts +13 -0
  60. package/dist/src/dev/fileHashTracker.d.ts +2 -0
  61. package/dist/src/dev/fileWatcher.d.ts +3 -0
  62. package/dist/src/dev/moduleMapper.d.ts +21 -0
  63. package/dist/src/dev/moduleVersionTracker.d.ts +7 -0
  64. package/dist/src/dev/pathUtils.d.ts +5 -0
  65. package/dist/src/dev/reactComponentClassifier.d.ts +2 -0
  66. package/dist/src/dev/rebuildTrigger.d.ts +10 -0
  67. package/dist/src/dev/simpleHTMLHMR.d.ts +4 -0
  68. package/dist/src/dev/simpleHTMXHMR.d.ts +4 -0
  69. package/dist/src/dev/simpleSvelteHMR.d.ts +1 -0
  70. package/dist/src/dev/simpleVueHMR.d.ts +1 -0
  71. package/dist/src/dev/webSocket.d.ts +9 -0
  72. package/dist/src/index.d.ts +5 -0
  73. package/dist/src/plugins/hmr.d.ts +62 -0
  74. package/dist/src/plugins/index.d.ts +3 -0
  75. package/dist/src/plugins/networking.d.ts +29 -0
  76. package/dist/src/plugins/pageRouter.d.ts +1 -0
  77. package/dist/src/svelte/renderToPipeableStream.d.ts +12 -0
  78. package/dist/src/svelte/renderToReadableStream.d.ts +13 -0
  79. package/dist/src/svelte/renderToString.d.ts +9 -0
  80. package/dist/src/utils/cleanup.d.ts +7 -0
  81. package/dist/src/utils/commonAncestor.d.ts +1 -0
  82. package/dist/src/utils/escapeScriptContent.d.ts +1 -0
  83. package/dist/src/utils/generateHeadElement.d.ts +17 -0
  84. package/dist/src/utils/getDurationString.d.ts +1 -0
  85. package/dist/src/utils/getEnv.d.ts +1 -0
  86. package/dist/src/utils/getRegisterClientScript.d.ts +10 -0
  87. package/dist/src/utils/index.d.ts +6 -0
  88. package/dist/src/utils/logger.d.ts +54 -0
  89. package/dist/src/utils/networking.d.ts +2 -0
  90. package/dist/src/utils/normalizePath.d.ts +9 -0
  91. package/dist/src/utils/registerClientScript.d.ts +51 -0
  92. package/dist/src/utils/stringModifiers.d.ts +2 -0
  93. package/dist/src/utils/validateSafePath.d.ts +1 -0
  94. package/dist/types/build.d.ts +41 -0
  95. package/dist/types/client.d.ts +108 -0
  96. package/dist/types/index.d.ts +4 -0
  97. package/dist/types/messages.d.ts +138 -0
  98. package/dist/types/websocket.d.ts +6 -0
  99. package/eslint.config.mjs +238 -0
  100. package/package.json +67 -0
  101. package/tsconfig.build.json +20 -0
  102. package/types/build.ts +54 -0
  103. package/types/client.ts +111 -0
  104. package/types/index.ts +4 -0
  105. package/types/messages.ts +205 -0
  106. package/types/websocket.ts +12 -0
  107. package/types/window-globals.ts +53 -0
package/dist/index.js ADDED
@@ -0,0 +1,3667 @@
1
+ // @bun
2
+ var __defProp = Object.defineProperty;
3
+ var __export = (target, all) => {
4
+ for (var name in all)
5
+ __defProp(target, name, {
6
+ get: all[name],
7
+ enumerable: true,
8
+ configurable: true,
9
+ set: (newValue) => all[name] = () => newValue
10
+ });
11
+ };
12
+ var __esm = (fn, res) => () => (fn && (res = fn(fn = 0)), res);
13
+ var __require = import.meta.require;
14
+
15
+ // src/constants.ts
16
+ var UNFOUND_INDEX = -1, SECONDS_IN_A_MINUTE = 60, MILLISECONDS_IN_A_SECOND = 1000, MILLISECONDS_IN_A_MINUTE, MINUTES_IN_AN_HOUR = 60, HOURS_IN_DAY = 24, MILLISECONDS_IN_A_DAY, TIME_PRECISION = 2, TWO_THIRDS, DEFAULT_PORT = 3000, DEFAULT_CHUNK_SIZE = 16384, BUN_BUILD_WARNING_SUPPRESSION = "wildcard sideEffects are not supported yet";
17
+ var init_constants = __esm(() => {
18
+ MILLISECONDS_IN_A_MINUTE = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE;
19
+ MILLISECONDS_IN_A_DAY = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE * MINUTES_IN_AN_HOUR * HOURS_IN_DAY;
20
+ TWO_THIRDS = 2 / 3;
21
+ });
22
+
23
+ // src/utils/stringModifiers.ts
24
+ var exports_stringModifiers = {};
25
+ __export(exports_stringModifiers, {
26
+ toPascal: () => toPascal,
27
+ toKebab: () => toKebab
28
+ });
29
+ var normalizeSlug = (str) => str.trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-9\-_]+/g, "").replace(/[-_]{2,}/g, "-"), toPascal = (str) => {
30
+ if (!str.includes("-") && !str.includes("_")) {
31
+ return str.charAt(0).toUpperCase() + str.slice(1);
32
+ }
33
+ return normalizeSlug(str).split(/[-_]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase()).join("");
34
+ }, toKebab = (str) => normalizeSlug(str).replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
35
+
36
+ // src/build/compileVue.ts
37
+ var exports_compileVue = {};
38
+ __export(exports_compileVue, {
39
+ vueHmrMetadata: () => vueHmrMetadata,
40
+ generateVueHmrId: () => generateVueHmrId,
41
+ detectVueChangeType: () => detectVueChangeType,
42
+ compileVue: () => compileVue,
43
+ clearVueHmrCaches: () => clearVueHmrCaches
44
+ });
45
+ import { existsSync as existsSync2 } from "fs";
46
+ import { mkdir as mkdir2 } from "fs/promises";
47
+ import { basename as basename2, dirname as dirname2, join as join2, relative as relative2, resolve as resolve2 } from "path";
48
+ import {
49
+ parse,
50
+ compileScript,
51
+ compileTemplate,
52
+ compileStyle
53
+ } from "@vue/compiler-sfc";
54
+ var {file: file2, write: write2, Transpiler: Transpiler2 } = globalThis.Bun;
55
+ var devClientDir2, hmrClientPath2, transpiler2, scriptCache, scriptSetupCache, templateCache, styleCache, vueHmrMetadata, detectVueChangeType = (filePath, descriptor) => {
56
+ const prevScript = scriptCache.get(filePath);
57
+ const prevScriptSetup = scriptSetupCache.get(filePath);
58
+ const prevTemplate = templateCache.get(filePath);
59
+ const prevStyle = styleCache.get(filePath);
60
+ const currentScript = descriptor.script?.content ?? "";
61
+ const currentScriptSetup = descriptor.scriptSetup?.content ?? "";
62
+ const currentTemplate = descriptor.template?.content ?? "";
63
+ const currentStyle = descriptor.styles.map((s) => `${s.scoped ? "scoped:" : ""}${s.content}`).join("|||");
64
+ scriptCache.set(filePath, currentScript);
65
+ scriptSetupCache.set(filePath, currentScriptSetup);
66
+ templateCache.set(filePath, currentTemplate);
67
+ styleCache.set(filePath, currentStyle);
68
+ if (prevScript === undefined && prevScriptSetup === undefined) {
69
+ return "full";
70
+ }
71
+ const scriptChanged = prevScript !== currentScript;
72
+ const scriptSetupChanged = prevScriptSetup !== currentScriptSetup;
73
+ const templateChanged = prevTemplate !== currentTemplate;
74
+ const styleChanged = prevStyle !== currentStyle;
75
+ if (scriptChanged || scriptSetupChanged) {
76
+ return "script";
77
+ }
78
+ if (styleChanged && !templateChanged) {
79
+ return "style-only";
80
+ }
81
+ if (templateChanged) {
82
+ return "template-only";
83
+ }
84
+ return "full";
85
+ }, generateVueHmrId = (sourceFilePath, vueRootDir) => {
86
+ return relative2(vueRootDir, sourceFilePath).replace(/\\/g, "/").replace(/\.vue$/, "");
87
+ }, clearVueHmrCaches = () => {
88
+ scriptCache.clear();
89
+ scriptSetupCache.clear();
90
+ templateCache.clear();
91
+ styleCache.clear();
92
+ vueHmrMetadata.clear();
93
+ }, extractImports = (sourceCode) => Array.from(sourceCode.matchAll(/import\s+[\s\S]+?['"]([^'"]+)['"]/g)).map((match) => match[1]).filter((importPath) => importPath !== undefined), toJs = (filePath) => {
94
+ if (filePath.endsWith(".vue"))
95
+ return filePath.replace(/\.vue$/, ".js");
96
+ if (filePath.endsWith(".ts"))
97
+ return filePath.replace(/\.ts$/, ".js");
98
+ return `${filePath}.js`;
99
+ }, stripExports = (code) => code.replace(/export\s+default/, "const script =").replace(/^export\s+/gm, ""), mergeVueImports = (code) => {
100
+ const lines = code.split(`
101
+ `);
102
+ const specifierSet = new Set;
103
+ const vueImportRegex = /^import\s+{([^}]+)}\s+from\s+['"]vue['"];?$/;
104
+ lines.forEach((line) => {
105
+ const match = line.match(vueImportRegex);
106
+ if (match?.[1])
107
+ match[1].split(",").forEach((importSpecifier) => specifierSet.add(importSpecifier.trim()));
108
+ });
109
+ const nonVueLines = lines.filter((line) => !vueImportRegex.test(line));
110
+ return specifierSet.size ? [
111
+ `import { ${[...specifierSet].join(", ")} } from "vue";`,
112
+ ...nonVueLines
113
+ ].join(`
114
+ `) : nonVueLines.join(`
115
+ `);
116
+ }, compileVueFile = async (sourceFilePath, outputDirs, cacheMap, isEntryPoint, vueRootDir) => {
117
+ const cachedResult = cacheMap.get(sourceFilePath);
118
+ if (cachedResult)
119
+ return cachedResult;
120
+ const relativeFilePath = relative2(vueRootDir, sourceFilePath).replace(/\\/g, "/");
121
+ const relativeWithoutExtension = relativeFilePath.replace(/\.vue$/, "");
122
+ const fileBaseName = basename2(sourceFilePath, ".vue");
123
+ const componentId = toKebab(fileBaseName);
124
+ const sourceContent = await file2(sourceFilePath).text();
125
+ const { descriptor } = parse(sourceContent, { filename: sourceFilePath });
126
+ const hmrId = generateVueHmrId(sourceFilePath, vueRootDir);
127
+ const changeType = detectVueChangeType(sourceFilePath, descriptor);
128
+ vueHmrMetadata.set(sourceFilePath, { hmrId, changeType });
129
+ const scriptSource = descriptor.scriptSetup?.content ?? descriptor.script?.content ?? "";
130
+ const importPaths = extractImports(scriptSource);
131
+ const childComponentPaths = importPaths.filter((path) => path.startsWith(".") && path.endsWith(".vue"));
132
+ const helperModulePaths = importPaths.filter((path) => path.startsWith(".") && !path.endsWith(".vue"));
133
+ const childBuildResults = await Promise.all(childComponentPaths.map((relativeChildPath) => compileVueFile(resolve2(dirname2(sourceFilePath), relativeChildPath), outputDirs, cacheMap, false, vueRootDir)));
134
+ const compiledScript = compileScript(descriptor, {
135
+ id: componentId,
136
+ inlineTemplate: false
137
+ });
138
+ const strippedScript = stripExports(compiledScript.content);
139
+ const transpiledScript = transpiler2.transformSync(strippedScript).replace(/(['"])(\.{1,2}\/[^'"]+)(['"])/g, (_, quoteStart, relativeImport, quoteEnd) => `${quoteStart}${toJs(relativeImport)}${quoteEnd}`);
140
+ const generateRenderFunction = (ssr) => compileTemplate({
141
+ compilerOptions: {
142
+ bindingMetadata: compiledScript.bindings,
143
+ prefixIdentifiers: true
144
+ },
145
+ filename: sourceFilePath,
146
+ id: componentId,
147
+ scoped: descriptor.styles.some((styleBlock) => styleBlock.scoped),
148
+ source: descriptor.template?.content ?? "",
149
+ ssr,
150
+ ssrCssVars: descriptor.cssVars
151
+ }).code.replace(/(['"])(\.{1,2}\/[^'"]+)(['"])/g, (_, quoteStart, relativeImport, quoteEnd) => `${quoteStart}${toJs(relativeImport)}${quoteEnd}`);
152
+ const localCss = descriptor.styles.map((styleBlock) => compileStyle({
153
+ filename: sourceFilePath,
154
+ id: componentId,
155
+ scoped: styleBlock.scoped,
156
+ source: styleBlock.content,
157
+ trim: true
158
+ }).code);
159
+ const allCss = [
160
+ ...localCss,
161
+ ...childBuildResults.flatMap((result2) => result2.cssCodes)
162
+ ];
163
+ let cssOutputPaths = [];
164
+ if (isEntryPoint && allCss.length) {
165
+ const cssOutputFile = join2(outputDirs.css, `${toKebab(fileBaseName)}.css`);
166
+ await mkdir2(dirname2(cssOutputFile), { recursive: true });
167
+ await write2(cssOutputFile, allCss.join(`
168
+ `));
169
+ cssOutputPaths = [cssOutputFile];
170
+ }
171
+ const assembleModule = (renderCode, renderFnName, includeHmr) => {
172
+ const hasScoped = descriptor.styles.some((styleBlock) => styleBlock.scoped);
173
+ const scopeIdCode = hasScoped ? `script.__scopeId = "data-v-${componentId}";` : "";
174
+ const hmrCode = includeHmr ? `
175
+ // Vue Native HMR Registration
176
+ script.__hmrId = ${JSON.stringify(hmrId)};
177
+ if (typeof __VUE_HMR_RUNTIME__ !== 'undefined') {
178
+ __VUE_HMR_RUNTIME__.createRecord(script.__hmrId, script);
179
+ if (typeof window !== 'undefined') {
180
+ window.__VUE_HMR_COMPONENTS__ = window.__VUE_HMR_COMPONENTS__ || {};
181
+ window.__VUE_HMR_COMPONENTS__[script.__hmrId] = script;
182
+ }
183
+ }` : "";
184
+ return mergeVueImports([
185
+ transpiledScript,
186
+ renderCode,
187
+ `script.${renderFnName} = ${renderFnName};`,
188
+ scopeIdCode,
189
+ hmrCode,
190
+ "export default script;"
191
+ ].join(`
192
+ `));
193
+ };
194
+ const clientCode = assembleModule(generateRenderFunction(false), "render", true);
195
+ const serverCode = assembleModule(generateRenderFunction(true), "ssrRender", false);
196
+ const clientOutputPath = join2(outputDirs.client, `${relativeWithoutExtension}.js`);
197
+ const serverOutputPath = join2(outputDirs.server, `${relativeWithoutExtension}.js`);
198
+ await mkdir2(dirname2(clientOutputPath), { recursive: true });
199
+ await mkdir2(dirname2(serverOutputPath), { recursive: true });
200
+ await write2(clientOutputPath, clientCode);
201
+ await write2(serverOutputPath, serverCode);
202
+ const result = {
203
+ clientPath: clientOutputPath,
204
+ cssCodes: allCss,
205
+ cssPaths: cssOutputPaths,
206
+ serverPath: serverOutputPath,
207
+ tsHelperPaths: [
208
+ ...helperModulePaths.map((helper) => resolve2(dirname2(sourceFilePath), helper.endsWith(".ts") ? helper : `${helper}.ts`)),
209
+ ...childBuildResults.flatMap((child) => child.tsHelperPaths)
210
+ ],
211
+ hmrId
212
+ };
213
+ cacheMap.set(sourceFilePath, result);
214
+ return result;
215
+ }, compileVue = async (entryPoints, vueRootDir, isDev = false) => {
216
+ const compiledOutputRoot = join2(vueRootDir, "compiled");
217
+ const clientOutputDir = join2(compiledOutputRoot, "client");
218
+ const indexOutputDir = join2(compiledOutputRoot, "indexes");
219
+ const serverOutputDir = join2(compiledOutputRoot, "pages");
220
+ const cssOutputDir = join2(compiledOutputRoot, "styles");
221
+ await Promise.all([
222
+ mkdir2(clientOutputDir, { recursive: true }),
223
+ mkdir2(indexOutputDir, { recursive: true }),
224
+ mkdir2(serverOutputDir, { recursive: true }),
225
+ mkdir2(cssOutputDir, { recursive: true })
226
+ ]);
227
+ const buildCache = new Map;
228
+ const allTsHelperPaths = new Set;
229
+ const compiledPages = await Promise.all(entryPoints.map(async (entryPath) => {
230
+ const result = await compileVueFile(resolve2(entryPath), {
231
+ client: clientOutputDir,
232
+ css: cssOutputDir,
233
+ server: serverOutputDir
234
+ }, buildCache, true, vueRootDir);
235
+ result.tsHelperPaths.forEach((path) => allTsHelperPaths.add(path));
236
+ const entryBaseName = basename2(entryPath, ".vue");
237
+ const indexOutputFile = join2(indexOutputDir, `${entryBaseName}.js`);
238
+ const clientOutputFile = join2(clientOutputDir, relative2(vueRootDir, entryPath).replace(/\\/g, "/").replace(/\.vue$/, ".js"));
239
+ await mkdir2(dirname2(indexOutputFile), { recursive: true });
240
+ const vueHmrImports = isDev ? [
241
+ `window.__HMR_FRAMEWORK__ = "vue";`,
242
+ `import "${hmrClientPath2}";`
243
+ ] : [];
244
+ await write2(indexOutputFile, [
245
+ ...vueHmrImports,
246
+ `import Comp from "${relative2(dirname2(indexOutputFile), clientOutputFile).replace(/\\/g, "/")}";`,
247
+ 'import { createSSRApp } from "vue";',
248
+ "",
249
+ "// HMR State Preservation: Check for preserved state from HMR",
250
+ 'let preservedState = (typeof window !== "undefined" && window.__HMR_PRESERVED_STATE__) ? window.__HMR_PRESERVED_STATE__ : {};',
251
+ "",
252
+ "// Fallback: check sessionStorage if window state is empty",
253
+ 'if (typeof window !== "undefined" && Object.keys(preservedState).length === 0) {',
254
+ " try {",
255
+ ' const stored = sessionStorage.getItem("__VUE_HMR_STATE__");',
256
+ " if (stored) {",
257
+ " preservedState = JSON.parse(stored);",
258
+ ' sessionStorage.removeItem("__VUE_HMR_STATE__");',
259
+ " }",
260
+ " } catch (e) {}",
261
+ "}",
262
+ "",
263
+ "const mergedProps = { ...(window.__INITIAL_PROPS__ ?? {}), ...preservedState };",
264
+ "",
265
+ "// Use createSSRApp for proper hydration of server-rendered content",
266
+ "const app = createSSRApp(Comp, mergedProps);",
267
+ 'app.mount("#root");',
268
+ "",
269
+ "// Store app instance for HMR - used for manual component updates",
270
+ 'if (typeof window !== "undefined") {',
271
+ " window.__VUE_APP__ = app;",
272
+ "}",
273
+ "",
274
+ "// Post-mount: Apply preserved state to reactive refs in component tree",
275
+ "// This restores state that lives in refs (like count) rather than props",
276
+ 'if (typeof window !== "undefined" && Object.keys(preservedState).length > 0) {',
277
+ " requestAnimationFrame(function() {",
278
+ " if (window.__VUE_APP__ && window.__VUE_APP__._instance) {",
279
+ " applyPreservedState(window.__VUE_APP__._instance, preservedState);",
280
+ " }",
281
+ " });",
282
+ "}",
283
+ "",
284
+ "function applyPreservedState(instance, state) {",
285
+ " // Apply to root component setupState",
286
+ " if (instance.setupState) {",
287
+ " Object.keys(state).forEach(function(key) {",
288
+ " const ref = instance.setupState[key];",
289
+ ' if (ref && typeof ref === "object" && "value" in ref) {',
290
+ " ref.value = state[key];",
291
+ " }",
292
+ " });",
293
+ " }",
294
+ " // Also apply to child components",
295
+ " if (instance.subTree) {",
296
+ " walkAndApply(instance.subTree, state);",
297
+ " }",
298
+ "}",
299
+ "",
300
+ "function walkAndApply(vnode, state) {",
301
+ " if (!vnode) return;",
302
+ " if (vnode.component && vnode.component.setupState) {",
303
+ " Object.keys(state).forEach(function(key) {",
304
+ " const ref = vnode.component.setupState[key];",
305
+ ' if (ref && typeof ref === "object" && "value" in ref) {',
306
+ " ref.value = state[key];",
307
+ " }",
308
+ " });",
309
+ " }",
310
+ " if (vnode.children && Array.isArray(vnode.children)) {",
311
+ " vnode.children.forEach(function(child) { walkAndApply(child, state); });",
312
+ " }",
313
+ " if (vnode.component && vnode.component.subTree) {",
314
+ " walkAndApply(vnode.component.subTree, state);",
315
+ " }",
316
+ "}",
317
+ "",
318
+ "// Clear preserved state after applying",
319
+ 'if (typeof window !== "undefined") {',
320
+ " window.__HMR_PRESERVED_STATE__ = undefined;",
321
+ "}"
322
+ ].join(`
323
+ `));
324
+ return {
325
+ clientPath: clientOutputFile,
326
+ cssPaths: result.cssPaths,
327
+ indexPath: indexOutputFile,
328
+ serverPath: result.serverPath
329
+ };
330
+ }));
331
+ await Promise.all(Array.from(allTsHelperPaths).map(async (tsPath) => {
332
+ const sourceCode = await file2(tsPath).text();
333
+ const transpiledCode = transpiler2.transformSync(sourceCode);
334
+ const relativeJsPath = relative2(vueRootDir, tsPath).replace(/\.ts$/, ".js");
335
+ const outClientPath = join2(clientOutputDir, relativeJsPath);
336
+ const outServerPath = join2(serverOutputDir, relativeJsPath);
337
+ await mkdir2(dirname2(outClientPath), { recursive: true });
338
+ await mkdir2(dirname2(outServerPath), { recursive: true });
339
+ await write2(outClientPath, transpiledCode);
340
+ await write2(outServerPath, transpiledCode);
341
+ }));
342
+ return {
343
+ vueClientPaths: compiledPages.map((result) => result.clientPath),
344
+ vueCssPaths: compiledPages.flatMap((result) => result.cssPaths),
345
+ vueIndexPaths: compiledPages.map((result) => result.indexPath),
346
+ vueServerPaths: compiledPages.map((result) => result.serverPath),
347
+ hmrMetadata: new Map(vueHmrMetadata)
348
+ };
349
+ };
350
+ var init_compileVue = __esm(() => {
351
+ devClientDir2 = (() => {
352
+ const fromSource = resolve2(import.meta.dir, "../dev/client");
353
+ if (existsSync2(fromSource))
354
+ return fromSource;
355
+ return resolve2(import.meta.dir, "./dev/client");
356
+ })();
357
+ hmrClientPath2 = join2(devClientDir2, "hmrClient.ts").replace(/\\/g, "/");
358
+ transpiler2 = new Transpiler2({ loader: "ts", target: "browser" });
359
+ scriptCache = new Map;
360
+ scriptSetupCache = new Map;
361
+ templateCache = new Map;
362
+ styleCache = new Map;
363
+ vueHmrMetadata = new Map;
364
+ });
365
+
366
+ // src/dev/simpleHTMLHMR.ts
367
+ var exports_simpleHTMLHMR = {};
368
+ __export(exports_simpleHTMLHMR, {
369
+ handleHTMLUpdate: () => handleHTMLUpdate
370
+ });
371
+ import { readFileSync as readFileSync4, existsSync as existsSync7 } from "fs";
372
+ import { resolve as resolve13 } from "path";
373
+ var handleHTMLUpdate = async (htmlFilePath) => {
374
+ try {
375
+ const resolvedPath = resolve13(htmlFilePath);
376
+ if (!existsSync7(resolvedPath)) {
377
+ return null;
378
+ }
379
+ const htmlContent = readFileSync4(resolvedPath, "utf-8");
380
+ const headMatch = htmlContent.match(/<head[^>]*>([\s\S]*?)<\/head>/i);
381
+ const bodyMatch = htmlContent.match(/<body[^>]*>([\s\S]*)<\/body>/i);
382
+ if (bodyMatch && bodyMatch[1]) {
383
+ const bodyContent = bodyMatch[1].trim();
384
+ const headContent = headMatch && headMatch[1] ? headMatch[1].trim() : null;
385
+ return {
386
+ body: bodyContent,
387
+ head: headContent
388
+ };
389
+ }
390
+ return htmlContent;
391
+ } catch {
392
+ return null;
393
+ }
394
+ };
395
+ var init_simpleHTMLHMR = () => {};
396
+
397
+ // src/utils/escapeScriptContent.ts
398
+ var ESCAPE_LOOKUP, ESCAPE_REGEX, escapeScriptContent = (content) => content.replace(ESCAPE_REGEX, (char) => {
399
+ const escaped = ESCAPE_LOOKUP[char];
400
+ return escaped !== undefined ? escaped : char;
401
+ });
402
+ var init_escapeScriptContent = __esm(() => {
403
+ ESCAPE_LOOKUP = {
404
+ "\u2028": "\\u2028",
405
+ "\u2029": "\\u2029",
406
+ "&": "\\u0026",
407
+ "<": "\\u003C",
408
+ ">": "\\u003E"
409
+ };
410
+ ESCAPE_REGEX = /[&><\u2028\u2029]/g;
411
+ });
412
+
413
+ // src/svelte/renderToReadableStream.ts
414
+ import { render } from "svelte/server";
415
+ var renderToReadableStream = async (component, props, {
416
+ bootstrapScriptContent,
417
+ bootstrapScripts = [],
418
+ bootstrapModules = [],
419
+ nonce,
420
+ onError = console.error,
421
+ progressiveChunkSize = DEFAULT_CHUNK_SIZE,
422
+ signal,
423
+ headContent,
424
+ bodyContent
425
+ } = {}) => {
426
+ try {
427
+ const { head, body } = typeof props === "undefined" ? render(component) : render(component, { props });
428
+ const nonceAttr = nonce ? ` nonce="${nonce}"` : "";
429
+ const scripts = (bootstrapScriptContent ? `<script${nonceAttr}>${escapeScriptContent(bootstrapScriptContent)}</script>` : "") + bootstrapScripts.map((src) => `<script${nonceAttr} src="${src}"></script>`).join("") + bootstrapModules.map((src) => `<script${nonceAttr} type="module" src="${src}"></script>`).join("");
430
+ const encoder = new TextEncoder;
431
+ const full = encoder.encode(`<!DOCTYPE html><html lang="en"><head>${head}${headContent ?? ""}</head><body>${body}${scripts}${bodyContent ?? ""}</body></html>`);
432
+ let offset = 0;
433
+ return new ReadableStream({
434
+ type: "bytes",
435
+ cancel(reason) {
436
+ onError?.(reason);
437
+ },
438
+ pull(controller) {
439
+ if (signal?.aborted) {
440
+ controller.close();
441
+ return;
442
+ }
443
+ if (offset >= full.length) {
444
+ controller.close();
445
+ return;
446
+ }
447
+ const end = Math.min(offset + progressiveChunkSize, full.length);
448
+ controller.enqueue(full.subarray(offset, end));
449
+ offset = end;
450
+ }
451
+ });
452
+ } catch (error) {
453
+ onError?.(error);
454
+ throw error;
455
+ }
456
+ };
457
+ var init_renderToReadableStream = __esm(() => {
458
+ init_constants();
459
+ init_escapeScriptContent();
460
+ });
461
+
462
+ // src/core/pageHandlers.ts
463
+ var exports_pageHandlers = {};
464
+ __export(exports_pageHandlers, {
465
+ handleVuePageRequest: () => handleVuePageRequest,
466
+ handleSveltePageRequest: () => handleSveltePageRequest,
467
+ handleReactPageRequest: () => handleReactPageRequest,
468
+ handlePageRequest: () => handlePageRequest,
469
+ handleHTMXPageRequest: () => handleHTMXPageRequest,
470
+ handleHTMLPageRequest: () => handleHTMLPageRequest
471
+ });
472
+ var {file: file3 } = globalThis.Bun;
473
+ import { createElement } from "react";
474
+ import { renderToReadableStream as renderReactToReadableStream } from "react-dom/server";
475
+ import { createSSRApp, h } from "vue";
476
+ import { renderToWebStream as renderVueToWebStream } from "vue/server-renderer";
477
+ var handleReactPageRequest = async (PageComponent, index, ...props) => {
478
+ const [maybeProps] = props;
479
+ const element = maybeProps !== undefined ? createElement(PageComponent, maybeProps) : createElement(PageComponent);
480
+ const stream = await renderReactToReadableStream(element, {
481
+ bootstrapModules: [index],
482
+ bootstrapScriptContent: maybeProps ? `window.__INITIAL_PROPS__=${JSON.stringify(maybeProps)}` : undefined
483
+ });
484
+ return new Response(stream, {
485
+ headers: { "Content-Type": "text/html" }
486
+ });
487
+ }, handleSveltePageRequest = async (_PageComponent, pagePath, indexPath, props) => {
488
+ const { default: ImportedPageComponent } = await import(pagePath);
489
+ const stream = await renderToReadableStream(ImportedPageComponent, props, {
490
+ bootstrapModules: indexPath ? [indexPath] : [],
491
+ bootstrapScriptContent: `window.__INITIAL_PROPS__=${JSON.stringify(props)}`
492
+ });
493
+ return new Response(stream, {
494
+ headers: { "Content-Type": "text/html" }
495
+ });
496
+ }, handleVuePageRequest = async (_PageComponent, pagePath, indexPath, headTag = "<head></head>", ...props) => {
497
+ const [maybeProps] = props;
498
+ const { default: ImportedPageComponent } = await import(pagePath);
499
+ const app = createSSRApp({
500
+ render: () => h(ImportedPageComponent, maybeProps ?? null)
501
+ });
502
+ const bodyStream = renderVueToWebStream(app);
503
+ const head = `<!DOCTYPE html><html>${headTag}<body><div id="root">`;
504
+ const tail = `</div><script>window.__INITIAL_PROPS__=${JSON.stringify(maybeProps ?? {})}</script><script type="module" src="${indexPath}"></script></body></html>`;
505
+ const stream = new ReadableStream({
506
+ start(controller) {
507
+ controller.enqueue(head);
508
+ const reader = bodyStream.getReader();
509
+ const pumpLoop = () => {
510
+ reader.read().then(({ done, value }) => done ? (controller.enqueue(tail), controller.close()) : (controller.enqueue(value), pumpLoop())).catch((err) => controller.error(err));
511
+ };
512
+ pumpLoop();
513
+ }
514
+ });
515
+ return new Response(stream, {
516
+ headers: { "Content-Type": "text/html" }
517
+ });
518
+ }, handleHTMLPageRequest = (pagePath) => file3(pagePath), handleHTMXPageRequest = (pagePath) => file3(pagePath), handlePageRequest = (PageComponent, ...props) => {
519
+ console.log("handlePageRequest coming soon.", PageComponent, props);
520
+ };
521
+ var init_pageHandlers = __esm(() => {
522
+ init_renderToReadableStream();
523
+ });
524
+
525
+ // src/utils/generateHeadElement.ts
526
+ var exports_generateHeadElement = {};
527
+ __export(exports_generateHeadElement, {
528
+ generateHeadElement: () => generateHeadElement
529
+ });
530
+ var generateHeadElement = ({
531
+ cssPath,
532
+ title = "AbsoluteJS",
533
+ description = "A page created using AbsoluteJS",
534
+ font,
535
+ icon = "/assets/ico/favicon.ico"
536
+ } = {}) => `<head>
537
+ <meta charset="UTF-8">
538
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
539
+ <title>${title}</title>
540
+ <meta name="description" content="${description}">
541
+ <link rel="icon" href="${icon}" type="image/x-icon">
542
+ ${font ? `<link rel="preconnect" href="https://fonts.googleapis.com">
543
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
544
+ <link href="https://fonts.googleapis.com/css2?family=${font}:wght@100..900&display=swap" rel="stylesheet">` : ""}
545
+ ${cssPath ? `<link rel="stylesheet" href="${cssPath}" type="text/css">` : ""}
546
+ </head>`;
547
+
548
+ // src/dev/simpleVueHMR.ts
549
+ var exports_simpleVueHMR = {};
550
+ __export(exports_simpleVueHMR, {
551
+ handleVueUpdate: () => handleVueUpdate
552
+ });
553
+ import { basename as basename6, join as join9, resolve as resolve14 } from "path";
554
+ var handleVueUpdate = async (vueFilePath, manifest, buildDir) => {
555
+ try {
556
+ const resolvedPath = resolve14(vueFilePath);
557
+ const fileName = basename6(resolvedPath);
558
+ const baseName = fileName.replace(/\.vue$/, "");
559
+ const pascalName = toPascal(baseName);
560
+ const componentKey = pascalName;
561
+ const indexKey = `${pascalName}Index`;
562
+ const cssKey = `${pascalName}CSS`;
563
+ const serverPath = manifest[componentKey];
564
+ if (!serverPath) {
565
+ console.warn("[Vue HMR] Server path not found in manifest for:", componentKey);
566
+ console.warn("[Vue HMR] Available manifest keys:", Object.keys(manifest).join(", "));
567
+ return null;
568
+ }
569
+ const absoluteServerPath = resolve14(serverPath) === serverPath || serverPath.startsWith("/") || /^[A-Za-z]:[\\/]/.test(serverPath) ? serverPath : join9(buildDir || process.cwd(), serverPath.replace(/^\//, ""));
570
+ const cacheBuster = `?t=${Date.now()}`;
571
+ const serverModule = await import(`${absoluteServerPath}${cacheBuster}`);
572
+ if (!serverModule || !serverModule.default) {
573
+ console.warn("[Vue HMR] Module has no default export:", absoluteServerPath);
574
+ return null;
575
+ }
576
+ const indexPath = manifest[indexKey];
577
+ if (!indexPath) {
578
+ console.warn("[Vue HMR] Index path not found in manifest for:", indexKey);
579
+ return null;
580
+ }
581
+ const { handleVuePageRequest: handleVuePageRequest2 } = await Promise.resolve().then(() => (init_pageHandlers(), exports_pageHandlers));
582
+ const { generateHeadElement: generateHeadElement2 } = await Promise.resolve().then(() => exports_generateHeadElement);
583
+ const response = await handleVuePageRequest2(serverModule.default, serverPath, indexPath, generateHeadElement2({
584
+ cssPath: manifest[cssKey] || "",
585
+ title: "AbsoluteJS + Vue"
586
+ }), { initialCount: 0 });
587
+ const html = await response.text();
588
+ const bodyMatch = html.match(/<body[^>]*>([\s\S]*)<\/body>/i);
589
+ if (bodyMatch && bodyMatch[1]) {
590
+ const bodyContent = bodyMatch[1].trim();
591
+ return bodyContent;
592
+ }
593
+ return html;
594
+ } catch (err) {
595
+ console.error("[Vue HMR] Error in handleVueUpdate:", err);
596
+ return null;
597
+ }
598
+ };
599
+ var init_simpleVueHMR = () => {};
600
+
601
+ // src/dev/simpleSvelteHMR.ts
602
+ var exports_simpleSvelteHMR = {};
603
+ __export(exports_simpleSvelteHMR, {
604
+ handleSvelteUpdate: () => handleSvelteUpdate
605
+ });
606
+ import { basename as basename7, join as join10, resolve as resolve15 } from "path";
607
+ var handleSvelteUpdate = async (svelteFilePath, manifest, buildDir) => {
608
+ try {
609
+ const resolvedPath = resolve15(svelteFilePath);
610
+ const fileName = basename7(resolvedPath);
611
+ const baseName = fileName.replace(/\.svelte$/, "");
612
+ const pascalName = toPascal(baseName);
613
+ const componentKey = pascalName;
614
+ const indexKey = `${pascalName}Index`;
615
+ const cssKey = `${pascalName}CSS`;
616
+ const serverPath = manifest[componentKey];
617
+ if (!serverPath) {
618
+ console.warn("[Svelte HMR] Server path not found in manifest for:", componentKey);
619
+ console.warn("[Svelte HMR] Available manifest keys:", Object.keys(manifest).join(", "));
620
+ return null;
621
+ }
622
+ const absoluteServerPath = resolve15(serverPath) === serverPath || serverPath.startsWith("/") || /^[A-Za-z]:[\\/]/.test(serverPath) ? serverPath : join10(buildDir || process.cwd(), serverPath.replace(/^\//, ""));
623
+ const cacheBuster = `?t=${Date.now()}`;
624
+ const serverModule = await import(`${absoluteServerPath}${cacheBuster}`);
625
+ if (!serverModule || !serverModule.default) {
626
+ console.warn("[Svelte HMR] Module has no default export:", absoluteServerPath);
627
+ return null;
628
+ }
629
+ const indexPath = manifest[indexKey];
630
+ if (!indexPath) {
631
+ console.warn("[Svelte HMR] Index path not found in manifest for:", indexKey);
632
+ return null;
633
+ }
634
+ const { handleSveltePageRequest: handleSveltePageRequest2 } = await Promise.resolve().then(() => (init_pageHandlers(), exports_pageHandlers));
635
+ const response = await handleSveltePageRequest2(serverModule.default, serverPath, indexPath, {
636
+ cssPath: manifest[cssKey] || "",
637
+ initialCount: 0
638
+ });
639
+ const html = await response.text();
640
+ const bodyMatch = html.match(/<body[^>]*>([\s\S]*)<\/body>/i);
641
+ if (bodyMatch && bodyMatch[1]) {
642
+ const bodyContent = bodyMatch[1].trim();
643
+ return bodyContent;
644
+ }
645
+ return html;
646
+ } catch (err) {
647
+ console.error("[Svelte HMR] Error in handleSvelteUpdate:", err);
648
+ return null;
649
+ }
650
+ };
651
+ var init_simpleSvelteHMR = () => {};
652
+
653
+ // src/dev/simpleHTMXHMR.ts
654
+ var exports_simpleHTMXHMR = {};
655
+ __export(exports_simpleHTMXHMR, {
656
+ handleHTMXUpdate: () => handleHTMXUpdate
657
+ });
658
+ import { readFileSync as readFileSync5, existsSync as existsSync8 } from "fs";
659
+ import { resolve as resolve16 } from "path";
660
+ var handleHTMXUpdate = async (htmxFilePath) => {
661
+ try {
662
+ const resolvedPath = resolve16(htmxFilePath);
663
+ if (!existsSync8(resolvedPath)) {
664
+ return null;
665
+ }
666
+ const htmlContent = readFileSync5(resolvedPath, "utf-8");
667
+ const headMatch = htmlContent.match(/<head[^>]*>([\s\S]*?)<\/head>/i);
668
+ const bodyMatch = htmlContent.match(/<body[^>]*>([\s\S]*)<\/body>/i);
669
+ if (bodyMatch && bodyMatch[1]) {
670
+ const bodyContent = bodyMatch[1].trim();
671
+ const headContent = headMatch && headMatch[1] ? headMatch[1].trim() : null;
672
+ return {
673
+ body: bodyContent,
674
+ head: headContent
675
+ };
676
+ }
677
+ return htmlContent;
678
+ } catch {
679
+ return null;
680
+ }
681
+ };
682
+ var init_simpleHTMXHMR = () => {};
683
+ // types/client.ts
684
+ var hmrState = {
685
+ isConnected: false,
686
+ isFirstHMRUpdate: true,
687
+ isHMRUpdating: false,
688
+ pingInterval: null,
689
+ reconnectTimeout: null
690
+ };
691
+ // types/messages.ts
692
+ var isValidHMRClientMessage = (data) => {
693
+ if (!data || typeof data !== "object") {
694
+ return false;
695
+ }
696
+ const message = data;
697
+ if (!("type" in message) || typeof message.type !== "string") {
698
+ return false;
699
+ }
700
+ switch (message.type) {
701
+ case "ping":
702
+ return true;
703
+ case "ready":
704
+ return true;
705
+ case "request-rebuild":
706
+ return true;
707
+ case "hydration-error":
708
+ return true;
709
+ default:
710
+ return false;
711
+ }
712
+ };
713
+ // types/websocket.ts
714
+ var WS_READY_STATE_OPEN = 1;
715
+ // src/index.ts
716
+ init_constants();
717
+
718
+ // src/core/build.ts
719
+ import {
720
+ copyFileSync,
721
+ cpSync,
722
+ mkdirSync,
723
+ readFileSync,
724
+ writeFileSync
725
+ } from "fs";
726
+ import { rm as rm3 } from "fs/promises";
727
+ import { basename as basename4, join as join6, resolve as resolve6 } from "path";
728
+ import { cwd, env as env2, exit } from "process";
729
+ var {$, build: bunBuild2, Glob: Glob3 } = globalThis.Bun;
730
+
731
+ // src/build/compileSvelte.ts
732
+ import { existsSync } from "fs";
733
+ import { mkdir, stat } from "fs/promises";
734
+ import {
735
+ dirname,
736
+ join,
737
+ basename,
738
+ extname,
739
+ resolve,
740
+ relative,
741
+ sep
742
+ } from "path";
743
+ import { env } from "process";
744
+ var {write, file, Transpiler } = globalThis.Bun;
745
+ import { compile, compileModule, preprocess } from "svelte/compiler";
746
+ var devClientDir = (() => {
747
+ const fromSource = resolve(import.meta.dir, "../dev/client");
748
+ if (existsSync(fromSource))
749
+ return fromSource;
750
+ return resolve(import.meta.dir, "./dev/client");
751
+ })();
752
+ var hmrClientPath = join(devClientDir, "hmrClient.ts").replace(/\\/g, "/");
753
+ var transpiler = new Transpiler({ loader: "ts", target: "browser" });
754
+ var exists = async (path) => {
755
+ try {
756
+ await stat(path);
757
+ return true;
758
+ } catch {
759
+ return false;
760
+ }
761
+ };
762
+ var resolveSvelte = async (spec, from) => {
763
+ const basePath = resolve(dirname(from), spec);
764
+ const explicit = /\.(svelte|svelte\.(?:ts|js))$/.test(basePath);
765
+ if (!explicit) {
766
+ const extensions = [".svelte", ".svelte.ts", ".svelte.js"];
767
+ const paths = extensions.map((ext) => `${basePath}${ext}`);
768
+ const checks = await Promise.all(paths.map(exists));
769
+ const match = paths.find((_, index) => checks[index]);
770
+ return match ?? null;
771
+ }
772
+ if (await exists(basePath))
773
+ return basePath;
774
+ if (!basePath.endsWith(".svelte"))
775
+ return null;
776
+ const tsPath = `${basePath}.ts`;
777
+ if (await exists(tsPath))
778
+ return tsPath;
779
+ const jsPath = `${basePath}.js`;
780
+ if (await exists(jsPath))
781
+ return jsPath;
782
+ return null;
783
+ };
784
+ var compileSvelte = async (entryPoints, svelteRoot, cache = new Map, isDev = false) => {
785
+ const compiledRoot = join(svelteRoot, "compiled");
786
+ const clientDir = join(compiledRoot, "client");
787
+ const indexDir = join(compiledRoot, "indexes");
788
+ const pagesDir = join(compiledRoot, "pages");
789
+ await Promise.all([clientDir, indexDir, pagesDir].map((dir) => mkdir(dir, { recursive: true })));
790
+ const dev = env.NODE_ENV !== "production";
791
+ const build2 = async (src) => {
792
+ const memoized = cache.get(src);
793
+ if (memoized)
794
+ return memoized;
795
+ const raw = await file(src).text();
796
+ const isModule = src.endsWith(".svelte.ts") || src.endsWith(".svelte.js");
797
+ const preprocessed = isModule ? raw : (await preprocess(raw, {})).code;
798
+ const transpiled = src.endsWith(".ts") || src.endsWith(".svelte.ts") ? transpiler.transformSync(preprocessed) : preprocessed;
799
+ const relDir = dirname(relative(svelteRoot, src)).replace(/\\/g, "/");
800
+ const baseName = basename(src).replace(/\.svelte(\.(ts|js))?$/, "");
801
+ const importPaths = Array.from(transpiled.matchAll(/from\s+['"]([^'"]+)['"]/g)).map((match) => match[1]).filter((path) => path !== undefined);
802
+ const resolvedImports = await Promise.all(importPaths.map((importPath) => resolveSvelte(importPath, src)));
803
+ const childSources = resolvedImports.filter((path) => path !== null);
804
+ await Promise.all(childSources.map((child) => build2(child)));
805
+ const generate = (mode) => (isModule ? compileModule(transpiled, { dev, filename: src }).js.code : compile(transpiled, {
806
+ css: "injected",
807
+ dev,
808
+ filename: src,
809
+ generate: mode
810
+ }).js.code).replace(/\.svelte(?:\.(?:ts|js))?(['"])/g, ".js$1");
811
+ const ssrPath = join(pagesDir, relDir, `${baseName}.js`);
812
+ const clientPath = join(clientDir, relDir, `${baseName}.js`);
813
+ await Promise.all([
814
+ mkdir(dirname(ssrPath), { recursive: true }),
815
+ mkdir(dirname(clientPath), { recursive: true })
816
+ ]);
817
+ if (isModule) {
818
+ const bundle = generate("client");
819
+ await Promise.all([
820
+ write(ssrPath, bundle),
821
+ write(clientPath, bundle)
822
+ ]);
823
+ } else {
824
+ const serverBundle = generate("server");
825
+ const clientBundle = generate("client");
826
+ await Promise.all([
827
+ write(ssrPath, serverBundle),
828
+ write(clientPath, clientBundle)
829
+ ]);
830
+ }
831
+ const built = { client: clientPath, ssr: ssrPath };
832
+ cache.set(src, built);
833
+ return built;
834
+ };
835
+ const roots = await Promise.all(entryPoints.map(build2));
836
+ await Promise.all(roots.map(async ({ client: client2 }) => {
837
+ const relClientDir = dirname(relative(clientDir, client2));
838
+ const name = basename(client2, extname(client2));
839
+ const indexPath = join(indexDir, relClientDir, `${name}.js`);
840
+ const importRaw = relative(dirname(indexPath), client2).split(sep).join("/");
841
+ const importPath = importRaw.startsWith(".") || importRaw.startsWith("/") ? importRaw : `./${importRaw}`;
842
+ const hmrImports = isDev ? `window.__HMR_FRAMEWORK__ = "svelte";
843
+ import "${hmrClientPath}";
844
+ ` : "";
845
+ const bootstrap = `${hmrImports}import Component from "${importPath}";
846
+ import { hydrate, mount, unmount } from "svelte";
847
+
848
+ var initialProps = (typeof window !== "undefined" && window.__INITIAL_PROPS__) ? window.__INITIAL_PROPS__ : {};
849
+ var isHMR = typeof window !== "undefined" && window.__SVELTE_COMPONENT__ !== undefined;
850
+ var component;
851
+
852
+ if (isHMR) {
853
+ var headLinks = document.querySelectorAll('link[rel="stylesheet"]');
854
+ var preservedLinks = [];
855
+ headLinks.forEach(function(link) {
856
+ var clone = link.cloneNode(true);
857
+ clone.setAttribute("data-hmr-preserve", "true");
858
+ document.head.appendChild(clone);
859
+ preservedLinks.push(clone);
860
+ });
861
+ if (typeof window.__SVELTE_UNMOUNT__ === "function") {
862
+ try { window.__SVELTE_UNMOUNT__(); } catch (err) { console.warn("[HMR] unmount error:", err); }
863
+ }
864
+ var preservedState = window.__HMR_PRESERVED_STATE__;
865
+ if (!preservedState) {
866
+ try {
867
+ var stored = sessionStorage.getItem("__SVELTE_HMR_STATE__");
868
+ if (stored) preservedState = JSON.parse(stored);
869
+ } catch (err) { /* ignore */ }
870
+ }
871
+ var mergedProps = preservedState ? Object.assign({}, initialProps, preservedState) : initialProps;
872
+ component = mount(Component, { target: document.body, props: mergedProps });
873
+ requestAnimationFrame(function() {
874
+ preservedLinks.forEach(function(link) { link.remove(); });
875
+ });
876
+ window.__HMR_PRESERVED_STATE__ = undefined;
877
+ } else {
878
+ component = hydrate(Component, { target: document.body, props: initialProps });
879
+ }
880
+
881
+ if (typeof window !== "undefined") {
882
+ window.__SVELTE_COMPONENT__ = component;
883
+ window.__SVELTE_UNMOUNT__ = function() { unmount(component); };
884
+ }`;
885
+ await mkdir(dirname(indexPath), { recursive: true });
886
+ return write(indexPath, bootstrap);
887
+ }));
888
+ return {
889
+ svelteIndexPaths: roots.map(({ client: client2 }) => {
890
+ const rel = dirname(relative(clientDir, client2));
891
+ return join(indexDir, rel, basename(client2));
892
+ }),
893
+ svelteClientPaths: roots.map(({ client: client2 }) => client2),
894
+ svelteServerPaths: roots.map(({ ssr }) => ssr)
895
+ };
896
+ };
897
+
898
+ // src/core/build.ts
899
+ init_compileVue();
900
+
901
+ // src/build/generateManifest.ts
902
+ init_constants();
903
+ import { extname as extname2 } from "path";
904
+
905
+ // src/utils/normalizePath.ts
906
+ var normalizePath = (path) => path.replace(/\\/g, "/");
907
+
908
+ // src/build/generateManifest.ts
909
+ var generateManifest = (outputs, buildPath) => outputs.reduce((manifest, artifact) => {
910
+ const normalizedArtifactPath = normalizePath(artifact.path);
911
+ const normalizedBuildPath = normalizePath(buildPath);
912
+ let relative3 = normalizedArtifactPath.startsWith(normalizedBuildPath) ? normalizedArtifactPath.slice(normalizedBuildPath.length) : normalizedArtifactPath;
913
+ relative3 = relative3.replace(/^\/+/, "");
914
+ const segments = relative3.split("/");
915
+ const fileWithHash = segments.pop();
916
+ if (!fileWithHash)
917
+ return manifest;
918
+ const [baseName] = fileWithHash.split(`.${artifact.hash}.`);
919
+ if (!baseName)
920
+ return manifest;
921
+ const pascalName = toPascal(baseName);
922
+ const ext = extname2(fileWithHash);
923
+ if (ext === ".css") {
924
+ manifest[`${pascalName}CSS`] = `/${relative3}`;
925
+ return manifest;
926
+ }
927
+ const idx = segments.findIndex((seg) => seg === "indexes" || seg === "pages" || seg === "client");
928
+ const folder = idx > UNFOUND_INDEX ? segments[idx] : segments[0];
929
+ const isReact = segments.some((seg) => seg === "react");
930
+ const isVue = segments.some((seg) => seg === "vue");
931
+ const isSvelte = segments.some((seg) => seg === "svelte");
932
+ const isClientComponent = segments.includes("client");
933
+ if (folder === "indexes") {
934
+ manifest[`${pascalName}Index`] = `/${relative3}`;
935
+ } else if (isClientComponent) {
936
+ manifest[`${pascalName}Client`] = `/${relative3}`;
937
+ } else if (folder === "pages") {
938
+ if (isReact) {
939
+ manifest[`${pascalName}Page`] = `/${relative3}`;
940
+ } else if (isVue || isSvelte) {
941
+ manifest[pascalName] = `/${relative3}`;
942
+ } else {
943
+ manifest[`${pascalName}Page`] = `/${relative3}`;
944
+ }
945
+ } else {
946
+ manifest[pascalName] = `/${relative3}`;
947
+ }
948
+ return manifest;
949
+ }, {});
950
+
951
+ // src/build/generateReactIndexes.ts
952
+ import { existsSync as existsSync3 } from "fs";
953
+ import { mkdir as mkdir3, rm, writeFile } from "fs/promises";
954
+ import { basename as basename3, join as join3, resolve as resolve3 } from "path";
955
+ var {Glob } = globalThis.Bun;
956
+ var devClientDir3 = (() => {
957
+ const fromSource = resolve3(import.meta.dir, "../dev/client");
958
+ if (existsSync3(fromSource))
959
+ return fromSource;
960
+ return resolve3(import.meta.dir, "./dev/client");
961
+ })();
962
+ var errorOverlayPath = join3(devClientDir3, "errorOverlay.ts").replace(/\\/g, "/");
963
+ var hmrClientPath3 = join3(devClientDir3, "hmrClient.ts").replace(/\\/g, "/");
964
+ var refreshSetupPath = join3(devClientDir3, "reactRefreshSetup.ts").replace(/\\/g, "/");
965
+ var generateReactIndexFiles = async (reactPagesDirectory, reactIndexesDirectory, isDev = false) => {
966
+ await rm(reactIndexesDirectory, { force: true, recursive: true });
967
+ await mkdir3(reactIndexesDirectory);
968
+ const pagesGlob = new Glob("*.*");
969
+ const files = [];
970
+ for await (const file3 of pagesGlob.scan({ cwd: reactPagesDirectory })) {
971
+ files.push(file3);
972
+ }
973
+ const promises = files.map(async (file3) => {
974
+ const fileName = basename3(file3);
975
+ const [componentName] = fileName.split(".");
976
+ const hmrPreamble = isDev ? [
977
+ `window.__HMR_FRAMEWORK__ = "react";`,
978
+ `window.__REACT_COMPONENT_KEY__ = "${componentName}Index";`,
979
+ `import '${refreshSetupPath}';`,
980
+ `import '${hmrClientPath3}';`,
981
+ `import { showErrorOverlay, hideErrorOverlay } from '${errorOverlayPath}';
982
+ `
983
+ ] : [];
984
+ const reactImports = isDev ? [
985
+ `import { hydrateRoot, createRoot } from 'react-dom/client';`,
986
+ `import { createElement, Component } from 'react';`
987
+ ] : [
988
+ `import { hydrateRoot, createRoot } from 'react-dom/client';`,
989
+ `import { createElement } from 'react';`
990
+ ];
991
+ const errorBoundaryDef = isDev ? [
992
+ `
993
+ // Dev-only Error Boundary to catch React render errors`,
994
+ `class ErrorBoundary extends Component {`,
995
+ ` constructor(props) {`,
996
+ ` super(props);`,
997
+ ` this.state = { hasError: false };`,
998
+ ` window.__ERROR_BOUNDARY__ = this;`,
999
+ ` }`,
1000
+ ` static getDerivedStateFromError() {`,
1001
+ ` return { hasError: true };`,
1002
+ ` }`,
1003
+ ` componentDidCatch(error) {`,
1004
+ ` showErrorOverlay({`,
1005
+ ` framework: 'react',`,
1006
+ ` kind: 'runtime',`,
1007
+ ` message: error && error.stack ? error.stack : String(error)`,
1008
+ ` });`,
1009
+ ` }`,
1010
+ ` componentDidUpdate(prevProps, prevState) {`,
1011
+ ` if (prevState.hasError && !this.state.hasError) {`,
1012
+ ` hideErrorOverlay();`,
1013
+ ` }`,
1014
+ ` }`,
1015
+ ` reset() {`,
1016
+ ` this.setState({ hasError: false });`,
1017
+ ` }`,
1018
+ ` render() {`,
1019
+ ` if (this.state.hasError) return null;`,
1020
+ ``,
1021
+ ` return this.props.children;`,
1022
+ ` }`,
1023
+ `}
1024
+ `
1025
+ ] : [];
1026
+ const content = [
1027
+ ...hmrPreamble,
1028
+ ...reactImports,
1029
+ `import type { ComponentType } from 'react'`,
1030
+ `import { ${componentName} } from '../pages/${componentName}';
1031
+ `,
1032
+ `type PropsOf<C> = C extends ComponentType<infer P> ? P : never;
1033
+ `,
1034
+ `declare global {`,
1035
+ ` interface Window {`,
1036
+ ` __INITIAL_PROPS__?: PropsOf<typeof ${componentName}>`,
1037
+ ` __REACT_ROOT__?: ReturnType<typeof hydrateRoot | typeof createRoot>`,
1038
+ ` __HMR_CLIENT_ONLY_MODE__?: boolean`,
1039
+ ` }`,
1040
+ `}
1041
+ `,
1042
+ ...errorBoundaryDef,
1043
+ `// Hydration with error handling and fallback`,
1044
+ `const isDev = ${isDev};`,
1045
+ `const componentPath = '../pages/${componentName}';
1046
+ `,
1047
+ `function isHydrationError(error) {`,
1048
+ ` if (!error) return false;`,
1049
+ ` const errorMessage = error instanceof Error ? error.message : String(error);`,
1050
+ ` const errorString = String(error);`,
1051
+ ` const fullMessage = errorMessage + ' ' + errorString;`,
1052
+ ` const hydrationKeywords = ['hydration', 'Hydration', 'mismatch', 'Mismatch', 'did not match', 'server rendered HTML', 'server HTML', 'client HTML', 'Hydration failed'];`,
1053
+ ` const isHydration = hydrationKeywords.some(keyword => fullMessage.includes(keyword));`,
1054
+ ` `,
1055
+ ` // Ignore whitespace-only mismatches in <head> - these are harmless formatting differences`,
1056
+ ` // The error often shows: + <link...> vs - {"\\n "} which is just formatting`,
1057
+ ` if (isHydration) {`,
1058
+ ` // Check if this is a head/link/stylesheet related mismatch`,
1059
+ ` const isHeadRelated = fullMessage.includes('<head') || fullMessage.includes('</head>') || fullMessage.includes('head>') || fullMessage.includes('<link') || fullMessage.includes('link>') || fullMessage.includes('stylesheet') || fullMessage.includes('fonts.googleapis') || fullMessage.includes('rel="stylesheet"');`,
1060
+ ` `,
1061
+ ` // Check if the mismatch involves only whitespace/newlines`,
1062
+ ` // Pattern: looks for {"\\n"} or {"\\n "} or similar whitespace-only content`,
1063
+ ` // Also check for patterns like: - {"\\n "} or + <link...>`,
1064
+ ` const hasWhitespacePattern = /\\{\\s*["']\\\\n[^"']*["']\\s*\\}/.test(fullMessage) || /\\{\\s*["'][\\\\n\\\\r\\\\s]+["']\\s*\\}/.test(fullMessage) || /-\\s*\\{\\s*["'][\\\\n\\\\r\\\\s]+["']\\s*\\}/.test(fullMessage);`,
1065
+ ` const isWhitespaceOnly = /^[\\s\\n\\r]*$/.test(errorString) || /^[\\s\\n\\r]*$/.test(errorMessage);`,
1066
+ ` const hasNewlinePattern = fullMessage.includes('\\\\n') || fullMessage.includes('\\\\r') || fullMessage.includes('\\n') || fullMessage.includes('\\r');`,
1067
+ ` `,
1068
+ ` // If it's head-related and involves whitespace/newlines, ignore it`,
1069
+ ` if (isHeadRelated && (hasWhitespacePattern || isWhitespaceOnly || hasNewlinePattern)) {`,
1070
+ ` return false; // Don't treat whitespace-only head mismatches as errors`,
1071
+ ` }`,
1072
+ ` }`,
1073
+ ` return isHydration;`,
1074
+ `}
1075
+ `,
1076
+ `function logHydrationError(error, componentName) {`,
1077
+ ` if (!isDev) return;`,
1078
+ ` if (window.__HMR_WS__ && window.__HMR_WS__.readyState === WebSocket.OPEN) {`,
1079
+ ` try {`,
1080
+ ` window.__HMR_WS__.send(JSON.stringify({`,
1081
+ ` type: 'hydration-error',`,
1082
+ ` data: {`,
1083
+ ` componentName: '${componentName}',`,
1084
+ ` componentPath: componentPath,`,
1085
+ ` error: error instanceof Error ? error.message : String(error),`,
1086
+ ` timestamp: Date.now()`,
1087
+ ` }`,
1088
+ ` }));`,
1089
+ ` } catch (err) {}`,
1090
+ ` }`,
1091
+ `}
1092
+ `,
1093
+ `// Track if we've already switched to client-only mode`,
1094
+ `let hasSwitchedToClientOnly = false;`,
1095
+ `let hydrationErrorDetected = false;
1096
+ `,
1097
+ `function handleHydrationFallback(error) {`,
1098
+ ` if (hasSwitchedToClientOnly) return; // Already handled`,
1099
+ ` hasSwitchedToClientOnly = true;`,
1100
+ ` hydrationErrorDetected = true;
1101
+ `,
1102
+ ` logHydrationError(error, '${componentName}');
1103
+ `,
1104
+ ` // Fallback: client-only render (no hydration)`,
1105
+ ` try {`,
1106
+ ` // Unmount existing root if it exists`,
1107
+ ` if (window.__REACT_ROOT__ && typeof window.__REACT_ROOT__.unmount === 'function') {`,
1108
+ ` try {`,
1109
+ ` window.__REACT_ROOT__.unmount();`,
1110
+ ` } catch (e) {`,
1111
+ ` // Ignore unmount errors`,
1112
+ ` }`,
1113
+ ` }
1114
+ `,
1115
+ ` // Render into the same root container when falling back to client-only`,
1116
+ ` const root = createRoot(container);`,
1117
+ ` root.render(${isDev ? `createElement(ErrorBoundary, null, createElement(${componentName}, mergedProps))` : `createElement(${componentName}, mergedProps)`});`,
1118
+ ` window.__REACT_ROOT__ = root;`,
1119
+ ` window.__HMR_CLIENT_ONLY_MODE__ = true;`,
1120
+ ` } catch (fallbackError) {`,
1121
+ ` window.location.reload();`,
1122
+ ` }`,
1123
+ `}
1124
+ `,
1125
+ `// HMR State Preservation: Check for preserved state and merge with initial props`,
1126
+ `// This allows state to be preserved across HMR updates without modifying component files`,
1127
+ `let preservedState = (typeof window !== 'undefined' && window.__HMR_PRESERVED_STATE__) ? window.__HMR_PRESERVED_STATE__ : {};
1128
+ `,
1129
+ `// Also check sessionStorage for state that survived a page reload (for React HMR)`,
1130
+ `if (typeof window !== 'undefined' && typeof sessionStorage !== 'undefined') {`,
1131
+ ` const hmrStateJson = sessionStorage.getItem('__REACT_HMR_STATE__');`,
1132
+ ` if (hmrStateJson) {`,
1133
+ ` try {`,
1134
+ ` const hmrState = JSON.parse(hmrStateJson);`,
1135
+ ` preservedState = { ...preservedState, ...hmrState };`,
1136
+ ` sessionStorage.removeItem('__REACT_HMR_STATE__');`,
1137
+ ` } catch (e) {}`,
1138
+ ` }`,
1139
+ `}
1140
+ `,
1141
+ `const mergedProps = { ...(window.__INITIAL_PROPS__ || {}), ...preservedState };`,
1142
+ `// Clear preserved state after using it (so it doesn't persist across multiple updates)`,
1143
+ `if (typeof window !== 'undefined') {`,
1144
+ ` window.__HMR_PRESERVED_STATE__ = undefined;`,
1145
+ `}
1146
+ `,
1147
+ `// Attempt hydration with error handling`,
1148
+ `// Use document (not document.body) when the page renders <html><head><body>`,
1149
+ `// to avoid "In HTML, <html> cannot be a child of <body>" hydration error`,
1150
+ `const container = typeof document !== 'undefined' ? document : null;`,
1151
+ `if (!container) {`,
1152
+ ` throw new Error('React root container not found: document is null');`,
1153
+ `}
1154
+ `,
1155
+ `// Guard: only hydrate on first load. During HMR re-imports, skip hydration`,
1156
+ `// so React Fast Refresh can swap components in-place and preserve state.`,
1157
+ `if (!window.__REACT_ROOT__) {`,
1158
+ ` let root;`,
1159
+ ` try {`,
1160
+ ` // Use onRecoverableError to catch hydration errors (React 19)`,
1161
+ ` root = hydrateRoot(`,
1162
+ ` container,`,
1163
+ ` ${isDev ? `createElement(ErrorBoundary, null, createElement(${componentName}, mergedProps))` : `createElement(${componentName}, mergedProps)`},`,
1164
+ ` {`,
1165
+ ` onRecoverableError: (error) => {`,
1166
+ ` // Check if this is a hydration error (isHydrationError filters out whitespace-only head mismatches)`,
1167
+ ` if (isDev && isHydrationError(error)) {`,
1168
+ ` // Real hydration error - handle it`,
1169
+ ` handleHydrationFallback(error);`,
1170
+ ` } else {`,
1171
+ ` // Not a hydration error, or it's a whitespace-only mismatch that was filtered out`,
1172
+ ` // Check if it's a whitespace-only head mismatch using the same logic as isHydrationError`,
1173
+ ` const errorMessage = error instanceof Error ? error.message : String(error);`,
1174
+ ` const errorString = String(error);`,
1175
+ ` const fullMessage = errorMessage + ' ' + errorString;`,
1176
+ ` const hydrationKeywords = ['hydration', 'Hydration', 'mismatch', 'Mismatch', 'did not match', 'server rendered HTML', 'server HTML', 'client HTML', 'Hydration failed'];`,
1177
+ ` const isHydration = hydrationKeywords.some(keyword => fullMessage.includes(keyword));`,
1178
+ ` if (isHydration) {`,
1179
+ ` // Check if this is a head/link/stylesheet related mismatch`,
1180
+ ` const isHeadRelated = fullMessage.includes('<head') || fullMessage.includes('</head>') || fullMessage.includes('head>') || fullMessage.includes('<link') || fullMessage.includes('link>') || fullMessage.includes('stylesheet') || fullMessage.includes('fonts.googleapis') || fullMessage.includes('rel="stylesheet"');`,
1181
+ ` // Check if the mismatch involves only whitespace/newlines`,
1182
+ ` const hasWhitespacePattern = /\\{\\s*["']\\\\n[^"']*["']\\s*\\}/.test(fullMessage) || /\\{\\s*["'][\\\\n\\\\r\\\\s]+["']\\s*\\}/.test(fullMessage) || /-\\s*\\{\\s*["'][\\\\n\\\\r\\\\s]+["']\\s*\\}/.test(fullMessage);`,
1183
+ ` const isWhitespaceOnly = /^[\\s\\n\\r]*$/.test(errorString) || /^[\\s\\n\\r]*$/.test(errorMessage);`,
1184
+ ` const hasNewlinePattern = fullMessage.includes('\\\\n') || fullMessage.includes('\\\\r') || fullMessage.includes('\\n') || fullMessage.includes('\\r');`,
1185
+ ` // If it's head-related and involves whitespace/newlines, silently ignore it`,
1186
+ ` if (isHeadRelated && (hasWhitespacePattern || isWhitespaceOnly || hasNewlinePattern)) {`,
1187
+ ` // Already logged by isHydrationError, just return silently`,
1188
+ ` return;`,
1189
+ ` }`,
1190
+ ` }`,
1191
+ ` // Log other recoverable errors`,
1192
+ ` console.error('React recoverable error:', error);`,
1193
+ ` }`,
1194
+ ` }`,
1195
+ ` }`,
1196
+ ` );`,
1197
+ ` window.__REACT_ROOT__ = root;`,
1198
+ ` } catch (error) {`,
1199
+ ` // Catch synchronous errors (shouldn't happen with hydrateRoot, but safety net)`,
1200
+ ` if (isDev && isHydrationError(error)) {`,
1201
+ ` handleHydrationFallback(error);`,
1202
+ ` } else {`,
1203
+ ` throw error;`,
1204
+ ` }`,
1205
+ ` }
1206
+ `,
1207
+ ` // Also listen for hydration errors via console.error (React logs them there)`,
1208
+ ` if (isDev) {`,
1209
+ ` const originalError = console.error;`,
1210
+ ` console.error = function(...args) {`,
1211
+ ` const errorMessage = args.map(arg => {`,
1212
+ ` if (arg instanceof Error) return arg.message;`,
1213
+ ` return String(arg);`,
1214
+ ` }).join(' ');`,
1215
+ ` `,
1216
+ ` // Check if this is a hydration error`,
1217
+ ` if (isHydrationError({ message: errorMessage }) && !hydrationErrorDetected) {`,
1218
+ ` hydrationErrorDetected = true;`,
1219
+ ` // Create a synthetic error for fallback`,
1220
+ ` const syntheticError = new Error(errorMessage);`,
1221
+ ` // Use setTimeout to ensure this happens after React's error handling`,
1222
+ ` setTimeout(() => {`,
1223
+ ` handleHydrationFallback(syntheticError);`,
1224
+ ` }, 0);`,
1225
+ ` }`,
1226
+ ` `,
1227
+ ` // Call original console.error`,
1228
+ ` originalError.apply(console, args);`,
1229
+ ` };`,
1230
+ ` }`,
1231
+ `}`
1232
+ ].join(`
1233
+ `);
1234
+ return writeFile(join3(reactIndexesDirectory, `${componentName}.tsx`), content);
1235
+ });
1236
+ await Promise.all(promises);
1237
+ if (isDev) {
1238
+ await writeFile(join3(reactIndexesDirectory, "_refresh.tsx"), `import 'react';
1239
+ import 'react-dom/client';
1240
+ `);
1241
+ }
1242
+ };
1243
+
1244
+ // src/build/wrapHTMLScript.ts
1245
+ var wrapHTMLScriptWithHMR = (code, scriptId) => {
1246
+ const escapedId = JSON.stringify(scriptId);
1247
+ return `${code}
1248
+
1249
+ // HMR acceptance - allows this script to be hot-reloaded
1250
+ if (typeof import.meta !== "undefined" && import.meta.hot) {
1251
+ import.meta.hot.accept();
1252
+ console.log('[HMR] Script ready:', ${escapedId});
1253
+ }
1254
+ `;
1255
+ };
1256
+
1257
+ // src/build/htmlScriptHMRPlugin.ts
1258
+ var createHTMLScriptHMRPlugin = (htmlDir, htmxDir) => {
1259
+ return {
1260
+ name: "html-script-hmr",
1261
+ setup(build2) {
1262
+ build2.onLoad({ filter: /\.(ts|js|tsx|jsx)$/ }, async (args) => {
1263
+ const normalizedPath = args.path.replace(/\\/g, "/");
1264
+ const isHtmlScript = htmlDir && normalizedPath.includes(htmlDir.replace(/\\/g, "/")) && normalizedPath.includes("/scripts/");
1265
+ const isHtmxScript = htmxDir && normalizedPath.includes(htmxDir.replace(/\\/g, "/")) && normalizedPath.includes("/scripts/");
1266
+ if (!isHtmlScript && !isHtmxScript) {
1267
+ return;
1268
+ }
1269
+ const text = await Bun.file(args.path).text();
1270
+ const wrapped = wrapHTMLScriptWithHMR(text, normalizedPath);
1271
+ const ext = args.path.split(".").pop() || "ts";
1272
+ const loader = ext;
1273
+ return {
1274
+ contents: wrapped,
1275
+ loader
1276
+ };
1277
+ });
1278
+ }
1279
+ };
1280
+ };
1281
+
1282
+ // src/build/outputLogs.ts
1283
+ init_constants();
1284
+ var outputLogs = (logs) => {
1285
+ for (const log of logs) {
1286
+ if (log.message.includes(BUN_BUILD_WARNING_SUPPRESSION))
1287
+ continue;
1288
+ if (log.level === "error")
1289
+ console.error(log);
1290
+ else if (log.level === "warning")
1291
+ console.warn(log);
1292
+ else
1293
+ console.info(log);
1294
+ }
1295
+ };
1296
+
1297
+ // src/build/scanEntryPoints.ts
1298
+ var {Glob: Glob2 } = globalThis.Bun;
1299
+ var scanEntryPoints = async (dir, pattern) => {
1300
+ const entryPaths = [];
1301
+ const glob = new Glob2(pattern);
1302
+ for await (const file3 of glob.scan({ absolute: true, cwd: dir })) {
1303
+ entryPaths.push(file3);
1304
+ }
1305
+ return entryPaths;
1306
+ };
1307
+
1308
+ // src/build/updateAssetPaths.ts
1309
+ import { readFile, writeFile as writeFile2 } from "fs/promises";
1310
+ var updateAssetPaths = async (manifest, directory) => {
1311
+ const htmlFiles = await scanEntryPoints(directory, "*.html");
1312
+ const assetRegex = /((?:<script[^>]+src=|<link[^>]*?rel=["']stylesheet["'][^>]*?href=)["'])(?!\/?(?:.*\/)?htmx\.min\.js)(\/?(?:.*\/)?)([^./"']+)(?:\.[^."'/]+)?(\.(?:js|ts|css))(["'][^>]*>)/g;
1313
+ const tasks = htmlFiles.map(async (filePath) => {
1314
+ const original = await readFile(filePath, "utf8");
1315
+ const updated = original.replace(assetRegex, (match, prefix, dir, name, ext, suffix) => {
1316
+ const pascal = toPascal(name);
1317
+ let key;
1318
+ if (ext === ".css") {
1319
+ key = `${pascal}CSS`;
1320
+ } else if (dir.includes("/indexes/")) {
1321
+ key = `${pascal}Index`;
1322
+ } else {
1323
+ key = pascal;
1324
+ }
1325
+ const newPath = manifest[key];
1326
+ if (newPath) {
1327
+ if (ext === ".js" || ext === ".ts") {
1328
+ const hasTypeModule = /type\s*=\s*["']module["']/i.test(match);
1329
+ if (!hasTypeModule) {
1330
+ const newSuffix = suffix.replace(/>$/, ' type="module">');
1331
+ return `${prefix}${newPath}${newSuffix}`;
1332
+ }
1333
+ }
1334
+ return `${prefix}${newPath}${suffix}`;
1335
+ }
1336
+ console.error(`error: no manifest entry for ${ext.slice(1)} "${name}" referenced in ${filePath}`);
1337
+ return match;
1338
+ });
1339
+ await writeFile2(filePath, updated, "utf8");
1340
+ });
1341
+ await Promise.all(tasks);
1342
+ };
1343
+
1344
+ // src/dev/buildHMRClient.ts
1345
+ var {build: bunBuild } = globalThis.Bun;
1346
+ import { existsSync as existsSync4 } from "fs";
1347
+ import { join as join4, resolve as resolve4 } from "path";
1348
+ var devClientDir4 = (() => {
1349
+ const fromSource = resolve4(import.meta.dir, "client");
1350
+ if (existsSync4(fromSource))
1351
+ return fromSource;
1352
+ return resolve4(import.meta.dir, "dev/client");
1353
+ })();
1354
+ var buildHMRClient = async () => {
1355
+ const entryPoint = join4(devClientDir4, "hmrClient.ts");
1356
+ const result = await bunBuild({
1357
+ entrypoints: [entryPoint],
1358
+ format: "iife",
1359
+ minify: false,
1360
+ target: "browser"
1361
+ });
1362
+ if (!result.success) {
1363
+ console.error("Failed to build HMR client:", result.logs);
1364
+ return "// HMR client build failed";
1365
+ }
1366
+ return await result.outputs[0].text();
1367
+ };
1368
+
1369
+ // src/build/rewriteReactImports.ts
1370
+ var escapeRegex = (str) => str.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
1371
+ var rewriteReactImports = async (outputPaths, vendorPaths) => {
1372
+ const jsFiles = outputPaths.filter((path) => path.endsWith(".js"));
1373
+ if (jsFiles.length === 0)
1374
+ return;
1375
+ const replacements = Object.entries(vendorPaths).sort(([keyA], [keyB]) => keyB.length - keyA.length);
1376
+ for (const filePath of jsFiles) {
1377
+ let content = await Bun.file(filePath).text();
1378
+ let modified = false;
1379
+ for (const [specifier, webPath] of replacements) {
1380
+ const escaped = escapeRegex(specifier);
1381
+ const fromRegex = new RegExp(`(from\\s*["'])${escaped}(["'])`, "g");
1382
+ const newContent = content.replace(fromRegex, `$1${webPath}$2`);
1383
+ if (newContent !== content) {
1384
+ content = newContent;
1385
+ modified = true;
1386
+ }
1387
+ const dynamicRegex = new RegExp(`(import\\s*\\(\\s*["'])${escaped}(["']\\s*\\))`, "g");
1388
+ const newContent2 = content.replace(dynamicRegex, `$1${webPath}$2`);
1389
+ if (newContent2 !== content) {
1390
+ content = newContent2;
1391
+ modified = true;
1392
+ }
1393
+ }
1394
+ if (modified) {
1395
+ await Bun.write(filePath, content);
1396
+ }
1397
+ }
1398
+ };
1399
+
1400
+ // src/core/devVendorPaths.ts
1401
+ var devVendorPaths = null;
1402
+ var setDevVendorPaths = (paths) => {
1403
+ devVendorPaths = paths;
1404
+ };
1405
+ var getDevVendorPaths = () => devVendorPaths;
1406
+
1407
+ // src/utils/cleanup.ts
1408
+ import { rm as rm2 } from "fs/promises";
1409
+ import { join as join5 } from "path";
1410
+ var cleanup = async ({
1411
+ svelteDir,
1412
+ vueDir,
1413
+ reactIndexesPath
1414
+ }) => {
1415
+ if (svelteDir) {
1416
+ await rm2(join5(svelteDir, "compiled"), { force: true, recursive: true });
1417
+ }
1418
+ if (vueDir) {
1419
+ await rm2(join5(vueDir, "compiled"), { force: true, recursive: true });
1420
+ }
1421
+ if (reactIndexesPath)
1422
+ await rm2(reactIndexesPath, { force: true, recursive: true });
1423
+ };
1424
+
1425
+ // src/utils/commonAncestor.ts
1426
+ var commonAncestor = (paths, fallback) => {
1427
+ if (paths.length === 0)
1428
+ return fallback;
1429
+ const segmentsList = paths.map((p) => normalizePath(p).split("/"));
1430
+ const [first] = segmentsList;
1431
+ if (!first)
1432
+ return fallback;
1433
+ const commonSegments = first.filter((segment, index) => segmentsList.every((pathSegs) => pathSegs[index] === segment));
1434
+ return commonSegments.length ? commonSegments.join("/") : fallback;
1435
+ };
1436
+
1437
+ // src/utils/getDurationString.ts
1438
+ init_constants();
1439
+ var getDurationString = (duration) => {
1440
+ let durationString;
1441
+ if (duration < MILLISECONDS_IN_A_SECOND) {
1442
+ durationString = `${duration.toFixed(TIME_PRECISION)}ms`;
1443
+ } else if (duration < MILLISECONDS_IN_A_MINUTE) {
1444
+ durationString = `${(duration / MILLISECONDS_IN_A_SECOND).toFixed(TIME_PRECISION)}s`;
1445
+ } else {
1446
+ durationString = `${(duration / MILLISECONDS_IN_A_MINUTE).toFixed(TIME_PRECISION)}m`;
1447
+ }
1448
+ return durationString;
1449
+ };
1450
+
1451
+ // src/utils/logger.ts
1452
+ var colors = {
1453
+ reset: "\x1B[0m",
1454
+ bold: "\x1B[1m",
1455
+ dim: "\x1B[2m",
1456
+ cyan: "\x1B[36m",
1457
+ green: "\x1B[32m",
1458
+ yellow: "\x1B[33m",
1459
+ red: "\x1B[31m",
1460
+ blue: "\x1B[34m",
1461
+ magenta: "\x1B[35m",
1462
+ white: "\x1B[37m"
1463
+ };
1464
+ var frameworkColors = {
1465
+ react: colors.blue,
1466
+ vue: colors.green,
1467
+ svelte: colors.yellow,
1468
+ angular: colors.magenta,
1469
+ html: colors.white,
1470
+ htmx: colors.white,
1471
+ css: colors.cyan,
1472
+ assets: colors.dim
1473
+ };
1474
+ var formatTimestamp = () => {
1475
+ const now = new Date;
1476
+ let hours = now.getHours();
1477
+ const minutes = now.getMinutes().toString().padStart(2, "0");
1478
+ const seconds = now.getSeconds().toString().padStart(2, "0");
1479
+ const ampm = hours >= 12 ? "PM" : "AM";
1480
+ hours = hours % 12 || 12;
1481
+ return `${hours}:${minutes}:${seconds} ${ampm}`;
1482
+ };
1483
+ var formatPath = (filePath) => {
1484
+ const cwd = process.cwd();
1485
+ let relative3 = filePath.startsWith(cwd) ? filePath.slice(cwd.length + 1) : filePath;
1486
+ relative3 = relative3.replace(/\\/g, "/");
1487
+ if (!relative3.startsWith("/")) {
1488
+ relative3 = "/" + relative3;
1489
+ }
1490
+ return relative3;
1491
+ };
1492
+ var getFrameworkColor = (framework) => {
1493
+ return frameworkColors[framework] || colors.white;
1494
+ };
1495
+ var log = (action, options) => {
1496
+ const timestamp = `${colors.dim}${formatTimestamp()}${colors.reset}`;
1497
+ const tag = `${colors.cyan}[hmr]${colors.reset}`;
1498
+ let message = action;
1499
+ if (options?.path) {
1500
+ const pathColor = options.framework ? getFrameworkColor(options.framework) : colors.white;
1501
+ message += ` ${pathColor}${formatPath(options.path)}${colors.reset}`;
1502
+ }
1503
+ if (options?.duration !== undefined) {
1504
+ message += ` ${colors.dim}(${options.duration}ms)${colors.reset}`;
1505
+ }
1506
+ console.log(`${timestamp} ${tag} ${message}`);
1507
+ };
1508
+ var logError = (message, error) => {
1509
+ const timestamp = `${colors.dim}${formatTimestamp()}${colors.reset}`;
1510
+ const tag = `${colors.red}[hmr]${colors.reset}`;
1511
+ const errorMsg = error instanceof Error ? error.message : error;
1512
+ const fullMessage = `${colors.red}error${colors.reset} ${message}${errorMsg ? `: ${errorMsg}` : ""}`;
1513
+ console.error(`${timestamp} ${tag} ${fullMessage}`);
1514
+ };
1515
+ var logWarn = (message) => {
1516
+ const timestamp = `${colors.dim}${formatTimestamp()}${colors.reset}`;
1517
+ const tag = `${colors.yellow}[hmr]${colors.reset}`;
1518
+ console.warn(`${timestamp} ${tag} ${colors.yellow}warning${colors.reset} ${message}`);
1519
+ };
1520
+ var startupBanner = (options) => {
1521
+ const { version, duration, port, host, networkUrl } = options;
1522
+ const name = `${colors.cyan}${colors.bold}ABSOLUTEJS${colors.reset}`;
1523
+ const ver = `${colors.dim}v${version}${colors.reset}`;
1524
+ const time = `${colors.dim}ready in${colors.reset} ${colors.bold}${getDurationString(duration)}${colors.reset}`;
1525
+ console.log("");
1526
+ console.log(` ${name} ${ver} ${time}`);
1527
+ console.log("");
1528
+ console.log(` ${colors.green}\u279C${colors.reset} ${colors.bold}Local:${colors.reset} http://${host === "0.0.0.0" ? "localhost" : host}:${port}/`);
1529
+ if (networkUrl) {
1530
+ console.log(` ${colors.green}\u279C${colors.reset} ${colors.bold}Network:${colors.reset} ${networkUrl}`);
1531
+ }
1532
+ console.log("");
1533
+ };
1534
+ var logger = {
1535
+ hmrUpdate(path, framework, duration) {
1536
+ log("hmr update", { path, framework, duration });
1537
+ },
1538
+ pageReload(path, framework, duration) {
1539
+ log("page reload", { path, framework, duration });
1540
+ },
1541
+ cssUpdate(path, framework, duration) {
1542
+ log("css update", { path, framework: framework ?? "css", duration });
1543
+ },
1544
+ scriptUpdate(path, framework, duration) {
1545
+ log("script update", { path, framework, duration });
1546
+ },
1547
+ error(message, error) {
1548
+ logError(message, error);
1549
+ },
1550
+ warn(message) {
1551
+ logWarn(message);
1552
+ },
1553
+ info(message) {
1554
+ log(message);
1555
+ },
1556
+ serverReload() {
1557
+ log(`${colors.cyan}server module reloaded${colors.reset}`);
1558
+ },
1559
+ ready: startupBanner
1560
+ };
1561
+ // src/utils/validateSafePath.ts
1562
+ import { resolve as resolve5, relative as relative3 } from "path";
1563
+ var validateSafePath = (targetPath, baseDirectory) => {
1564
+ const absoluteBase = resolve5(baseDirectory);
1565
+ const absoluteTarget = resolve5(baseDirectory, targetPath);
1566
+ const relativePath = normalizePath(relative3(absoluteBase, absoluteTarget));
1567
+ if (relativePath.startsWith("../") || relativePath === "..") {
1568
+ throw new Error(`Unsafe path: ${targetPath}`);
1569
+ }
1570
+ return absoluteTarget;
1571
+ };
1572
+
1573
+ // src/core/build.ts
1574
+ var isDev = env2.NODE_ENV === "development";
1575
+ var vueFeatureFlags = {
1576
+ __VUE_OPTIONS_API__: "true",
1577
+ __VUE_PROD_DEVTOOLS__: isDev ? "true" : "false",
1578
+ __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: isDev ? "true" : "false"
1579
+ };
1580
+ var build2 = async ({
1581
+ buildDirectory = "build",
1582
+ assetsDirectory,
1583
+ publicDirectory,
1584
+ reactDirectory,
1585
+ htmlDirectory,
1586
+ htmxDirectory,
1587
+ angularDirectory,
1588
+ svelteDirectory,
1589
+ vueDirectory,
1590
+ tailwind,
1591
+ options,
1592
+ incrementalFiles
1593
+ }) => {
1594
+ const buildStart = performance.now();
1595
+ const projectRoot = cwd();
1596
+ const isIncremental = incrementalFiles && incrementalFiles.length > 0;
1597
+ const normalizedIncrementalFiles = incrementalFiles?.map(normalizePath);
1598
+ const throwOnError = options?.throwOnError === true;
1599
+ const hmr = options?.injectHMR === true;
1600
+ const buildPath = validateSafePath(buildDirectory, projectRoot);
1601
+ const assetsPath = assetsDirectory && validateSafePath(assetsDirectory, projectRoot);
1602
+ const reactDir = reactDirectory && validateSafePath(reactDirectory, projectRoot);
1603
+ const htmlDir = htmlDirectory && validateSafePath(htmlDirectory, projectRoot);
1604
+ const htmxDir = htmxDirectory && validateSafePath(htmxDirectory, projectRoot);
1605
+ const svelteDir = svelteDirectory && validateSafePath(svelteDirectory, projectRoot);
1606
+ const vueDir = vueDirectory && validateSafePath(vueDirectory, projectRoot);
1607
+ const angularDir = angularDirectory && validateSafePath(angularDirectory, projectRoot);
1608
+ const reactIndexesPath = reactDir && join6(reactDir, "indexes");
1609
+ const reactPagesPath = reactDir && join6(reactDir, "pages");
1610
+ const htmlPagesPath = htmlDir && join6(htmlDir, "pages");
1611
+ const htmlScriptsPath = htmlDir && join6(htmlDir, "scripts");
1612
+ const sveltePagesPath = svelteDir && join6(svelteDir, "pages");
1613
+ const vuePagesPath = vueDir && join6(vueDir, "pages");
1614
+ const htmxPagesPath = htmxDir && join6(htmxDir, "pages");
1615
+ const angularPagesPath = angularDir && join6(angularDir, "pages");
1616
+ const frontends = [
1617
+ reactDir,
1618
+ htmlDir,
1619
+ htmxDir,
1620
+ svelteDir,
1621
+ vueDir,
1622
+ angularDir
1623
+ ].filter(Boolean);
1624
+ const isSingle = frontends.length === 1;
1625
+ const clientRoots = [
1626
+ reactDir,
1627
+ svelteDir,
1628
+ htmlDir,
1629
+ vueDir,
1630
+ angularDir
1631
+ ].filter((dir) => Boolean(dir));
1632
+ const clientRoot = isSingle ? clientRoots[0] ?? projectRoot : commonAncestor(clientRoots, projectRoot);
1633
+ let serverOutDir;
1634
+ if (svelteDir)
1635
+ serverOutDir = join6(buildPath, basename4(svelteDir), "pages");
1636
+ else if (vueDir)
1637
+ serverOutDir = join6(buildPath, basename4(vueDir), "pages");
1638
+ let serverRoot;
1639
+ if (sveltePagesPath)
1640
+ serverRoot = sveltePagesPath;
1641
+ else if (vuePagesPath)
1642
+ serverRoot = vuePagesPath;
1643
+ const publicPath = publicDirectory && validateSafePath(publicDirectory, projectRoot);
1644
+ if (!isIncremental) {
1645
+ await rm3(buildPath, { force: true, recursive: true });
1646
+ }
1647
+ mkdirSync(buildPath, { recursive: true });
1648
+ if (publicPath)
1649
+ cpSync(publicPath, buildPath, { force: true, recursive: true });
1650
+ const filterToIncrementalEntries = (entryPoints, mapToSource) => {
1651
+ if (!isIncremental || !incrementalFiles)
1652
+ return entryPoints;
1653
+ const normalizedIncremental = new Set(incrementalFiles.map((f) => resolve6(f)));
1654
+ const matchingEntries = [];
1655
+ for (const entry of entryPoints) {
1656
+ const sourceFile = mapToSource(entry);
1657
+ if (sourceFile && normalizedIncremental.has(resolve6(sourceFile))) {
1658
+ matchingEntries.push(entry);
1659
+ }
1660
+ }
1661
+ return matchingEntries;
1662
+ };
1663
+ if (reactIndexesPath && reactPagesPath) {
1664
+ await generateReactIndexFiles(reactPagesPath, reactIndexesPath, hmr);
1665
+ }
1666
+ if (assetsPath && (!isIncremental || normalizedIncrementalFiles?.some((f) => f.includes("/assets/")))) {
1667
+ cpSync(assetsPath, join6(buildPath, "assets"), {
1668
+ force: true,
1669
+ recursive: true
1670
+ });
1671
+ }
1672
+ if (tailwind && (!isIncremental || normalizedIncrementalFiles?.some((f) => f.endsWith(".css")))) {
1673
+ await $`bunx @tailwindcss/cli -i ${tailwind.input} -o ${join6(buildPath, tailwind.output)}`;
1674
+ }
1675
+ const allReactEntries = reactIndexesPath ? await scanEntryPoints(reactIndexesPath, "*.tsx") : [];
1676
+ const allHtmlEntries = htmlScriptsPath ? await scanEntryPoints(htmlScriptsPath, "*.{js,ts}") : [];
1677
+ const allSvelteEntries = sveltePagesPath ? await scanEntryPoints(sveltePagesPath, "*.svelte") : [];
1678
+ const allVueEntries = vuePagesPath ? await scanEntryPoints(vuePagesPath, "*.vue") : [];
1679
+ const allAngularEntries = angularPagesPath ? await scanEntryPoints(angularPagesPath, "*.ts") : [];
1680
+ const allHtmlCssEntries = htmlDir ? await scanEntryPoints(join6(htmlDir, "styles"), "*.css") : [];
1681
+ const allHtmxCssEntries = htmxDir ? await scanEntryPoints(join6(htmxDir, "styles"), "*.css") : [];
1682
+ const allReactCssEntries = reactDir ? await scanEntryPoints(join6(reactDir, "styles"), "*.css") : [];
1683
+ const allSvelteCssEntries = svelteDir ? await scanEntryPoints(join6(svelteDir, "styles"), "*.css") : [];
1684
+ const shouldIncludeHtmlAssets = !isIncremental || normalizedIncrementalFiles?.some((f) => f.includes("/html/") && (f.endsWith(".html") || f.endsWith(".css")));
1685
+ const shouldIncludeHtmxAssets = !isIncremental || normalizedIncrementalFiles?.some((f) => f.includes("/htmx/") && (f.endsWith(".html") || f.endsWith(".css")));
1686
+ const reactEntries = isIncremental && reactIndexesPath && reactPagesPath ? filterToIncrementalEntries(allReactEntries, (entry) => {
1687
+ if (entry.startsWith(resolve6(reactIndexesPath))) {
1688
+ const pageName = basename4(entry, ".tsx");
1689
+ return join6(reactPagesPath, `${pageName}.tsx`);
1690
+ }
1691
+ return null;
1692
+ }) : allReactEntries;
1693
+ const htmlEntries = isIncremental && htmlScriptsPath && !shouldIncludeHtmlAssets ? filterToIncrementalEntries(allHtmlEntries, (entry) => entry) : allHtmlEntries;
1694
+ const svelteEntries = isIncremental ? filterToIncrementalEntries(allSvelteEntries, (entry) => entry) : allSvelteEntries;
1695
+ const vueEntries = isIncremental ? filterToIncrementalEntries(allVueEntries, (entry) => entry) : allVueEntries;
1696
+ const angularEntries = isIncremental ? filterToIncrementalEntries(allAngularEntries, (entry) => entry) : allAngularEntries;
1697
+ const htmlCssEntries = isIncremental && !shouldIncludeHtmlAssets ? filterToIncrementalEntries(allHtmlCssEntries, (entry) => entry) : allHtmlCssEntries;
1698
+ const htmxCssEntries = isIncremental && !shouldIncludeHtmxAssets ? filterToIncrementalEntries(allHtmxCssEntries, (entry) => entry) : allHtmxCssEntries;
1699
+ const reactCssEntries = isIncremental ? filterToIncrementalEntries(allReactCssEntries, (entry) => entry) : allReactCssEntries;
1700
+ const svelteCssEntries = isIncremental ? filterToIncrementalEntries(allSvelteCssEntries, (entry) => entry) : allSvelteCssEntries;
1701
+ const { svelteServerPaths, svelteIndexPaths, svelteClientPaths } = svelteDir ? await compileSvelte(svelteEntries, svelteDir, new Map, hmr) : {
1702
+ svelteClientPaths: [],
1703
+ svelteIndexPaths: [],
1704
+ svelteServerPaths: []
1705
+ };
1706
+ const { vueServerPaths, vueIndexPaths, vueClientPaths, vueCssPaths } = vueDir ? await compileVue(vueEntries, vueDir, hmr) : {
1707
+ vueClientPaths: [],
1708
+ vueCssPaths: [],
1709
+ vueIndexPaths: [],
1710
+ vueServerPaths: []
1711
+ };
1712
+ const serverEntryPoints = [...svelteServerPaths, ...vueServerPaths];
1713
+ const reactClientEntryPoints = [...reactEntries];
1714
+ const nonReactClientEntryPoints = [
1715
+ ...svelteIndexPaths,
1716
+ ...svelteClientPaths,
1717
+ ...htmlEntries,
1718
+ ...vueIndexPaths,
1719
+ ...vueClientPaths
1720
+ ];
1721
+ const cssEntryPoints = [
1722
+ ...vueCssPaths,
1723
+ ...reactCssEntries,
1724
+ ...svelteCssEntries,
1725
+ ...htmlCssEntries,
1726
+ ...htmxCssEntries
1727
+ ];
1728
+ if (serverEntryPoints.length === 0 && reactClientEntryPoints.length === 0 && nonReactClientEntryPoints.length === 0 && htmxDir === undefined && htmlDir === undefined) {
1729
+ logger.warn("No entry points found, manifest will be empty");
1730
+ return {};
1731
+ }
1732
+ let serverLogs = [];
1733
+ let serverOutputs = [];
1734
+ if (serverEntryPoints.length > 0) {
1735
+ const result = await bunBuild2({
1736
+ entrypoints: serverEntryPoints,
1737
+ format: "esm",
1738
+ naming: `[dir]/[name].[hash].[ext]`,
1739
+ outdir: serverOutDir,
1740
+ root: serverRoot,
1741
+ target: "bun",
1742
+ throw: false
1743
+ });
1744
+ serverLogs = result.logs;
1745
+ serverOutputs = result.outputs;
1746
+ if (!result.success && result.logs.length > 0) {
1747
+ const errLog = result.logs.find((l) => l.level === "error") ?? result.logs[0];
1748
+ const err = new Error(typeof errLog.message === "string" ? errLog.message : String(errLog.message));
1749
+ err.logs = result.logs;
1750
+ logger.error("Server build failed", err);
1751
+ if (throwOnError)
1752
+ throw err;
1753
+ exit(1);
1754
+ }
1755
+ }
1756
+ let reactClientLogs = [];
1757
+ let reactClientOutputs = [];
1758
+ if (hmr && reactIndexesPath && reactClientEntryPoints.length > 0) {
1759
+ const refreshEntry = join6(reactIndexesPath, "_refresh.tsx");
1760
+ if (!reactClientEntryPoints.includes(refreshEntry)) {
1761
+ reactClientEntryPoints.push(refreshEntry);
1762
+ }
1763
+ }
1764
+ const vendorPaths = getDevVendorPaths();
1765
+ if (reactClientEntryPoints.length > 0) {
1766
+ const reactBuildConfig = {
1767
+ entrypoints: reactClientEntryPoints,
1768
+ format: "esm",
1769
+ minify: !isDev,
1770
+ naming: `[dir]/[name].[hash].[ext]`,
1771
+ outdir: buildPath,
1772
+ root: clientRoot,
1773
+ splitting: true,
1774
+ target: "browser",
1775
+ throw: false
1776
+ };
1777
+ if (vendorPaths) {
1778
+ reactBuildConfig.external = Object.keys(vendorPaths);
1779
+ }
1780
+ if (hmr) {
1781
+ reactBuildConfig.reactFastRefresh = true;
1782
+ }
1783
+ const reactClientResult = await bunBuild2(reactBuildConfig);
1784
+ reactClientLogs = reactClientResult.logs;
1785
+ reactClientOutputs = reactClientResult.outputs;
1786
+ if (!reactClientResult.success && reactClientResult.logs.length > 0) {
1787
+ const errLog = reactClientResult.logs.find((l) => l.level === "error") ?? reactClientResult.logs[0];
1788
+ const err = new Error(typeof errLog.message === "string" ? errLog.message : String(errLog.message));
1789
+ err.logs = reactClientResult.logs;
1790
+ logger.error("React client build failed", err);
1791
+ if (throwOnError)
1792
+ throw err;
1793
+ exit(1);
1794
+ }
1795
+ if (vendorPaths) {
1796
+ await rewriteReactImports(reactClientOutputs.map((artifact) => artifact.path), vendorPaths);
1797
+ }
1798
+ }
1799
+ let nonReactClientLogs = [];
1800
+ let nonReactClientOutputs = [];
1801
+ if (nonReactClientEntryPoints.length > 0) {
1802
+ const htmlScriptPlugin = hmr ? createHTMLScriptHMRPlugin(htmlDir, htmxDir) : undefined;
1803
+ const nonReactClientResult = await bunBuild2({
1804
+ define: vueDirectory ? vueFeatureFlags : undefined,
1805
+ entrypoints: nonReactClientEntryPoints,
1806
+ format: "esm",
1807
+ minify: !isDev,
1808
+ naming: `[dir]/[name].[hash].[ext]`,
1809
+ outdir: buildPath,
1810
+ plugins: htmlScriptPlugin ? [htmlScriptPlugin] : undefined,
1811
+ root: clientRoot,
1812
+ target: "browser",
1813
+ splitting: !isDev,
1814
+ throw: false
1815
+ });
1816
+ nonReactClientLogs = nonReactClientResult.logs;
1817
+ nonReactClientOutputs = nonReactClientResult.outputs;
1818
+ if (!nonReactClientResult.success && nonReactClientResult.logs.length > 0) {
1819
+ const errLog = nonReactClientResult.logs.find((l) => l.level === "error") ?? nonReactClientResult.logs[0];
1820
+ const err = new Error(typeof errLog.message === "string" ? errLog.message : String(errLog.message));
1821
+ err.logs = nonReactClientResult.logs;
1822
+ logger.error("Non-React client build failed", err);
1823
+ if (throwOnError)
1824
+ throw err;
1825
+ exit(1);
1826
+ }
1827
+ }
1828
+ let cssLogs = [];
1829
+ let cssOutputs = [];
1830
+ if (cssEntryPoints.length > 0) {
1831
+ const cssResult = await bunBuild2({
1832
+ entrypoints: cssEntryPoints,
1833
+ naming: `[name].[hash].[ext]`,
1834
+ outdir: join6(buildPath, assetsPath ? basename4(assetsPath) : "assets", "css"),
1835
+ target: "browser",
1836
+ throw: false
1837
+ });
1838
+ cssLogs = cssResult.logs;
1839
+ cssOutputs = cssResult.outputs;
1840
+ if (!cssResult.success && cssResult.logs.length > 0) {
1841
+ const errLog = cssResult.logs.find((l) => l.level === "error") ?? cssResult.logs[0];
1842
+ const err = new Error(typeof errLog.message === "string" ? errLog.message : String(errLog.message));
1843
+ err.logs = cssResult.logs;
1844
+ logger.error("CSS build failed", err);
1845
+ if (throwOnError)
1846
+ throw err;
1847
+ exit(1);
1848
+ }
1849
+ }
1850
+ const allLogs = [
1851
+ ...serverLogs,
1852
+ ...reactClientLogs,
1853
+ ...nonReactClientLogs,
1854
+ ...cssLogs
1855
+ ];
1856
+ outputLogs(allLogs);
1857
+ const manifest = generateManifest([
1858
+ ...serverOutputs,
1859
+ ...reactClientOutputs,
1860
+ ...nonReactClientOutputs,
1861
+ ...cssOutputs
1862
+ ], buildPath);
1863
+ for (const artifact of serverOutputs) {
1864
+ const fileWithHash = basename4(artifact.path);
1865
+ const [baseName] = fileWithHash.split(`.${artifact.hash}.`);
1866
+ if (!baseName)
1867
+ continue;
1868
+ manifest[toPascal(baseName)] = artifact.path;
1869
+ }
1870
+ const htmlOrHtmlCssChanged = !isIncremental || normalizedIncrementalFiles?.some((f) => f.includes("/html/") && (f.endsWith(".html") || f.endsWith(".css")));
1871
+ const htmxOrHtmxCssChanged = !isIncremental || normalizedIncrementalFiles?.some((f) => f.includes("/htmx/") && (f.endsWith(".html") || f.endsWith(".css")));
1872
+ const shouldCopyHtml = htmlOrHtmlCssChanged;
1873
+ const shouldCopyHtmx = htmxOrHtmxCssChanged;
1874
+ const shouldUpdateHtmlAssetPaths = !isIncremental || normalizedIncrementalFiles?.some((f) => f.includes("/html/") && (f.endsWith(".html") || f.endsWith(".css")));
1875
+ const shouldUpdateHtmxAssetPaths = !isIncremental || normalizedIncrementalFiles?.some((f) => f.includes("/htmx/") && (f.endsWith(".html") || f.endsWith(".css")));
1876
+ const hmrClientBundle = hmr && (htmlDir || htmxDir) ? await buildHMRClient() : null;
1877
+ const injectHMRIntoHTMLFile = (filePath, framework) => {
1878
+ if (!hmrClientBundle)
1879
+ return;
1880
+ let html = readFileSync(filePath, "utf-8");
1881
+ if (html.includes("data-hmr-client"))
1882
+ return;
1883
+ const tag = `<script>window.__HMR_FRAMEWORK__="${framework}";</script>` + `<script data-hmr-client>${hmrClientBundle}</script>`;
1884
+ const bodyClose = /<\/body\s*>/i.exec(html);
1885
+ html = bodyClose ? html.slice(0, bodyClose.index) + tag + html.slice(bodyClose.index) : html + tag;
1886
+ writeFileSync(filePath, html);
1887
+ };
1888
+ if (htmlDir && htmlPagesPath) {
1889
+ const outputHtmlPages = isSingle ? join6(buildPath, "pages") : join6(buildPath, basename4(htmlDir), "pages");
1890
+ if (shouldCopyHtml) {
1891
+ mkdirSync(outputHtmlPages, { recursive: true });
1892
+ cpSync(htmlPagesPath, outputHtmlPages, {
1893
+ force: true,
1894
+ recursive: true
1895
+ });
1896
+ }
1897
+ if (shouldUpdateHtmlAssetPaths) {
1898
+ await updateAssetPaths(manifest, outputHtmlPages);
1899
+ }
1900
+ const htmlPageFiles = await scanEntryPoints(outputHtmlPages, "*.html");
1901
+ for (const htmlFile of htmlPageFiles) {
1902
+ if (hmr)
1903
+ injectHMRIntoHTMLFile(htmlFile, "html");
1904
+ const fileName = basename4(htmlFile, ".html");
1905
+ manifest[fileName] = htmlFile;
1906
+ }
1907
+ }
1908
+ if (htmxDir && htmxPagesPath) {
1909
+ const outputHtmxPages = isSingle ? join6(buildPath, "pages") : join6(buildPath, basename4(htmxDir), "pages");
1910
+ if (shouldCopyHtmx) {
1911
+ mkdirSync(outputHtmxPages, { recursive: true });
1912
+ cpSync(htmxPagesPath, outputHtmxPages, {
1913
+ force: true,
1914
+ recursive: true
1915
+ });
1916
+ }
1917
+ if (shouldCopyHtmx) {
1918
+ const htmxDestDir = isSingle ? buildPath : join6(buildPath, basename4(htmxDir));
1919
+ mkdirSync(htmxDestDir, { recursive: true });
1920
+ const glob = new Glob3("htmx*.min.js");
1921
+ for (const relPath of glob.scanSync({ cwd: htmxDir })) {
1922
+ const src = join6(htmxDir, relPath);
1923
+ const dest = join6(htmxDestDir, "htmx.min.js");
1924
+ copyFileSync(src, dest);
1925
+ break;
1926
+ }
1927
+ }
1928
+ if (shouldUpdateHtmxAssetPaths) {
1929
+ await updateAssetPaths(manifest, outputHtmxPages);
1930
+ }
1931
+ const htmxPageFiles = await scanEntryPoints(outputHtmxPages, "*.html");
1932
+ for (const htmxFile of htmxPageFiles) {
1933
+ if (hmr)
1934
+ injectHMRIntoHTMLFile(htmxFile, "htmx");
1935
+ const fileName = basename4(htmxFile, ".html");
1936
+ manifest[fileName] = htmxFile;
1937
+ }
1938
+ }
1939
+ if (!options?.preserveIntermediateFiles)
1940
+ await cleanup({
1941
+ reactIndexesPath,
1942
+ svelteDir,
1943
+ vueDir
1944
+ });
1945
+ if (!isIncremental && !options?.injectHMR) {
1946
+ console.log(`Build completed in ${getDurationString(performance.now() - buildStart)}`);
1947
+ }
1948
+ return manifest;
1949
+ };
1950
+ // src/core/devBuild.ts
1951
+ import { readdir as readdir2 } from "fs/promises";
1952
+ import { statSync } from "fs";
1953
+ import { resolve as resolve18 } from "path";
1954
+
1955
+ // src/build/buildReactVendor.ts
1956
+ import { mkdirSync as mkdirSync2 } from "fs";
1957
+ import { join as join7 } from "path";
1958
+ import { rm as rm4 } from "fs/promises";
1959
+ var {build: bunBuild3 } = globalThis.Bun;
1960
+ var reactSpecifiers = [
1961
+ "react",
1962
+ "react-dom",
1963
+ "react-dom/client",
1964
+ "react/jsx-runtime",
1965
+ "react/jsx-dev-runtime"
1966
+ ];
1967
+ var toSafeFileName = (specifier) => specifier.replace(/\//g, "_");
1968
+ var computeVendorPaths = () => {
1969
+ const paths = {};
1970
+ for (const specifier of reactSpecifiers) {
1971
+ paths[specifier] = `/react/vendor/${toSafeFileName(specifier)}.js`;
1972
+ }
1973
+ return paths;
1974
+ };
1975
+ var generateEntrySource = async (specifier) => {
1976
+ const mod = await import(specifier);
1977
+ const exportNames = Object.keys(mod).filter((key) => key !== "default" && key !== "__esModule");
1978
+ const lines = [];
1979
+ if (exportNames.length > 0) {
1980
+ lines.push(`export { ${exportNames.join(", ")} } from '${specifier}';`);
1981
+ }
1982
+ if ("default" in mod) {
1983
+ lines.push(`export { default } from '${specifier}';`);
1984
+ }
1985
+ return lines.join(`
1986
+ `) + `
1987
+ `;
1988
+ };
1989
+ var buildReactVendor = async (buildDir) => {
1990
+ const vendorDir = join7(buildDir, "react", "vendor");
1991
+ mkdirSync2(vendorDir, { recursive: true });
1992
+ const tmpDir = join7(buildDir, "_vendor_tmp");
1993
+ mkdirSync2(tmpDir, { recursive: true });
1994
+ const entrypoints = [];
1995
+ for (const specifier of reactSpecifiers) {
1996
+ const safeName = toSafeFileName(specifier);
1997
+ const entryPath = join7(tmpDir, `${safeName}.ts`);
1998
+ const source = await generateEntrySource(specifier);
1999
+ await Bun.write(entryPath, source);
2000
+ entrypoints.push(entryPath);
2001
+ }
2002
+ const result = await bunBuild3({
2003
+ entrypoints,
2004
+ format: "esm",
2005
+ minify: false,
2006
+ naming: "[name].[ext]",
2007
+ outdir: vendorDir,
2008
+ splitting: true,
2009
+ target: "browser",
2010
+ throw: false
2011
+ });
2012
+ await rm4(tmpDir, { force: true, recursive: true });
2013
+ if (!result.success) {
2014
+ console.warn("\u26A0\uFE0F React vendor build had errors:", result.logs);
2015
+ }
2016
+ };
2017
+
2018
+ // src/dev/dependencyGraph.ts
2019
+ import { readFileSync as readFileSync2, readdirSync, existsSync as existsSync5 } from "fs";
2020
+ import { resolve as resolve7 } from "path";
2021
+ var createDependencyGraph = () => ({
2022
+ dependencies: new Map,
2023
+ dependents: new Map
2024
+ });
2025
+ var extractDependencies = (filePath) => {
2026
+ try {
2027
+ if (!existsSync5(filePath)) {
2028
+ return [];
2029
+ }
2030
+ const content = readFileSync2(filePath, "utf-8");
2031
+ const dependencies = [];
2032
+ const lowerPath = filePath.toLowerCase();
2033
+ const isHtml = lowerPath.endsWith(".html") || lowerPath.endsWith(".htm");
2034
+ if (isHtml) {
2035
+ const linkRegex = /<link\s+[^>]*rel=["']stylesheet["'][^>]*href=["']([^"']+)["'][^>]*>/gi;
2036
+ let matchLink;
2037
+ while ((matchLink = linkRegex.exec(content)) !== null) {
2038
+ const href = matchLink[1];
2039
+ if (!href)
2040
+ continue;
2041
+ const resolvedHref = resolveImportPath(href, filePath);
2042
+ if (resolvedHref) {
2043
+ dependencies.push(resolvedHref);
2044
+ }
2045
+ }
2046
+ return dependencies;
2047
+ }
2048
+ const importRegex = /import\s+.*?\s+from\s+['"]([^'"]+)['"]/g;
2049
+ const importWithoutFromRegex = /import\s+['"]([^'"]+)['"]/g;
2050
+ const requireRegex = /require\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
2051
+ const dynamicImportRegex = /import\s*\(\s*['"]([^'"]+)['"]\s*\)/g;
2052
+ let match;
2053
+ while ((match = importRegex.exec(content)) !== null) {
2054
+ if (match[1]) {
2055
+ const resolved = resolveImportPath(match[1], filePath);
2056
+ if (resolved)
2057
+ dependencies.push(resolved);
2058
+ }
2059
+ }
2060
+ while ((match = importWithoutFromRegex.exec(content)) !== null) {
2061
+ if (match[1]) {
2062
+ const resolved = resolveImportPath(match[1], filePath);
2063
+ if (resolved)
2064
+ dependencies.push(resolved);
2065
+ }
2066
+ }
2067
+ while ((match = requireRegex.exec(content)) !== null) {
2068
+ if (match[1]) {
2069
+ const resolved = resolveImportPath(match[1], filePath);
2070
+ if (resolved)
2071
+ dependencies.push(resolved);
2072
+ }
2073
+ }
2074
+ while ((match = dynamicImportRegex.exec(content)) !== null) {
2075
+ if (match[1]) {
2076
+ const resolved = resolveImportPath(match[1], filePath);
2077
+ if (resolved)
2078
+ dependencies.push(resolved);
2079
+ }
2080
+ }
2081
+ return dependencies;
2082
+ } catch {
2083
+ return [];
2084
+ }
2085
+ };
2086
+ var resolveImportPath = (importPath, fromFile) => {
2087
+ if (!importPath.startsWith(".") && !importPath.startsWith("/")) {
2088
+ return null;
2089
+ }
2090
+ const fromDir = resolve7(fromFile, "..");
2091
+ const resolved = resolve7(fromDir, importPath);
2092
+ const normalized = resolve7(resolved);
2093
+ const extensions = [
2094
+ ".ts",
2095
+ ".tsx",
2096
+ ".js",
2097
+ ".jsx",
2098
+ ".vue",
2099
+ ".svelte",
2100
+ ".css",
2101
+ ".html"
2102
+ ];
2103
+ for (const ext of extensions) {
2104
+ const withExt = normalized + ext;
2105
+ try {
2106
+ readFileSync2(withExt);
2107
+ return normalized + ext;
2108
+ } catch {}
2109
+ }
2110
+ try {
2111
+ readFileSync2(normalized);
2112
+ return normalized;
2113
+ } catch {
2114
+ return null;
2115
+ }
2116
+ };
2117
+ var addFileToGraph = (graph, filePath) => {
2118
+ const normalizedPath = resolve7(filePath);
2119
+ if (!existsSync5(normalizedPath)) {
2120
+ return;
2121
+ }
2122
+ const dependencies = extractDependencies(normalizedPath);
2123
+ const existingDeps = graph.dependencies.get(normalizedPath);
2124
+ if (existingDeps) {
2125
+ for (const dep of existingDeps) {
2126
+ const dependents = graph.dependents.get(dep);
2127
+ if (dependents) {
2128
+ dependents.delete(normalizedPath);
2129
+ }
2130
+ }
2131
+ }
2132
+ const newDeps = new Set(dependencies);
2133
+ graph.dependencies.set(normalizedPath, newDeps);
2134
+ for (const dep of dependencies) {
2135
+ if (!graph.dependents.has(dep)) {
2136
+ graph.dependents.set(dep, new Set);
2137
+ }
2138
+ graph.dependents.get(dep).add(normalizedPath);
2139
+ }
2140
+ };
2141
+ var getAffectedFiles = (graph, changedFile) => {
2142
+ const normalizedPath = resolve7(changedFile);
2143
+ const affected = new Set;
2144
+ const toProcess = [normalizedPath];
2145
+ while (toProcess.length > 0) {
2146
+ const current = toProcess.pop();
2147
+ if (affected.has(current)) {
2148
+ continue;
2149
+ }
2150
+ affected.add(current);
2151
+ const dependents = graph.dependents.get(current);
2152
+ if (dependents) {
2153
+ for (const dependent of dependents) {
2154
+ toProcess.push(dependent);
2155
+ }
2156
+ }
2157
+ }
2158
+ return Array.from(affected);
2159
+ };
2160
+ var removeFileFromGraph = (graph, filePath) => {
2161
+ const normalizedPath = resolve7(filePath);
2162
+ const deps = graph.dependencies.get(normalizedPath);
2163
+ if (deps) {
2164
+ for (const dep of deps) {
2165
+ const dependents2 = graph.dependents.get(dep);
2166
+ if (dependents2) {
2167
+ dependents2.delete(normalizedPath);
2168
+ }
2169
+ }
2170
+ graph.dependencies.delete(normalizedPath);
2171
+ }
2172
+ const dependents = graph.dependents.get(normalizedPath);
2173
+ if (dependents) {
2174
+ for (const dependent of dependents) {
2175
+ const depList = graph.dependencies.get(dependent);
2176
+ if (depList) {
2177
+ depList.delete(normalizedPath);
2178
+ }
2179
+ }
2180
+ graph.dependents.delete(normalizedPath);
2181
+ }
2182
+ };
2183
+ var buildInitialDependencyGraph = (graph, directories) => {
2184
+ const processedFiles = new Set;
2185
+ const scanDirectory = (dir) => {
2186
+ const normalizedDir = resolve7(dir);
2187
+ try {
2188
+ const entries = readdirSync(normalizedDir, { withFileTypes: true });
2189
+ for (const entry of entries) {
2190
+ const fullPath = resolve7(normalizedDir, entry.name);
2191
+ if (fullPath.includes("/node_modules/") || fullPath.includes("/.git/") || fullPath.includes("/build/") || fullPath.includes("/compiled/") || fullPath.includes("/indexes/") || entry.name.startsWith(".")) {
2192
+ continue;
2193
+ }
2194
+ if (entry.isDirectory()) {
2195
+ scanDirectory(fullPath);
2196
+ } else if (entry.isFile()) {
2197
+ const ext = entry.name.split(".").pop()?.toLowerCase();
2198
+ if ([
2199
+ "ts",
2200
+ "tsx",
2201
+ "js",
2202
+ "jsx",
2203
+ "vue",
2204
+ "svelte",
2205
+ "html",
2206
+ "htm"
2207
+ ].includes(ext || "")) {
2208
+ if (!processedFiles.has(fullPath)) {
2209
+ addFileToGraph(graph, fullPath);
2210
+ processedFiles.add(fullPath);
2211
+ }
2212
+ }
2213
+ }
2214
+ }
2215
+ } catch {}
2216
+ };
2217
+ for (const dir of directories) {
2218
+ const resolvedDir = resolve7(dir);
2219
+ if (existsSync5(resolvedDir)) {
2220
+ scanDirectory(resolvedDir);
2221
+ }
2222
+ }
2223
+ };
2224
+
2225
+ // src/dev/moduleVersionTracker.ts
2226
+ var globalVersionCounter = 0;
2227
+ var getNextVersion = () => ++globalVersionCounter;
2228
+ var createModuleVersionTracker = () => new Map;
2229
+ var incrementModuleVersion = (versions, modulePath) => {
2230
+ const newVersion = getNextVersion();
2231
+ versions.set(modulePath, newVersion);
2232
+ return newVersion;
2233
+ };
2234
+ var incrementModuleVersions = (versions, modulePaths) => {
2235
+ const updated = new Map;
2236
+ for (const path of modulePaths) {
2237
+ const version = incrementModuleVersion(versions, path);
2238
+ updated.set(path, version);
2239
+ }
2240
+ return updated;
2241
+ };
2242
+ var serializeModuleVersions = (versions) => {
2243
+ const serialized = {};
2244
+ for (const [path, version] of versions.entries()) {
2245
+ serialized[path] = version;
2246
+ }
2247
+ return serialized;
2248
+ };
2249
+
2250
+ // src/dev/configResolver.ts
2251
+ import { resolve as resolve8 } from "path";
2252
+ var resolveBuildPaths = (config) => {
2253
+ const cwd2 = process.cwd();
2254
+ const normalize = (path) => path.replace(/\\/g, "/");
2255
+ const withDefault = (value, fallback) => normalize(resolve8(cwd2, value ?? fallback));
2256
+ const optional = (value) => value ? normalize(resolve8(cwd2, value)) : undefined;
2257
+ return {
2258
+ buildDir: withDefault(config.buildDirectory, "build"),
2259
+ assetsDir: optional(config.assetsDirectory),
2260
+ reactDir: optional(config.reactDirectory),
2261
+ svelteDir: optional(config.svelteDirectory),
2262
+ vueDir: optional(config.vueDirectory),
2263
+ angularDir: optional(config.angularDirectory),
2264
+ htmlDir: optional(config.htmlDirectory),
2265
+ htmxDir: optional(config.htmxDirectory)
2266
+ };
2267
+ };
2268
+
2269
+ // src/dev/clientManager.ts
2270
+ var createHMRState = (config) => ({
2271
+ connectedClients: new Set,
2272
+ debounceTimeout: null,
2273
+ dependencyGraph: createDependencyGraph(),
2274
+ fileChangeQueue: new Map,
2275
+ fileHashes: new Map,
2276
+ isRebuilding: false,
2277
+ moduleVersions: createModuleVersionTracker(),
2278
+ rebuildQueue: new Set,
2279
+ rebuildTimeout: null,
2280
+ sourceFileVersions: new Map,
2281
+ watchers: [],
2282
+ config,
2283
+ resolvedPaths: resolveBuildPaths(config),
2284
+ vueChangeTypes: new Map,
2285
+ assetStore: new Map
2286
+ });
2287
+ var incrementSourceFileVersion = (state, filePath) => {
2288
+ const currentVersion = state.sourceFileVersions.get(filePath) || 0;
2289
+ const newVersion = currentVersion + 1;
2290
+ state.sourceFileVersions.set(filePath, newVersion);
2291
+ return newVersion;
2292
+ };
2293
+ var incrementSourceFileVersions = (state, filePaths) => {
2294
+ for (const filePath of filePaths) {
2295
+ incrementSourceFileVersion(state, filePath);
2296
+ }
2297
+ };
2298
+
2299
+ // src/dev/fileWatcher.ts
2300
+ import { watch } from "fs";
2301
+ import { existsSync as existsSync6 } from "fs";
2302
+ import { join as join8, resolve as resolve9 } from "path";
2303
+
2304
+ // src/dev/pathUtils.ts
2305
+ var getWatchPaths = (config, resolved) => {
2306
+ const paths = [];
2307
+ const push = (base, sub) => {
2308
+ if (!base)
2309
+ return;
2310
+ const normalizedBase = normalizePath(base);
2311
+ paths.push(sub ? `${normalizedBase}/${sub}` : normalizedBase);
2312
+ };
2313
+ const cfg = resolved ?? {
2314
+ reactDir: config.reactDirectory,
2315
+ svelteDir: config.svelteDirectory,
2316
+ vueDir: config.vueDirectory,
2317
+ angularDir: config.angularDirectory,
2318
+ htmlDir: config.htmlDirectory,
2319
+ htmxDir: config.htmxDirectory,
2320
+ assetsDir: config.assetsDirectory
2321
+ };
2322
+ push(cfg.reactDir, "components");
2323
+ push(cfg.reactDir, "pages");
2324
+ push(cfg.reactDir, "styles");
2325
+ push(cfg.svelteDir, "components");
2326
+ push(cfg.svelteDir, "pages");
2327
+ push(cfg.svelteDir, "composables");
2328
+ push(cfg.svelteDir, "styles");
2329
+ push(cfg.vueDir, "components");
2330
+ push(cfg.vueDir, "pages");
2331
+ push(cfg.vueDir, "composables");
2332
+ push(cfg.vueDir, "styles");
2333
+ push(cfg.angularDir, "components");
2334
+ push(cfg.angularDir, "pages");
2335
+ push(cfg.angularDir, "styles");
2336
+ push(cfg.htmlDir, "pages");
2337
+ push(cfg.htmlDir, "scripts");
2338
+ push(cfg.htmlDir, "styles");
2339
+ push(cfg.htmxDir, "pages");
2340
+ push(cfg.htmxDir, "styles");
2341
+ push(cfg.assetsDir);
2342
+ return paths;
2343
+ };
2344
+ var shouldIgnorePath = (path) => {
2345
+ const normalizedPath = path.replace(/\\/g, "/");
2346
+ return normalizedPath.includes("/build/") || normalizedPath.includes("/compiled/") || normalizedPath.includes("/indexes/") || normalizedPath.includes("/node_modules/") || normalizedPath.includes("/.git/") || normalizedPath.endsWith(".log") || normalizedPath.endsWith(".tmp") || normalizedPath.startsWith(".") || normalizedPath === "compiled" || normalizedPath.endsWith("/compiled") || normalizedPath.endsWith("/compiled/");
2347
+ };
2348
+ var detectFramework = (filePath, resolved) => {
2349
+ if (shouldIgnorePath(filePath)) {
2350
+ return "ignored";
2351
+ }
2352
+ const normalized = filePath.replace(/\\/g, "/");
2353
+ const startsWithDir = (dir) => dir ? normalized.startsWith(dir.replace(/\\/g, "/")) : false;
2354
+ if (resolved) {
2355
+ if (startsWithDir(resolved.htmxDir))
2356
+ return "htmx";
2357
+ if (startsWithDir(resolved.reactDir))
2358
+ return "react";
2359
+ if (startsWithDir(resolved.svelteDir))
2360
+ return "svelte";
2361
+ if (startsWithDir(resolved.vueDir))
2362
+ return "vue";
2363
+ if (startsWithDir(resolved.angularDir))
2364
+ return "angular";
2365
+ if (startsWithDir(resolved.htmlDir))
2366
+ return "html";
2367
+ if (startsWithDir(resolved.assetsDir))
2368
+ return "assets";
2369
+ } else {
2370
+ if (normalized.includes("/htmx/"))
2371
+ return "htmx";
2372
+ if (normalized.includes("/react/"))
2373
+ return "react";
2374
+ if (normalized.includes("/svelte/"))
2375
+ return "svelte";
2376
+ if (normalized.includes("/vue/"))
2377
+ return "vue";
2378
+ if (normalized.includes("/angular/"))
2379
+ return "angular";
2380
+ if (normalized.includes("/html/"))
2381
+ return "html";
2382
+ }
2383
+ if (normalized.endsWith(".tsx") || normalized.endsWith(".jsx"))
2384
+ return "react";
2385
+ if (normalized.endsWith(".svelte"))
2386
+ return "svelte";
2387
+ if (normalized.endsWith(".vue"))
2388
+ return "vue";
2389
+ if (normalized.endsWith(".html"))
2390
+ return "html";
2391
+ if (normalized.endsWith(".ts") && normalized.includes("angular"))
2392
+ return "angular";
2393
+ if (normalized.includes("/assets/"))
2394
+ return "assets";
2395
+ if (normalized.endsWith(".css")) {
2396
+ if (normalized.includes("/vue/") || normalized.includes("/vue-"))
2397
+ return "vue";
2398
+ if (normalized.includes("/svelte/") || normalized.includes("/svelte-"))
2399
+ return "svelte";
2400
+ if (normalized.includes("/react/") || normalized.includes("/react-"))
2401
+ return "react";
2402
+ if (normalized.includes("/angular/") || normalized.includes("/angular-"))
2403
+ return "angular";
2404
+ if (normalized.includes("/html/") || normalized.includes("/html-"))
2405
+ return "html";
2406
+ if (normalized.includes("/htmx/") || normalized.includes("/htmx-"))
2407
+ return "htmx";
2408
+ return "assets";
2409
+ }
2410
+ return "unknown";
2411
+ };
2412
+
2413
+ // src/dev/fileWatcher.ts
2414
+ var startFileWatching = (state, config, onFileChange) => {
2415
+ const watchPaths = getWatchPaths(config, state.resolvedPaths);
2416
+ for (const path of watchPaths) {
2417
+ const absolutePath = resolve9(path).replace(/\\/g, "/");
2418
+ if (!existsSync6(absolutePath)) {
2419
+ continue;
2420
+ }
2421
+ const watcher = watch(absolutePath, { recursive: true }, (event, filename) => {
2422
+ if (!filename)
2423
+ return;
2424
+ if (filename === "compiled" || filename === "build" || filename === "indexes" || filename.includes("/compiled") || filename.includes("/build") || filename.includes("/indexes") || filename.endsWith("/")) {
2425
+ return;
2426
+ }
2427
+ const fullPath = join8(absolutePath, filename).replace(/\\/g, "/");
2428
+ if (shouldIgnorePath(fullPath)) {
2429
+ return;
2430
+ }
2431
+ if (event === "rename" && !existsSync6(fullPath)) {
2432
+ try {
2433
+ removeFileFromGraph(state.dependencyGraph, fullPath);
2434
+ } catch {}
2435
+ onFileChange(fullPath);
2436
+ return;
2437
+ }
2438
+ if (existsSync6(fullPath)) {
2439
+ onFileChange(fullPath);
2440
+ try {
2441
+ addFileToGraph(state.dependencyGraph, fullPath);
2442
+ } catch {}
2443
+ }
2444
+ });
2445
+ state.watchers.push(watcher);
2446
+ }
2447
+ };
2448
+
2449
+ // src/dev/assetStore.ts
2450
+ import { resolve as resolve10 } from "path";
2451
+ import { readdir, unlink } from "fs/promises";
2452
+ var mimeTypes = {
2453
+ ".css": "text/css",
2454
+ ".html": "text/html",
2455
+ ".js": "application/javascript",
2456
+ ".mjs": "application/javascript",
2457
+ ".json": "application/json",
2458
+ ".svg": "image/svg+xml",
2459
+ ".woff": "font/woff",
2460
+ ".woff2": "font/woff2"
2461
+ };
2462
+ var getMimeType = (filePath) => {
2463
+ const ext = filePath.slice(filePath.lastIndexOf("."));
2464
+ return mimeTypes[ext] ?? "application/octet-stream";
2465
+ };
2466
+ var HASHED_FILE_RE = /\.[a-z0-9]{8}\.(js|css|mjs)$/;
2467
+ var stripHash = (webPath) => webPath.replace(/\.[a-z0-9]{8}(\.(js|css|mjs))$/, "$1");
2468
+ var populateAssetStore = async (store, manifest, buildDir) => {
2469
+ const loadPromises = [];
2470
+ const newIdentities = new Map;
2471
+ for (const webPath of Object.values(manifest)) {
2472
+ if (!webPath.startsWith("/"))
2473
+ continue;
2474
+ newIdentities.set(stripHash(webPath), webPath);
2475
+ }
2476
+ for (const existingPath of store.keys()) {
2477
+ const identity = stripHash(existingPath);
2478
+ const replacement = newIdentities.get(identity);
2479
+ if (replacement && replacement !== existingPath) {
2480
+ store.delete(existingPath);
2481
+ }
2482
+ }
2483
+ for (const webPath of newIdentities.values()) {
2484
+ loadPromises.push(Bun.file(resolve10(buildDir, webPath.slice(1))).bytes().then((bytes) => {
2485
+ store.set(webPath, bytes);
2486
+ }).catch(() => {}));
2487
+ }
2488
+ try {
2489
+ const scanDir = async (dir, prefix) => {
2490
+ const entries = await readdir(dir, { withFileTypes: true });
2491
+ const subTasks = [];
2492
+ for (const entry of entries) {
2493
+ if (entry.isDirectory()) {
2494
+ subTasks.push(scanDir(resolve10(dir, entry.name), `${prefix}${entry.name}/`));
2495
+ } else if (entry.name.startsWith("chunk-")) {
2496
+ const webPath = `/${prefix}${entry.name}`;
2497
+ if (!store.has(webPath)) {
2498
+ subTasks.push(Bun.file(resolve10(dir, entry.name)).bytes().then((bytes) => {
2499
+ store.set(webPath, bytes);
2500
+ }).catch(() => {}));
2501
+ }
2502
+ }
2503
+ }
2504
+ await Promise.all(subTasks);
2505
+ };
2506
+ await scanDir(buildDir, "");
2507
+ } catch {}
2508
+ await Promise.all(loadPromises);
2509
+ };
2510
+ var cleanStaleAssets = async (store, manifest, buildDir) => {
2511
+ const liveByIdentity = new Map;
2512
+ for (const webPath of store.keys()) {
2513
+ const diskPath = resolve10(buildDir, webPath.slice(1));
2514
+ liveByIdentity.set(stripHash(diskPath), diskPath);
2515
+ }
2516
+ const absBuildDir = resolve10(buildDir);
2517
+ for (const val of Object.values(manifest)) {
2518
+ if (!HASHED_FILE_RE.test(val))
2519
+ continue;
2520
+ if (val.startsWith(absBuildDir)) {
2521
+ liveByIdentity.set(stripHash(val), val);
2522
+ }
2523
+ }
2524
+ try {
2525
+ const walkAndClean = async (dir) => {
2526
+ const entries = await readdir(dir, { withFileTypes: true });
2527
+ const tasks = [];
2528
+ for (const entry of entries) {
2529
+ const fullPath = resolve10(dir, entry.name);
2530
+ if (entry.isDirectory()) {
2531
+ tasks.push(walkAndClean(fullPath));
2532
+ } else if (HASHED_FILE_RE.test(entry.name)) {
2533
+ const identity = stripHash(fullPath);
2534
+ const livePath = liveByIdentity.get(identity);
2535
+ if (livePath && livePath !== fullPath) {
2536
+ tasks.push(unlink(fullPath).catch(() => {}));
2537
+ }
2538
+ }
2539
+ }
2540
+ await Promise.all(tasks);
2541
+ };
2542
+ await walkAndClean(buildDir);
2543
+ } catch {}
2544
+ };
2545
+ var lookupAsset = (store, path) => store.get(path);
2546
+
2547
+ // src/dev/rebuildTrigger.ts
2548
+ import { existsSync as existsSync9 } from "fs";
2549
+ import { basename as basename8, resolve as resolve17 } from "path";
2550
+
2551
+ // src/dev/fileHashTracker.ts
2552
+ import { createHash } from "crypto";
2553
+ import { readFileSync as readFileSync3 } from "fs";
2554
+ var computeFileHash = (filePath) => {
2555
+ try {
2556
+ const fileContent = readFileSync3(filePath);
2557
+ const hash = createHash("sha256");
2558
+ hash.update(fileContent);
2559
+ return hash.digest("hex");
2560
+ } catch {
2561
+ return Date.now().toString();
2562
+ }
2563
+ };
2564
+ var hasFileChanged = (filePath, currentHash, previousHashes) => {
2565
+ const normalizedPath = normalizePath(filePath);
2566
+ const previousHash = previousHashes.get(normalizedPath);
2567
+ if (!previousHash) {
2568
+ return true;
2569
+ }
2570
+ return previousHash !== currentHash;
2571
+ };
2572
+
2573
+ // src/dev/moduleMapper.ts
2574
+ import { basename as basename5, resolve as resolve12 } from "path";
2575
+
2576
+ // src/dev/reactComponentClassifier.ts
2577
+ import { resolve as resolve11 } from "path";
2578
+ var classifyComponent = (filePath) => {
2579
+ const normalizedPath = resolve11(filePath);
2580
+ if (normalizedPath.includes("/react/pages/")) {
2581
+ return "server";
2582
+ }
2583
+ if (normalizedPath.includes("/react/components/") || normalizedPath.includes("/react/composables/")) {
2584
+ return "client";
2585
+ }
2586
+ return "client";
2587
+ };
2588
+
2589
+ // src/dev/moduleMapper.ts
2590
+ var mapSourceFileToManifestKeys = (sourceFile, framework, resolvedPaths) => {
2591
+ const normalizedFile = resolve12(sourceFile);
2592
+ const fileName = basename5(normalizedFile);
2593
+ const baseName = fileName.replace(/\.(tsx?|jsx?|vue|svelte|css|html)$/, "");
2594
+ const pascalName = toPascal(baseName);
2595
+ const keys = [];
2596
+ const inSubdir = (dir, sub) => {
2597
+ if (!dir)
2598
+ return false;
2599
+ const prefix = `${dir.replace(/\\/g, "/")}/${sub}/`;
2600
+ return normalizedFile.startsWith(prefix);
2601
+ };
2602
+ switch (framework) {
2603
+ case "react":
2604
+ if (inSubdir(resolvedPaths?.reactDir, "pages") || normalizedFile.includes("/react/pages/")) {
2605
+ keys.push(`${pascalName}Index`);
2606
+ keys.push(`${pascalName}CSS`);
2607
+ }
2608
+ break;
2609
+ case "svelte":
2610
+ if (inSubdir(resolvedPaths?.svelteDir, "pages") || normalizedFile.includes("/svelte/pages/")) {
2611
+ keys.push(pascalName);
2612
+ keys.push(`${pascalName}Index`);
2613
+ keys.push(`${pascalName}CSS`);
2614
+ }
2615
+ break;
2616
+ case "vue":
2617
+ if (inSubdir(resolvedPaths?.vueDir, "pages") || normalizedFile.includes("/vue/pages/")) {
2618
+ keys.push(pascalName);
2619
+ keys.push(`${pascalName}Index`);
2620
+ keys.push(`${pascalName}CSS`);
2621
+ }
2622
+ break;
2623
+ case "angular":
2624
+ if (inSubdir(resolvedPaths?.angularDir, "pages") || normalizedFile.includes("/angular/pages/")) {
2625
+ keys.push(pascalName);
2626
+ keys.push(`${pascalName}Index`);
2627
+ }
2628
+ break;
2629
+ case "html":
2630
+ case "htmx":
2631
+ break;
2632
+ case "assets":
2633
+ if (normalizedFile.endsWith(".css")) {
2634
+ keys.push(`${pascalName}CSS`);
2635
+ }
2636
+ break;
2637
+ }
2638
+ return keys;
2639
+ };
2640
+ var createModuleUpdates = (changedFiles, framework, manifest, resolvedPaths) => {
2641
+ const updates = [];
2642
+ const processedFiles = new Set;
2643
+ for (const sourceFile of changedFiles) {
2644
+ const normalizedFile = resolve12(sourceFile);
2645
+ const normalizedPath = normalizedFile.replace(/\\/g, "/");
2646
+ if (processedFiles.has(normalizedFile))
2647
+ continue;
2648
+ processedFiles.add(normalizedFile);
2649
+ const moduleKeys = mapSourceFileToManifestKeys(normalizedFile, framework, resolvedPaths);
2650
+ const isReactPage = resolvedPaths?.reactDir ? normalizedPath.startsWith(`${resolvedPaths.reactDir.replace(/\\/g, "/")}/pages/`) : normalizedPath.includes("/react/pages/");
2651
+ if (framework === "react" && !isReactPage) {
2652
+ continue;
2653
+ }
2654
+ const modulePaths = {};
2655
+ for (const key of moduleKeys) {
2656
+ if (manifest[key]) {
2657
+ modulePaths[key] = manifest[key];
2658
+ }
2659
+ }
2660
+ if (Object.keys(modulePaths).length > 0) {
2661
+ const componentType = framework === "react" ? classifyComponent(normalizedFile) : undefined;
2662
+ updates.push({
2663
+ componentType,
2664
+ framework,
2665
+ moduleKeys: Object.keys(modulePaths),
2666
+ modulePaths,
2667
+ sourceFile: normalizedFile
2668
+ });
2669
+ }
2670
+ }
2671
+ return updates;
2672
+ };
2673
+ var groupModuleUpdatesByFramework = (updates) => {
2674
+ const grouped = new Map;
2675
+ for (const update of updates) {
2676
+ if (!grouped.has(update.framework)) {
2677
+ grouped.set(update.framework, []);
2678
+ }
2679
+ grouped.get(update.framework).push(update);
2680
+ }
2681
+ return grouped;
2682
+ };
2683
+
2684
+ // src/dev/webSocket.ts
2685
+ var handleClientConnect = (state, client2, manifest) => {
2686
+ state.connectedClients.add(client2);
2687
+ const serverVersions = serializeModuleVersions(state.moduleVersions);
2688
+ client2.send(JSON.stringify({
2689
+ data: {
2690
+ manifest,
2691
+ serverVersions
2692
+ },
2693
+ timestamp: Date.now(),
2694
+ type: "manifest"
2695
+ }));
2696
+ client2.send(JSON.stringify({
2697
+ message: "HMR client connected successfully",
2698
+ timestamp: Date.now(),
2699
+ type: "connected"
2700
+ }));
2701
+ };
2702
+ var handleClientDisconnect = (state, client2) => {
2703
+ state.connectedClients.delete(client2);
2704
+ };
2705
+ var handleHMRMessage = (state, client2, message) => {
2706
+ try {
2707
+ let parsedData;
2708
+ if (typeof message === "string") {
2709
+ parsedData = JSON.parse(message);
2710
+ } else if (message instanceof Buffer) {
2711
+ parsedData = JSON.parse(message.toString());
2712
+ } else if (message instanceof ArrayBuffer) {
2713
+ parsedData = JSON.parse(new TextDecoder().decode(new Uint8Array(message)));
2714
+ } else if (ArrayBuffer.isView(message)) {
2715
+ parsedData = JSON.parse(new TextDecoder().decode(message));
2716
+ } else if (typeof message === "object" && message !== null) {
2717
+ parsedData = message;
2718
+ } else {
2719
+ return;
2720
+ }
2721
+ if (!isValidHMRClientMessage(parsedData)) {
2722
+ return;
2723
+ }
2724
+ const data = parsedData;
2725
+ switch (data.type) {
2726
+ case "ping":
2727
+ client2.send(JSON.stringify({
2728
+ timestamp: Date.now(),
2729
+ type: "pong"
2730
+ }));
2731
+ break;
2732
+ case "request-rebuild":
2733
+ break;
2734
+ case "ready":
2735
+ break;
2736
+ case "hydration-error":
2737
+ break;
2738
+ }
2739
+ } catch {}
2740
+ };
2741
+ var broadcastToClients = (state, message) => {
2742
+ const messageStr = JSON.stringify({
2743
+ ...message,
2744
+ timestamp: Date.now()
2745
+ });
2746
+ let sentCount = 0;
2747
+ const clientsToRemove = [];
2748
+ for (const client2 of state.connectedClients) {
2749
+ if (client2.readyState === WS_READY_STATE_OPEN) {
2750
+ try {
2751
+ client2.send(messageStr);
2752
+ sentCount++;
2753
+ } catch {
2754
+ clientsToRemove.push(client2);
2755
+ }
2756
+ } else {
2757
+ clientsToRemove.push(client2);
2758
+ }
2759
+ }
2760
+ for (const client2 of clientsToRemove) {
2761
+ state.connectedClients.delete(client2);
2762
+ }
2763
+ };
2764
+
2765
+ // src/dev/rebuildTrigger.ts
2766
+ var parseErrorLocationFromMessage = (msg) => {
2767
+ const pathLineCol = msg.match(/^([^\s:]+):(\d+)(?::(\d+))?/);
2768
+ if (pathLineCol) {
2769
+ const [, file4, lineStr, colStr] = pathLineCol;
2770
+ return {
2771
+ file: file4,
2772
+ line: lineStr ? parseInt(lineStr, 10) : undefined,
2773
+ column: colStr ? parseInt(colStr, 10) : undefined
2774
+ };
2775
+ }
2776
+ const atMatch = msg.match(/(?:at|in)\s+([^(:\s]+)(?:\s*\([^)]*line\s*(\d+)[^)]*col(?:umn)?\s*(\d+)[^)]*\)|:(\d+):(\d+)?)/i);
2777
+ if (atMatch) {
2778
+ const [, file4, line1, col1, line2, col2] = atMatch;
2779
+ return {
2780
+ file: file4?.trim(),
2781
+ line: line1 ? parseInt(line1, 10) : line2 ? parseInt(line2, 10) : undefined,
2782
+ column: col1 ? parseInt(col1, 10) : col2 ? parseInt(col2, 10) : undefined
2783
+ };
2784
+ }
2785
+ const parenMatch = msg.match(/([^\s(]+)\s*\([^)]*line\s*(\d+)[^)]*col(?:umn)?\s*(\d+)/i);
2786
+ if (parenMatch) {
2787
+ const [, file4, lineStr, colStr] = parenMatch;
2788
+ return {
2789
+ file: file4 ?? undefined,
2790
+ line: lineStr ? parseInt(lineStr, 10) : undefined,
2791
+ column: colStr ? parseInt(colStr, 10) : undefined
2792
+ };
2793
+ }
2794
+ return {};
2795
+ };
2796
+ var extractBuildErrorDetails = (error, affectedFrameworks, resolvedPaths) => {
2797
+ let logs = error?.logs;
2798
+ if (!logs && error instanceof AggregateError && error.errors?.length) {
2799
+ logs = error.errors;
2800
+ }
2801
+ if (logs && Array.isArray(logs) && logs.length > 0) {
2802
+ const errLog = logs.find((l) => l.level === "error") ?? logs[0];
2803
+ const pos = errLog?.position;
2804
+ const file4 = pos && "file" in pos ? pos.file : undefined;
2805
+ const line = pos && "line" in pos ? pos.line : undefined;
2806
+ const column = pos && "column" in pos ? pos.column : undefined;
2807
+ const lineText = pos && "lineText" in pos ? pos.lineText : undefined;
2808
+ const framework = file4 && resolvedPaths ? detectFramework(file4, resolvedPaths) : affectedFrameworks[0] ?? "unknown";
2809
+ return {
2810
+ file: file4,
2811
+ line,
2812
+ column,
2813
+ lineText,
2814
+ framework: framework !== "ignored" ? framework : affectedFrameworks[0]
2815
+ };
2816
+ }
2817
+ const msg = error instanceof Error ? error.message : String(error);
2818
+ const parsed = parseErrorLocationFromMessage(msg);
2819
+ let fw = affectedFrameworks[0];
2820
+ if (parsed.file && resolvedPaths) {
2821
+ const detected = detectFramework(parsed.file, resolvedPaths);
2822
+ fw = detected !== "ignored" ? detected : affectedFrameworks[0];
2823
+ }
2824
+ return { ...parsed, framework: fw };
2825
+ };
2826
+ var queueFileChange = (state, filePath, config, onRebuildComplete) => {
2827
+ const framework = detectFramework(filePath, state.resolvedPaths);
2828
+ if (framework === "ignored") {
2829
+ return;
2830
+ }
2831
+ const currentHash = computeFileHash(filePath);
2832
+ if (!hasFileChanged(filePath, currentHash, state.fileHashes)) {
2833
+ return;
2834
+ }
2835
+ if (!state.fileChangeQueue.has(framework)) {
2836
+ state.fileChangeQueue.set(framework, []);
2837
+ }
2838
+ const queue = state.fileChangeQueue.get(framework);
2839
+ if (!queue.includes(filePath)) {
2840
+ queue.push(filePath);
2841
+ }
2842
+ if (state.isRebuilding) {
2843
+ return;
2844
+ }
2845
+ if (state.rebuildTimeout) {
2846
+ clearTimeout(state.rebuildTimeout);
2847
+ }
2848
+ const DEBOUNCE_MS = config.options?.hmr?.debounceMs ?? 500;
2849
+ state.rebuildTimeout = setTimeout(() => {
2850
+ const filesToProcess = new Map;
2851
+ const uniqueFilesByFramework = new Map;
2852
+ for (const [fwKey, filePaths] of state.fileChangeQueue) {
2853
+ uniqueFilesByFramework.set(fwKey, new Set(filePaths));
2854
+ }
2855
+ for (const [fwKey, filePathSet] of uniqueFilesByFramework) {
2856
+ const validFiles = [];
2857
+ const processedFiles = new Set;
2858
+ for (const filePathInSet of filePathSet) {
2859
+ if (!existsSync9(filePathInSet)) {
2860
+ state.fileHashes.delete(filePathInSet);
2861
+ try {
2862
+ const affectedFiles = getAffectedFiles(state.dependencyGraph, filePathInSet);
2863
+ const deletedPathResolved = resolve17(filePathInSet);
2864
+ for (const affectedFile of affectedFiles) {
2865
+ if (affectedFile !== deletedPathResolved && !processedFiles.has(affectedFile) && existsSync9(affectedFile)) {
2866
+ validFiles.push(affectedFile);
2867
+ processedFiles.add(affectedFile);
2868
+ }
2869
+ }
2870
+ } catch {}
2871
+ continue;
2872
+ }
2873
+ const fileHash = computeFileHash(filePathInSet);
2874
+ const storedHash = state.fileHashes.get(filePathInSet);
2875
+ if (!storedHash || storedHash !== fileHash) {
2876
+ const normalizedFilePath = resolve17(filePathInSet);
2877
+ if (!processedFiles.has(normalizedFilePath)) {
2878
+ validFiles.push(normalizedFilePath);
2879
+ processedFiles.add(normalizedFilePath);
2880
+ }
2881
+ state.fileHashes.set(normalizedFilePath, fileHash);
2882
+ incrementSourceFileVersions(state, [normalizedFilePath]);
2883
+ try {
2884
+ const dependents = state.dependencyGraph.dependents.get(normalizedFilePath);
2885
+ if (dependents && dependents.size > 0) {
2886
+ const dependentFiles = Array.from(dependents).filter((f) => existsSync9(f));
2887
+ if (dependentFiles.length > 0) {
2888
+ incrementSourceFileVersions(state, dependentFiles);
2889
+ }
2890
+ }
2891
+ } catch {}
2892
+ try {
2893
+ const affectedFiles = getAffectedFiles(state.dependencyGraph, normalizedFilePath);
2894
+ for (const affectedFile of affectedFiles) {
2895
+ if (!processedFiles.has(affectedFile) && affectedFile !== normalizedFilePath && existsSync9(affectedFile)) {
2896
+ validFiles.push(affectedFile);
2897
+ processedFiles.add(affectedFile);
2898
+ }
2899
+ }
2900
+ } catch {
2901
+ if (!processedFiles.has(normalizedFilePath)) {
2902
+ validFiles.push(normalizedFilePath);
2903
+ processedFiles.add(normalizedFilePath);
2904
+ }
2905
+ }
2906
+ }
2907
+ }
2908
+ if (validFiles.length > 0) {
2909
+ const firstFile = validFiles[0];
2910
+ if (firstFile) {
2911
+ const detectedFramework = detectFramework(firstFile, state.resolvedPaths);
2912
+ filesToProcess.set(detectedFramework, validFiles);
2913
+ }
2914
+ }
2915
+ }
2916
+ state.fileChangeQueue.clear();
2917
+ if (filesToProcess.size === 0) {
2918
+ return;
2919
+ }
2920
+ const affectedFrameworks = Array.from(filesToProcess.keys());
2921
+ for (const frameworkKey of affectedFrameworks) {
2922
+ state.rebuildQueue.add(frameworkKey);
2923
+ }
2924
+ const filesToRebuild = [];
2925
+ for (const [, filePaths] of filesToProcess) {
2926
+ filesToRebuild.push(...filePaths);
2927
+ }
2928
+ triggerRebuild(state, config, onRebuildComplete, filesToRebuild);
2929
+ }, DEBOUNCE_MS);
2930
+ };
2931
+ var triggerRebuild = async (state, config, onRebuildComplete, filesToRebuild) => {
2932
+ if (state.isRebuilding) {
2933
+ return null;
2934
+ }
2935
+ state.isRebuilding = true;
2936
+ const affectedFrameworks = Array.from(state.rebuildQueue);
2937
+ state.rebuildQueue.clear();
2938
+ const startTime = Date.now();
2939
+ broadcastToClients(state, {
2940
+ data: { affectedFrameworks },
2941
+ message: "Rebuild started...",
2942
+ type: "rebuild-start"
2943
+ });
2944
+ try {
2945
+ const manifest = await build2({
2946
+ ...config,
2947
+ incrementalFiles: filesToRebuild && filesToRebuild.length > 0 ? filesToRebuild : undefined,
2948
+ options: {
2949
+ ...config.options,
2950
+ injectHMR: true,
2951
+ throwOnError: true
2952
+ }
2953
+ });
2954
+ if (!manifest) {
2955
+ throw new Error("Build failed - no manifest generated");
2956
+ }
2957
+ const duration = Date.now() - startTime;
2958
+ broadcastToClients(state, {
2959
+ data: {
2960
+ affectedFrameworks,
2961
+ manifest
2962
+ },
2963
+ message: "Rebuild completed successfully",
2964
+ type: "rebuild-complete"
2965
+ });
2966
+ if (filesToRebuild && filesToRebuild.length > 0) {
2967
+ const allModuleUpdates = [];
2968
+ for (const framework of affectedFrameworks) {
2969
+ const frameworkFiles = filesToRebuild.filter((file4) => detectFramework(file4, state.resolvedPaths) === framework);
2970
+ if (frameworkFiles.length > 0) {
2971
+ const moduleUpdates = createModuleUpdates(frameworkFiles, framework, manifest, state.resolvedPaths);
2972
+ if (moduleUpdates.length > 0) {
2973
+ allModuleUpdates.push(...moduleUpdates);
2974
+ }
2975
+ }
2976
+ }
2977
+ if (affectedFrameworks.includes("react") && filesToRebuild && state.resolvedPaths.reactDir) {
2978
+ const reactFiles = filesToRebuild.filter((file4) => detectFramework(file4, state.resolvedPaths) === "react");
2979
+ if (reactFiles.length > 0) {
2980
+ const reactPageFiles = reactFiles.filter((file4) => {
2981
+ const normalized = file4.replace(/\\/g, "/");
2982
+ return normalized.includes("/pages/");
2983
+ });
2984
+ const sourceFiles = reactPageFiles.length > 0 ? reactPageFiles : reactFiles;
2985
+ const primarySource = sourceFiles[0];
2986
+ try {
2987
+ const hasComponentChanges = reactFiles.some((file4) => file4.endsWith(".tsx") || file4.endsWith(".ts") || file4.endsWith(".jsx"));
2988
+ const hasCSSChanges = reactFiles.some((file4) => file4.endsWith(".css"));
2989
+ if (hasCSSChanges && !hasComponentChanges) {
2990
+ logger.cssUpdate(primarySource ?? reactFiles[0] ?? "", "react", duration);
2991
+ } else {
2992
+ logger.hmrUpdate(primarySource ?? reactFiles[0] ?? "", "react", duration);
2993
+ }
2994
+ broadcastToClients(state, {
2995
+ data: {
2996
+ framework: "react",
2997
+ manifest,
2998
+ sourceFiles,
2999
+ primarySource,
3000
+ hasComponentChanges,
3001
+ hasCSSChanges
3002
+ },
3003
+ type: "react-update"
3004
+ });
3005
+ } catch {}
3006
+ }
3007
+ }
3008
+ if (affectedFrameworks.includes("html") && filesToRebuild && state.resolvedPaths.htmlDir) {
3009
+ const htmlFrameworkFiles = filesToRebuild.filter((file4) => detectFramework(file4, state.resolvedPaths) === "html");
3010
+ if (htmlFrameworkFiles.length > 0) {
3011
+ const scriptFiles = htmlFrameworkFiles.filter((f) => (f.endsWith(".ts") || f.endsWith(".js") || f.endsWith(".tsx") || f.endsWith(".jsx")) && f.replace(/\\/g, "/").includes("/scripts/"));
3012
+ const htmlPageFiles = htmlFrameworkFiles.filter((f) => f.endsWith(".html"));
3013
+ if (scriptFiles.length > 0 && htmlPageFiles.length === 0) {
3014
+ for (const scriptFile of scriptFiles) {
3015
+ const { basename: basename9 } = await import("path");
3016
+ const { toPascal: toPascal2 } = await Promise.resolve().then(() => exports_stringModifiers);
3017
+ const scriptBaseName = basename9(scriptFile).replace(/\.(ts|js|tsx|jsx)$/, "");
3018
+ const pascalName = toPascal2(scriptBaseName);
3019
+ const manifestKey = pascalName;
3020
+ const scriptPath = manifest[manifestKey] || null;
3021
+ if (scriptPath) {
3022
+ logger.scriptUpdate(scriptFile, "html", duration);
3023
+ broadcastToClients(state, {
3024
+ data: {
3025
+ framework: "html",
3026
+ scriptPath,
3027
+ sourceFile: scriptFile,
3028
+ manifest
3029
+ },
3030
+ type: "script-update"
3031
+ });
3032
+ } else {
3033
+ logger.warn(`Script not found in manifest: ${manifestKey}`);
3034
+ }
3035
+ }
3036
+ }
3037
+ }
3038
+ }
3039
+ if (affectedFrameworks.includes("html") && filesToRebuild && state.resolvedPaths.htmlDir) {
3040
+ const htmlFrameworkFiles = filesToRebuild.filter((file4) => detectFramework(file4, state.resolvedPaths) === "html");
3041
+ if (htmlFrameworkFiles.length > 0) {
3042
+ const htmlPageFiles = htmlFrameworkFiles.filter((f) => f.endsWith(".html"));
3043
+ const pagesToUpdate = htmlPageFiles;
3044
+ const isSingle = !config.reactDirectory && !config.svelteDirectory && !config.vueDirectory && !config.htmxDirectory;
3045
+ const outputHtmlPages = isSingle ? resolve17(state.resolvedPaths.buildDir, "pages") : resolve17(state.resolvedPaths.buildDir, basename8(config.htmlDirectory ?? "html"), "pages");
3046
+ for (const pageFile of pagesToUpdate) {
3047
+ const htmlPageName = basename8(pageFile);
3048
+ const builtHtmlPagePath = resolve17(outputHtmlPages, htmlPageName);
3049
+ try {
3050
+ const { handleHTMLUpdate: handleHTMLUpdate2 } = await Promise.resolve().then(() => (init_simpleHTMLHMR(), exports_simpleHTMLHMR));
3051
+ const newHTML = await handleHTMLUpdate2(builtHtmlPagePath);
3052
+ if (newHTML) {
3053
+ logger.hmrUpdate(pageFile, "html", duration);
3054
+ broadcastToClients(state, {
3055
+ data: {
3056
+ framework: "html",
3057
+ html: newHTML,
3058
+ sourceFile: builtHtmlPagePath
3059
+ },
3060
+ type: "html-update"
3061
+ });
3062
+ }
3063
+ } catch {}
3064
+ }
3065
+ }
3066
+ }
3067
+ if (affectedFrameworks.includes("vue") && filesToRebuild && config.vueDirectory) {
3068
+ const vueFiles = filesToRebuild.filter((file4) => detectFramework(file4, state.resolvedPaths) === "vue");
3069
+ if (vueFiles.length > 0) {
3070
+ const vueComponentFiles = vueFiles.filter((f) => f.endsWith(".vue"));
3071
+ const vueCssFiles = vueFiles.filter((f) => f.endsWith(".css"));
3072
+ const isCssOnlyChange = vueComponentFiles.length === 0 && vueCssFiles.length > 0;
3073
+ const vuePageFiles = vueFiles.filter((f) => f.replace(/\\/g, "/").includes("/pages/"));
3074
+ const pagesToUpdate = vuePageFiles.length > 0 ? vuePageFiles : vueComponentFiles;
3075
+ if (isCssOnlyChange && vueCssFiles.length > 0) {
3076
+ const { basename: basename9 } = await import("path");
3077
+ const { toPascal: toPascal2 } = await Promise.resolve().then(() => exports_stringModifiers);
3078
+ const cssFile = vueCssFiles[0];
3079
+ if (cssFile) {
3080
+ const cssBaseName = basename9(cssFile, ".css");
3081
+ const cssPascalName = toPascal2(cssBaseName);
3082
+ const cssKey = `${cssPascalName}CSS`;
3083
+ const cssUrl = manifest[cssKey] || null;
3084
+ logger.cssUpdate(cssFile, "vue", duration);
3085
+ broadcastToClients(state, {
3086
+ data: {
3087
+ framework: "vue",
3088
+ updateType: "css-only",
3089
+ cssUrl,
3090
+ cssBaseName,
3091
+ manifest,
3092
+ sourceFile: cssFile
3093
+ },
3094
+ type: "vue-update"
3095
+ });
3096
+ }
3097
+ }
3098
+ for (const vuePagePath of pagesToUpdate) {
3099
+ try {
3100
+ const { basename: basename9, relative: relative5 } = await import("path");
3101
+ const { toPascal: toPascal2 } = await Promise.resolve().then(() => exports_stringModifiers);
3102
+ const fileName = basename9(vuePagePath);
3103
+ const baseName = fileName.replace(/\.vue$/, "");
3104
+ const pascalName = toPascal2(baseName);
3105
+ const vueRoot = config.vueDirectory;
3106
+ const hmrId = vueRoot ? relative5(vueRoot, vuePagePath).replace(/\\/g, "/").replace(/\.vue$/, "") : baseName;
3107
+ const cssKey = `${pascalName}CSS`;
3108
+ const cssUrl = manifest[cssKey] || null;
3109
+ const { vueHmrMetadata: vueHmrMetadata2 } = await Promise.resolve().then(() => (init_compileVue(), exports_compileVue));
3110
+ const hmrMeta = vueHmrMetadata2.get(resolve17(vuePagePath));
3111
+ const changeType = hmrMeta?.changeType ?? "full";
3112
+ if (changeType === "style-only") {
3113
+ logger.cssUpdate(vuePagePath, "vue", duration);
3114
+ broadcastToClients(state, {
3115
+ data: {
3116
+ framework: "vue",
3117
+ updateType: "css-only",
3118
+ changeType: "style-only",
3119
+ cssUrl,
3120
+ cssBaseName: baseName,
3121
+ hmrId,
3122
+ manifest,
3123
+ sourceFile: vuePagePath
3124
+ },
3125
+ type: "vue-update"
3126
+ });
3127
+ continue;
3128
+ }
3129
+ const { handleVueUpdate: handleVueUpdate2 } = await Promise.resolve().then(() => (init_simpleVueHMR(), exports_simpleVueHMR));
3130
+ const newHTML = await handleVueUpdate2(vuePagePath, manifest, state.resolvedPaths.buildDir);
3131
+ const componentPath = manifest[`${pascalName}Client`] || null;
3132
+ logger.hmrUpdate(vuePagePath, "vue", duration);
3133
+ broadcastToClients(state, {
3134
+ data: {
3135
+ framework: "vue",
3136
+ html: newHTML,
3137
+ hmrId,
3138
+ changeType,
3139
+ componentPath,
3140
+ cssUrl,
3141
+ updateType: "full",
3142
+ manifest,
3143
+ sourceFile: vuePagePath
3144
+ },
3145
+ type: "vue-update"
3146
+ });
3147
+ } catch {}
3148
+ }
3149
+ }
3150
+ }
3151
+ if (affectedFrameworks.includes("svelte") && filesToRebuild && config.svelteDirectory) {
3152
+ const svelteFiles = filesToRebuild.filter((file4) => detectFramework(file4, state.resolvedPaths) === "svelte");
3153
+ if (svelteFiles.length > 0) {
3154
+ const svelteComponentFiles = svelteFiles.filter((f) => f.endsWith(".svelte"));
3155
+ const svelteCssFiles = svelteFiles.filter((f) => f.endsWith(".css"));
3156
+ const isCssOnlyChange = svelteComponentFiles.length === 0 && svelteCssFiles.length > 0;
3157
+ const sveltePageFiles = svelteFiles.filter((f) => f.replace(/\\/g, "/").includes("/pages/"));
3158
+ const pagesToUpdate = sveltePageFiles.length > 0 ? sveltePageFiles : svelteComponentFiles;
3159
+ if (isCssOnlyChange && svelteCssFiles.length > 0) {
3160
+ const { basename: basename9 } = await import("path");
3161
+ const { toPascal: toPascal2 } = await Promise.resolve().then(() => exports_stringModifiers);
3162
+ const cssFile = svelteCssFiles[0];
3163
+ if (cssFile) {
3164
+ const cssBaseName = basename9(cssFile, ".css");
3165
+ const cssPascalName = toPascal2(cssBaseName);
3166
+ const cssKey = `${cssPascalName}CSS`;
3167
+ const cssUrl = manifest[cssKey] || null;
3168
+ logger.cssUpdate(cssFile, "svelte", duration);
3169
+ broadcastToClients(state, {
3170
+ data: {
3171
+ framework: "svelte",
3172
+ updateType: "css-only",
3173
+ cssUrl,
3174
+ cssBaseName,
3175
+ manifest,
3176
+ sourceFile: cssFile
3177
+ },
3178
+ type: "svelte-update"
3179
+ });
3180
+ }
3181
+ }
3182
+ for (const sveltePagePath of pagesToUpdate) {
3183
+ try {
3184
+ const { handleSvelteUpdate: handleSvelteUpdate2 } = await Promise.resolve().then(() => (init_simpleSvelteHMR(), exports_simpleSvelteHMR));
3185
+ const newHTML = await handleSvelteUpdate2(sveltePagePath, manifest, state.resolvedPaths.buildDir);
3186
+ const { basename: basename9 } = await import("path");
3187
+ const { toPascal: toPascal2 } = await Promise.resolve().then(() => exports_stringModifiers);
3188
+ const fileName = basename9(sveltePagePath);
3189
+ const baseName = fileName.replace(/\.svelte$/, "");
3190
+ const pascalName = toPascal2(baseName);
3191
+ const cssKey = `${pascalName}CSS`;
3192
+ const cssUrl = manifest[cssKey] || null;
3193
+ logger.hmrUpdate(sveltePagePath, "svelte", duration);
3194
+ broadcastToClients(state, {
3195
+ data: {
3196
+ framework: "svelte",
3197
+ html: newHTML,
3198
+ cssUrl,
3199
+ cssBaseName: baseName,
3200
+ updateType: "full",
3201
+ manifest,
3202
+ sourceFile: sveltePagePath
3203
+ },
3204
+ type: "svelte-update"
3205
+ });
3206
+ } catch {}
3207
+ }
3208
+ }
3209
+ }
3210
+ if (affectedFrameworks.includes("htmx") && filesToRebuild && state.resolvedPaths.htmxDir) {
3211
+ const htmxFrameworkFiles = filesToRebuild.filter((file4) => detectFramework(file4, state.resolvedPaths) === "htmx");
3212
+ if (htmxFrameworkFiles.length > 0) {
3213
+ const htmxScriptFiles = htmxFrameworkFiles.filter((f) => (f.endsWith(".ts") || f.endsWith(".js") || f.endsWith(".tsx") || f.endsWith(".jsx")) && f.replace(/\\/g, "/").includes("/scripts/"));
3214
+ const htmxHtmlFiles = htmxFrameworkFiles.filter((f) => f.endsWith(".html"));
3215
+ if (htmxScriptFiles.length > 0 && htmxHtmlFiles.length === 0) {
3216
+ for (const scriptFile of htmxScriptFiles) {
3217
+ const { basename: basename9 } = await import("path");
3218
+ const { toPascal: toPascal2 } = await Promise.resolve().then(() => exports_stringModifiers);
3219
+ const scriptBaseName = basename9(scriptFile).replace(/\.(ts|js|tsx|jsx)$/, "");
3220
+ const pascalName = toPascal2(scriptBaseName);
3221
+ const manifestKey = pascalName;
3222
+ const scriptPath = manifest[manifestKey] || null;
3223
+ if (scriptPath) {
3224
+ logger.scriptUpdate(scriptFile, "htmx", duration);
3225
+ broadcastToClients(state, {
3226
+ data: {
3227
+ framework: "htmx",
3228
+ scriptPath,
3229
+ sourceFile: scriptFile,
3230
+ manifest
3231
+ },
3232
+ type: "script-update"
3233
+ });
3234
+ }
3235
+ }
3236
+ }
3237
+ }
3238
+ }
3239
+ if (affectedFrameworks.includes("htmx") && filesToRebuild && state.resolvedPaths.htmxDir) {
3240
+ const htmxFrameworkFiles = filesToRebuild.filter((file4) => detectFramework(file4, state.resolvedPaths) === "htmx");
3241
+ if (htmxFrameworkFiles.length > 0) {
3242
+ const htmxPageFiles = htmxFrameworkFiles.filter((f) => f.endsWith(".html"));
3243
+ const isSingle = !config.reactDirectory && !config.svelteDirectory && !config.vueDirectory && !config.htmlDirectory;
3244
+ const outputHtmxPages = isSingle ? resolve17(state.resolvedPaths.buildDir, "pages") : resolve17(state.resolvedPaths.buildDir, basename8(config.htmxDirectory ?? "htmx"), "pages");
3245
+ for (const htmxPageFile of htmxPageFiles) {
3246
+ const htmxPageName = basename8(htmxPageFile);
3247
+ const builtHtmxPagePath = resolve17(outputHtmxPages, htmxPageName);
3248
+ try {
3249
+ const { handleHTMXUpdate: handleHTMXUpdate2 } = await Promise.resolve().then(() => (init_simpleHTMXHMR(), exports_simpleHTMXHMR));
3250
+ const newHTML = await handleHTMXUpdate2(builtHtmxPagePath);
3251
+ if (newHTML) {
3252
+ logger.hmrUpdate(htmxPageFile, "htmx", duration);
3253
+ broadcastToClients(state, {
3254
+ data: {
3255
+ framework: "htmx",
3256
+ html: newHTML,
3257
+ sourceFile: builtHtmxPagePath
3258
+ },
3259
+ type: "htmx-update"
3260
+ });
3261
+ }
3262
+ } catch {}
3263
+ }
3264
+ }
3265
+ }
3266
+ const updatedModulePaths = [];
3267
+ for (const update of allModuleUpdates) {
3268
+ updatedModulePaths.push(update.sourceFile);
3269
+ for (const modulePath of Object.values(update.modulePaths)) {
3270
+ updatedModulePaths.push(modulePath);
3271
+ }
3272
+ }
3273
+ if (updatedModulePaths.length > 0) {
3274
+ incrementModuleVersions(state.moduleVersions, updatedModulePaths);
3275
+ }
3276
+ if (allModuleUpdates.length > 0) {
3277
+ const updatesByFramework = groupModuleUpdatesByFramework(allModuleUpdates);
3278
+ const serverVersions = serializeModuleVersions(state.moduleVersions);
3279
+ for (const [framework, updates] of updatesByFramework) {
3280
+ const moduleVersions = {};
3281
+ for (const update of updates) {
3282
+ const sourceVersion = state.moduleVersions.get(update.sourceFile);
3283
+ if (sourceVersion !== undefined) {
3284
+ moduleVersions[update.sourceFile] = sourceVersion;
3285
+ }
3286
+ for (const [, path] of Object.entries(update.modulePaths)) {
3287
+ const pathVersion = state.moduleVersions.get(path);
3288
+ if (pathVersion !== undefined) {
3289
+ moduleVersions[path] = pathVersion;
3290
+ }
3291
+ }
3292
+ }
3293
+ broadcastToClients(state, {
3294
+ data: {
3295
+ framework,
3296
+ manifest,
3297
+ modules: updates.map((update) => ({
3298
+ componentType: update.componentType,
3299
+ moduleKeys: update.moduleKeys,
3300
+ modulePaths: update.modulePaths,
3301
+ sourceFile: update.sourceFile,
3302
+ version: state.moduleVersions.get(update.sourceFile)
3303
+ })),
3304
+ moduleVersions,
3305
+ serverVersions
3306
+ },
3307
+ message: `${framework} modules updated`,
3308
+ type: "module-update"
3309
+ });
3310
+ }
3311
+ }
3312
+ }
3313
+ for (const framework of affectedFrameworks) {
3314
+ broadcastToClients(state, {
3315
+ data: {
3316
+ framework,
3317
+ manifest
3318
+ },
3319
+ message: `${framework} framework updated`,
3320
+ type: "framework-update"
3321
+ });
3322
+ }
3323
+ onRebuildComplete({ manifest, hmrState: state });
3324
+ await populateAssetStore(state.assetStore, manifest, state.resolvedPaths.buildDir);
3325
+ await cleanStaleAssets(state.assetStore, manifest, state.resolvedPaths.buildDir);
3326
+ return manifest;
3327
+ } catch (error) {
3328
+ const errorData = extractBuildErrorDetails(error, affectedFrameworks, state.resolvedPaths);
3329
+ broadcastToClients(state, {
3330
+ data: {
3331
+ affectedFrameworks,
3332
+ error: error instanceof Error ? error.message : String(error),
3333
+ ...errorData
3334
+ },
3335
+ message: "Rebuild failed",
3336
+ type: "rebuild-error"
3337
+ });
3338
+ return null;
3339
+ } finally {
3340
+ state.isRebuilding = false;
3341
+ if (state.fileChangeQueue.size > 0) {
3342
+ const pending = Array.from(state.fileChangeQueue.keys());
3343
+ const queuedFiles = [];
3344
+ for (const [, filePaths] of state.fileChangeQueue) {
3345
+ queuedFiles.push(...filePaths);
3346
+ }
3347
+ state.fileChangeQueue.clear();
3348
+ for (const f of pending)
3349
+ state.rebuildQueue.add(f);
3350
+ if (state.rebuildTimeout)
3351
+ clearTimeout(state.rebuildTimeout);
3352
+ state.rebuildTimeout = setTimeout(() => {
3353
+ triggerRebuild(state, config, onRebuildComplete, queuedFiles.length > 0 ? queuedFiles : undefined);
3354
+ }, 50);
3355
+ }
3356
+ }
3357
+ };
3358
+
3359
+ // src/core/devBuild.ts
3360
+ var devBuild = async (config) => {
3361
+ const cached = globalThis.__hmrDevResult;
3362
+ if (cached) {
3363
+ const serverMtime = statSync(resolve18(Bun.main)).mtimeMs;
3364
+ const lastMtime = globalThis.__hmrServerMtime;
3365
+ globalThis.__hmrServerMtime = serverMtime;
3366
+ if (serverMtime !== lastMtime) {
3367
+ logger.serverReload();
3368
+ } else {
3369
+ globalThis.__hmrSkipServerRestart = true;
3370
+ }
3371
+ return cached;
3372
+ }
3373
+ const state = createHMRState(config);
3374
+ const watchPaths = getWatchPaths(config, state.resolvedPaths);
3375
+ buildInitialDependencyGraph(state.dependencyGraph, watchPaths);
3376
+ if (config.reactDirectory) {
3377
+ setDevVendorPaths(computeVendorPaths());
3378
+ }
3379
+ try {
3380
+ const pkg = await Bun.file(resolve18(import.meta.dir, "..", "..", "package.json")).json();
3381
+ if (pkg.name === "@absolutejs/absolute") {
3382
+ globalThis.__absoluteVersion = pkg.version;
3383
+ }
3384
+ } catch {}
3385
+ const buildStart = performance.now();
3386
+ const manifest = await build2({
3387
+ ...config,
3388
+ options: {
3389
+ ...config.options,
3390
+ injectHMR: true
3391
+ }
3392
+ });
3393
+ if (!manifest || Object.keys(manifest).length === 0) {
3394
+ console.log("\u26A0\uFE0F Manifest is empty - this is OK for HTML/HTMX-only projects");
3395
+ }
3396
+ await populateAssetStore(state.assetStore, manifest ?? {}, state.resolvedPaths.buildDir);
3397
+ await cleanStaleAssets(state.assetStore, manifest ?? {}, state.resolvedPaths.buildDir);
3398
+ if (config.reactDirectory) {
3399
+ await buildReactVendor(state.resolvedPaths.buildDir);
3400
+ const vendorDir = resolve18(state.resolvedPaths.buildDir, "react", "vendor");
3401
+ try {
3402
+ const entries = await readdir2(vendorDir);
3403
+ for (const entry of entries) {
3404
+ const webPath = `/react/vendor/${entry}`;
3405
+ const bytes = await Bun.file(resolve18(vendorDir, entry)).bytes();
3406
+ state.assetStore.set(webPath, bytes);
3407
+ }
3408
+ } catch {}
3409
+ }
3410
+ startFileWatching(state, config, (filePath) => {
3411
+ queueFileChange(state, filePath, config, (newBuildResult) => {
3412
+ Object.assign(manifest, newBuildResult.manifest);
3413
+ });
3414
+ });
3415
+ globalThis.__hmrBuildDuration = performance.now() - buildStart;
3416
+ const result = {
3417
+ hmrState: state,
3418
+ manifest
3419
+ };
3420
+ globalThis.__hmrDevResult = result;
3421
+ globalThis.__hmrServerMtime = statSync(resolve18(Bun.main)).mtimeMs;
3422
+ return result;
3423
+ };
3424
+ // src/core/lookup.ts
3425
+ var isWrapped = (source) => ("manifest" in source) && typeof source.manifest === "object" && !Array.isArray(source.manifest);
3426
+ var asset = (source, name) => {
3427
+ const assetPath = isWrapped(source) ? source.manifest[name] : source[name];
3428
+ if (assetPath === undefined) {
3429
+ throw new Error(`Asset "${name}" not found in manifest.`);
3430
+ }
3431
+ return assetPath;
3432
+ };
3433
+
3434
+ // src/core/index.ts
3435
+ init_pageHandlers();
3436
+ // src/plugins/pageRouter.ts
3437
+ var pageRouterPlugin = () => {
3438
+ console.log("Page Router Plugin Not Implemented Yet");
3439
+ };
3440
+ // src/plugins/hmr.ts
3441
+ var STORE_KEY = "__elysiaStore";
3442
+ var restoreStore = (app) => {
3443
+ const saved = globalThis[STORE_KEY];
3444
+ if (saved) {
3445
+ const store = app.store;
3446
+ for (const key of Object.keys(saved)) {
3447
+ store[key] = saved[key];
3448
+ }
3449
+ }
3450
+ globalThis[STORE_KEY] = app.store;
3451
+ };
3452
+ var hmr = (hmrState2, manifest) => {
3453
+ return (app) => {
3454
+ restoreStore(app);
3455
+ return app.onBeforeHandle(({ request }) => {
3456
+ const rawUrl = request.url;
3457
+ const qIdx = rawUrl.indexOf("?");
3458
+ const pathEnd = qIdx === -1 ? rawUrl.length : qIdx;
3459
+ const pathStart = rawUrl.indexOf("/", rawUrl.indexOf("//") + 2);
3460
+ const pathname = rawUrl.slice(pathStart, pathEnd);
3461
+ const bytes = lookupAsset(hmrState2.assetStore, pathname);
3462
+ if (bytes) {
3463
+ return new Response(new Uint8Array(bytes).buffer, {
3464
+ headers: {
3465
+ "Cache-Control": "public, max-age=31536000, immutable",
3466
+ "Content-Type": getMimeType(pathname)
3467
+ }
3468
+ });
3469
+ }
3470
+ }).ws("/hmr", {
3471
+ close: (ws) => handleClientDisconnect(hmrState2, ws),
3472
+ message: (ws, msg) => handleHMRMessage(hmrState2, ws, msg),
3473
+ open: (ws) => handleClientConnect(hmrState2, ws, manifest)
3474
+ }).get("/hmr-status", () => ({
3475
+ connectedClients: hmrState2.connectedClients.size,
3476
+ isRebuilding: hmrState2.isRebuilding,
3477
+ manifestKeys: Object.keys(manifest),
3478
+ rebuildQueue: Array.from(hmrState2.rebuildQueue),
3479
+ timestamp: Date.now()
3480
+ }));
3481
+ };
3482
+ };
3483
+ // src/plugins/networking.ts
3484
+ init_constants();
3485
+ import { argv } from "process";
3486
+ var {env: env3 } = globalThis.Bun;
3487
+
3488
+ // src/utils/networking.ts
3489
+ import os from "os";
3490
+ var getAllNetworkIPs = () => {
3491
+ const interfaces = os.networkInterfaces();
3492
+ const addresses = Object.values(interfaces).flat().filter((iface) => iface !== undefined);
3493
+ const ipv4Addresses = [];
3494
+ for (const addr of addresses) {
3495
+ if (addr.internal)
3496
+ continue;
3497
+ if (addr.family === "IPv4") {
3498
+ ipv4Addresses.push(addr.address);
3499
+ }
3500
+ }
3501
+ return ipv4Addresses;
3502
+ };
3503
+ var getLocalIPAddress = () => {
3504
+ const allIPs = getAllNetworkIPs();
3505
+ if (allIPs.length > 0 && allIPs[0]) {
3506
+ return allIPs[0];
3507
+ }
3508
+ console.warn("No IP address found, falling back to localhost");
3509
+ return "localhost";
3510
+ };
3511
+
3512
+ // src/plugins/networking.ts
3513
+ var host = env3.HOST ?? "localhost";
3514
+ var port = env3.PORT ?? DEFAULT_PORT;
3515
+ var localIP;
3516
+ var args = argv;
3517
+ var hostFlag = args.includes("--host");
3518
+ if (hostFlag) {
3519
+ localIP = getLocalIPAddress();
3520
+ host = "0.0.0.0";
3521
+ }
3522
+ var networking = (app) => app.listen({
3523
+ hostname: host,
3524
+ port
3525
+ }, () => {
3526
+ const isHotReload = !!globalThis.__hmrServerStartup;
3527
+ globalThis.__hmrServerStartup = true;
3528
+ if (isHotReload) {
3529
+ return;
3530
+ }
3531
+ const buildDuration = globalThis.__hmrBuildDuration ?? 0;
3532
+ const version = globalThis.__absoluteVersion ?? "";
3533
+ logger.ready({
3534
+ duration: buildDuration,
3535
+ host,
3536
+ networkUrl: hostFlag ? `http://${localIP}:${port}/` : undefined,
3537
+ port,
3538
+ version
3539
+ });
3540
+ });
3541
+ // src/utils/getEnv.ts
3542
+ var {env: env4 } = globalThis.Bun;
3543
+ var getEnv = (key) => {
3544
+ const environmentVariable = env4[key];
3545
+ if (typeof environmentVariable !== "string" || environmentVariable.length === 0) {
3546
+ throw new Error(`Missing environment variable ${key}`);
3547
+ }
3548
+ return environmentVariable;
3549
+ };
3550
+ // src/utils/registerClientScript.ts
3551
+ var scriptRegistry = new Map;
3552
+ var requestCounter = 0;
3553
+ var getRequestId = () => `req_${Date.now()}_${++requestCounter}`;
3554
+ var registerClientScript = (script, requestId) => {
3555
+ const id = requestId || globalThis.__absolutejs_requestId || getRequestId();
3556
+ if (!scriptRegistry.has(id)) {
3557
+ scriptRegistry.set(id, new Set);
3558
+ }
3559
+ scriptRegistry.get(id).add(script);
3560
+ return id;
3561
+ };
3562
+ if (typeof globalThis !== "undefined") {
3563
+ globalThis.registerClientScript = registerClientScript;
3564
+ }
3565
+ var getAndClearClientScripts = (requestId) => {
3566
+ const scripts = scriptRegistry.get(requestId);
3567
+ if (!scripts) {
3568
+ return [];
3569
+ }
3570
+ const scriptArray = Array.from(scripts);
3571
+ scriptRegistry.delete(requestId);
3572
+ return scriptArray;
3573
+ };
3574
+ var generateClientScriptCode = (scripts) => {
3575
+ if (scripts.length === 0) {
3576
+ return "";
3577
+ }
3578
+ const scriptCode = scripts.map((script, index) => {
3579
+ const funcString = script.toString();
3580
+ const bodyMatch = funcString.match(/\{([\s\S]*)\}/);
3581
+ if (!bodyMatch || !bodyMatch[1]) {
3582
+ return "";
3583
+ }
3584
+ const body = bodyMatch[1].trim();
3585
+ return `
3586
+ (function() {
3587
+ function executeScript_${index}() {
3588
+ ${body}
3589
+ }
3590
+
3591
+ // Try executing immediately if DOM is ready
3592
+ if (document.readyState === 'complete' || document.readyState === 'interactive') {
3593
+ executeScript_${index}();
3594
+ } else {
3595
+ document.addEventListener('DOMContentLoaded', executeScript_${index});
3596
+ }
3597
+
3598
+ // Also try with delays to ensure element is available after hydration
3599
+ setTimeout(executeScript_${index}, 100);
3600
+ setTimeout(executeScript_${index}, 300);
3601
+ setTimeout(executeScript_${index}, 500);
3602
+ setTimeout(executeScript_${index}, 1000);
3603
+
3604
+ // Fallback on window load
3605
+ window.addEventListener('load', executeScript_${index});
3606
+ })();`;
3607
+ }).join(`
3608
+ `);
3609
+ return `<script>
3610
+ (function() {
3611
+ ${scriptCode}
3612
+ })();
3613
+ </script>`;
3614
+ };
3615
+ var clearAllClientScripts = () => {
3616
+ scriptRegistry.clear();
3617
+ };
3618
+ // src/utils/getRegisterClientScript.ts
3619
+ var getRegisterClientScript = () => {
3620
+ const globalRegister = globalThis.registerClientScript;
3621
+ if (globalRegister && typeof globalRegister === "function") {
3622
+ return globalRegister;
3623
+ }
3624
+ return null;
3625
+ };
3626
+ export {
3627
+ updateAssetPaths,
3628
+ registerClientScript,
3629
+ pageRouterPlugin,
3630
+ networking,
3631
+ isValidHMRClientMessage,
3632
+ hmrState,
3633
+ hmr,
3634
+ handleVuePageRequest,
3635
+ handleSveltePageRequest,
3636
+ handleReactPageRequest,
3637
+ handlePageRequest,
3638
+ handleHTMXPageRequest,
3639
+ handleHTMLPageRequest,
3640
+ getRegisterClientScript,
3641
+ getLocalIPAddress,
3642
+ getEnv,
3643
+ getAndClearClientScripts,
3644
+ getAllNetworkIPs,
3645
+ generateHeadElement,
3646
+ generateClientScriptCode,
3647
+ devBuild,
3648
+ clearAllClientScripts,
3649
+ build2 as build,
3650
+ asset,
3651
+ WS_READY_STATE_OPEN,
3652
+ UNFOUND_INDEX,
3653
+ TWO_THIRDS,
3654
+ TIME_PRECISION,
3655
+ SECONDS_IN_A_MINUTE,
3656
+ MINUTES_IN_AN_HOUR,
3657
+ MILLISECONDS_IN_A_SECOND,
3658
+ MILLISECONDS_IN_A_MINUTE,
3659
+ MILLISECONDS_IN_A_DAY,
3660
+ HOURS_IN_DAY,
3661
+ DEFAULT_PORT,
3662
+ DEFAULT_CHUNK_SIZE,
3663
+ BUN_BUILD_WARNING_SUPPRESSION
3664
+ };
3665
+
3666
+ //# debugId=76147DED80C02ADD64756E2164756E21
3667
+ //# sourceMappingURL=index.js.map