@timber-js/app 0.1.55 → 0.1.57

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.
@@ -23,6 +23,11 @@
23
23
  * that depend on these APIs are safe to call from any environment —
24
24
  * they return null or no-op when the APIs aren't available.
25
25
  *
26
+ * Singleton guarantee: With the simplified chunking strategy (LOCAL-337),
27
+ * this module lives in exactly one client chunk. The previous globalThis +
28
+ * Symbol.for workaround for cross-chunk duplication is no longer needed.
29
+ * See design/27-chunking-strategy.md.
30
+ *
26
31
  * See design/19-client-navigation.md §"NavigationContext"
27
32
  */
28
33
  import React, { type ReactNode } from 'react';
@@ -1 +1 @@
1
- {"version":3,"file":"navigation-context.d.ts","sourceRoot":"","sources":["../../src/client/navigation-context.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAEH,OAAO,KAAK,EAAE,EAAiB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAM7D,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC1C,QAAQ,EAAE,MAAM,CAAC;CAClB;AAyCD;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,eAAe,GAAG,IAAI,CAM7D;AAMD,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,QAAQ,GACT,EAAE,uBAAuB,GAAG,KAAK,CAAC,YAAY,CAO9C;AA6BD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAE/D;AAED,wBAAgB,kBAAkB,IAAI,eAAe,CAEpD;AA6BD;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,IAAI,CAKvD;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,GAAG,KAAK,CAAC,YAAY,CAMrB"}
1
+ {"version":3,"file":"navigation-context.d.ts","sourceRoot":"","sources":["../../src/client/navigation-context.ts"],"names":[],"mappings":"AAEA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GA+BG;AAEH,OAAO,KAAK,EAAE,EAAiB,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAM7D,MAAM,WAAW,eAAe;IAC9B,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC;IAC1C,QAAQ,EAAE,MAAM,CAAC;CAClB;AAyBD;;;;GAIG;AACH,wBAAgB,oBAAoB,IAAI,eAAe,GAAG,IAAI,CAM7D;AAMD,MAAM,WAAW,uBAAuB;IACtC,KAAK,EAAE,eAAe,CAAC;IACvB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB;AAED;;;;;GAKG;AACH,wBAAgB,kBAAkB,CAAC,EACjC,KAAK,EACL,QAAQ,GACT,EAAE,uBAAuB,GAAG,KAAK,CAAC,YAAY,CAO9C;AAiBD,wBAAgB,kBAAkB,CAAC,KAAK,EAAE,eAAe,GAAG,IAAI,CAE/D;AAED,wBAAgB,kBAAkB,IAAI,eAAe,CAEpD;AAqBD;;;GAGG;AACH,wBAAgB,uBAAuB,IAAI,MAAM,GAAG,IAAI,CAKvD;AAED;;;GAGG;AACH,wBAAgB,yBAAyB,CAAC,EACxC,KAAK,EACL,QAAQ,GACT,EAAE;IACD,KAAK,EAAE,MAAM,GAAG,IAAI,CAAC;IACrB,QAAQ,CAAC,EAAE,SAAS,CAAC;CACtB,GAAG,KAAK,CAAC,YAAY,CAMrB"}
@@ -0,0 +1,58 @@
1
+ /**
2
+ * TopLoader — Built-in progress bar for client navigations.
3
+ *
4
+ * Shows an animated progress bar at the top of the viewport while an RSC
5
+ * navigation is in flight. Injected automatically by the framework into
6
+ * TransitionRoot — users never render this component directly.
7
+ *
8
+ * Configuration is via timber.config.ts `topLoader` key. Enabled by default.
9
+ * Users who want a fully custom progress indicator disable the built-in one
10
+ * (`topLoader: { enabled: false }`) and use `useNavigationPending()` directly.
11
+ *
12
+ * Animation approach: pure CSS @keyframes. The bar crawls from 0% to ~90%
13
+ * width over ~30s using ease-out timing. When navigation completes, the bar
14
+ * snaps to 100% and fades out over 200ms. No JS animation loops (RAF, setInterval).
15
+ *
16
+ * Phase transitions are derived synchronously during render (React's
17
+ * getDerivedStateFromProps pattern) — no useEffect needed for state tracking.
18
+ * The finishing → hidden cleanup uses onTransitionEnd from the CSS transition.
19
+ *
20
+ * When delay > 0, CSS animation-delay + a visibility keyframe ensure the bar
21
+ * stays invisible during the delay period. If navigation finishes before the
22
+ * delay, the bar was never visible so the finish transition is also invisible.
23
+ *
24
+ * See design/19-client-navigation.md §"useNavigationPending()"
25
+ * See LOCAL-336 for design decisions.
26
+ */
27
+ export interface TopLoaderConfig {
28
+ /** Whether the top-loader is enabled. Default: true. */
29
+ enabled?: boolean;
30
+ /** Bar color. Default: '#2299DD'. */
31
+ color?: string;
32
+ /** Bar height in pixels. Default: 3. */
33
+ height?: number;
34
+ /** Show subtle glow/shadow effect. Default: true. */
35
+ shadow?: boolean;
36
+ /** Delay in ms before showing the bar. Default: 0. */
37
+ delay?: number;
38
+ /** CSS z-index. Default: 1600. */
39
+ zIndex?: number;
40
+ }
41
+ /**
42
+ * Internal top-loader component. Injected by TransitionRoot.
43
+ *
44
+ * Reads pending navigation state from PendingNavigationContext.
45
+ * Phase transitions are derived synchronously during render:
46
+ *
47
+ * hidden → crawling: when isPending becomes true
48
+ * crawling → finishing: when isPending becomes false
49
+ * finishing → hidden: when CSS transition ends (onTransitionEnd)
50
+ * finishing → crawling: when isPending becomes true again
51
+ *
52
+ * No useEffect — all state changes are either derived during render
53
+ * (getDerivedStateFromProps pattern) or triggered by DOM events.
54
+ */
55
+ export declare function TopLoader({ config }: {
56
+ config?: TopLoaderConfig;
57
+ }): React.ReactElement | null;
58
+ //# sourceMappingURL=top-loader.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"top-loader.d.ts","sourceRoot":"","sources":["../../src/client/top-loader.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;GAyBG;AASH,MAAM,WAAW,eAAe;IAC9B,wDAAwD;IACxD,OAAO,CAAC,EAAE,OAAO,CAAC;IAClB,qCAAqC;IACrC,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,wCAAwC;IACxC,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,qDAAqD;IACrD,MAAM,CAAC,EAAE,OAAO,CAAC;IACjB,sDAAsD;IACtD,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,kCAAkC;IAClC,MAAM,CAAC,EAAE,MAAM,CAAC;CACjB;AA6CD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,EAAE,MAAM,EAAE,EAAE;IAAE,MAAM,CAAC,EAAE,eAAe,CAAA;CAAE,GAAG,KAAK,CAAC,YAAY,GAAG,IAAI,CAyF7F"}
@@ -22,6 +22,7 @@
22
22
  * See design/19-client-navigation.md §"NavigationContext"
23
23
  */
24
24
  import { type ReactNode } from 'react';
25
+ import { type TopLoaderConfig } from './top-loader.js';
25
26
  /**
26
27
  * Root wrapper component that enables transition-based rendering.
27
28
  *
@@ -39,8 +40,9 @@ import { type ReactNode } from 'react';
39
40
  * Non-navigation renders:
40
41
  * transitionRender(newWrappedElement);
41
42
  */
42
- export declare function TransitionRoot({ initial }: {
43
+ export declare function TransitionRoot({ initial, topLoaderConfig }: {
43
44
  initial: ReactNode;
45
+ topLoaderConfig?: TopLoaderConfig;
44
46
  }): ReactNode;
45
47
  /**
46
48
  * Trigger a transition render for non-navigation updates.
@@ -1 +1 @@
1
- {"version":3,"file":"transition-root.d.ts","sourceRoot":"","sources":["../../src/client/transition-root.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAA0C,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAsB/E;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,EAAE;IAAE,OAAO,EAAE,SAAS,CAAA;CAAE,GAAG,SAAS,CAyC7E;AAID;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,CAIzD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C"}
1
+ {"version":3,"file":"transition-root.d.ts","sourceRoot":"","sources":["../../src/client/transition-root.tsx"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;GAsBG;AAEH,OAAO,EAAoD,KAAK,SAAS,EAAE,MAAM,OAAO,CAAC;AAEzF,OAAO,EAAa,KAAK,eAAe,EAAE,MAAM,iBAAiB,CAAC;AAqBlE;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,cAAc,CAAC,EAAE,OAAO,EAAE,eAAe,EAAE,EAAE;IAAE,OAAO,EAAE,SAAS,CAAC;IAAC,eAAe,CAAC,EAAE,eAAe,CAAA;CAAE,GAAG,SAAS,CAgDjI;AAID;;;;;;GAMG;AACH,wBAAgB,gBAAgB,CAAC,OAAO,EAAE,SAAS,GAAG,IAAI,CAIzD;AAED;;;;;;;;;;;;GAYG;AACH,wBAAgB,kBAAkB,CAChC,UAAU,EAAE,MAAM,EAClB,OAAO,EAAE,MAAM,OAAO,CAAC,SAAS,CAAC,GAChC,OAAO,CAAC,IAAI,CAAC,CAMf;AAED;;;GAGG;AACH,wBAAgB,qBAAqB,IAAI,OAAO,CAE/C"}
package/dist/index.d.ts CHANGED
@@ -83,6 +83,30 @@ export interface TimberUserConfig {
83
83
  recmaPlugins?: unknown[];
84
84
  remarkRehypeOptions?: Record<string, unknown>;
85
85
  };
86
+ /**
87
+ * Built-in top-loader progress bar for client navigations.
88
+ * Shows an animated bar at the top of the viewport during RSC navigations.
89
+ * Enabled by default — set `enabled: false` to opt out.
90
+ *
91
+ * Users who want a fully custom progress indicator should disable this
92
+ * and use `useNavigationPending()` directly.
93
+ *
94
+ * See LOCAL-336 for design decisions.
95
+ */
96
+ topLoader?: {
97
+ /** Whether the top-loader is enabled. Default: true. */
98
+ enabled?: boolean;
99
+ /** Bar color. Default: '#2299DD'. */
100
+ color?: string;
101
+ /** Bar height in pixels. Default: 3. */
102
+ height?: number;
103
+ /** Show subtle glow/shadow effect. Default: true. */
104
+ shadow?: boolean;
105
+ /** Delay in ms before showing the bar (avoids flash on fast navs). Default: 0. */
106
+ delay?: number;
107
+ /** CSS z-index. Default: 1600. */
108
+ zIndex?: number;
109
+ };
86
110
  }
87
111
  /**
88
112
  * Resolve `clientJavascript` into a fully resolved config.
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"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"}
package/dist/index.js CHANGED
@@ -1,6 +1,6 @@
1
1
  import { r as setViteServer, t as formatSize } from "./_chunks/format-DNt20Kt8.js";
2
2
  import { i as scanRoutes, n as generateRouteMap, t as collectInterceptionRewrites } from "./_chunks/interception-DGDIjDbR.js";
3
- import { existsSync, readFileSync, statSync } from "node:fs";
3
+ import { existsSync, readFileSync } from "node:fs";
4
4
  import { dirname, extname, join, resolve } from "node:path";
5
5
  import { fileURLToPath, pathToFileURL } from "node:url";
6
6
  import { createRequire } from "node:module";
@@ -11932,7 +11932,8 @@ function generateConfigModule(ctx) {
11932
11932
  dev: ctx.dev ?? false,
11933
11933
  slowPhaseMs: ctx.config.dev?.slowPhaseMs ?? 200,
11934
11934
  slowRequestMs: ctx.config.slowRequestMs ?? 3e3,
11935
- cookieSecrets
11935
+ cookieSecrets,
11936
+ topLoader: ctx.config.topLoader
11936
11937
  };
11937
11938
  return [
11938
11939
  "// Auto-generated runtime config — do not edit.",
@@ -14232,156 +14233,14 @@ function timberReactProd() {
14232
14233
  //#endregion
14233
14234
  //#region src/plugins/chunks.ts
14234
14235
  /**
14235
- * timber-chunks — Vite sub-plugin for intelligent client chunk splitting.
14236
- *
14237
- * Splits client bundles into cache tiers based on update frequency:
14238
- *
14239
- * Tier 1: vendor-react — react, react-dom, scheduler (changes rarely)
14240
- * Tier 2: vendor-timber — timber runtime, RSC runtime (changes per framework update)
14241
- * Tier 3: vendor-app — user node_modules (changes on dependency updates)
14242
- * Tier 4: shared-app — small shared app utilities/components (< 5KB source)
14243
- * Tier 5: [route]-* — per-route page/layout chunks (default Rollup splitting)
14244
- *
14245
- * The shared-app tier prevents tiny utility modules (constants, helpers,
14246
- * small UI components) from becoming individual chunks when shared across
14247
- * routes. Without this, Rolldown creates per-module chunks for any code
14248
- * shared between two or more entry points, producing many sub-1KB chunks.
14249
- *
14250
- * Server environments (RSC, SSR) are left to Vite's default chunking since
14251
- * Cloudflare Workers load all code from a single deployment bundle with no
14252
- * benefit from cache-tier separation.
14253
- *
14254
- * Design docs: 27-chunking-strategy.md
14255
- */
14256
- /**
14257
- * Source file size threshold for the shared-app chunk.
14258
- * Modules under this size that aren't route files get merged into shared-app
14259
- * instead of getting their own tiny chunks.
14260
- */
14261
- var SMALL_MODULE_THRESHOLD = 5 * 1024;
14262
- /**
14263
- * Route convention file basenames (without extension).
14264
- * These files define route segments and must stay in per-route chunks
14265
- * to preserve route-based code splitting.
14266
- */
14267
- var ROUTE_FILE_BASENAMES = new Set([
14268
- "page",
14269
- "layout",
14270
- "loading",
14271
- "error",
14272
- "not-found",
14273
- "template",
14274
- "access",
14275
- "middleware",
14276
- "default",
14277
- "route"
14278
- ]);
14279
- /**
14280
- * Cache for source file sizes to avoid repeated statSync calls.
14281
- * Populated lazily during the build.
14282
- */
14283
- var sizeCache = /* @__PURE__ */ new Map();
14284
- /**
14285
- * Get the source file size, with caching.
14286
- * Returns Infinity for virtual modules or files that can't be stat'd.
14287
- */
14288
- function getSourceSize(id) {
14289
- const cached = sizeCache.get(id);
14290
- if (cached !== void 0) return cached;
14291
- try {
14292
- const size = statSync(id).size;
14293
- sizeCache.set(id, size);
14294
- return size;
14295
- } catch {
14296
- sizeCache.set(id, Infinity);
14297
- return Infinity;
14298
- }
14299
- }
14300
- /**
14301
- * Extract the basename without extension from a module ID.
14302
- * e.g. '/project/app/dashboard/page.tsx' → 'page'
14303
- */
14304
- function getBasename(id) {
14305
- const lastSlash = id.lastIndexOf("/");
14306
- const filename = lastSlash >= 0 ? id.substring(lastSlash + 1) : id;
14307
- const dotIndex = filename.indexOf(".");
14308
- return dotIndex >= 0 ? filename.substring(0, dotIndex) : filename;
14309
- }
14310
- /**
14311
- * Check if a module is a React ecosystem package (tier 1).
14312
- */
14313
- function isReactVendor(id) {
14314
- return id.includes("node_modules/react-dom") || id.includes("node_modules/react/") || id.includes("node_modules/scheduler");
14315
- }
14316
- /**
14317
- * Check if a module is part of the timber framework runtime (tier 2).
14318
- *
14319
- * Matches both monorepo paths (packages/timber-app/...) and consumer
14320
- * project paths (node_modules/@timber-js/app/...) so the chunk
14321
- * assignment is consistent regardless of how timber is installed.
14322
- */
14323
- function isTimberRuntime(id) {
14324
- return id.includes("/timber-app/") || id.includes("/@timber-js/app/") || id.includes("react-server-dom") || id.includes("@vitejs/plugin-rsc");
14325
- }
14326
- /**
14327
- * Check if a module is a user-installed node_modules dependency (tier 3).
14328
- * Excludes React ecosystem and timber runtime packages which have their own tiers.
14329
- */
14330
- function isUserVendor(id) {
14331
- return id.includes("node_modules/") && !isReactVendor(id) && !isTimberRuntime(id);
14332
- }
14333
- /**
14334
- * Check if a module is a route convention file that should stay per-route.
14335
- */
14336
- function isRouteFile(id) {
14337
- return ROUTE_FILE_BASENAMES.has(getBasename(id));
14338
- }
14339
- /**
14340
- * Categorize a module ID into a cache tier chunk name.
14341
- *
14342
- * Returns a chunk name for vendor modules and small shared app code,
14343
- * or undefined to let Rollup's default splitting handle route code.
14344
- */
14345
- function assignChunk(id) {
14346
- if (isReactVendor(id)) return "vendor-react";
14347
- if (isTimberRuntime(id)) return "vendor-timber";
14348
- if (isUserVendor(id)) return "vendor-app";
14349
- if (!id.includes("\0") && id.startsWith("/") && !isRouteFile(id)) {
14350
- if (getSourceSize(id) < SMALL_MODULE_THRESHOLD) return "shared-app";
14351
- }
14352
- }
14353
- /**
14354
- * Group timber's internal 'use client' modules into the vendor-timber chunk.
14355
- *
14356
- * The RSC plugin creates separate entry points for each 'use client' module,
14357
- * which manualChunks can't merge. This function is passed as the RSC plugin's
14358
- * `clientChunks` callback to group timber internals into a single chunk.
14359
- *
14360
- * User client components that are small (< 5KB) are grouped into shared-client
14361
- * to prevent thin facade wrappers from becoming individual chunks. This handles
14362
- * the RSC client reference facade problem where each 'use client' module gets
14363
- * a ~100-300 byte re-export wrapper chunk.
14364
- */
14365
- function assignClientChunk(meta) {
14366
- if (meta.id.includes("/timber-app/") || meta.id.includes("/@timber-js/app/")) return "vendor-timber";
14367
- if (!meta.id.includes("\0") && meta.id.startsWith("/")) {
14368
- if (getSourceSize(meta.id) < SMALL_MODULE_THRESHOLD) return "shared-client";
14369
- }
14370
- }
14371
- /**
14372
14236
  * Create the timber-chunks Vite plugin.
14373
14237
  *
14374
- * Uses Vite's per-environment config to apply manualChunks only to
14375
- * the client build. The config hook runs before environments are
14376
- * created, so we use `environments.client` to target the client.
14238
+ * Currently a no-op — Rolldown's default splitting produces the desired
14239
+ * output (one main bundle + per-route chunks). The plugin is retained as
14240
+ * a hook point for future chunking adjustments if needed.
14377
14241
  */
14378
14242
  function timberChunks() {
14379
- return {
14380
- name: "timber-chunks",
14381
- config() {
14382
- return { environments: { client: { build: { rollupOptions: { output: { manualChunks: assignChunk } } } } } };
14383
- }
14384
- };
14243
+ return { name: "timber-chunks" };
14385
14244
  }
14386
14245
  //#endregion
14387
14246
  //#region src/plugins/server-bundle.ts
@@ -14948,8 +14807,7 @@ function timber(config) {
14948
14807
  rsc: "virtual:timber-rsc-entry",
14949
14808
  ssr: "virtual:timber-ssr-entry",
14950
14809
  client: "virtual:timber-browser-entry"
14951
- },
14952
- clientChunks: assignClientChunk
14810
+ }
14953
14811
  });
14954
14812
  });
14955
14813
  return [