@hachej/boring-core 0.1.50 → 0.1.52

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.
@@ -456,8 +456,51 @@ function ChatFirstPublicShell({
456
456
  ] });
457
457
  }
458
458
 
459
+ // src/app/front/vitePreloadRecovery.ts
460
+ var INSTALL_FLAG = "__boringVitePreloadRecoveryInstalled__";
461
+ var RELOADED_ENTRY_KEY = "boring-ui:vite-preload-reloaded-entry";
462
+ function currentFrontendEntry(documentRef, fallback) {
463
+ const moduleScripts = Array.from(documentRef.scripts).filter((script) => script.type === "module" && Boolean(script.src));
464
+ const assetEntry = moduleScripts.find((script) => script.src.includes("/assets/"));
465
+ return assetEntry?.src ?? moduleScripts[0]?.src ?? fallback;
466
+ }
467
+ function shouldReloadForFrontendEntry(storage, entry) {
468
+ if (storage.getItem(RELOADED_ENTRY_KEY) === entry) return false;
469
+ storage.setItem(RELOADED_ENTRY_KEY, entry);
470
+ return true;
471
+ }
472
+ function installVitePreloadRecovery() {
473
+ if (typeof window === "undefined" || typeof document === "undefined") return;
474
+ const recoverableWindow = window;
475
+ if (recoverableWindow[INSTALL_FLAG]) return;
476
+ recoverableWindow[INSTALL_FLAG] = true;
477
+ window.addEventListener("vite:preloadError", (event) => {
478
+ event.preventDefault();
479
+ const entry = currentFrontendEntry(document, window.location.href);
480
+ let shouldReload = false;
481
+ try {
482
+ shouldReload = shouldReloadForFrontendEntry(window.sessionStorage, entry);
483
+ } catch {
484
+ shouldReload = false;
485
+ }
486
+ if (!shouldReload) {
487
+ console.warn(
488
+ "[boring-core] dynamic import failed after a reload attempt; leaving the panel error visible.",
489
+ event.payload
490
+ );
491
+ return;
492
+ }
493
+ console.warn(
494
+ "[boring-core] dynamic import failed; reloading to pick up the latest app assets.",
495
+ event.payload
496
+ );
497
+ window.location.reload();
498
+ });
499
+ }
500
+
459
501
  // src/app/front/CoreWorkspaceAgentFront.tsx
460
502
  import { Fragment as Fragment3, jsx as jsx5, jsxs as jsxs4 } from "react/jsx-runtime";
503
+ installVitePreloadRecovery();
461
504
  var DEFAULT_WORKSPACE_ROUTE = "/workspace/:id";
462
505
  var DEFAULT_WORKSPACE_ID_PARAM = "id";
463
506
  function DefaultTopBarRight() {
@@ -286,6 +286,9 @@ function contentType(filePath) {
286
286
  const ext = path.extname(filePath).toLowerCase();
287
287
  return MIME_TYPES[ext] ?? "application/octet-stream";
288
288
  }
289
+ function isFrontendAssetPath(pathname) {
290
+ return pathname === "/assets" || pathname.startsWith("/assets/");
291
+ }
289
292
  function injectCspNonceIntoHtml(html, nonce) {
290
293
  if (!nonce) return html;
291
294
  const metaTag = `<meta name="boring-csp-nonce" content="${nonce}" />`;
@@ -411,6 +414,7 @@ async function serveFrontendShell(request, reply, indexPath, telemetry) {
411
414
  }
412
415
  const html = await readFile(indexPath, "utf-8");
413
416
  captureAppOpened(telemetry, request.id);
417
+ reply.header("cache-control", "no-store");
414
418
  reply.type("text/html; charset=utf-8");
415
419
  return reply.send(injectCspNonceIntoHtml(html, request.cspNonce));
416
420
  }
@@ -498,9 +502,17 @@ async function registerFrontendFallback(app, appRoot, telemetry) {
498
502
  return { error: "invalid_path" };
499
503
  }
500
504
  if (await pathIsFile(candidate)) {
505
+ if (isFrontendAssetPath(pathname)) {
506
+ reply.header("cache-control", "public, max-age=31536000, immutable");
507
+ }
501
508
  reply.type(contentType(candidate));
502
509
  return reply.send(createReadStream(candidate));
503
510
  }
511
+ if (isFrontendAssetPath(pathname)) {
512
+ reply.status(404);
513
+ reply.header("cache-control", "no-store");
514
+ return { error: "asset_not_found" };
515
+ }
504
516
  return serveFrontendShell(request, reply, indexPath, telemetry);
505
517
  });
506
518
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@hachej/boring-core",
3
- "version": "0.1.50",
3
+ "version": "0.1.52",
4
4
  "type": "module",
5
5
  "license": "MIT",
6
6
  "description": "Foundation package for boring-ui-v2 apps: DB, auth, config, HTTP app factory, and frontend app shell.",
@@ -79,9 +79,9 @@
79
79
  "react-router-dom": "^7.14.2",
80
80
  "smol-toml": "^1.6.1",
81
81
  "zod": "^3.25.76",
82
- "@hachej/boring-agent": "0.1.50",
83
- "@hachej/boring-ui-kit": "0.1.50",
84
- "@hachej/boring-workspace": "0.1.50"
82
+ "@hachej/boring-agent": "0.1.52",
83
+ "@hachej/boring-workspace": "0.1.52",
84
+ "@hachej/boring-ui-kit": "0.1.52"
85
85
  },
86
86
  "devDependencies": {
87
87
  "@testing-library/jest-dom": "^6.9.1",