@absolutejs/absolute 0.8.14 → 0.9.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 (33) hide show
  1. package/README.md +146 -19
  2. package/dist/build/compileVue.d.ts +5 -0
  3. package/dist/{src/build → build}/generateManifest.d.ts +1 -1
  4. package/dist/core/build.d.ts +4 -0
  5. package/dist/{src/core → core}/index.d.ts +1 -0
  6. package/dist/core/lookup.d.ts +2 -0
  7. package/dist/core/pageHandlers.d.ts +14 -0
  8. package/dist/{src/index.d.ts → index.d.ts} +1 -1
  9. package/dist/index.js +384 -183
  10. package/dist/index.js.map +11 -9
  11. package/dist/types.d.ts +24 -0
  12. package/eslint.config.mjs +33 -3
  13. package/package.json +7 -7
  14. package/tsconfig.lint.json +20 -0
  15. package/dist/src/core/build.d.ts +0 -2
  16. package/dist/src/core/pageHandlers.d.ts +0 -10
  17. package/dist/src/types.d.ts +0 -20
  18. /package/dist/{src/svelte → build}/compileSvelte.d.ts +0 -0
  19. /package/dist/{src/build → build}/generateReactIndexes.d.ts +0 -0
  20. /package/dist/{src/build → build}/scanEntryPoints.d.ts +0 -0
  21. /package/dist/{src/build → build}/updateScriptTags.d.ts +0 -0
  22. /package/dist/{src/constants.d.ts → constants.d.ts} +0 -0
  23. /package/dist/{src/plugins → plugins}/index.d.ts +0 -0
  24. /package/dist/{src/plugins → plugins}/networkingPlugin.d.ts +0 -0
  25. /package/dist/{src/plugins → plugins}/pageRouterPlugin.d.ts +0 -0
  26. /package/dist/{src/svelte → svelte}/renderToPipeableStream.d.ts +0 -0
  27. /package/dist/{src/svelte → svelte}/renderToReadableStream.d.ts +0 -0
  28. /package/dist/{src/svelte → svelte}/renderToString.d.ts +0 -0
  29. /package/dist/{src/utils → utils}/escapeScriptContent.d.ts +0 -0
  30. /package/dist/{src/utils → utils}/getDurationString.d.ts +0 -0
  31. /package/dist/{src/utils → utils}/index.d.ts +0 -0
  32. /package/dist/{src/utils → utils}/networking.d.ts +0 -0
  33. /package/dist/{src/utils → utils}/validateSafePath.d.ts +0 -0
package/dist/index.js CHANGED
@@ -11,49 +11,223 @@ var TWO_THIRDS = 2 / 3;
11
11
  var DEFAULT_PORT = 3000;
12
12
  var DEFAULT_CHUNK_SIZE = 16384;
13
13
  // src/core/build.ts
14
- import { rm as rm2, mkdir as mkdir3, cp } from "fs/promises";
15
- import { basename as basename3, join as join3 } from "path";
16
- import { cwd, exit } from "process";
14
+ import { rm as rm2, mkdir as mkdir4, cp } from "fs/promises";
15
+ import { basename as basename4, join as join4, sep as sep2 } from "path";
16
+ import { cwd, env as env2, exit } from "process";
17
17
  var {$, build: bunBuild } = globalThis.Bun;
18
18
 
