i18n-keyless-react 2.3.1 → 2.3.2

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.
@@ -9,16 +9,25 @@ var __rewriteRelativeImportExtension = (this && this.__rewriteRelativeImportExte
9
9
  // A single AsyncLocalStorage instance, created lazily on the server only. Each
10
10
  // `run()` creates an isolated store, so the instance is correctly a process singleton.
11
11
  //
12
- // CRITICAL: the instance is stored on `globalThis` under a `Symbol.for(...)` key, NOT in a
13
- // module-level variable. Bundlers that build separate server-entry and SSR-render
14
- // environments (e.g. TanStack Start / Vite SSR) instantiate this package more than once in
15
- // the same process. With a module-local `als`, `runWithI18nKeyless` (called from the server
16
- // entry) would set `als` on copy A, while `getRequestScope`/`recordUsedKey` (called during
17
- // the React render) would read copy B's `als` — `undefined` — and SSR would silently fall
18
- // back to the primary language with a hydration mismatch. Routing every read and write
19
- // through the shared `globalThis` slot guarantees all module copies use ONE ALS.
20
- const ALS_KEY = Symbol.for("i18n-keyless.als");
21
- const ALS_INIT_KEY = Symbol.for("i18n-keyless.alsInit");
12
+ // CRITICAL two layered problems, one solution:
13
+ //
14
+ // 1. A module-local `als` is duplicated when a bundler instantiates this package more than
15
+ // once (e.g. TanStack Start / Vite SSR build a separate server-entry and SSR-render
16
+ // environment). `runWithI18nKeyless` (server entry) would set `als` on copy A while
17
+ // `getRequestScope`/`recordUsedKey` (React render) read copy B's `als` — `undefined` —
18
+ // so SSR silently falls back to the primary language with a hydration mismatch.
19
+ //
20
+ // 2. Storing the instance on `globalThis` fixes (1) ONLY if the key is realm-independent.
21
+ // `Symbol.for()`'s registry is PER-REALM: TanStack Start / Vite SSR run the server entry
22
+ // and the React render in two different V8 realms that SHARE the same `globalThis` object
23
+ // but each resolve `Symbol.for("x")` to a DIFFERENT symbol — so the write-side and
24
+ // read-side miss each other even through one globalThis. (Confirmed empirically: same
25
+ // globalThis on both sides, yet getAls() returned the ALS on the server entry and
26
+ // `undefined` in the render.) A plain STRING key is realm-independent and bridges them.
27
+ //
28
+ // So: route every read and write through one `globalThis` slot keyed by a plain string.
29
+ const ALS_KEY = "__i18n_keyless_als__";
30
+ const ALS_INIT_KEY = "__i18n_keyless_alsInit__";
22
31
  const registry = globalThis;
23
32
  function getAls() {
24
33
  return registry[ALS_KEY];
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "i18n-keyless-react",
3
3
  "private": false,
4
- "version": "2.3.1",
4
+ "version": "2.3.2",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
7
7
  "module": "./dist/index.js",
@@ -24,7 +24,7 @@
24
24
  "postpublish": "rm -rf ./dist && rm *.tgz"
25
25
  },
26
26
  "dependencies": {
27
- "i18n-keyless-core": "2.3.1",
27
+ "i18n-keyless-core": "2.3.2",
28
28
  "zustand": "^5.0.3"
29
29
  },
30
30
  "peerDependencies": {