@timber-js/app 0.1.18 → 0.1.20

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.
@@ -18,9 +18,24 @@
18
18
  * (populated by ssr-entry.ts) to ensure correct per-request isolation
19
19
  * across concurrent requests with streaming Suspense.
20
20
  *
21
+ * Reactivity: useParams() uses useSyncExternalStore so that components
22
+ * in unchanged layouts (e.g., sidebar items) re-render atomically when
23
+ * params change during client-side navigation. This matches the pattern
24
+ * used by usePathname() and useSearchParams().
25
+ *
21
26
  * Design doc: design/09-typescript.md §"Typed Routes"
22
27
  */
23
28
  import type { Routes } from '#/index.js';
29
+ /**
30
+ * Subscribe to params changes. Called by useSyncExternalStore.
31
+ * Exported for testing — not intended for direct use by app code.
32
+ */
33
+ export declare function subscribe(callback: () => void): () => void;
34
+ /**
35
+ * Get the current params snapshot (client).
36
+ * Exported for testing — not intended for direct use by app code.
37
+ */
38
+ export declare function getSnapshot(): Record<string, string | string[]>;
24
39
  /**
25
40
  * Set the current route params. Called by the framework internals
26
41
  * during navigation — not intended for direct use by app code.
@@ -29,6 +44,10 @@ import type { Routes } from '#/index.js';
29
44
  * During SSR, params are also available via getSsrData().params
30
45
  * (ALS-backed), but setCurrentParams is still called for the
31
46
  * module-level fallback path.
47
+ *
48
+ * After mutation, all useSyncExternalStore subscribers are notified
49
+ * so that every mounted useParams() consumer re-renders in the same
50
+ * React commit — even components in unchanged layouts.
32
51
  */
33
52
  export declare function setCurrentParams(params: Record<string, string | string[]>): void;
34
53
  /**
@@ -38,8 +57,8 @@ export declare function setCurrentParams(params: Record<string, string | string[
38
57
  * it does not affect the runtime return value.
39
58
  *
40
59
  * During SSR, reads from the ALS-backed SSR data context to ensure
41
- * per-request isolation. On the client, reads from module-level state
42
- * (set by the segment router on each navigation).
60
+ * per-request isolation. On the client, subscribes to the module-level
61
+ * params store via useSyncExternalStore.
43
62
  *
44
63
  * @overload Typed — when a known route path is passed, returns the
45
64
  * exact params shape from the generated Routes interface.
@@ -1 +1 @@
1
- {"version":3,"file":"use-params.d.ts","sourceRoot":"","sources":["../../src/client/use-params.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;GAqBG;AAEH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AASzC;;;;;;;;GAQG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,IAAI,CAEhF;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACjF,wBAAgB,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC"}
1
+ {"version":3,"file":"use-params.d.ts","sourceRoot":"","sources":["../../src/client/use-params.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;GA0BG;AAGH,OAAO,KAAK,EAAE,MAAM,EAAE,MAAM,YAAY,CAAC;AAczC;;;GAGG;AACH,wBAAgB,SAAS,CAAC,QAAQ,EAAE,MAAM,IAAI,GAAG,MAAM,IAAI,CAG1D;AAED;;;GAGG;AACH,wBAAgB,WAAW,IAAI,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAE/D;AAeD;;;;;;;;;;;;GAYG;AACH,wBAAgB,gBAAgB,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,GAAG,IAAI,CAKhF;AAMD;;;;;;;;;;;;;GAaG;AACH,wBAAgB,SAAS,CAAC,CAAC,SAAS,MAAM,MAAM,EAAE,KAAK,EAAE,CAAC,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC;AACjF,wBAAgB,SAAS,CAAC,KAAK,CAAC,EAAE,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,MAAM,GAAG,MAAM,EAAE,CAAC,CAAC"}
@@ -1 +1 @@
1
- {"version":3,"file":"use-router.d.ts","sourceRoot":"","sources":["../../src/client/use-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,MAAM,WAAW,iBAAiB;IAChC,qDAAqD;IACrD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACzD,6DAA6D;IAC7D,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5D,sDAAsD;IACtD,OAAO,IAAI,IAAI,CAAC;IAChB,+BAA+B;IAC/B,IAAI,IAAI,IAAI,CAAC;IACb,kCAAkC;IAClC,OAAO,IAAI,IAAI,CAAC;IAChB,wCAAwC;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,IAAI,iBAAiB,CAyD7C"}
1
+ {"version":3,"file":"use-router.d.ts","sourceRoot":"","sources":["../../src/client/use-router.ts"],"names":[],"mappings":"AAAA;;;;;;;;;GASG;AAKH,MAAM,WAAW,iBAAiB;IAChC,qDAAqD;IACrD,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IACzD,6DAA6D;IAC7D,OAAO,CAAC,IAAI,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE;QAAE,MAAM,CAAC,EAAE,OAAO,CAAA;KAAE,GAAG,IAAI,CAAC;IAC5D,sDAAsD;IACtD,OAAO,IAAI,IAAI,CAAC;IAChB,+BAA+B;IAC/B,IAAI,IAAI,IAAI,CAAC;IACb,kCAAkC;IAClC,OAAO,IAAI,IAAI,CAAC;IAChB,wCAAwC;IACxC,QAAQ,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,CAAC;CAC9B;AAED;;;;;;;;;;;;;;;;GAgBG;AACH,wBAAgB,SAAS,IAAI,iBAAiB,CAuD7C"}
package/dist/index.js CHANGED
@@ -11752,7 +11752,7 @@ function listenForClientErrors(server, projectRoot) {
11752
11752
  //#endregion
11753
11753
  //#region src/plugins/entries.ts
11754
11754
  var __dirname$1 = dirname(fileURLToPath(import.meta.url));
11755
- var SRC_DIR$1 = existsSync(resolve(__dirname$1, "..", "server", "rsc-entry", "index.ts")) ? resolve(__dirname$1, "..") : resolve(__dirname$1, "..", "src");
11755
+ var SRC_DIR = existsSync(resolve(__dirname$1, "..", "server", "rsc-entry", "index.ts")) ? resolve(__dirname$1, "..") : resolve(__dirname$1, "..", "src");
11756
11756
  var VIRTUAL_IDS = {
11757
11757
  rscEntry: "virtual:timber-rsc-entry",
11758
11758
  ssrEntry: "virtual:timber-ssr-entry",
@@ -11769,9 +11769,9 @@ var VIRTUAL_IDS = {
11769
11769
  * published package via the `files` field.
11770
11770
  */
