@pablozaiden/webapp 0.5.2 → 0.5.3

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@pablozaiden/webapp",
3
- "version": "0.5.2",
3
+ "version": "0.5.3",
4
4
  "description": "Opinionated Bun + React webapp framework for single-server apps",
5
5
  "license": "MIT",
6
6
  "type": "module",
@@ -31,18 +31,23 @@ export async function buildWebAppBinary(options: BuildWebAppBinaryOptions): Prom
31
31
  try {
32
32
  mkdirSync(cacheDir, { recursive: true });
33
33
  const webEntry = resolve(dirname(resolve(options.entrypoint)), options.web?.entry ?? "./web/main.tsx");
34
- const browserEntry = resolve(cacheDir, "webapp-browser-entry.ts");
34
+ const rendererEntry = resolve(cacheDir, "webapp-renderer-prelude.ts");
35
+ const clientEntry = resolve(cacheDir, "webapp-client-entry.ts");
35
36
  const browserOutDir = resolve(cacheDir, "browser");
36
- writeFileSync(browserEntry, `import { createRoot } from "react-dom/client";
37
+ writeFileSync(rendererEntry, `import { createRoot } from "react-dom/client";
37
38
  import { configureWebAppRenderer } from "@pablozaiden/webapp/web";
38
39
 
39
40
  configureWebAppRenderer(createRoot);
40
- import ${JSON.stringify(webEntry)};
41
+ `);
42
+ writeFileSync(clientEntry, `import ${JSON.stringify(webEntry)};
41
43
  `);
42
44
  const browserBuild = await Bun.build({
43
- entrypoints: [browserEntry],
45
+ entrypoints: [rendererEntry, clientEntry],
44
46
  outdir: browserOutDir,
45
47
  target: "browser",
48
+ format: "esm",
49
+ splitting: true,
50
+ publicPath: "/webapp-compiled/",
46
51
  minify: true,
47
52
  sourcemap: "external",
48
53
  define: options.define,
@@ -54,13 +59,17 @@ import ${JSON.stringify(webEntry)};
54
59
  throw new Error("Browser build failed");
55
60
  }
56
61
  const assets = browserBuild.outputs
62
+ .filter((output) => extname(output.path).toLowerCase() !== ".map")
57
63
  .map((output) => {
58
64
  const ext = extname(output.path).toLowerCase();
65
+ const fileName = basename(output.path);
59
66
  const publicPath = `/webapp-compiled/${basename(output.path)}`;
67
+ const scriptKind = ext === ".js" ? compiledScriptKind(fileName) : undefined;
60
68
  return {
61
69
  path: publicPath,
62
70
  contentType: contentTypeForOutput(ext),
63
- role: ext === ".css" ? "style" : ext === ".js" ? "script" : "asset",
71
+ role: ext === ".css" ? "style" : scriptKind ? "script" : "asset",
72
+ ...(scriptKind ? { scriptOrder: scriptKind === "renderer" ? 0 : 1 } : {}),
64
73
  body: readFileSync(output.path).toString("base64"),
65
74
  };
66
75
  });
@@ -115,3 +124,9 @@ function contentTypeForOutput(ext: string): string {
115
124
  if (ext === ".map") return "application/json; charset=utf-8";
116
125
  return "application/octet-stream";
117
126
  }
127
+
128
+ function compiledScriptKind(fileName: string): "renderer" | "client" | undefined {
129
+ if (/^webapp-renderer-prelude(?:[-.][\w-]+)?\.(?:mjs|js)$/.test(fileName)) return "renderer";
130
+ if (/^webapp-client-entry(?:[-.][\w-]+)?\.(?:mjs|js)$/.test(fileName)) return "client";
131
+ return undefined;
132
+ }
@@ -147,6 +147,7 @@ type CompiledClientAsset = {
147
147
  path: string;
148
148
  contentType: string;
149
149
  role: "script" | "style" | "asset";
150
+ scriptOrder?: number;
150
151
  body: string;
151
152
  };
152
153
 
@@ -481,7 +482,11 @@ function generatedHtml(
481
482
  const htmlAppleTouchPath = appleTouchPath.replace(/^\//, "./");
482
483
  const styleTags = compiledAssets?.filter((asset) => asset.role === "style").map((asset) => ` <link rel="stylesheet" href="${escapeAttribute(asset.path)}" />`).join("\n") ?? "";
483
484
  const scriptTags = compiledAssets
484
- ? compiledAssets.filter((asset) => asset.role === "script").map((asset) => ` <script type="module" src="${escapeAttribute(asset.path)}"></script>`).join("\n")
485
+ ? compiledAssets
486
+ .filter((asset) => asset.role === "script")
487
+ .sort((left, right) => (left.scriptOrder ?? 0) - (right.scriptOrder ?? 0))
488
+ .map((asset) => ` <script type="module" src="${escapeAttribute(asset.path)}"></script>`)
489
+ .join("\n")
485
490
  : ` <script type="module" src="${escapeAttribute(relativePrelude ?? "")}"></script>
486
491
  <script type="module" src="${escapeAttribute(relativeEntry ?? "")}"></script>`;
487
492
  const manifestTags = pwaEnabled(web)