@absolutejs/absolute 0.4.0 → 0.5.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 (76) hide show
  1. package/build/HomeIndex.paddd8c9.js +20725 -0
  2. package/build/NotAuthorizedIndex.7em4g7an.js +20717 -0
  3. package/build/ProtectedIndex.k3vgnatp.js +22282 -0
  4. package/build/TestingIndex.j74ezacm.js +33877 -0
  5. package/build/assets/favicon.ico +0 -0
  6. package/build/assets/jpeg/mercadolibre-logo.jpeg +0 -0
  7. package/build/assets/jpeg/yahoo-Icon.jpeg +0 -0
  8. package/build/assets/png/Facebook_Logo_Primary.png +0 -0
  9. package/build/assets/png/LI-In-Bug.png +0 -0
  10. package/build/assets/png/LINE_Brand_icon.png +0 -0
  11. package/build/assets/png/Okta_Wordmark_Black_S.png +0 -0
  12. package/build/assets/png/Polar_logo_black_web.png +0 -0
  13. package/build/assets/png/SLA-Slack-from-Salesforce-logo.png +0 -0
  14. package/build/assets/png/Synology_logo_Standard.png +0 -0
  15. package/build/assets/png/Zoom_Logo_Bloom_RGB.png +0 -0
  16. package/build/assets/png/naver-btnD_icon_circle.png +0 -0
  17. package/build/assets/png/naver-btnG_icon_circle.png +0 -0
  18. package/build/assets/png/osu!logo.png +0 -0
  19. package/build/assets/png/twitter-logo-black.png +0 -0
  20. package/build/assets/svg/42-logo.svg +1 -0
  21. package/build/assets/svg/DA_Alert_Color-Logo.svg +27 -0
  22. package/build/assets/svg/Figma-Icon-(Full-color).svg +7 -0
  23. package/build/assets/svg/GitHub_Invertocat_Dark.svg +14 -0
  24. package/build/assets/svg/Microsoft-Entra-ID-color-icon.svg +9 -0
  25. package/build/assets/svg/PATREON_SYMBOL_1_BLACK_RGB.svg +8 -0
  26. package/build/assets/svg/Reddit_Icon_FullColor.svg +142 -0
  27. package/build/assets/svg/amazoncognito-logo.svg +1 -0
  28. package/build/assets/svg/anilist-logo.svg +1 -0
  29. package/build/assets/svg/apple-logo.svg +1 -0
  30. package/build/assets/svg/atlassian-logo.svg +1 -0
  31. package/build/assets/svg/auth0-logo.svg +1 -0
  32. package/build/assets/svg/authentik-logo.svg +1 -0
  33. package/build/assets/svg/autodesk-logo.svg +1 -0
  34. package/build/assets/svg/battlenet-logo.svg +1 -0
  35. package/build/assets/svg/bitbucket-logo.svg +1 -0
  36. package/build/assets/svg/box-logo.svg +1 -0
  37. package/build/assets/svg/bungie-logo.svg +1 -0
  38. package/build/assets/svg/coinbase-logo.svg +1 -0
  39. package/build/assets/svg/discord-logo.svg +1 -0
  40. package/build/assets/svg/dribbble-logo.svg +1 -0
  41. package/build/assets/svg/dropbox-logo.svg +1 -0
  42. package/build/assets/svg/epicgames-logo.svg +1 -0
  43. package/build/assets/svg/etsy-logo.svg +1 -0
  44. package/build/assets/svg/gitea-logo.svg +1 -0
  45. package/build/assets/svg/gitlab-logo.svg +1 -0
  46. package/build/assets/svg/google-logo.svg +7 -0
  47. package/build/assets/svg/intuit-logo.svg +4 -0
  48. package/build/assets/svg/kakao-logo.svg +1 -0
  49. package/build/assets/svg/keycloak-logo.svg +1 -0
  50. package/build/assets/svg/kick-logo.svg +1 -0
  51. package/build/assets/svg/lichess-logo.svg +1 -0
  52. package/build/assets/svg/linear-logo.svg +1 -0
  53. package/build/assets/svg/logomark_black.svg +25 -0
  54. package/build/assets/svg/mastadon-logo-purple.svg +10 -0
  55. package/build/assets/svg/mercadopago-logo.svg +1 -0
  56. package/build/assets/svg/myanimelist-logo.svg +1 -0
  57. package/build/assets/svg/notion-logo.svg +1 -0
  58. package/build/assets/svg/rgb-tiltify22_mark_blue.svg +3 -0
  59. package/build/assets/svg/roblox-logo.svg +1 -0
  60. package/build/assets/svg/salesforce-logo.svg +1 -0
  61. package/build/assets/svg/shikimori-logo.svg +1 -0
  62. package/build/assets/svg/spotify-Primary_Logo_Green_RGB.svg +1 -0
  63. package/build/assets/svg/start.gg_Icon_RGB.svg +15 -0
  64. package/build/assets/svg/strava-logo.svg +1 -0
  65. package/build/assets/svg/tiktok-logo.svg +1 -0
  66. package/build/assets/svg/twitch-glitch_flat_purple.svg +21 -0
  67. package/build/assets/svg/vk-logo.svg +1 -0
  68. package/build/assets/svg/workos-logo-color.svg +21 -0
  69. package/build/assets/svg/yandex-icon_grad_circ.svg +20 -0
  70. package/dist/index.js +223 -3
  71. package/dist/src/core/build.d.ts +2 -16
  72. package/dist/src/types.d.ts +19 -0
  73. package/package.json +8 -9
  74. package/src/core/build.ts +18 -45
  75. package/src/plugins/networkingPlugin.ts +5 -3
  76. package/src/types.ts +20 -0