11771
11771
  var ENTRY_FILE_MAP = {
11772
- [VIRTUAL_IDS.rscEntry]: resolve(SRC_DIR$1, "server", "rsc-entry", "index.ts"),
11773
- [VIRTUAL_IDS.ssrEntry]: resolve(SRC_DIR$1, "server", "ssr-entry.ts"),
11774
- [VIRTUAL_IDS.browserEntry]: resolve(SRC_DIR$1, "client", "browser-entry.ts")
11772
+ [VIRTUAL_IDS.rscEntry]: resolve(SRC_DIR, "server", "rsc-entry", "index.ts"),
11773
+ [VIRTUAL_IDS.ssrEntry]: resolve(SRC_DIR, "server", "ssr-entry.ts"),
11774
+ [VIRTUAL_IDS.browserEntry]: resolve(SRC_DIR, "client", "browser-entry.ts")
11775
11775
  };
11776
11776
  /** The \0-prefixed resolved ID for virtual:timber-config */
11777
11777
  var RESOLVED_CONFIG_ID = `\0${VIRTUAL_IDS.config}`;
@@ -12288,7 +12288,6 @@ function generateManifestModule(tree) {
12288
12288
  //#region src/plugins/shims.ts
12289
12289
  var __dirname = dirname(fileURLToPath(import.meta.url));
12290
12290
  var PKG_ROOT = __dirname.endsWith("plugins") ? resolve(__dirname, "..", "..") : resolve(__dirname, "..");
12291
- var SRC_DIR = resolve(PKG_ROOT, "src");
12292
12291
  var SHIMS_DIR = resolve(PKG_ROOT, "src", "shims");
12293
12292
  /**
12294
12293
  * Virtual module IDs for server-only and client-only poison pills.
@@ -12323,34 +12322,6 @@ function stripJsExtension(id) {
12323
12322
  return id.endsWith(".js") ? id.slice(0, -3) : id;
12324
12323
  }
12325
12324
  /**
12326
- * Resolve a #/* subpath import to an absolute file path.
12327
- *
12328
- * The package.json "imports" field maps #/* → ./src/*. Vite's resolver
12329
- * handles this via Node.js subpath imports, but in dev mode the resulting
12330
- * module URL can differ from a relative import to the same file. This
12331
- * causes module duplication — the same file loaded as two separate ES
12332
- * modules with separate module-level state.
12333
- *
12334
- * This function resolves #/foo/bar.js to <PKG_ROOT>/src/foo/bar.ts
12335
- * (trying .ts first, then .tsx, then .js, then the raw path).
12336
- * Returns null if the import is not a #/ import or the file doesn't exist.
12337
- */
12338
- function resolveSubpathImport(id) {
12339
- if (!id.startsWith("#/")) return null;
12340
- const basePath = resolve(SRC_DIR, id.slice(2));
12341
- const withoutJs = stripJsExtension(basePath);
12342
- for (const ext of [
12343
- ".ts",
12344
- ".tsx",
12345
- ".js"
12346
- ]) {
12347
- const candidate = withoutJs + ext;
12348
- if (existsSync(candidate)) return candidate;
12349
- }
12350
- if (existsSync(basePath)) return basePath;
12351
- return null;
12352
- }
12353
- /**
12354
12325
  * Create the timber-shims Vite plugin.
12355
12326
  *
12356
12327
  * Hooks: resolveId, load
@@ -12362,8 +12333,6 @@ function timberShims(_ctx) {
12362
12333
  resolveId(id) {
12363
12334
  if (id === "server-only") return SERVER_ONLY_VIRTUAL;
12364
12335
  if (id === "client-only") return CLIENT_ONLY_VIRTUAL;
12365
- const subpathResolved = resolveSubpathImport(id);
12366
- if (subpathResolved) return subpathResolved;
12367
12336
  const cleanId = stripJsExtension(id);
12368
12337
  if (cleanId in SHIM_MAP) {
12369
12338
  if (this.environment?.name === "client" && cleanId === "next/navigation") return resolve(SHIMS_DIR, "navigation-client.ts");