@absolutejs/absolute 0.8.15 → 0.9.1

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 (37) hide show
  1. package/dist/build/compileSvelte.d.ts +10 -0
  2. package/dist/build/compileVue.d.ts +5 -0
  3. package/dist/{src/build → build}/generateManifest.d.ts +1 -1
  4. package/dist/build/updateHTMLAssetPaths.d.ts +1 -0
  5. package/dist/core/build.d.ts +2 -0
  6. package/dist/{src/core → core}/index.d.ts +1 -0
  7. package/dist/core/lookup.d.ts +1 -0
  8. package/dist/core/pageHandlers.d.ts +14 -0
  9. package/dist/{src/index.d.ts → index.d.ts} +1 -1
  10. package/dist/index.js +546 -187
  11. package/dist/index.js.map +15 -11
  12. package/dist/types.d.ts +24 -0
  13. package/dist/utils/generateHeadElement.d.ts +17 -0
  14. package/dist/utils/index.d.ts +3 -0
  15. package/dist/utils/stringModifiers.d.ts +2 -0
  16. package/eslint.config.mjs +38 -4
  17. package/package.json +8 -8
  18. package/tsconfig.build.json +20 -0
  19. package/dist/src/build/updateScriptTags.d.ts +0 -1
  20. package/dist/src/core/build.d.ts +0 -2
  21. package/dist/src/core/pageHandlers.d.ts +0 -10
  22. package/dist/src/svelte/compileSvelte.d.ts +0 -4
  23. package/dist/src/types.d.ts +0 -20
  24. package/dist/src/utils/index.d.ts +0 -2
  25. /package/dist/{src/build → build}/generateReactIndexes.d.ts +0 -0
  26. /package/dist/{src/build → build}/scanEntryPoints.d.ts +0 -0
  27. /package/dist/{src/constants.d.ts → constants.d.ts} +0 -0
  28. /package/dist/{src/plugins → plugins}/index.d.ts +0 -0
  29. /package/dist/{src/plugins → plugins}/networkingPlugin.d.ts +0 -0
  30. /package/dist/{src/plugins → plugins}/pageRouterPlugin.d.ts +0 -0
  31. /package/dist/{src/svelte → svelte}/renderToPipeableStream.d.ts +0 -0
  32. /package/dist/{src/svelte → svelte}/renderToReadableStream.d.ts +0 -0
  33. /package/dist/{src/svelte → svelte}/renderToString.d.ts +0 -0
  34. /package/dist/{src/utils → utils}/escapeScriptContent.d.ts +0 -0
  35. /package/dist/{src/utils → utils}/getDurationString.d.ts +0 -0
  36. /package/dist/{src/utils → utils}/networking.d.ts +0 -0
  37. /package/dist/{src/utils → utils}/validateSafePath.d.ts +0 -0