@@ -0,0 +1,21 @@
1
+ <?xml version="1.0" encoding="utf-8"?>
2
+ <!-- Generator: Adobe Illustrator 23.0.6, SVG Export Plug-In . SVG Version: 6.00 Build 0) -->
3
+ <svg version="1.1" id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px"
4
+ viewBox="0 0 2400 2800" style="enable-background:new 0 0 2400 2800;" xml:space="preserve">
5
+ <style type="text/css">
6
+ .st0{fill:#FFFFFF;}
7
+ .st1{fill:#9146FF;}
8
+ </style>
9
+ <title>Asset 2</title>
10
+ <g>
11
+ <polygon class="st0" points="2200,1300 1800,1700 1400,1700 1050,2050 1050,1700 600,1700 600,200 2200,200 "/>
12
+ <g>
13
+ <g id="Layer_1-2">
14
+ <path class="st1" d="M500,0L0,500v1800h600v500l500-500h400l900-900V0H500z M2200,1300l-400,400h-400l-350,350v-350H600V200h1600
15
+ V1300z"/>
16
+ <rect x="1700" y="550" class="st1" width="200" height="600"/>
17
+ <rect x="1150" y="550" class="st1" width="200" height="600"/>
18
+ </g>
19
+ </g>
20
+ </g>
21
+ </svg>
@@ -0,0 +1 @@
1
+ <svg role="img" viewBox="0 0 24 24" xmlns="http://www.w3.org/2000/svg"><title>VK</title><path d="m9.489.004.729-.003h3.564l.73.003.914.01.433.007.418.011.403.014.388.016.374.021.36.025.345.03.333.033c1.74.196 2.933.616 3.833 1.516.9.9 1.32 2.092 1.516 3.833l.034.333.029.346.025.36.02.373.025.588.012.41.013.644.009.915.004.98-.001 3.313-.003.73-.01.914-.007.433-.011.418-.014.403-.016.388-.021.374-.025.36-.03.345-.033.333c-.196 1.74-.616 2.933-1.516 3.833-.9.9-2.092 1.32-3.833 1.516l-.333.034-.346.029-.36.025-.373.02-.588.025-.41.012-.644.013-.915.009-.98.004-3.313-.001-.73-.003-.914-.01-.433-.007-.418-.011-.403-.014-.388-.016-.374-.021-.36-.025-.345-.03-.333-.033c-1.74-.196-2.933-.616-3.833-1.516-.9-.9-1.32-2.092-1.516-3.833l-.034-.333-.029-.346-.025-.36-.02-.373-.025-.588-.012-.41-.013-.644-.009-.915-.004-.98.001-3.313.003-.73.01-.914.007-.433.011-.418.014-.403.016-.388.021-.374.025-.36.03-.345.033-.333c.196-1.74.616-2.933 1.516-3.833.9-.9 2.092-1.32 3.833-1.516l.333-.034.346-.029.36-.025.373-.02.588-.025.41-.012.644-.013.915-.009ZM6.79 7.3H4.05c.13 6.24 3.25 9.99 8.72 9.99h.31v-3.57c2.01.2 3.53 1.67 4.14 3.57h2.84c-.78-2.84-2.83-4.41-4.11-5.01 1.28-.74 3.08-2.54 3.51-4.98h-2.58c-.56 1.98-2.22 3.78-3.8 3.95V7.3H10.5v6.92c-1.6-.4-3.62-2.34-3.71-6.92Z"/></svg>
@@ -0,0 +1,21 @@
1
+ <svg version="1.1" id="Layer_1" xmlns:x="ns_extend;" xmlns:i="ns_ai;" xmlns:graph="ns_graphs;" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" x="0px" y="0px" viewBox="0 0 55.4 48" style="enable-background:new 0 0 55.4 48;" xml:space="preserve">
2
+ <style type="text/css">
3
+ .st0{fill:#6363F1;}
4
+ </style>
5
+ <metadata>
6
+ <sfw xmlns="ns_sfw;">
7
+ <slices>
8
+ </slices>
9
+ <sliceSourceBounds bottomLeftOrigin="true" height="48" width="55.4" x="55.4" y="-228.6">
10
+ </sliceSourceBounds>
11
+ </sfw>
12
+ </metadata>
13
+ <g>
14
+ <path id="logo-icon" class="st0" d="M0,24c0,1.1,0.3,2.1,0.8,3l9.7,16.8c1,1.7,2.5,3.1,4.4,3.7c3.6,1.2,7.5-0.3,9.4-3.5l2.3-4.1
15
+ l-9.2-16l9.8-16.9L29.5,3c0.7-1.2,1.6-2.2,2.7-3H17.2c-2.6,0-5.1,1.4-6.4,3.7L0.8,21C0.3,21.9,0,22.9,0,24z">
16
+ </path>
17
+ <path id="logo-icon_1_" class="st0" d="M55.4,24c0-1.1-0.3-2.1-0.8-3l-9.8-17c-1.9-3.3-5.8-4.7-9.4-3.5c-1.9,0.6-3.4,2-4.4,3.7
18
+ L28.7,8L38,24l-9.8,16.9L25.9,45c-0.7,1.2-1.6,2.2-2.7,3h15.1c2.6,0,5.1-1.4,6.4-3.7l10-17.3C55.1,26.1,55.4,25.1,55.4,24z">
19
+ </path>
20
+ </g>
21
+ </svg>
@@ -0,0 +1,20 @@
1
+ <svg width="120" height="120" viewBox="0 0 120 120" fill="none" xmlns="http://www.w3.org/2000/svg">
2
+ <g clip-path="url(#clip0_2488_6932)">
3
+ <path d="M20 60C20 37.9086 37.9086 20 60 20V20C82.0914 20 100 37.9086 100 60V60C100 82.0914 82.0914 100 60 100V100C37.9086 100 20 82.0914 20 60V60Z" fill="white"/>
4
+ <path d="M59.9998 120C45.0899 119.64 39.1877 109.673 37.3861 100.047C36.4082 94.8144 36.8371 86.1138 37.3861 83.0083C38.2783 77.9468 39.7196 70.672 41.3152 62.2305C43.5972 50.1344 49.6538 43.2542 62.7279 40.8007L84.1132 36.7167C84.6794 33.5425 85.7533 25.1358 84.7753 19.9542C82.9566 10.2259 75.4588 0.154419 60.24 2.17953e-06C27.0916 5.07745e-06 -0.000214137 26.8516 -0.000211239 60C-0.000208341 93.1484 26.8514 120 59.9998 120Z" fill="url(#paint0_linear_2488_6932)"/>
5
+ <path d="M59.9998 0C74.9097 0.360309 82.2874 10.346 84.089 19.9714C85.067 25.2045 83.1625 33.8862 82.6134 36.9917C81.7212 42.0532 80.28 49.328 78.6843 57.7695C76.4024 69.8656 70.3458 76.7458 57.2717 79.1993L37.3709 83.1066C36.8047 86.2807 34.9345 94.8595 35.9125 100.041C37.7312 109.769 44.5408 119.846 59.7596 120C92.908 120 120 93.1484 120 60C120 26.8516 93.1482 0 59.9998 0Z" fill="url(#paint1_linear_2488_6932)"/>
6
+ </g>
7
+ <defs>
8
+ <linearGradient id="paint0_linear_2488_6932" x1="-0.000431424" y1="120" x2="94.4319" y2="6.72576" gradientUnits="userSpaceOnUse">
9
+ <stop stop-color="#D2DFFF"/>
10
+ <stop offset="1" stop-color="#4E7FFF"/>
11
+ </linearGradient>
12
+ <linearGradient id="paint1_linear_2488_6932" x1="120" y1="-2.85362e-06" x2="24.0889" y2="109.927" gradientUnits="userSpaceOnUse">
13
+ <stop stop-color="#D2DFFF"/>
14
+ <stop offset="1" stop-color="#4E7FFF"/>
15
+ </linearGradient>
16
+ <clipPath id="clip0_2488_6932">
17
+ <rect width="120" height="120" fill="white"/>
18
+ </clipPath>
19
+ </defs>
20
+ </svg>
package/dist/index.js CHANGED
@@ -1,4 +1,224 @@
1
1
  // @bun
2
- var _t=60,y=1000,h=60000,mt=60,It=24,Nt=86400000,d=2,v=3000;import{rm as j,mkdir as A,writeFile as tt}from"fs/promises";import{join as n,basename as ot}from"path";import{cwd as rt,exit as st}from"process";var{$:w,build:nt,Glob:B}=globalThis.Bun;import{readFile as V,writeFile as X}from"fs/promises";var{Glob:Z}=globalThis.Bun;var H=async(o,r)=>{let s=new Z("*.html"),t=[];for await(let a of s.scan({cwd:r,absolute:!0}))t.push(a);for(let a of t){let c=await V(a,"utf8");for(let[m,p]of Object.entries(o)){let u=m.replace(/[.*+?^${}()|[\]\\]/g,"\\$&"),$=new RegExp(`(<script[^>]+src=["'])(/?(?:.*\\/)?${u})(?:\\.[^."'/]+)?(\\.js)(["'][^>]*>)`,"g");c=c.replace($,(l,i,x,I,f)=>{return`${i}${p}${f}`})}await X(a,c,"utf8")}};var Ot=async({buildDir:o="build",assetsDir:r,reactIndexDir:s,javascriptDir:t,typeScriptDir:a,reactPagesDir:c,htmlDir:m,htmxDir:p,tailwind:u})=>{let $=performance.now(),l=rt(),i=n(l,o),x=r&&n(l,r),I=s&&n(l,s),f=t&&n(l,t),C=a&&n(l,a),T=c&&n(l,c),E=m&&n(l,m),P=p&&n(l,p);await j(i,{force:!0,recursive:!0}),await A(i),T&&I&&await it(T,I);let q=I&&await L(I,"*.tsx"),z=f&&await L(f,"*.js"),G=C&&await L(C,"*.ts"),R=[...q??[],...z??[],...G??[]];if(R.length===0)return console.warn("No entry points found, skipping build"),null;let{logs:J,outputs:K}=await nt({entrypoints:R,format:"esm",naming:"[dir]/[name].[hash].[ext]",outdir:i,target:"bun"}).catch((e)=>{console.error("Build failed:",e),st(1)});if(J.forEach((e)=>{if(e.level==="error")console.error(e);else if(e.level==="warning")console.warn(e);else if(e.level==="info"||e.level==="debug")console.info(e)}),x&&await w`cp -R ${x} ${i}`,E)await A(n(i,"html")),await w`cp -R ${E} ${n(i)}`;if(P)await A(n(i,"htmx")),await w`cp -R ${P} ${n(i)}`;if(u)await w`tailwindcss -i ${u.input} -o ${n(i,u.output)}`;let U=K.reduce((e,b)=>{let _=b.path;if(_.startsWith(i))_=_.slice(i.length);_=_.replace(/^\/+/,"");let g=_.split("/").pop();if(!g)return e;let O=`.${b.hash}.`;if(!g.includes(O))throw new Error(`Expected hash delimiter ${O} in ${g}`);let[Q]=g.split(O);return e[Q]="/"+_,e},{});E&&await H(U,E);let N=performance.now()-$,S;if(N<y)S=`${N.toFixed(d)}ms`;else if(N<h)S=`${(N/y).toFixed(d)}s`;else S=`${(N/h).toFixed(d)}m`;return console.log(`Build completed in ${S}`),U},it=async(o,r)=>{await j(r,{force:!0,recursive:!0}),await A(r);let s=new B("*.*"),t=[];for await(let c of s.scan({cwd:o}))t.push(c);let a=t.map(async(c)=>{let m=ot(c),[p]=m.split("."),u=["import { hydrateRoot } from 'react-dom/client';",`import { ${p} } from '../pages/${p}';
3
- `,`hydrateRoot(document, <${p} />);`].join(`
4
- `);return tt(n(r,`${p}Index.tsx`),u)});await Promise.all(a)},L=async(o,r)=>{let s=[],t=new B(r);for await(let a of t.scan({absolute:!0,cwd:o}))s.push(a);return s};import{createElement as et}from"react";import{renderToReadableStream as at}from"react-dom/server.browser";var Ct=async(o,r)=>{let s=et(o),t=await at(s,{bootstrapModules:[r]});return new Response(t,{headers:{"Content-Type":"text/html"}})},Tt=(o)=>Bun.file(o);import{argv as pt}from"process";var{env:F}=globalThis.Bun;import ct from"os";var k=()=>{let o=ct.networkInterfaces(),s=Object.values(o).flat().filter((t)=>t!==void 0).find((t)=>t.family==="IPv4"&&!t.internal);if(s)return s.address;return console.warn("No IP address found, falling back to localhost"),"localhost"};var D=F.HOST??"0.0.0.0",M=F.PORT??v,Y,lt=pt,W=lt.includes("--host");if(W)Y=k(),D="0.0.0.0";var Yt=(o)=>o.listen({hostname:D,port:M},()=>{if(console.log(`Server started on http://${D==="0.0.0.0"?"localhost":D}:${M}`),W)console.log(`Server started on network: http://${Y}:${M}`)});export{H as updateScriptTags,Yt as networkingPlugin,Ct as handleReactPageRequest,Tt as handleHTMLPageRequest,k as getLocalIPAddress,Ot as build,d as TIME_PRECISION,_t as SECONDS_IN_A_MINUTE,mt as MINUTES_IN_AN_HOUR,y as MILLISECONDS_IN_A_SECOND,h as MILLISECONDS_IN_A_MINUTE,Nt as MILLISECONDS_IN_A_DAY,It as HOURS_IN_A_DAY,v as DEFAULT_PORT};
2
+ // src/constants.ts
3
+ var SECONDS_IN_A_MINUTE = 60;
4
+ var MILLISECONDS_IN_A_SECOND = 1000;
5
+ var MILLISECONDS_IN_A_MINUTE = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE;
6
+ var MINUTES_IN_AN_HOUR = 60;
7
+ var HOURS_IN_A_DAY = 24;
8
+ var MILLISECONDS_IN_A_DAY = MILLISECONDS_IN_A_SECOND * SECONDS_IN_A_MINUTE * MINUTES_IN_AN_HOUR * HOURS_IN_A_DAY;
9
+ var TIME_PRECISION = 2;
10
+ var DEFAULT_PORT = 3000;
11
+ // src/core/build.ts
12
+ import { rm, mkdir, writeFile as writeFile2 } from "fs/promises";
13
+ import { join, basename } from "path";
14
+ import { cwd, exit } from "process";
15
+ var {$, build: bunBuild, Glob: Glob2 } = globalThis.Bun;
16
+
17
+ // src/utils/updateScriptTags.ts
18
+ import { readFile, writeFile } from "fs/promises";
19
+ var {Glob } = globalThis.Bun;
20
+ var updateScriptTags = async (manifest, htmlDir) => {
21
+ const htmlGlob = new Glob("*.html");
22
+ const htmlFiles = [];
23
+ for await (const file of htmlGlob.scan({
24
+ cwd: htmlDir,
25
+ absolute: true
26
+ })) {
27
+ htmlFiles.push(file);
28
+ }
29
+ for (const filePath of htmlFiles) {
30
+ let content = await readFile(filePath, "utf8");
31
+ for (const [scriptName, newPath] of Object.entries(manifest)) {
32
+ const escapedScriptName = scriptName.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
33
+ const regex = new RegExp(`(<script[^>]+src=["'])(/?(?:.*\\/)?${escapedScriptName})(?:\\.[^."'/]+)?(\\.js)(["'][^>]*>)`, "g");
34
+ content = content.replace(regex, (_, prefix, _oldBase, _ext, suffix) => {
35
+ return `${prefix}${newPath}${suffix}`;
36
+ });
37
+ }
38
+ await writeFile(filePath, content, "utf8");
39
+ }
40
+ };
41
+
42
+ // src/core/build.ts
43
+ var build = async ({
44
+ buildDirectory = "build",
45
+ assetsDirectory,
46
+ reactDirectory,
47
+ html,
48
+ htmxDirectory,
49
+ tailwind
50
+ }) => {
51
+ const start = performance.now();
52
+ const projectRoot = cwd();
53
+ const buildDirAbsolute = join(projectRoot, buildDirectory);
54
+ const assetsDirAbsolute = assetsDirectory && join(projectRoot, assetsDirectory);
55
+ const reactIndexDirAbsolute = reactDirectory && join(projectRoot, reactDirectory, "indexes");
56
+ const reactPagesDirAbsolute = reactDirectory && join(projectRoot, reactDirectory, "pages");
57
+ const htmlDirAbsolute = html?.directory ? join(projectRoot, html.directory) : undefined;
58
+ const htmxDirAbsolute = htmxDirectory && join(projectRoot, htmxDirectory);
59
+ await rm(buildDirAbsolute, { force: true, recursive: true });
60
+ await mkdir(buildDirAbsolute);
61
+ reactPagesDirAbsolute && reactIndexDirAbsolute && await generateReactIndexFiles(reactPagesDirAbsolute, reactIndexDirAbsolute);
62
+ const reactEntryPaths = reactIndexDirAbsolute && await scanEntryPoints(reactIndexDirAbsolute, "*.tsx");
63
+ const entryPaths = [...reactEntryPaths ?? []];
64
+ if (entryPaths.length === 0) {
65
+ console.warn("No entry points found, skipping build");
66
+ return null;
67
+ }
68
+ const { logs, outputs } = await bunBuild({
69
+ entrypoints: entryPaths,
70
+ format: "esm",
71
+ naming: `[dir]/[name].[hash].[ext]`,
72
+ outdir: buildDirAbsolute,
73
+ target: "bun"
74
+ }).catch((error) => {
75
+ console.error("Build failed:", error);
76
+ exit(1);
77
+ });
78
+ logs.forEach((log) => {
79
+ if (log.level === "error")
80
+ console.error(log);
81
+ else if (log.level === "warning")
82
+ console.warn(log);
83
+ else if (log.level === "info" || log.level === "debug")
84
+ console.info(log);
85
+ });
86
+ assetsDirAbsolute && await $`cp -R ${assetsDirAbsolute} ${buildDirAbsolute}`;
87
+ if (htmlDirAbsolute) {
88
+ await mkdir(join(buildDirAbsolute, "html"));
89
+ await $`cp -R ${htmlDirAbsolute} ${join(buildDirAbsolute)}`;
90
+ }
91
+ if (htmxDirAbsolute) {
92
+ await mkdir(join(buildDirAbsolute, "htmx"));
93
+ await $`cp -R ${htmxDirAbsolute} ${join(buildDirAbsolute)}`;
94
+ }
95
+ if (tailwind) {
96
+ await $`tailwindcss -i ${tailwind.input} -o ${join(buildDirAbsolute, tailwind.output)}`;
97
+ }
98
+ const manifest = outputs.reduce((acc, artifact) => {
99
+ let relativePath = artifact.path;
100
+ if (relativePath.startsWith(buildDirAbsolute)) {
101
+ relativePath = relativePath.slice(buildDirAbsolute.length);
102
+ }
103
+ relativePath = relativePath.replace(/^\/+/, "");
104
+ const baseName = relativePath.split("/").pop();
105
+ if (!baseName)
106
+ return acc;
107
+ const hashDelimiter = `.${artifact.hash}.`;
108
+ if (!baseName.includes(hashDelimiter)) {
109
+ throw new Error(`Expected hash delimiter ${hashDelimiter} in ${baseName}`);
110
+ }
111
+ const [fileName] = baseName.split(hashDelimiter);
112
+ acc[fileName] = "/" + relativePath;
113
+ return acc;
114
+ }, {});
115
+ htmlDirAbsolute && await updateScriptTags(manifest, htmlDirAbsolute);
116
+ const end = performance.now();
117
+ const durationMs = end - start;
118
+ let duration;
119
+ if (durationMs < MILLISECONDS_IN_A_SECOND) {
120
+ duration = `${durationMs.toFixed(TIME_PRECISION)}ms`;
121
+ } else if (durationMs < MILLISECONDS_IN_A_MINUTE) {
122
+ duration = `${(durationMs / MILLISECONDS_IN_A_SECOND).toFixed(TIME_PRECISION)}s`;
123
+ } else {
124
+ duration = `${(durationMs / MILLISECONDS_IN_A_MINUTE).toFixed(TIME_PRECISION)}m`;
125
+ }
126
+ console.log(`Build completed in ${duration}`);
127
+ return manifest;
128
+ };
129
+ var generateReactIndexFiles = async (reactPagesDirAbsolute, reactIndexDirAbsolute) => {
130
+ await rm(reactIndexDirAbsolute, { force: true, recursive: true });
131
+ await mkdir(reactIndexDirAbsolute);
132
+ const pagesGlob = new Glob2("*.*");
133
+ const files = [];
134
+ for await (const file of pagesGlob.scan({ cwd: reactPagesDirAbsolute })) {
135
+ files.push(file);
136
+ }
137
+ const promises = files.map(async (file) => {
138
+ const fileName = basename(file);
139
+ const [componentName] = fileName.split(".");
140
+ const content = [
141
+ `import { hydrateRoot } from 'react-dom/client';`,
142
+ `import { ${componentName} } from '../pages/${componentName}';
143
+ `,
144
+ `hydrateRoot(document, <${componentName} />);`
145
+ ].join(`
146
+ `);
147
+ return writeFile2(join(reactIndexDirAbsolute, `${componentName}Index.tsx`), content);
148
+ });
149
+ await Promise.all(promises);
150
+ };
151
+ var scanEntryPoints = async (dir, pattern) => {
152
+ const entryPaths = [];
153
+ const glob = new Glob2(pattern);
154
+ for await (const file of glob.scan({ absolute: true, cwd: dir })) {
155
+ entryPaths.push(file);
156
+ }
157
+ return entryPaths;
158
+ };
159
+ // src/core/pageHandlers.ts
160
+ import { createElement } from "react";
161
+ import { renderToReadableStream } from "react-dom/server.browser";
162
+ var handleReactPageRequest = async (pageComponent, index) => {
163
+ const page = createElement(pageComponent);
164
+ const stream = await renderToReadableStream(page, {
165
+ bootstrapModules: [index]
166
+ });
167
+ return new Response(stream, {
168
+ headers: { "Content-Type": "text/html" }
169
+ });
170
+ };
171
+ var handleHTMLPageRequest = (html) => Bun.file(html);
172
+ // src/plugins/networkingPlugin.ts
173
+ import { argv } from "process";
174
+ var {env } = globalThis.Bun;
175
+
176
+ // src/utils/networking.ts
177
+ import os from "os";
178
+ var getLocalIPAddress = () => {
179
+ const interfaces = os.networkInterfaces();
180
+ const addresses = Object.values(interfaces).flat().filter((iface) => iface !== undefined);
181
+ const ipAddress = addresses.find((iface) => iface.family === "IPv4" && !iface.internal);
182
+ if (ipAddress)
183
+ return ipAddress.address;
184
+ console.warn("No IP address found, falling back to localhost");
185
+ return "localhost";
186
+ };
187
+
188
+ // src/plugins/networkingPlugin.ts
189
+ var host = env.HOST ?? "localhost";
190
+ var port = env.PORT ?? DEFAULT_PORT;
191
+ var localIP;
192
+ var args = argv;
193
+ var hostFlag = args.includes("--host");
194
+ if (hostFlag) {
195
+ localIP = getLocalIPAddress();
196
+ host = "0.0.0.0";
197
+ }
198
+ var networkingPlugin = (app) => app.listen({
199
+ hostname: host,
200
+ port
201
+ }, () => {
202
+ if (hostFlag) {
203
+ console.log(`Server started on http://localhost:${port}`);
204
+ console.log(`Server started on network: http://${localIP}:${port}`);
205
+ } else {
206
+ console.log(`Server started on http://${host}:${port}`);
207
+ }
208
+ });
209
+ export {
210
+ updateScriptTags,
211
+ networkingPlugin,
212
+ handleReactPageRequest,
213
+ handleHTMLPageRequest,
214
+ getLocalIPAddress,
215
+ build,
216
+ TIME_PRECISION,
217
+ SECONDS_IN_A_MINUTE,
218
+ MINUTES_IN_AN_HOUR,
219
+ MILLISECONDS_IN_A_SECOND,
220
+ MILLISECONDS_IN_A_MINUTE,
221
+ MILLISECONDS_IN_A_DAY,
222
+ HOURS_IN_A_DAY,
223
+ DEFAULT_PORT
224
+ };
@@ -1,16 +1,2 @@
1
- type BuildConfig = {
2
- buildDir?: string;
3
- assetsDir?: string;
4
- reactIndexDir?: string;
5
- javascriptDir?: string;
6
- typeScriptDir?: string;
7
- reactPagesDir?: string;
8
- htmlDir?: string;
9
- htmxDir?: string;
10
- tailwind?: {
11
- input: string;
12
- output: string;
13
- };
14
- };
15
- export declare const build: ({ buildDir, assetsDir, reactIndexDir, javascriptDir, typeScriptDir, reactPagesDir, htmlDir, htmxDir, tailwind }: BuildConfig) => Promise<Record<string, string> | null>;
16
- export {};
1
+ import { BuildConfig } from "../types";
2
+ export declare const build: ({ buildDirectory, assetsDirectory, reactDirectory, html, htmxDirectory, tailwind }: BuildConfig) => Promise<Record<string, string> | null>;
@@ -0,0 +1,19 @@
1
+ export type HTMLScriptOption = "ts" | "js" | "ts+ssr" | "js+ssr" | undefined;
2
+ export type BuildConfig = {
3
+ buildDirectory?: string;
4
+ assetsDirectory?: string;
5
+ reactDirectory?: string;
6
+ vueDirectory?: string;
7
+ angularDirectory?: string;
8
+ astroDirectory?: string;
9
+ svelteDirectory?: string;
10
+ html?: {
11
+ directory?: string;
12
+ scriptingOption: HTMLScriptOption;
13
+ };
14
+ htmxDirectory?: string;
15
+ tailwind?: {
16
+ input: string;
17
+ output: string;
18
+ };
19
+ };
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@absolutejs/absolute",
3
- "version": "0.4.0",
3
+ "version": "0.5.1",
4
4
  "description": "A fullstack meta-framework for building web applications with TypeScript",
5
5
  "repository": {
6
6
  "type": "git",
@@ -11,7 +11,7 @@
11
11
  "license": "CC BY-NC 4.0",
12
12
  "author": "Alex Kahn",
13
13
  "scripts": {
14
- "build": "rm -rf dist && bun build src/index.ts --outdir dist --minify --splitting --target=bun --external react --external react-dom --external elysia && tsc --emitDeclarationOnly --project tsconfig.json",
14
+ "build": "rm -rf dist && bun build src/index.ts --outdir dist --target=bun --external react --external react-dom --external elysia && tsc --emitDeclarationOnly --project tsconfig.json",
15
15
  "test": "echo \"Error: no test specified\" && exit 1",
16
16
  "format": "prettier --write \"./**/*.{js,jsx,ts,tsx,css,json}\"",
17
17
  "dev": "bun run --watch example/server.ts",
@@ -23,19 +23,18 @@
23
23
  "react-dom": ">= 19.1.0"
24
24
  },
25
25
  "devDependencies": {
26
+ "elysia": "1.2.25",
26
27
  "@elysiajs/static": "1.0.2",
27
28
  "@types/bun": "1.1.1",
28
29
  "@types/react": "19.1.0",
29
30
  "@types/react-dom": "19.1.2",
30
31
  "@types/vue": "2.0.0",
31
- "autoprefixer": "10.4.20",
32
- "elysia": "1.2.25",
33
- "postcss": "8.4.49",
34
- "prettier": "3.5.3",
32
+ "typescript": "5.7.2",
35
33
  "react": "19.1.0",
36
34
  "svelte": "4.2.15",
37
- "tailwindcss": "3.4.17",
38
- "typescript": "5.7.2",
39
- "vue": "3.4.26"
35
+ "vue": "3.4.26",
36
+ "postcss": "8.4.49",
37
+ "autoprefixer": "10.4.20",
38
+ "tailwindcss": "3.4.17"
40
39
  }
41
40
  }
package/src/core/build.ts CHANGED
@@ -8,48 +8,31 @@ import {
8
8
  TIME_PRECISION
9
9
  } from "../constants";
10
10
  import { updateScriptTags } from "../utils/updateScriptTags";
11
-
12
- type BuildConfig = {
13
- buildDir?: string;
14
- assetsDir?: string;
15
- reactIndexDir?: string;
16
- javascriptDir?: string;
17
- typeScriptDir?: string;
18
- reactPagesDir?: string;
19
- htmlDir?: string;
20
- htmxDir?: string;
21
- tailwind?: {
22
- input: string;
23
- output: string;
24
- };
25
- };
11
+ import { BuildConfig } from "../types";
26
12
 
27
13
  export const build = async ({
28
- buildDir = "build",
29
- assetsDir,
30
- reactIndexDir,
31
- javascriptDir,
32
- typeScriptDir,
33
- reactPagesDir,
34
- htmlDir,
35
- htmxDir,
14
+ buildDirectory = "build",
15
+ assetsDirectory,
16
+ reactDirectory,
17
+ html,
18
+ htmxDirectory,
36
19
  tailwind
37
20
  }: BuildConfig) => {
38
21
  const start = performance.now();
39
22
 
40
23
  const projectRoot = cwd();
41
- const buildDirAbsolute = join(projectRoot, buildDir);
42
- const assetsDirAbsolute = assetsDir && join(projectRoot, assetsDir);
24
+ const buildDirAbsolute = join(projectRoot, buildDirectory);
25
+ const assetsDirAbsolute =
26
+ assetsDirectory && join(projectRoot, assetsDirectory);
43
27
  const reactIndexDirAbsolute =
44
- reactIndexDir && join(projectRoot, reactIndexDir);
45
- const javascriptDirAbsolute =
46
- javascriptDir && join(projectRoot, javascriptDir);
47
- const typeScriptDirAbsolute =
48
- typeScriptDir && join(projectRoot, typeScriptDir);
28
+ reactDirectory && join(projectRoot, reactDirectory, "indexes");
49
29
  const reactPagesDirAbsolute =
50
- reactPagesDir && join(projectRoot, reactPagesDir);
51
- const htmlDirAbsolute = htmlDir && join(projectRoot, htmlDir);
52
- const htmxDirAbsolute = htmxDir && join(projectRoot, htmxDir);
30
+ reactDirectory && join(projectRoot, reactDirectory, "pages");
31
+ const htmlDirAbsolute = html?.directory
32
+ ? join(projectRoot, html.directory)
33
+ : undefined;
34
+
35
+ const htmxDirAbsolute = htmxDirectory && join(projectRoot, htmxDirectory);
53
36
 
54
37
  await rm(buildDirAbsolute, { force: true, recursive: true });
55
38
  await mkdir(buildDirAbsolute);
@@ -64,18 +47,8 @@ export const build = async ({
64
47
  const reactEntryPaths =
65
48
  reactIndexDirAbsolute &&
66
49
  (await scanEntryPoints(reactIndexDirAbsolute, "*.tsx"));
67
- const javascriptEntryPaths =
68
- javascriptDirAbsolute &&
69
- (await scanEntryPoints(javascriptDirAbsolute, "*.js"));
70
- const typeScriptEntryPaths =
71
- typeScriptDirAbsolute &&
72
- (await scanEntryPoints(typeScriptDirAbsolute, "*.ts"));
73
-
74
- const entryPaths = [
75
- ...(reactEntryPaths ?? []),
76
- ...(javascriptEntryPaths ?? []),
77
- ...(typeScriptEntryPaths ?? [])
78
- ];
50
+
51
+ const entryPaths = [...(reactEntryPaths ?? [])];
79
52
 
80
53
  if (entryPaths.length === 0) {
81
54
  console.warn("No entry points found, skipping build");
@@ -4,7 +4,7 @@ import { Elysia } from "elysia";
4
4
  import { getLocalIPAddress } from "../utils/networking";
5
5
  import { DEFAULT_PORT } from "../constants";
6
6
 
7
- let host = env.HOST ?? "0.0.0.0";
7
+ let host = env.HOST ?? "localhost";
8
8
  const port = env.PORT ?? DEFAULT_PORT;
9
9
  let localIP: string | undefined;
10
10
 
@@ -23,12 +23,14 @@ export const networkingPlugin = (app: Elysia) =>
23
23
  port: port
24
24
  },
25
25
  () => {
26
- const displayHost = host === "0.0.0.0" ? "localhost" : host;
27
- console.log(`Server started on http://${displayHost}:${port}`);
26
+ //TODO: I dont think this works properly
28
27
  if (hostFlag) {
28
+ console.log(`Server started on http://localhost:${port}`);
29
29
  console.log(
30
30
  `Server started on network: http://${localIP}:${port}`
31
31
  );
32
+ } else {
33
+ console.log(`Server started on http://${host}:${port}`);
32
34
  }
33
35
  }
34
36
  );
package/src/types.ts ADDED
@@ -0,0 +1,20 @@
1
+ export type HTMLScriptOption = "ts" | "js" | "ts+ssr" | "js+ssr" | undefined;
2
+
3
+ export type BuildConfig = {
4
+ buildDirectory?: string;
5
+ assetsDirectory?: string;
6
+ reactDirectory?: string;
7
+ vueDirectory?: string;
8
+ angularDirectory?: string;
9
+ astroDirectory?: string;
10
+ svelteDirectory?: string;
11
+ html?: {
12
+ directory?: string;
13
+ scriptingOption: HTMLScriptOption;
14
+ };
15
+ htmxDirectory?: string;
16
+ tailwind?: {
17
+ input: string;
18
+ output: string;
19
+ };
20
+ };