bosia 0.6.0 → 0.6.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "bosia",
3
- "version": "0.6.0",
3
+ "version": "0.6.1",
4
4
  "type": "module",
5
5
  "description": "A fast, batteries-included fullstack framework — SSR · Svelte 5 Runes · Bun · ElysiaJS. File-based routing inspired by SvelteKit. No Node.js, no Vite, no adapters.",
6
6
  "keywords": [
@@ -33,6 +33,7 @@
33
33
  "exports": {
34
34
  ".": "./src/lib/index.ts",
35
35
  "./client": "./src/lib/client.ts",
36
+ "./server": "./src/lib/server.ts",
36
37
  "./plugins/server-timing": "./src/core/plugins/server-timing.ts",
37
38
  "./plugins/inspector": "./src/core/plugins/inspector/index.ts"
38
39
  },
package/src/core/cache.ts CHANGED
@@ -28,16 +28,26 @@ function parseMaxEntries(raw: string | undefined): number {
28
28
  return n;
29
29
  }
30
30
 
31
- export const CACHE_KEYS: readonly string[] = parseCacheKeys(process.env.CACHE_KEYS);
32
- export const CACHE_MAX_ENTRIES = parseMaxEntries(process.env.CACHE_MAX_ENTRIES);
31
+ // `invalidate` / `invalidateAll` are re-exported from the public `bosia`
32
+ // barrel, so this module also evaluates in the browser bundle. Guard every
33
+ // `process.env` read — otherwise hydration throws `ReferenceError: Can't
34
+ // find variable: process` (Safari) the moment the barrel is imported.
35
+ const env: Record<string, string | undefined> =
36
+ typeof process !== "undefined" && process.env ? process.env : {};
37
+ const isServer = typeof process !== "undefined";
38
+
39
+ export const CACHE_KEYS: readonly string[] = parseCacheKeys(env.CACHE_KEYS);
40
+ export const CACHE_MAX_ENTRIES = parseMaxEntries(env.CACHE_MAX_ENTRIES);
33
41
  export const CACHE_ENABLED = CACHE_MAX_ENTRIES > 0;
34
42
 
35
- if (CACHE_ENABLED) {
36
- console.log(
37
- `💾 Response cache: max ${CACHE_MAX_ENTRIES} entries, identity keys [${CACHE_KEYS.join(", ")}]`,
38
- );
39
- } else {
40
- console.log("💾 Response cache: disabled (CACHE_MAX_ENTRIES=0)");
43
+ if (isServer) {
44
+ if (CACHE_ENABLED) {
45
+ console.log(
46
+ `💾 Response cache: max ${CACHE_MAX_ENTRIES} entries, identity keys [${CACHE_KEYS.join(", ")}]`,
47
+ );
48
+ } else {
49
+ console.log("💾 Response cache: disabled (CACHE_MAX_ENTRIES=0)");
50
+ }
41
51
  }
42
52
 
43
53
  // ─── Entry shape ─────────────────────────────────────────
package/src/core/dev.ts CHANGED
@@ -247,6 +247,12 @@ const devServer = Bun.serve({
247
247
  const forwardedHeaders = new Headers(req.headers);
248
248
  forwardedHeaders.set("x-forwarded-host", reqUrl.host);
249
249
  forwardedHeaders.set("x-forwarded-proto", reqUrl.protocol.replace(":", ""));
250
+ // Force inner app to respond uncompressed. Bun's `fetch()` auto-decodes
251
+ // gzip/br bodies but leaves the original `Content-Encoding` header on
252
+ // the Response, so passing it through made Safari throw -1015 ("cannot
253
+ // decode raw data") on every HTML navigation. Identity on the dev wire
254
+ // is fine — it's localhost.
255
+ forwardedHeaders.set("accept-encoding", "identity");
250
256
 
251
257
  // HMR-driven reloads can land on the proxy before the freshly-respawned
252
258
  // inner has bound APP_PORT. Retry for a few seconds on idempotent HTML
@@ -20,7 +20,7 @@ export interface InspectorOptions {
20
20
  interface ServerError {
21
21
  id: string;
22
22
  ts: number;
23
- source: "elysia" | "uncaught" | "rejection";
23
+ source: "server" | "uncaught" | "rejection";
24
24
  message: string;
25
25
  stack?: string;
26
26
  file?: string;
@@ -147,7 +147,7 @@ function installProcessListeners() {
147
147
  function installGlobalReporter() {
148
148
  globalThis.__BOSIA_REPORT_ERROR__ = (e) => {
149
149
  pushServerError({
150
- source: e.source ?? "elysia",
150
+ source: e.source ?? "server",
151
151
  message: e.message,
152
152
  stack: e.stack,
153
153
  });
@@ -282,7 +282,7 @@ export function inspector(options: InspectorOptions = {}): BosiaPlugin | false {
282
282
  chained = chained.onError(({ error }) => {
283
283
  const e = error as Error;
284
284
  pushServerError({
285
- source: "elysia",
285
+ source: "server",
286
286
  message: e?.message ?? String(error),
287
287
  stack: e?.stack,
288
288
  });
package/src/lib/index.ts CHANGED
@@ -6,7 +6,9 @@
6
6
  export { cn, getServerTime } from "./utils.ts";
7
7
  export { sequence } from "../core/hooks.ts";
8
8
  export { error, redirect, fail } from "../core/errors.ts";
9
- export { invalidate, invalidateAll } from "../core/cache.ts";
9
+ // `invalidate` / `invalidateAll` (server response-cache eviction) live in
10
+ // "bosia/server" — they touch server-process state and pulling them into
11
+ // the shared barrel leaks `process.env` reads into client bundles.
10
12
  export type { HttpError, Redirect, RedirectOptions, ActionFailure } from "../core/errors.ts";
11
13
  export type {
12
14
  RequestEvent,
@@ -0,0 +1,12 @@
1
+ // ─── Bosia Server API ─────────────────────────────────────
2
+ // Server-only helpers — import from "bosia/server".
3
+ // Kept separate from "bosia" because these modules touch server-process
4
+ // state (the response-cache Map, `process.env`) and have no meaning in
5
+ // the browser. Importing them through the shared `bosia` barrel would
6
+ // drag `process.env` reads into client bundles via the lib re-export
7
+ // graph (see ROADMAP v0.6.0 entry on the Safari hydration ReferenceError).
8
+ //
9
+ // Usage in user apps (form actions, +server.ts, hooks):
10
+ // import { invalidate, invalidateAll } from "bosia/server";
11
+
12
+ export { invalidate, invalidateAll } from "../core/cache.ts";