package/dist/index.js CHANGED
@@ -11,49 +11,337 @@ 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 sep3 } from "path";
16
+ import { cwd as cwd3, 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, stat } from "fs/promises";
21
+ import {
22
+ dirname,
23
+ join,
24
+ basename,
25
+ extname,
26
+ resolve,
27
+ relative,
28
+ sep
29
+ } from "path";
30
+ import { cwd, env } from "process";
31
+ var {write, file, Transpiler } = globalThis.Bun;
32
+ import { compile, compileModule, preprocess } from "svelte/compiler";
33
+ var exists = async (filepath) => {
34
+ try {
35
+ await stat(filepath);
36
+ return true;
37
+ } catch {
38
+ return false;
39
+ }
40
+ };
41
+ var resolveSvelte = async (spec, from) => {
42
+ const basePath = resolve(dirname(from), spec);
43
+ const explicit = /\.(svelte|svelte\.(?:ts|js))$/.test(basePath);
44
+ if (!explicit) {
45
+ const extensions = [".svelte", ".svelte.ts", ".svelte.js"];
46
+ const paths = extensions.map((ext) => `${basePath}${ext}`);
47
+ const checks = await Promise.all(paths.map(exists));
48
+ const match = paths.find((_, index) => checks[index]);
49
+ return match ?? null;
50
+ }
51
+ if (await exists(basePath))
52
+ return basePath;
53
+ if (!basePath.endsWith(".svelte"))
54
+ return null;
55
+ const tsPath = `${basePath}.ts`;
56
+ if (await exists(tsPath))
57
+ return tsPath;
58
+ const jsPath = `${basePath}.js`;
59
+ if (await exists(jsPath))
60
+ return jsPath;
61
+ return null;
62
+ };
63
+ var transpiler = new Transpiler({ loader: "ts", target: "browser" });
64
+ var projectRoot = cwd();
65
+ var compileSvelte = async (entryPoints, outRoot, cache = new Map) => {
66
+ const clientFolder = "client";
67
+ const indexFolder = "indexes";
68
+ const pagesFolder = "pages";
69
+ await Promise.all([clientFolder, indexFolder, pagesFolder].map((d) => mkdir(join(outRoot, d), { recursive: true })));
70
+ const dev = env.NODE_ENV === "development";
71
+ const build = async (src) => {
72
+ const memo = cache.get(src);
73
+ if (memo)
74
+ return memo;
75
+ const raw = await file(src).text();
76
+ const isModule = src.endsWith(".svelte.ts") || src.endsWith(".svelte.js");
77
+ const prepped = isModule ? raw : (await preprocess(raw, {})).code;
78
+ const transpiledCode = src.endsWith(".ts") || src.endsWith(".svelte.ts") ? transpiler.transformSync(prepped) : prepped;
79
+ const relDir = dirname(relative(projectRoot, src));
80
+ const baseName = basename(src).replace(/\.svelte(\.(ts|js))?$/, "");
81
+ const importPaths = Array.from(transpiledCode.matchAll(/from\s+['"]([^'"]+)['"]/g)).map((m) => m[1]).filter((p) => p !== undefined);
82
+ const resolveResults = await Promise.all(importPaths.map((p) => resolveSvelte(p, src)));
83
+ const childSources = resolveResults.filter((path) => path !== undefined);
84
+ await Promise.all(childSources.map((p) => build(p)));
85
+ const generate = (mode) => (isModule ? compileModule(transpiledCode, { dev, filename: src }).js.code : compile(transpiledCode, {
86
+ css: "injected",
87
+ dev,
88
+ filename: src,
89
+ generate: mode
90
+ }).js.code).replace(/\.svelte(?:\.(?:ts|js))?(['"])/g, ".js$1");
91
+ const ssrPath = join(outRoot, pagesFolder, relDir, `${baseName}.js`);
92
+ const clientPath = join(outRoot, clientFolder, relDir, `${baseName}.js`);
93
+ await Promise.all([
94
+ mkdir(dirname(ssrPath), { recursive: true }),
95
+ mkdir(dirname(clientPath), { recursive: true })
96
+ ]);
97
+ if (isModule) {
98
+ const bundle = generate("client");
99
+ await Promise.all([
100
+ write(ssrPath, bundle),
101
+ write(clientPath, bundle)
102
+ ]);
36
103
  } else {
37
- manifest[baseName] = `/${relativePath}`;
104
+ const serverBundle = generate("server");
105
+ const clientBundle = generate("client");
106
+ await Promise.all([
107
+ write(ssrPath, serverBundle),
108
+ write(clientPath, clientBundle)
109
+ ]);
38
110
  }
39
- return manifest;
40
- }, {});
111
+ const built = { client: clientPath, ssr: ssrPath };
112
+ cache.set(src, built);
113
+ return built;
114
+ };
115
+ const roots = await Promise.all(entryPoints.map(build));
116
+ await Promise.all(roots.map(({ client }) => {
117
+ const relClientDir = dirname(relative(join(outRoot, clientFolder), client));
118
+ const name = basename(client, extname(client));
119
+ const indexDir = join(outRoot, indexFolder, relClientDir);
120
+ const importPathRaw = relative(indexDir, client).split(sep).join("/");
121
+ const importPath = importPathRaw.startsWith(".") ? importPathRaw : `./${importPathRaw}`;
122
+ const indexPath = join(indexDir, `${name}.js`);
123
+ const boot = `import C from "${importPath}";
124
+ import { hydrate } from "svelte";
125
+ hydrate(C,{target:document.body,props:window.__INITIAL_PROPS__??{}});`;
126
+ return mkdir(indexDir, { recursive: true }).then(() => write(indexPath, boot));
127
+ }));
128
+ return {
129
+ svelteClientPaths: roots.map(({ client }) => {
130
+ const rel = dirname(relative(join(outRoot, clientFolder), client));
131
+ return join(outRoot, indexFolder, rel, basename(client));
132
+ }),
133
+ svelteServerPaths: roots.map(({ ssr }) => ssr)
134
+ };
135
+ };
136
+
137
+ // src/build/compileVue.ts
138
+ import { mkdir as mkdir2 } from "fs/promises";
139
+ import { basename as basename2, dirname as dirname2, join as join2, relative as relative2, resolve as resolve2 } from "path";
140
+ import { cwd as cwd2 } from "process";
141
+ import {
142
+ parse,
143
+ compileScript,
144
+ compileTemplate,
145
+ compileStyle
146
+ } from "@vue/compiler-sfc";
147
+ var {file: file2, write: write2, Transpiler: Transpiler2 } = globalThis.Bun;
148
+
149
+ // src/utils/stringModifiers.ts
150
+ var normalizeSlug = (str) => str.trim().replace(/\s+/g, "-").replace(/[^A-Za-z0-9\-_]+/g, "").replace(/[-_]{2,}/g, "-");
151
+ var toPascal = (str) => normalizeSlug(str).split(/[-_]/).filter(Boolean).map((segment) => segment.charAt(0).toUpperCase() + segment.slice(1).toLowerCase()).join("");
152
+ var toKebab = (str) => normalizeSlug(str).replace(/([a-z0-9])([A-Z])/g, "$1-$2").toLowerCase();
153
+
154
+ // src/build/compileVue.ts
155
+ var transpiler2 = new Transpiler2({ loader: "ts", target: "browser" });
156
+ var projectRoot2 = cwd2();
157
+ var extractImports = (sourceCode) => Array.from(sourceCode.matchAll(/import\s+[\s\S]+?['"]([^'"]+)['"]/g)).map((match) => match[1]).filter((importPath) => importPath !== undefined);
158
+ var toJsFileName = (path) => {
159
+ if (path.endsWith(".vue")) {
160
+ return path.replace(/\.vue$/, ".js");
161
+ }
162
+ if (path.endsWith(".ts")) {
163
+ return path.replace(/\.ts$/, ".js");
164
+ }
165
+ return `${path}.js`;
166
+ };
167
+ var stripModuleExports = (sourceCode) => sourceCode.replace(/export\s+default/, "const script =").replace(/^export\s+/gm, "");
168
+ var buildVueFile = async (absolutePath, outputDirs, cache, isEntryPage = false) => {
169
+ if (cache.has(absolutePath))
170
+ return cache.get(absolutePath);
171
+ const relativePath = relative2(projectRoot2, absolutePath).replace(/\\/g, "/");
172
+ const relativePathWithoutExt = relativePath.replace(/\.vue$/, "");
173
+ const componentName = basename2(absolutePath, ".vue");
174
+ const kebabId = toKebab(componentName);
175
+ const sourceCode = await file2(absolutePath).text();
176
+ const { descriptor } = parse(sourceCode, { filename: absolutePath });
177
+ const originalSetupCode = descriptor.scriptSetup?.content ?? descriptor.script?.content ?? "";
178
+ const relativeImports = extractImports(originalSetupCode);
179
+ const childVueImports = relativeImports.filter((importPath) => importPath.startsWith(".") && importPath.endsWith(".vue"));
180
+ const tsHelperImports = relativeImports.filter((importPath) => importPath.startsWith(".") && !importPath.endsWith(".vue"));
181
+ const childBuildResults = await Promise.all(childVueImports.map((importPath) => buildVueFile(resolve2(dirname2(absolutePath), importPath), outputDirs, cache, false)));
182
+ const compiledScript = compileScript(descriptor, {
183
+ id: kebabId,
184
+ inlineTemplate: false
185
+ });
186
+ const transformedScript = transpiler2.transformSync(stripModuleExports(compiledScript.content)).replace(/(['"])(\.{1,2}\/[^'"]+)(['"])/g, (_, quote, importPath, endQuote) => quote + toJsFileName(importPath) + endQuote);
187
+ const renderBlock = (forServer) => compileTemplate({
188
+ compilerOptions: {
189
+ bindingMetadata: compiledScript.bindings,
190
+ prefixIdentifiers: true
191
+ },
192
+ filename: absolutePath,
193
+ id: kebabId,
194
+ scoped: descriptor.styles.some((s) => s.scoped),
195
+ source: descriptor.template?.content ?? "",
196
+ ssr: forServer,
197
+ ssrCssVars: descriptor.cssVars
198
+ }).code.replace(/(['"])(\.{1,2}\/[^'"]+)(['"])/g, (_, quote, importPath, endQuote) => quote + toJsFileName(importPath) + endQuote);
199
+ const ownCssCodes = descriptor.styles.map((styleBlock) => compileStyle({
200
+ filename: absolutePath,
201
+ id: kebabId,
202
+ scoped: styleBlock.scoped,
203
+ source: styleBlock.content,
204
+ trim: true
205
+ }).code);
206
+ const aggregatedCssCodes = [
207
+ ...ownCssCodes,
208
+ ...childBuildResults.flatMap((result) => result.cssCodes)
209
+ ];
210
+ let emittedCssPaths = [];
211
+ if (isEntryPage && aggregatedCssCodes.length) {
212
+ const cssOutputPath = join2(outputDirs.css, `${toKebab(componentName)}.css`);
213
+ await mkdir2(dirname2(cssOutputPath), { recursive: true });
214
+ await write2(cssOutputPath, aggregatedCssCodes.join(`
215
+ `));
216
+ emittedCssPaths = [cssOutputPath];
217
+ }
218
+ const buildModule = (renderCode, renderFunctionName) => {
219
+ const vueHeader = 'import { defineComponent } from "vue";';
220
+ return [
221
+ transformedScript,
222
+ renderCode,
223
+ vueHeader,
224
+ `export default defineComponent({ ...script, ${renderFunctionName} });`
225
+ ].join(`
226
+ `);
227
+ };
228
+ const clientModuleCode = buildModule(renderBlock(false), "render");
229
+ const serverModuleCode = buildModule(renderBlock(true), "ssrRender");
230
+ const clientOutPath = join2(outputDirs.client, `${relativePathWithoutExt}.js`);
231
+ const serverOutPath = join2(outputDirs.server, `${relativePathWithoutExt}.js`);
232
+ await mkdir2(dirname2(clientOutPath), { recursive: true });
233
+ await mkdir2(dirname2(serverOutPath), { recursive: true });
234
+ await write2(clientOutPath, clientModuleCode);
235
+ await write2(serverOutPath, serverModuleCode);
236
+ const buildResult = {
237
+ clientPath: clientOutPath,
238
+ cssCodes: aggregatedCssCodes,
239
+ cssPaths: emittedCssPaths,
240
+ serverPath: serverOutPath,
241
+ tsHelperPaths: [
242
+ ...tsHelperImports.map((helper) => resolve2(dirname2(absolutePath), helper.endsWith(".ts") ? helper : `${helper}.ts`)),
243
+ ...childBuildResults.flatMap((result) => result.tsHelperPaths)
244
+ ]
245
+ };
246
+ cache.set(absolutePath, buildResult);
247
+ return buildResult;
248
+ };
249
+ var compileVue = async (pageEntryPoints, outputDirectory) => {
250
+ const clientDir = join2(outputDirectory, "client");
251
+ const indexDir = join2(outputDirectory, "indexes");
252
+ const pagesDir = join2(outputDirectory, "pages");
253
+ const stylesDir = join2(outputDirectory, "styles");
254
+ await Promise.all([
255
+ mkdir2(clientDir, { recursive: true }),
256
+ mkdir2(indexDir, { recursive: true }),
257
+ mkdir2(pagesDir, { recursive: true }),
258
+ mkdir2(stylesDir, { recursive: true })
259
+ ]);
260
+ const buildCache = new Map;
261
+ const tsHelperSet = new Set;
262
+ const pageResults = await Promise.all(pageEntryPoints.map(async (pageEntry) => {
263
+ const buildResult = await buildVueFile(resolve2(pageEntry), { client: clientDir, css: stylesDir, server: pagesDir }, buildCache, true);
264
+ buildResult.tsHelperPaths.forEach((p) => tsHelperSet.add(p));
265
+ const relPath = relative2(projectRoot2, pageEntry).replace(/\.vue$/, "");
266
+ const indexPath = join2(indexDir, `${relPath}.js`);
267
+ const clientEntryPath = join2(clientDir, `${relPath}.js`);
268
+ await mkdir2(dirname2(indexPath), { recursive: true });
269
+ await write2(indexPath, [
270
+ `import Comp from "${relative2(dirname2(indexPath), clientEntryPath)}";`,
271
+ 'import { createSSRApp } from "vue";',
272
+ "const props = window.__INITIAL_PROPS__ ?? {};",
273
+ 'createSSRApp(Comp, props).mount("#root");'
274
+ ].join(`
275
+ `));
276
+ return {
277
+ cssPaths: buildResult.cssPaths,
278
+ indexPath,
279
+ serverPath: buildResult.serverPath
280
+ };
281
+ }));
282
+ await Promise.all(Array.from(tsHelperSet).map(async (src) => {
283
+ const code = transpiler2.transformSync(await file2(src).text());
284
+ const rel = relative2(projectRoot2, src).replace(/\.ts$/, ".js");
285
+ const clientDest = join2(clientDir, rel);
286
+ const serverDest = join2(pagesDir, rel);
287
+ await Promise.all([
288
+ mkdir2(dirname2(clientDest), { recursive: true }),
289
+ mkdir2(dirname2(serverDest), { recursive: true })
290
+ ]);
291
+ await Promise.all([
292
+ write2(clientDest, code),
293
+ write2(serverDest, code)
294
+ ]);
295
+ }));
296
+ return {
297
+ vueCssPaths: pageResults.flatMap((pageResult) => pageResult.cssPaths),
298
+ vueIndexPaths: pageResults.map((pageResult) => pageResult.indexPath),
299
+ vueServerPaths: pageResults.map((pageResult) => pageResult.serverPath)
300
+ };
41
301
  };
42
302
 
303
+ // src/build/generateManifest.ts
304
+ import { extname as extname2 } from "path";
305
+ var generateManifest = (outputs, buildPath) => outputs.reduce((manifest, artifact) => {
306
+ let relative3 = artifact.path.startsWith(buildPath) ? artifact.path.slice(buildPath.length) : artifact.path;
307
+ relative3 = relative3.replace(/^\/+/, "");
308
+ const segments = relative3.split("/");
309
+ const fileWithHash = segments.pop();
310
+ if (!fileWithHash)
311
+ return manifest;
312
+ const [baseName] = fileWithHash.split(`.${artifact.hash}.`);
313
+ if (!baseName)
314
+ return manifest;
315
+ const ext = extname2(fileWithHash);
316
+ if (ext === ".css") {
317
+ manifest[`${toPascal(baseName)}CSS`] = `/${relative3}`;
318
+ return manifest;
319
+ }
320
+ const folder = segments.length > 1 ? segments[1] : segments[0];
321
+ if (folder === "indexes") {
322
+ manifest[`${baseName}Index`] = `/${relative3}`;
323
+ } else if (folder === "pages") {
324
+ manifest[baseName] ??= artifact.path;
325
+ } else {
326
+ manifest[baseName] = `/${relative3}`;
327
+ }
328
+ return manifest;
329
+ }, {});
330
+
43
331
  // src/build/generateReactIndexes.ts
44
- import { mkdir, rm, writeFile } from "fs/promises";
45
- import { basename, join } from "path";
332
+ import { mkdir as mkdir3, rm, writeFile } from "fs/promises";
333
+ import { basename as basename3, join as join3 } from "path";
46
334
  var {Glob } = globalThis.Bun;
47
335
  var generateReactIndexFiles = async (reactPagesDirectory, reactIndexesDirectory) => {
48
336
  await rm(reactIndexesDirectory, { force: true, recursive: true });
49
- await mkdir(reactIndexesDirectory);
337
+ await mkdir3(reactIndexesDirectory);
50
338
  const pagesGlob = new Glob("*.*");
51
339
  const files = [];
52
- for await (const file of pagesGlob.scan({ cwd: reactPagesDirectory })) {
53
- files.push(file);
340
+ for await (const file3 of pagesGlob.scan({ cwd: reactPagesDirectory })) {
341
+ files.push(file3);
54
342
  }
55
- const promises = files.map(async (file) => {
56
- const fileName = basename(file);
343
+ const promises = files.map(async (file3) => {
344
+ const fileName = basename3(file3);
57
345
  const [componentName] = fileName.split(".");
58
346
  const content = [
59
347
  `import { hydrateRoot } from 'react-dom/client';`,
@@ -71,7 +359,7 @@ var generateReactIndexFiles = async (reactPagesDirectory, reactIndexesDirectory)
71
359
  `hydrateRoot(document, <${componentName} {...window.__INITIAL_PROPS__} />);`
72
360
  ].join(`
73
361
  `);
74
- return writeFile(join(reactIndexesDirectory, `${componentName}Index.tsx`), content);
362
+ return writeFile(join3(reactIndexesDirectory, `${componentName}.tsx`), content);
75
363
  });
76
364
  await Promise.all(promises);
77
365
  };
@@ -81,78 +369,32 @@ var {Glob: Glob2 } = globalThis.Bun;
81
369
  var scanEntryPoints = async (dir, pattern) => {
82
370
  const entryPaths = [];
83
371
  const glob = new Glob2(pattern);
84
- for await (const file of glob.scan({ absolute: true, cwd: dir })) {
85
- entryPaths.push(file);
372
+ for await (const file3 of glob.scan({ absolute: true, cwd: dir })) {
373
+ entryPaths.push(file3);
86
374
  }
87
375
  return entryPaths;
88
376
  };
89
377
 
90
- // src/build/updateScriptTags.ts
378
+ // src/build/updateHTMLAssetPaths.ts
91
379
  import { readFile, writeFile as writeFile2 } from "fs/promises";
92
- var updateScriptTags = async (manifest, htmlDir) => {
380
+ var updateHTMLAssetPaths = async (manifest, htmlDir) => {
93
381
  const htmlFiles = await scanEntryPoints(htmlDir, "*.html");
382
+ const assetRegex = /((?:<script[^>]+src=|<link[^>]*?rel=["']stylesheet["'][^>]*?href=)["'])(\/?(?:.*\/)?)([^./"']+)(?:\.[^."'/]+)?(\.(?:js|ts|css))(["'][^>]*>)/g;
94
383
  const tasks = htmlFiles.map(async (filePath) => {
95
384
  const original = await readFile(filePath, "utf8");
96
- const updated = Object.entries(manifest).reduce((html, [scriptName, newPath]) => {
97
- const esc = scriptName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
98
- const regex = new RegExp(`(<script[^>]+src=["'])(/?(?:.*/)?${esc})(?:\\.[^."'/]+)?(\\.js)(["'][^>]*>)`, "g");
99
- return html.replace(regex, (_, prefix, __, ___, suffix) => `${prefix}${newPath}${suffix}`);
100
- }, original);
385
+ const updated = original.replace(assetRegex, (match, prefix, _dir, name, ext, suffix) => {
386
+ const key = ext === ".css" ? `${toPascal(name)}CSS` : name;
387
+ const newPath = manifest[key];
388
+ if (newPath)
389
+ return `${prefix}${newPath}${suffix}`;
390
+ console.error(`error: no manifest entry for ${ext.slice(1)} "${name}" referenced in ${filePath}`);
391
+ return match;
392
+ });
101
393
  await writeFile2(filePath, updated, "utf8");
102
394
  });
103
395
  await Promise.all(tasks);
104
396
  };
105
397
 
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
398
  // src/utils/getDurationString.ts
157
399
  var getDurationString = (duration) => {
158
400
  let durationString;
@@ -167,152 +409,216 @@ var getDurationString = (duration) => {
167
409
  };
168
410
 
169
411
  // src/utils/validateSafePath.ts
170
- import { resolve, relative, sep } from "path";
412
+ import { resolve as resolve3, relative as relative3, sep as sep2 } from "path";
171
413
  var validateSafePath = (targetPath, baseDirectory) => {
172
- const absoluteBase = resolve(baseDirectory);
173
- const absoluteTarget = resolve(baseDirectory, targetPath);
174
- if (relative(absoluteBase, absoluteTarget).startsWith(`..${sep}`)) {
414
+ const absoluteBase = resolve3(baseDirectory);
415
+ const absoluteTarget = resolve3(baseDirectory, targetPath);
416
+ if (relative3(absoluteBase, absoluteTarget).startsWith(`..${sep2}`)) {
175
417
  throw new Error(`Unsafe path: ${targetPath}`);
176
418
  }
177
419
  return absoluteTarget;
178
420
  };
179
421
 
180
422
  // src/core/build.ts
423
+ var commonAncestor = (paths, fallback) => {
424
+ if (paths.length === 0)
425
+ return fallback;
426
+ const segmentsList = paths.map((p) => p.split(sep3));
427
+ const [first] = segmentsList;
428
+ if (!first)
429
+ return fallback;
430
+ const commonSegments = first.filter((segment, index) => segmentsList.every((pathSegs) => pathSegs[index] === segment));
431
+ return commonSegments.length ? commonSegments.join(sep3) : fallback;
432
+ };
433
+ var isDev = env2.NODE_ENV === "development";
434
+ var vueFeatureFlags = {
435
+ __VUE_OPTIONS_API__: "true",
436
+ __VUE_PROD_DEVTOOLS__: isDev ? "true" : "false",
437
+ __VUE_PROD_HYDRATION_MISMATCH_DETAILS__: isDev ? "true" : "false"
438
+ };
181
439
  var build = async ({
182
440
  buildDirectory = "build",
183
- assetsDirectory,
441
+ assetsDirectory = "assets",
184
442
  reactDirectory,
185
443
  htmlDirectory,
186
444
  htmxDirectory,
187
445
  svelteDirectory,
446
+ vueDirectory,
188
447
  tailwind,
189
448
  options
190
449
  }) => {
191
450
  const buildStart = performance.now();
192
- const projectRoot = cwd();
193
- const buildPath = validateSafePath(buildDirectory, projectRoot);
194
- 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);
451
+ const projectRoot3 = cwd3();
452
+ const buildPath = validateSafePath(buildDirectory, projectRoot3);
453
+ const assetsPath = assetsDirectory && validateSafePath(assetsDirectory, projectRoot3);
454
+ const reactDir = reactDirectory && validateSafePath(reactDirectory, projectRoot3);
455
+ const htmlDir = htmlDirectory && validateSafePath(htmlDirectory, projectRoot3);
456
+ const htmxDir = htmxDirectory && validateSafePath(htmxDirectory, projectRoot3);
457
+ const svelteDir = svelteDirectory && validateSafePath(svelteDirectory, projectRoot3);
458
+ const vueDir = vueDirectory && validateSafePath(vueDirectory, projectRoot3);
459
+ const reactIndexesPath = reactDir && join4(reactDir, "indexes");
460
+ const reactPagesPath = reactDir && join4(reactDir, "pages");
461
+ const htmlPagesPath = htmlDir && join4(htmlDir, "pages");
462
+ const htmlScriptsPath = htmlDir && join4(htmlDir, "scripts");
463
+ const sveltePagesPath = svelteDir && join4(svelteDir, "pages");
464
+ const vuePagesPath = vueDir && join4(vueDir, "pages");
465
+ const frontends = [reactDir, htmlDir, htmxDir, svelteDir, vueDir].filter(Boolean);
466
+ const isSingle = frontends.length === 1;
467
+ let serverOutDir;
468
+ if (svelteDir)
469
+ serverOutDir = join4(buildPath, basename4(svelteDir), "pages");
470
+ else if (vueDir)
471
+ serverOutDir = join4(buildPath, basename4(vueDir), "pages");
472
+ let serverRoot;
473
+ if (svelteDir)
474
+ serverRoot = join4(svelteDir, "pages");
475
+ else if (vueDir)
476
+ serverRoot = join4(vueDir, "pages");
215
477
  await rm2(buildPath, { force: true, recursive: true });
216
- await mkdir3(buildPath);
217
- if (reactIndexesPath && reactPagesPath) {
478
+ await mkdir4(buildPath);
479
+ if (reactIndexesPath && reactPagesPath)
218
480
  await generateReactIndexFiles(reactPagesPath, reactIndexesPath);
219
- }
220
- if (assetsPath) {
221
- await cp(assetsPath, join3(buildPath, "assets"), {
481
+ if (assetsPath)
482
+ await cp(assetsPath, join4(buildPath, "assets"), {
222
483
  force: true,
223
484
  recursive: true
224
485
  });
225
- }
226
- if (htmxPath) {
227
- await mkdir3(join3(buildPath, "htmx"));
228
- await cp(htmxPath, join3(buildPath, "htmx"), {
486
+ if (htmxDir) {
487
+ await mkdir4(join4(buildPath, "htmx"));
488
+ await cp(htmxDir, join4(buildPath, "htmx"), {
229
489
  force: true,
230
490
  recursive: true
231
491
  });
232
492
  }
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
493
+ if (tailwind)
494
+ await $`bunx @tailwindcss/cli -i ${tailwind.input} -o ${join4(buildPath, tailwind.output)}`;
495
+ const reactEntries = reactIndexesPath ? await scanEntryPoints(reactIndexesPath, "*.tsx") : [];
496
+ const htmlEntries = htmlScriptsPath ? await scanEntryPoints(htmlScriptsPath, "*.{js,ts}") : [];
497
+ const svelteEntries = sveltePagesPath ? await scanEntryPoints(sveltePagesPath, "*.svelte") : [];
498
+ const vueEntries = vuePagesPath ? await scanEntryPoints(vuePagesPath, "*.vue") : [];
499
+ const htmlCssEntries = htmlDir ? await scanEntryPoints(join4(htmlDir, "styles"), "*.css") : [];
500
+ const reactCssEntries = reactDir ? await scanEntryPoints(join4(reactDir, "styles"), "*.css") : [];
501
+ const svelteCssEntries = svelteDir ? await scanEntryPoints(join4(svelteDir, "styles"), "*.css") : [];
502
+ const { svelteServerPaths, svelteClientPaths } = svelteDir ? await compileSvelte(svelteEntries, svelteDir) : { svelteClientPaths: [], svelteServerPaths: [] };
503
+ const { vueServerPaths, vueIndexPaths, vueCssPaths } = vueDir ? await compileVue(vueEntries, vueDir) : { vueCssPaths: [], vueIndexPaths: [], vueServerPaths: [] };
504
+ const serverEntryPoints = [...svelteServerPaths, ...vueServerPaths];
505
+ const clientEntryPoints = [
506
+ ...reactEntries,
507
+ ...svelteClientPaths,
508
+ ...htmlEntries,
509
+ ...vueIndexPaths
244
510
  ];
245
- if (serverEntryPoints.length === 0) {
246
- console.warn("No server entry points found, skipping manifest generation");
247
- return null;
511
+ const cssEntryPoints = [
512
+ ...vueCssPaths,
513
+ ...reactCssEntries,
514
+ ...svelteCssEntries,
515
+ ...htmlCssEntries
516
+ ];
517
+ if (serverEntryPoints.length === 0 && clientEntryPoints.length === 0) {
518
+ console.warn("No entry points found, manifest will be empty.");
519
+ return {};
520
+ }
521
+ let serverLogs = [];
522
+ let serverOutputs = [];
523
+ if (serverEntryPoints.length > 0) {
524
+ const { logs, outputs } = await bunBuild({
525
+ entrypoints: serverEntryPoints,
526
+ format: "esm",
527
+ naming: `[dir]/[name].[hash].[ext]`,
528
+ outdir: serverOutDir,
529
+ root: serverRoot,
530
+ target: "bun"
531
+ }).catch((err) => {
532
+ console.error("Server build failed:", err);
533
+ exit(1);
534
+ });
535
+ serverLogs = logs;
536
+ serverOutputs = outputs;
248
537
  }
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
- });
260
538
  let clientLogs = [];
261
539
  let clientOutputs = [];
262
- if (svelteDirectoryPath) {
540
+ if (clientEntryPoints.length > 0) {
541
+ const roots = [reactDir, svelteDir, htmlDir, vueDir].filter((dir) => Boolean(dir));
542
+ const clientRoot = isSingle ? roots[0] ?? projectRoot3 : commonAncestor(roots, projectRoot3);
263
543
  const { logs, outputs } = await bunBuild({
264
- entrypoints: svelteClientPaths,
544
+ define: vueDirectory ? vueFeatureFlags : undefined,
545
+ entrypoints: clientEntryPoints,
265
546
  format: "esm",
266
547
  naming: `[dir]/[name].[hash].[ext]`,
267
- outdir: svelteOutDir,
268
- root: svelteDirectoryPath,
548
+ outdir: buildPath,
549
+ root: clientRoot,
269
550
  target: "browser"
270
- }).catch((error) => {
271
- console.error("Client build failed:", error);
551
+ }).catch((err) => {
552
+ console.error("Client build failed:", err);
272
553
  exit(1);
273
554
  });
274
555
  clientLogs = logs;
275
556
  clientOutputs = outputs;
276
557
  }
277
- [...serverLogs, ...clientLogs].forEach((log) => {
558
+ let cssLogs = [];
559
+ let cssOutputs = [];
560
+ if (cssEntryPoints.length > 0) {
561
+ const { logs, outputs } = await bunBuild({
562
+ entrypoints: cssEntryPoints,
563
+ naming: `[name].[hash].[ext]`,
564
+ outdir: join4(buildPath, basename4(assetsPath), "css"),
565
+ target: "browser"
566
+ }).catch((err) => {
567
+ console.error("CSS build failed:", err);
568
+ exit(1);
569
+ });
570
+ cssLogs = logs;
571
+ cssOutputs = outputs;
572
+ }
573
+ const allLogs = [...serverLogs, ...clientLogs, ...cssLogs];
574
+ for (const log of allLogs) {
278
575
  if (log.level === "error")
279
576
  console.error(log);
280
577
  else if (log.level === "warning")
281
578
  console.warn(log);
282
579
  else
283
580
  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 });
581
+ }
582
+ const manifest = generateManifest([...serverOutputs, ...clientOutputs, ...cssOutputs], buildPath);
583
+ if (htmlDir && htmlPagesPath) {
584
+ const outputHtmlPages = join4(buildPath, basename4(htmlDir), "pages");
585
+ await mkdir4(outputHtmlPages, { recursive: true });
289
586
  await cp(htmlPagesPath, outputHtmlPages, {
290
587
  force: true,
291
588
  recursive: true
292
589
  });
293
- await updateScriptTags(manifest, outputHtmlPages);
590
+ await updateHTMLAssetPaths(manifest, outputHtmlPages);
294
591
  }
295
- if (!options?.preserveIntermediateFiles && svelteDirectoryPath) {
296
- await rm2(join3(svelteDirectoryPath, "indexes"), {
592
+ if (!options?.preserveIntermediateFiles && svelteDir) {
593
+ await rm2(join4(svelteDir, "indexes"), { force: true, recursive: true });
594
+ await rm2(join4(svelteDir, "client"), { force: true, recursive: true });
595
+ await Promise.all(svelteServerPaths.map((path) => rm2(path, { force: true })));
596
+ await rm2(join4(svelteDir, "pages", "example"), {
297
597
  force: true,
298
598
  recursive: true
299
599
  });
300
- await rm2(join3(svelteDirectoryPath, "client"), {
600
+ }
601
+ if (!options?.preserveIntermediateFiles && vueDir) {
602
+ await rm2(join4(vueDir, "indexes"), { force: true, recursive: true });
603
+ await rm2(join4(vueDir, "client"), { force: true, recursive: true });
604
+ await rm2(join4(vueDir, "styles"), { force: true, recursive: true });
605
+ await Promise.all(vueServerPaths.map((path) => rm2(path, { force: true })));
606
+ await rm2(join4(vueDir, "pages", "example"), {
301
607
  force: true,
302
608
  recursive: true
303
609
  });
304
- await Promise.all(svelteServerPaths.map((filePath) => rm2(filePath, { force: true })));
305
610
  }
306
- if (!options?.preserveIntermediateFiles && reactIndexesPath) {
611
+ if (!options?.preserveIntermediateFiles && reactIndexesPath)
307
612
  await rm2(reactIndexesPath, { force: true, recursive: true });
308
- }
309
613
  console.log(`Build completed in ${getDurationString(performance.now() - buildStart)}`);
310
614
  return manifest;
311
615
  };
312
616
  // src/core/pageHandlers.ts
313
- var {file: file2 } = globalThis.Bun;
617
+ var {file: file3 } = globalThis.Bun;
314
618
  import { createElement } from "react";
315
619
  import { renderToReadableStream as renderReactToReadableStream } from "react-dom/server";
620
+ import { createSSRApp, h } from "vue";
621
+ import { renderToWebStream as renderVueToWebStream } from "vue/server-renderer";
316
622
 
317
623
  // src/svelte/renderToReadableStream.ts
318
624
  import { render } from "svelte/server";
@@ -326,7 +632,10 @@ var ESCAPE_LOOKUP = {
326
632
  ">": "\\u003E"
327
633
  };
328
634
  var ESCAPE_REGEX = /[&><\u2028\u2029]/g;
329
- var escapeScriptContent = (content) => content.replace(ESCAPE_REGEX, (char) => ESCAPE_LOOKUP[char]);
635
+ var escapeScriptContent = (content) => content.replace(ESCAPE_REGEX, (char) => {
636
+ const escaped = ESCAPE_LOOKUP[char];
637
+ return escaped !== undefined ? escaped : char;
638
+ });
330
639
 
331
640
  // src/svelte/renderToReadableStream.ts
332
641
  var renderToReadableStream = async (component, props, {
@@ -382,26 +691,54 @@ var handleReactPageRequest = async (pageComponent, index, ...props) => {
382
691
  headers: { "Content-Type": "text/html" }
383
692
  });
384
693
  };
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`];
694
+ var handleSveltePageRequest = async (_PageComponent, pagePath, indexPath, props) => {
392
695
  const { default: ImportedPageComponent } = await import(pagePath);
393
696
  const stream = await renderToReadableStream(ImportedPageComponent, props, {
394
- bootstrapModules: [indexPath],
697
+ bootstrapModules: indexPath ? [indexPath] : [],
395
698
  bootstrapScriptContent: `window.__INITIAL_PROPS__=${JSON.stringify(props)}`
396
699
  });
397
700
  return new Response(stream, {
398
701
  headers: { "Content-Type": "text/html" }
399
702
  });
400
703
  };
401
- var handleHTMLPageRequest = (html) => file2(html);
704
+ var handleVuePageRequest = async (_PageComponent, pagePath, indexPath, headTag = "<head></head>", ...props) => {
705
+ const [maybeProps] = props;
706
+ const { default: ImportedPageComponent } = await import(pagePath);
707
+ const app = createSSRApp({
708
+ render: () => h(ImportedPageComponent, maybeProps ?? {})
709
+ });
710
+ const bodyStream = renderVueToWebStream(app);
711
+ const head = `<!DOCTYPE html><html>${headTag}<body><div id="root">`;
712
+ const tail = `</div><script>window.__INITIAL_PROPS__=${JSON.stringify(maybeProps ?? {})}</script><script type="module" src="${indexPath}"></script></body></html>`;
713
+ const stream = new ReadableStream({
714
+ start(controller) {
715
+ controller.enqueue(head);
716
+ const reader = bodyStream.getReader();
717
+ const pumpLoop = () => {
718
+ reader.read().then(({ done, value }) => done ? (controller.enqueue(tail), controller.close()) : (controller.enqueue(value), pumpLoop())).catch((err) => controller.error(err));
719
+ };
720
+ pumpLoop();
721
+ }
722
+ });
723
+ return new Response(stream, {
724
+ headers: { "Content-Type": "text/html" }
725
+ });
726
+ };
727
+ var handleHTMLPageRequest = (html) => file3(html);
728
+ var handlePageRequest = (PageComponent, ...props) => {
729
+ console.log("handlePageRequest coming soon.", PageComponent, props);
730
+ };
731
+ // src/core/lookup.ts
732
+ var asset = (manifest, name) => {
733
+ const assetPath = manifest[name];
734
+ if (assetPath === undefined) {
735
+ throw new Error(`Asset "${name}" not found in manifest.`);
736
+ }
737
+ return assetPath;
738
+ };
402
739
  // src/plugins/networkingPlugin.ts
403
740
  import { argv } from "process";
404
- var {env: env2 } = globalThis.Bun;
741
+ var {env: env3 } = globalThis.Bun;
405
742
 
406
743
  // src/utils/networking.ts
407
744
  import os from "os";
@@ -416,8 +753,8 @@ var getLocalIPAddress = () => {
416
753
  };
417
754
 
418
755
  // src/plugins/networkingPlugin.ts
419
- var host = env2.HOST ?? "localhost";
420
- var port = env2.PORT ?? DEFAULT_PORT;
756
+ var host = env3.HOST ?? "localhost";
757
+ var port = env3.PORT ?? DEFAULT_PORT;
421
758
  var localIP;
422
759
  var args = argv;
423
760
  var hostFlag = args.includes("--host");
@@ -440,15 +777,37 @@ var networkingPlugin = (app) => app.listen({
440
777
  var pageRouterPlugin = () => {
441
778
  console.log("Page Router Plugin Not Implemented Yet");
442
779
  };
780
+ // src/utils/generateHeadElement.ts
781
+ var generateHeadElement = ({
782
+ cssPath,
783
+ title = "AbsoluteJS",
784
+ description = "A page created using AbsoluteJS",
785
+ font,
786
+ icon = "/assets/ico/favicon.ico"
787
+ } = {}) => `<head>
788
+ <meta charset="UTF-8">
789
+ <meta name="viewport" content="width=device-width, initial-scale=1.0">
790
+ <title>${title}</title>
791
+ <meta name="description" content="${description}">
792
+ <link rel="icon" href="${icon}" type="image/x-icon">
793
+ ${font ? `<link rel="preconnect" href="https://fonts.googleapis.com">
794
+ <link rel="preconnect" href="https://fonts.gstatic.com" crossorigin>
795
+ <link href="https://fonts.googleapis.com/css2?family=${font}:wght@100..900&display=swap" rel="stylesheet">` : ""}
796
+ ${cssPath ? `<link rel="stylesheet" href="${cssPath}" type="text/css">` : ""}
797
+ </head>`;
443
798
  export {
444
- updateScriptTags,
799
+ updateHTMLAssetPaths,
445
800
  pageRouterPlugin,
446
801
  networkingPlugin,
802
+ handleVuePageRequest,
447
803
  handleSveltePageRequest,
448
804
  handleReactPageRequest,
805
+ handlePageRequest,
449
806
  handleHTMLPageRequest,
450
807
  getLocalIPAddress,
808
+ generateHeadElement,
451
809
  build,
810
+ asset,
452
811
  TWO_THIRDS,
453
812
  TIME_PRECISION,
454
813
  SECONDS_IN_A_MINUTE,
@@ -461,5 +820,5 @@ export {
461
820
  DEFAULT_CHUNK_SIZE
462
821
  };
463
822
 
464
- //# debugId=F0D0DE61A724A5EB64756E2164756E21
823
+ //# debugId=919FA38EE8B07AC264756E2164756E21
465
824
  //# sourceMappingURL=index.js.map