19
- // src/build/generateManifest.ts
20
- var generateManifest = (outputs, buildDirectoryAbsolute, svelteDirName) => {
21
- const prefix = svelteDirName ? `(?:${svelteDirName}/)?` : "";
22
- const pagesRegex = new RegExp(`^${prefix}pages/`);
23
- const indexesRegex = new RegExp(`^${prefix}indexes/`);
24
- return outputs.reduce((manifest, artifact) => {
25
- let relativePath = artifact.path.startsWith(buildDirectoryAbsolute) ? artifact.path.slice(buildDirectoryAbsolute.length) : artifact.path;
26
- relativePath = relativePath.replace(/^\/+/, "");
27
- const segments = relativePath.split("/");
28
- const fileWithHash = segments.pop();
29
- if (!fileWithHash)
30
- return manifest;
31
- const [baseName] = fileWithHash.split(`.${artifact.hash}.`);
32
- if (indexesRegex.test(relativePath)) {
33
- manifest[`${baseName}Index`] = `/${relativePath}`;
34
- } else if (pagesRegex.test(relativePath)) {
35
- manifest[baseName] = artifact.path;
19
+ // src/build/compileSvelte.ts
20
+ import { mkdir } from "fs/promises";
21
+ import { basename, join } from "path";
22
+ import { env } from "process";
23
+ var {write, file } = globalThis.Bun;
24
+ import { compile, preprocess } from "svelte/compiler";
25
+ var compileSvelte = async (entryPoints, outputDirectory) => {
26
+ const pagesDir = join(outputDirectory, "pages");
27
+ const clientDir = join(outputDirectory, "client");
28
+ const indexesDir = join(outputDirectory, "indexes");
29
+ await Promise.all([
30
+ mkdir(clientDir, { recursive: true }),
31
+ mkdir(indexesDir, { recursive: true })
32
+ ]);
33
+ const isDev = env.NODE_ENV === "development";
34
+ const builds = await Promise.all(entryPoints.map(async (entry) => {
35
+ const source = await file(entry).text();
36
+ const { code: pre } = await preprocess(source, {});
37
+ const name = basename(entry, ".svelte");
38
+ const { js: ssrJs } = compile(pre, {
39
+ css: "injected",
40
+ dev: isDev,
41
+ filename: entry,
42
+ generate: "server"
43
+ });
44
+ const ssrPath = join(pagesDir, `${name}.js`);
45
+ const { js: clientJs } = compile(pre, {
46
+ css: "injected",
47
+ dev: isDev,
48
+ filename: entry,
49
+ generate: "client"
50
+ });
51
+ const clientComponentPath = join(clientDir, `${name}.js`);
52
+ const bootstrap = `import Component from "../client/${name}.js";
53
+ import { hydrate } from "svelte";
54
+ hydrate(Component,{target:document.body,props:window.__INITIAL_PROPS__??{}});`;
55
+ const clientIndexPath = join(indexesDir, `${name}.js`);
56
+ await Promise.all([
57
+ write(ssrPath, ssrJs.code),
58
+ write(clientComponentPath, clientJs.code),
59
+ write(clientIndexPath, bootstrap)
60
+ ]);
61
+ return { clientIndexPath, ssrPath };
62
+ }));
63
+ return {
64
+ svelteClientPaths: builds.map(({ clientIndexPath }) => clientIndexPath),
65
+ svelteServerPaths: builds.map(({ ssrPath }) => ssrPath)
66
+ };
67
+ };
68
+
69
+ // src/build/compileVue.ts
70
+ import { mkdir as mkdir2 } from "fs/promises";
71
+ import { basename as basename2, extname, join as join2, relative } from "path";
72
+ import {
73
+ parse,
74
+ compileScript,
75
+ compileTemplate,
76
+ compileStyle
77
+ } from "@vue/compiler-sfc";
78
+ var {file: file2, write: write2 } = globalThis.Bun;
79
+ var compileVue = async (entryPoints, outputDirectory) => {
80
+ const pagesDir = join2(outputDirectory, "pages");
81
+ const scriptsDir = join2(outputDirectory, "scripts");
82
+ const stylesDir = join2(outputDirectory, "styles");
83
+ const clientDir = join2(outputDirectory, "client");
84
+ const indexesDir = join2(outputDirectory, "indexes");
85
+ await Promise.all([
86
+ mkdir2(pagesDir, { recursive: true }),
87
+ mkdir2(scriptsDir, { recursive: true }),
88
+ mkdir2(stylesDir, { recursive: true }),
89
+ mkdir2(clientDir, { recursive: true }),
90
+ mkdir2(indexesDir, { recursive: true })
91
+ ]);
92
+ const results = await Promise.all(entryPoints.map(async (entry) => {
93
+ const source = await file2(entry).text();
94
+ const filename = basename2(entry);
95
+ const name = basename2(entry, extname(entry));
96
+ const { descriptor } = parse(source, { filename });
97
+ const cssFiles = await Promise.all(descriptor.styles.map(async (styleBlock, idx) => {
98
+ const outName = descriptor.styles.length === 1 ? `${name}.css` : `${name}.${idx}.css`;
99
+ const { code } = compileStyle({
100
+ filename,
101
+ id: name,
102
+ scoped: Boolean(styleBlock.scoped),
103
+ source: styleBlock.content,
104
+ trim: true
105
+ });
106
+ await write2(join2(stylesDir, outName), code);
107
+ return outName;
108
+ }));
109
+ const scriptBlock = compileScript(descriptor, {
110
+ id: name,
111
+ inlineTemplate: false
112
+ });
113
+ const scriptPath = join2(scriptsDir, `${name}.ts`);
114
+ const cleanedScript = scriptBlock.content.replace(/setup\(\s*__props\s*:\s*any/g, "setup(__props");
115
+ await write2(scriptPath, cleanedScript);
116
+ const ssrTpl = compileTemplate({
117
+ compilerOptions: {
118
+ bindingMetadata: scriptBlock.bindings,
119
+ prefixIdentifiers: true
120
+ },
121
+ filename,
122
+ id: name,
123
+ source: descriptor.template?.content ?? "",
124
+ ssr: true,
125
+ ssrCssVars: descriptor.cssVars
126
+ });
127
+ const serverImport = `import scriptMod, * as named from '../scripts/${name}.ts';`;
128
+ let ssrCode = ssrTpl.code.replace(/(import\s+[^\n]+["']vue\/server-renderer["'][^\n]*\n)/, `$1${serverImport}
129
+ `);
130
+ if (/import\s*\{[^}]+\}\s*from\s*['"]vue['"]/.test(ssrCode)) {
131
+ ssrCode = ssrCode.replace(/import\s*\{([^}]+)\}\s*from\s*['"]vue['"];?/, (_, imports) => `import { defineComponent, ${imports.trim()} } from 'vue';`);
36
132
  } else {
37
- manifest[baseName] = `/${relativePath}`;
133
+ ssrCode = `import { defineComponent } from 'vue';
134
+ ${ssrCode}`;
38
135
  }
39
- return manifest;
136
+ const ssrPath = join2(pagesDir, `${name}.js`);
137
+ await write2(ssrPath, [
138
+ ssrCode,
139
+ `export default defineComponent({ ...scriptMod, ...named, ssrRender });`
140
+ ].join(`
141
+ `));
142
+ const clientTpl = compileTemplate({
143
+ compilerOptions: {
144
+ bindingMetadata: scriptBlock.bindings,
145
+ cacheHandlers: true,
146
+ hoistStatic: true,
147
+ mode: "module",
148
+ prefixIdentifiers: true
149
+ },
150
+ filename,
151
+ id: name,
152
+ source: descriptor.template?.content ?? ""
153
+ });
154
+ let clientCode = clientTpl.code;
155
+ const clientImport = `import scriptMod, * as named from '../scripts/${name}.ts'`;
156
+ if (/import\s*\{[^}]+\}\s*from\s*['"]vue['"]/.test(clientCode)) {
157
+ clientCode = clientCode.replace(/import\s*\{([^}]+)\}\s*from\s*['"]vue['"];?/, (_, imports) => `import { defineComponent, ${imports.trim()} } from 'vue';
158
+ ${clientImport}`);
159
+ } else {
160
+ clientCode = `import { defineComponent } from 'vue';
161
+ ${clientImport}
162
+ ${clientCode}`;
163
+ }
164
+ const clientComponentPath = join2(clientDir, `${name}.js`);
165
+ await write2(clientComponentPath, [
166
+ clientCode,
167
+ `export default defineComponent({ ...scriptMod, ...named, render })`
168
+ ].join(`
169
+ `));
170
+ const clientIndexPath = join2(indexesDir, `${name}.js`);
171
+ await write2(clientIndexPath, [
172
+ `import Comp from '${relative(indexesDir, clientComponentPath)}'`,
173
+ `import { createSSRApp } from 'vue'`,
174
+ `const props = window.__INITIAL_PROPS__ ?? {}`,
175
+ `const app = createSSRApp(Comp, props)`,
176
+ `app.mount('#app')`
177
+ ].join(`
178
+ `));
179
+ return {
180
+ clientIndexPath,
181
+ cssFiles,
182
+ cssKey: `${name}CSS`,
183
+ serverPath: ssrPath
184
+ };
185
+ }));
186
+ const vueClientPaths = results.map(({ clientIndexPath }) => clientIndexPath);
187
+ const vueServerPaths = results.map(({ serverPath }) => serverPath);
188
+ const vueCssPaths = results.reduce((acc, { cssKey, cssFiles }) => {
189
+ acc[cssKey] = cssFiles;
190
+ return acc;
40
191
  }, {});
192
+ return { vueClientPaths, vueCssPaths, vueServerPaths };
41
193
  };
42
194
 
195
+ // src/build/generateManifest.ts
196
+ var generateManifest = (outputs, buildDirectoryAbsolute) => outputs.reduce((manifest, artifact) => {
197
+ let relative2 = artifact.path.startsWith(buildDirectoryAbsolute) ? artifact.path.slice(buildDirectoryAbsolute.length) : artifact.path;
198
+ relative2 = relative2.replace(/^\/+/, "");
199
+ const segments = relative2.split("/");
200
+ const fileWithHash = segments.pop();
201
+ if (!fileWithHash)
202
+ return manifest;
203
+ const [baseName] = fileWithHash.split(`.${artifact.hash}.`);
204
+ if (!baseName)
205
+ return manifest;
206
+ const folder = segments.length > 1 ? segments[1] : segments[0];
207
+ if (folder === "indexes") {
208
+ manifest[`${baseName}Index`] = `/${relative2}`;
209
+ } else if (folder === "pages") {
210
+ manifest[baseName] = artifact.path;
211
+ } else {
212
+ manifest[baseName] = `/${relative2}`;
213
+ }
214
+ return manifest;
215
+ }, {});
216
+
43
217
  // src/build/generateReactIndexes.ts
44
- import { mkdir, rm, writeFile } from "fs/promises";
45
- import { basename, join } from "path";
218
+ import { mkdir as mkdir3, rm, writeFile } from "fs/promises";
219
+ import { basename as basename3, join as join3 } from "path";
46
220
  var {Glob } = globalThis.Bun;
47
221
  var generateReactIndexFiles = async (reactPagesDirectory, reactIndexesDirectory) => {
48
222
  await rm(reactIndexesDirectory, { force: true, recursive: true });
49
- await mkdir(reactIndexesDirectory);
223
+ await mkdir3(reactIndexesDirectory);
50
224
  const pagesGlob = new Glob("*.*");
51
225
  const files = [];
52
- for await (const file of pagesGlob.scan({ cwd: reactPagesDirectory })) {
53
- files.push(file);
226
+ for await (const file3 of pagesGlob.scan({ cwd: reactPagesDirectory })) {
227
+ files.push(file3);
54
228
  }
55
- const promises = files.map(async (file) => {
56
- const fileName = basename(file);
229
+ const promises = files.map(async (file3) => {
230
+ const fileName = basename3(file3);
57
231
  const [componentName] = fileName.split(".");
58
232
  const content = [
59
233
  `import { hydrateRoot } from 'react-dom/client';`,
@@ -71,7 +245,7 @@ var generateReactIndexFiles = async (reactPagesDirectory, reactIndexesDirectory)
71
245
  `hydrateRoot(document, <${componentName} {...window.__INITIAL_PROPS__} />);`
72
246
  ].join(`
73
247
  `);
74
- return writeFile(join(reactIndexesDirectory, `${componentName}Index.tsx`), content);
248
+ return writeFile(join3(reactIndexesDirectory, `${componentName}.tsx`), content);
75
249
  });
76
250
  await Promise.all(promises);
77
251
  };
@@ -81,8 +255,8 @@ var {Glob: Glob2 } = globalThis.Bun;
81
255
  var scanEntryPoints = async (dir, pattern) => {
82
256
  const entryPaths = [];
83
257
  const glob = new Glob2(pattern);
84
- for await (const file of glob.scan({ absolute: true, cwd: dir })) {
85
- entryPaths.push(file);
258
+ for await (const file3 of glob.scan({ absolute: true, cwd: dir })) {
259
+ entryPaths.push(file3);
86
260
  }
87
261
  return entryPaths;
88
262
  };
@@ -103,56 +277,6 @@ var updateScriptTags = async (manifest, htmlDir) => {
103
277
  await Promise.all(tasks);
104
278
  };
105
279
 
106
- // src/svelte/compileSvelte.ts
107
- import { mkdir as mkdir2 } from "fs/promises";
108
- import { basename as basename2, join as join2 } from "path";
109
- import { env } from "process";
110
- var {write, file } = globalThis.Bun;
111
- import { compile, preprocess } from "svelte/compiler";
112
- var compileSvelte = async (entryPoints, outputDirectory) => {
113
- const pagesDir = join2(outputDirectory, "pages");
114
- const clientDir = join2(outputDirectory, "client");
115
- const indexesDir = join2(outputDirectory, "indexes");
116
- await Promise.all([
117
- mkdir2(clientDir, { recursive: true }),
118
- mkdir2(indexesDir, { recursive: true })
119
- ]);
120
- const isDev = env.NODE_ENV === "development";
121
- const builds = await Promise.all(entryPoints.map(async (entry) => {
122
- const source = await file(entry).text();
123
- const { code: pre } = await preprocess(source, {});
124
- const name = basename2(entry, ".svelte");
125
- const { js: ssrJs } = compile(pre, {
126
- css: "injected",
127
- dev: isDev,
128
- filename: entry,
129
- generate: "server"
130
- });
131
- const ssrPath = join2(pagesDir, `${name}.js`);
132
- const { js: clientJs } = compile(pre, {
133
- css: "injected",
134
- dev: isDev,
135
- filename: entry,
136
- generate: "client"
137
- });
138
- const clientComponentPath = join2(clientDir, `${name}.js`);
139
- const bootstrap = `import Component from "../client/${name}.js";
140
- import { hydrate } from "svelte";
141
- hydrate(Component,{target:document.body,props:window.__INITIAL_PROPS__??{}});`;
142
- const clientIndexPath = join2(indexesDir, `${name}.js`);
143
- await Promise.all([
144
- write(ssrPath, ssrJs.code),
145
- write(clientComponentPath, clientJs.code),
146
- write(clientIndexPath, bootstrap)
147
- ]);
148
- return { clientIndexPath, ssrPath };
149
- }));
150
- return {
151
- svelteClientPaths: builds.map(({ clientIndexPath }) => clientIndexPath),
152
- svelteServerPaths: builds.map(({ ssrPath }) => ssrPath)
153
- };
154
- };
155
-
156
280
  // src/utils/getDurationString.ts
157
281
  var getDurationString = (duration) => {
158
282
  let durationString;
@@ -167,17 +291,33 @@ var getDurationString = (duration) => {
167
291
  };
168
292
 
169
293
  // src/utils/validateSafePath.ts
170
- import { resolve, relative, sep } from "path";
294
+ import { resolve, relative as relative2, sep } from "path";
171
295
  var validateSafePath = (targetPath, baseDirectory) => {
172
296
  const absoluteBase = resolve(baseDirectory);
173
297
  const absoluteTarget = resolve(baseDirectory, targetPath);
174
- if (relative(absoluteBase, absoluteTarget).startsWith(`..${sep}`)) {
298
+ if (relative2(absoluteBase, absoluteTarget).startsWith(`..${sep}`)) {
175
299
  throw new Error(`Unsafe path: ${targetPath}`);
176
300
  }
177
301
  return absoluteTarget;
178
302
  };
179
303
 
180
304
  // src/core/build.ts
305
+ var commonAncestor = (paths, fallback) => {
306
+ if (paths.length === 0)
307
+ return fallback;
308
+ const segmentsList = paths.map((p) => p.split(sep2));
309
+ const [first] = segmentsList;
310
+ if (!first)
311
+ return fallback;
312
+ const commonSegments = first.filter((segment, index) => segmentsList.every((pathSegs) => pathSegs[index] === segment));
313
+ return commonSegments.length ? commonSegments.join(sep2) : fallback;
314
+ };
315
+ var isDev = env2.NODE_ENV === "development";
316
+ var vueFeatureFlags = {
317
+ __VUE_OPTIONS_API__: "true",
318
+ __VUE_PROD_DEVTOOLS__: isDev ? "true" : "false",
319
+ __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: isDev ? "true" : "false"
320
+ };
181
321
  var build = async ({
182
322
  buildDirectory = "build",
183
323
  assetsDirectory,
@@ -185,6 +325,7 @@ var build = async ({
185
325
  htmlDirectory,
186
326
  htmxDirectory,
187
327
  svelteDirectory,
328
+ vueDirectory,
188
329
  tailwind,
189
330
  options
190
331
  }) => {
@@ -192,127 +333,139 @@ var build = async ({
192
333
  const projectRoot = cwd();
193
334
  const buildPath = validateSafePath(buildDirectory, projectRoot);
194
335
  const assetsPath = assetsDirectory && validateSafePath(assetsDirectory, projectRoot);
195
- const reactDirectoryPath = reactDirectory && validateSafePath(reactDirectory, projectRoot);
196
- const htmlDirectoryPath = htmlDirectory && validateSafePath(htmlDirectory, projectRoot);
197
- const htmxPath = htmxDirectory && validateSafePath(htmxDirectory, projectRoot);
198
- const svelteDirectoryPath = svelteDirectory && validateSafePath(svelteDirectory, projectRoot);
199
- const reactIndexesPath = reactDirectoryPath && join3(reactDirectoryPath, "indexes");
200
- const reactPagesPath = reactDirectoryPath && join3(reactDirectoryPath, "pages");
201
- const htmlPagesPath = htmlDirectoryPath && join3(htmlDirectoryPath, "pages");
202
- const htmlScriptsPath = htmlDirectoryPath && join3(htmlDirectoryPath, "scripts");
203
- const sveltePagesPath = svelteDirectoryPath && join3(svelteDirectoryPath, "pages");
204
- const isSingleFrontend = [
205
- reactDirectoryPath,
206
- htmlDirectoryPath,
207
- htmxPath,
208
- svelteDirectoryPath
209
- ].filter(Boolean).length === 1;
210
- const isSvelteOnly = isSingleFrontend && svelteDirectoryPath !== undefined;
211
- const serverOutDir = isSvelteOnly ? join3(buildPath, "pages") : buildPath;
212
- const serverRoot = isSvelteOnly ? join3(svelteDirectoryPath, "pages") : undefined;
213
- const svelteOutDir = isSingleFrontend ? buildPath : join3(buildPath, basename3(svelteDirectoryPath ?? ""));
214
- const svelteDirName = svelteDirectoryPath && basename3(svelteDirectoryPath);
336
+ const reactDir = reactDirectory && validateSafePath(reactDirectory, projectRoot);
337
+ const htmlDir = htmlDirectory && validateSafePath(htmlDirectory, projectRoot);
338
+ const htmxDir = htmxDirectory && validateSafePath(htmxDirectory, projectRoot);
339
+ const svelteDir = svelteDirectory && validateSafePath(svelteDirectory, projectRoot);
340
+ const vueDir = vueDirectory && validateSafePath(vueDirectory, projectRoot);
341
+ const reactIndexesPath = reactDir && join4(reactDir, "indexes");
342
+ const reactPagesPath = reactDir && join4(reactDir, "pages");
343
+ const htmlPagesPath = htmlDir && join4(htmlDir, "pages");
344
+ const htmlScriptsPath = htmlDir && join4(htmlDir, "scripts");
345
+ const sveltePagesPath = svelteDir && join4(svelteDir, "pages");
346
+ const vuePagesPath = vueDir && join4(vueDir, "pages");
347
+ const frontends = [reactDir, htmlDir, htmxDir, svelteDir, vueDir].filter(Boolean);
348
+ const isSingle = frontends.length === 1;
349
+ let serverOutDir;
350
+ if (svelteDir) {
351
+ serverOutDir = join4(buildPath, basename4(svelteDir), "pages");
352
+ } else if (vueDir) {
353
+ serverOutDir = join4(buildPath, basename4(vueDir), "pages");
354
+ }
355
+ let serverRoot;
356
+ if (svelteDir) {
357
+ serverRoot = join4(svelteDir, "pages");
358
+ } else if (vueDir) {
359
+ serverRoot = join4(vueDir, "pages");
360
+ }
215
361
  await rm2(buildPath, { force: true, recursive: true });
216
- await mkdir3(buildPath);
217
- if (reactIndexesPath && reactPagesPath) {
362
+ await mkdir4(buildPath);
363
+ if (reactIndexesPath && reactPagesPath)
218
364
  await generateReactIndexFiles(reactPagesPath, reactIndexesPath);
219
- }
220
- if (assetsPath) {
221
- await cp(assetsPath, join3(buildPath, "assets"), {
365
+ if (assetsPath)
366
+ await cp(assetsPath, join4(buildPath, "assets"), {
222
367
  force: true,
223
368
  recursive: true
224
369
  });
225
- }
226
- if (htmxPath) {
227
- await mkdir3(join3(buildPath, "htmx"));
228
- await cp(htmxPath, join3(buildPath, "htmx"), {
370
+ if (htmxDir) {
371
+ await mkdir4(join4(buildPath, "htmx"));
372
+ await cp(htmxDir, join4(buildPath, "htmx"), {
229
373
  force: true,
230
374
  recursive: true
231
375
  });
232
376
  }
233
- if (tailwind) {
234
- await $`bunx @tailwindcss/cli -i ${tailwind.input} -o ${join3(buildPath, tailwind.output)}`;
235
- }
236
- const reactEntryPoints = reactIndexesPath ? await scanEntryPoints(reactIndexesPath, "*.tsx") : [];
237
- const svelteEntryPoints = sveltePagesPath ? await scanEntryPoints(sveltePagesPath, "*.svelte") : [];
238
- const htmlEntryPoints = htmlScriptsPath ? await scanEntryPoints(htmlScriptsPath, "*.{js,ts}") : [];
239
- const { svelteServerPaths, svelteClientPaths } = svelteDirectoryPath ? await compileSvelte(svelteEntryPoints, svelteDirectoryPath) : { svelteClientPaths: [], svelteServerPaths: [] };
240
- const serverEntryPoints = [
241
- ...reactEntryPoints,
242
- ...htmlEntryPoints,
243
- ...svelteServerPaths
377
+ if (tailwind)
378
+ await $`bunx @tailwindcss/cli -i ${tailwind.input} -o ${join4(buildPath, tailwind.output)}`;
379
+ const reactEntries = reactIndexesPath ? await scanEntryPoints(reactIndexesPath, "*.tsx") : [];
380
+ const htmlEntries = htmlScriptsPath ? await scanEntryPoints(htmlScriptsPath, "*.{js,ts}") : [];
381
+ const svelteEntries = sveltePagesPath ? await scanEntryPoints(sveltePagesPath, "*.svelte") : [];
382
+ const vueEntries = vuePagesPath ? await scanEntryPoints(vuePagesPath, "*.vue") : [];
383
+ const { svelteServerPaths, svelteClientPaths } = svelteDir ? await compileSvelte(svelteEntries, svelteDir) : { svelteClientPaths: [], svelteServerPaths: [] };
384
+ const { vueServerPaths, vueClientPaths, vueCssPaths } = vueDir ? await compileVue(vueEntries, vueDir) : { vueClientPaths: [], vueCssPaths: {}, vueServerPaths: [] };
385
+ const serverEntryPoints = [...svelteServerPaths, ...vueServerPaths];
386
+ const clientEntryPoints = [
387
+ ...reactEntries,
388
+ ...svelteClientPaths,
389
+ ...htmlEntries,
390
+ ...vueClientPaths
244
391
  ];
245
- if (serverEntryPoints.length === 0) {
246
- console.warn("No server entry points found, skipping manifest generation");
392
+ if (serverEntryPoints.length === 0 && clientEntryPoints.length === 0) {
393
+ console.warn("No entry points found");
247
394
  return null;
248
395
  }
249
- const { logs: serverLogs, outputs: serverOutputs } = await bunBuild({
250
- entrypoints: serverEntryPoints,
251
- format: "esm",
252
- naming: `[dir]/[name].[hash].[ext]`,
253
- outdir: serverOutDir,
254
- root: serverRoot,
255
- target: "bun"
256
- }).catch((error) => {
257
- console.error("Server build failed:", error);
258
- exit(1);
259
- });
396
+ let serverLogs = [];
397
+ let serverOutputs = [];
398
+ if (serverEntryPoints.length > 0) {
399
+ const { logs, outputs } = await bunBuild({
400
+ entrypoints: serverEntryPoints,
401
+ format: "esm",
402
+ naming: `[dir]/[name].[hash].[ext]`,
403
+ outdir: serverOutDir,
404
+ root: serverRoot,
405
+ target: "bun"
406
+ }).catch((err) => {
407
+ console.error("Server build failed:", err);
408
+ exit(1);
409
+ });
410
+ serverLogs = logs;
411
+ serverOutputs = outputs;
412
+ }
260
413
  let clientLogs = [];
261
414
  let clientOutputs = [];
262
- if (svelteDirectoryPath) {
415
+ if (clientEntryPoints.length > 0) {
416
+ const roots = [reactDir, svelteDir, htmlDir, vueDir].filter((dir) => Boolean(dir));
417
+ const clientRoot = isSingle ? roots[0] ?? projectRoot : commonAncestor(roots, projectRoot);
263
418
  const { logs, outputs } = await bunBuild({
264
- entrypoints: svelteClientPaths,
419
+ define: vueDirectory ? vueFeatureFlags : undefined,
420
+ entrypoints: clientEntryPoints,
265
421
  format: "esm",
266
422
  naming: `[dir]/[name].[hash].[ext]`,
267
- outdir: svelteOutDir,
268
- root: svelteDirectoryPath,
423
+ outdir: buildPath,
424
+ root: clientRoot,
269
425
  target: "browser"
270
- }).catch((error) => {
271
- console.error("Client build failed:", error);
426
+ }).catch((err) => {
427
+ console.error("Client build failed:", err);
272
428
  exit(1);
273
429
  });
274
430
  clientLogs = logs;
275
431
  clientOutputs = outputs;
276
432
  }
277
- [...serverLogs, ...clientLogs].forEach((log) => {
278
- if (log.level === "error")
279
- console.error(log);
280
- else if (log.level === "warning")
281
- console.warn(log);
282
- else
283
- console.info(log);
284
- });
285
- const manifest = generateManifest([...serverOutputs, ...clientOutputs], buildPath, svelteDirName);
286
- if (htmlDirectoryPath && htmlPagesPath) {
287
- const outputHtmlPages = join3(buildPath, basename3(htmlDirectoryPath), "pages");
288
- await mkdir3(outputHtmlPages, { recursive: true });
433
+ const allLogs = [...serverLogs, ...clientLogs];
434
+ for (const log of allLogs) {
435
+ if (typeof log !== "object" || log === null || !("level" in log))
436
+ continue;
437
+ if (log.level === "error" && (console.error(log), 1))
438
+ continue;
439
+ if (log.level === "warning" && (console.warn(log), 1))
440
+ continue;
441
+ console.info(log);
442
+ }
443
+ const manifest = generateManifest([...serverOutputs, ...clientOutputs], buildPath);
444
+ if (htmlDir && htmlPagesPath) {
445
+ const outputHtmlPages = join4(buildPath, basename4(htmlDir), "pages");
446
+ await mkdir4(outputHtmlPages, { recursive: true });
289
447
  await cp(htmlPagesPath, outputHtmlPages, {
290
448
  force: true,
291
449
  recursive: true
292
450
  });
293
451
  await updateScriptTags(manifest, outputHtmlPages);
294
452
  }
295
- if (!options?.preserveIntermediateFiles && svelteDirectoryPath) {
296
- await rm2(join3(svelteDirectoryPath, "indexes"), {
297
- force: true,
298
- recursive: true
299
- });
300
- await rm2(join3(svelteDirectoryPath, "client"), {
301
- force: true,
302
- recursive: true
303
- });
304
- await Promise.all(svelteServerPaths.map((filePath) => rm2(filePath, { force: true })));
453
+ if (!options?.preserveIntermediateFiles && svelteDir) {
454
+ await rm2(join4(svelteDir, "indexes"), { force: true, recursive: true });
455
+ await rm2(join4(svelteDir, "client"), { force: true, recursive: true });
456
+ await Promise.all(svelteServerPaths.map((path) => rm2(path, { force: true })));
305
457
  }
306
- if (!options?.preserveIntermediateFiles && reactIndexesPath) {
458
+ if (!options?.preserveIntermediateFiles && reactIndexesPath)
307
459
  await rm2(reactIndexesPath, { force: true, recursive: true });
308
- }
309
460
  console.log(`Build completed in ${getDurationString(performance.now() - buildStart)}`);
310
- return manifest;
461
+ return { ...manifest, ...vueCssPaths };
311
462
  };
312
463
  // src/core/pageHandlers.ts
313
- var {file: file2 } = globalThis.Bun;
464
+ var {file: file3 } = globalThis.Bun;
314
465
  import { createElement } from "react";
315
466
  import { renderToReadableStream as renderReactToReadableStream } from "react-dom/server";
467
+ import { createSSRApp, h } from "vue";
468
+ import { renderToWebStream as renderVueToWebStream } from "vue/server-renderer";
316
469
 
317
470
  // src/svelte/renderToReadableStream.ts
318
471
  import { render } from "svelte/server";
@@ -326,7 +479,10 @@ var ESCAPE_LOOKUP = {
326
479
  ">": "\\u003E"
327
480
  };
328
481
  var ESCAPE_REGEX = /[&><\u2028\u2029]/g;
329
- var escapeScriptContent = (content) => content.replace(ESCAPE_REGEX, (char) => ESCAPE_LOOKUP[char]);
482
+ var escapeScriptContent = (content) => content.replace(ESCAPE_REGEX, (char) => {
483
+ const escaped = ESCAPE_LOOKUP[char];
484
+ return escaped !== undefined ? escaped : char;
485
+ });
330
486
 
331
487
  // src/svelte/renderToReadableStream.ts
332
488
  var renderToReadableStream = async (component, props, {
@@ -382,26 +538,67 @@ var handleReactPageRequest = async (pageComponent, index, ...props) => {
382
538
  headers: { "Content-Type": "text/html" }
383
539
  });
384
540
  };
385
- var handleSveltePageRequest = async (PageComponent, manifest, props) => {
386
- const componentPath = PageComponent.toString();
387
- const pathSegments = componentPath.split("/");
388
- const lastSegment = pathSegments[pathSegments.length - 1] ?? "";
389
- const componentName = lastSegment.replace(/\.svelte$/, "");
390
- const pagePath = manifest[componentName];
391
- const indexPath = manifest[`${componentName}Index`];
541
+ var handleSveltePageRequest = async (_PageComponent, pagePath, indexPath, props) => {
392
542
  const { default: ImportedPageComponent } = await import(pagePath);
393
543
  const stream = await renderToReadableStream(ImportedPageComponent, props, {
394
- bootstrapModules: [indexPath],
544
+ bootstrapModules: indexPath ? [indexPath] : [],
395
545
  bootstrapScriptContent: `window.__INITIAL_PROPS__=${JSON.stringify(props)}`
396
546
  });
397
547
  return new Response(stream, {
398
548
  headers: { "Content-Type": "text/html" }
399
549
  });
400
550
  };
401
- var handleHTMLPageRequest = (html) => file2(html);
551
+ var handleVuePageRequest = async (_PageComponent, pagePath, indexPath, ...props) => {
552
+ const [maybeProps] = props;
553
+ const { default: ImportedPageComponent } = await import(pagePath);
554
+ const app = createSSRApp({
555
+ render: () => h(ImportedPageComponent, maybeProps ?? {})
556
+ });
557
+ const bodyStream = renderVueToWebStream(app);
558
+ const head = '<!DOCTYPE html><html><head></head><body><div id="app">';
559
+ const tail = `</div><script>window.__INITIAL_PROPS__=${JSON.stringify(maybeProps ?? {})}</script><script type="module" src="${indexPath}"></script></body></html>`;
560
+ const stream = new ReadableStream({
561
+ start(controller) {
562
+ controller.enqueue(head);
563
+ const reader = bodyStream.getReader();
564
+ const pumpLoop = () => {
565
+ reader.read().then(({ done, value }) => done ? (controller.enqueue(tail), controller.close()) : (controller.enqueue(value), pumpLoop())).catch((err) => controller.error(err));
566
+ };
567
+ pumpLoop();
568
+ }
569
+ });
570
+ return new Response(stream, {
571
+ headers: { "Content-Type": "text/html" }
572
+ });
573
+ };
574
+ var handleHTMLPageRequest = (html) => file3(html);
575
+ var handlePageRequest = (PageComponent, ...props) => {
576
+ console.log("handlePageRequest coming soon.", PageComponent, props);
577
+ };
578
+ // src/core/lookup.ts
579
+ var asset = (manifest, name) => {
580
+ const assetPath = manifest[name];
581
+ if (assetPath === undefined) {
582
+ throw new Error(`Asset "${name}" not found in manifest.`);
583
+ }
584
+ if (Array.isArray(assetPath)) {
585
+ throw new Error(`"${name}" is an array, use 'assets' instead.`);
586
+ }
587
+ return assetPath;
588
+ };
589
+ var assets = (manifest, name) => {
590
+ const assetPaths = manifest[name];
591
+ if (assetPaths === undefined) {
592
+ throw new Error(`Assets "${name}" not found in manifest.`);
593
+ }
594
+ if (!Array.isArray(assetPaths)) {
595
+ throw new Error(`"${name}" is not an array, use 'asset' instead.`);
596
+ }
597
+ return assetPaths;
598
+ };
402
599
  // src/plugins/networkingPlugin.ts
403
600
  import { argv } from "process";
404
- var {env: env2 } = globalThis.Bun;
601
+ var {env: env3 } = globalThis.Bun;
405
602
 
406
603
  // src/utils/networking.ts
407
604
  import os from "os";
@@ -416,8 +613,8 @@ var getLocalIPAddress = () => {
416
613
  };
417
614
 
418
615
  // src/plugins/networkingPlugin.ts
419
- var host = env2.HOST ?? "localhost";
420
- var port = env2.PORT ?? DEFAULT_PORT;
616
+ var host = env3.HOST ?? "localhost";
617
+ var port = env3.PORT ?? DEFAULT_PORT;
421
618
  var localIP;
422
619
  var args = argv;
423
620
  var hostFlag = args.includes("--host");
@@ -444,11 +641,15 @@ export {
444
641
  updateScriptTags,
445
642
  pageRouterPlugin,
446
643
  networkingPlugin,
644
+ handleVuePageRequest,
447
645
  handleSveltePageRequest,
448
646
  handleReactPageRequest,
647
+ handlePageRequest,
449
648
  handleHTMLPageRequest,
450
649
  getLocalIPAddress,
451
650
  build,
651
+ assets,
652
+ asset,
452
653
  TWO_THIRDS,
453
654
  TIME_PRECISION,
454
655
  SECONDS_IN_A_MINUTE,
@@ -461,5 +662,5 @@ export {
461
662
  DEFAULT_CHUNK_SIZE
462
663
  };
463
664
 
464
- //# debugId=F0D0DE61A724A5EB64756E2164756E21
665
+ //# debugId=F6760E8AC62BE5FB64756E2164756E21
465
666
  //# sourceMappingURL=index.js.map