@timber-js/app 0.1.42 → 0.1.43
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": "@timber-js/app",
|
|
3
|
-
"version": "0.1.
|
|
3
|
+
"version": "0.1.43",
|
|
4
4
|
"description": "Vite-native React framework for Cloudflare Workers — correct HTTP semantics, real status codes, pages that work without JavaScript",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"cloudflare-workers",
|
|
@@ -100,7 +100,7 @@
|
|
|
100
100
|
"nuqs": "^2.0.0",
|
|
101
101
|
"react": "^19.2.4",
|
|
102
102
|
"react-dom": "^19.2.4",
|
|
103
|
-
"vite": "^8.0.
|
|
103
|
+
"vite": "^8.0.1",
|
|
104
104
|
"zod": "^3.22.0 || ^4.0.0"
|
|
105
105
|
},
|
|
106
106
|
"peerDependenciesMeta": {
|
|
@@ -47,16 +47,35 @@ export interface NavigationState {
|
|
|
47
47
|
* The context is created lazily to avoid calling createContext at module
|
|
48
48
|
* level. In the RSC environment, React.createContext doesn't exist —
|
|
49
49
|
* calling it at import time would crash the server.
|
|
50
|
+
*
|
|
51
|
+
* IMPORTANT: Context instances are stored on globalThis, NOT in module-
|
|
52
|
+
* level variables. The RSC client bundler duplicates this module across
|
|
53
|
+
* the browser-entry chunk (index) and client-reference chunk (shared-app)
|
|
54
|
+
* because both entry graphs import it. Module-level variables would create
|
|
55
|
+
* separate singleton instances per chunk — the provider in TransitionRoot
|
|
56
|
+
* (index chunk) would use context A while the consumer in LinkStatusProvider
|
|
57
|
+
* (shared-app chunk) reads from context B. globalThis guarantees a single
|
|
58
|
+
* instance regardless of how many times the module is duplicated.
|
|
59
|
+
*
|
|
60
|
+
* See design/19-client-navigation.md §"Singleton Context Guarantee"
|
|
50
61
|
*/
|
|
51
|
-
|
|
62
|
+
|
|
63
|
+
// Symbol keys for globalThis storage — prevents collisions with user code
|
|
64
|
+
const NAV_CTX_KEY = Symbol.for('__timber_nav_ctx');
|
|
65
|
+
const PENDING_CTX_KEY = Symbol.for('__timber_pending_nav_ctx');
|
|
52
66
|
|
|
53
67
|
function getOrCreateContext(): React.Context<NavigationState | null> | undefined {
|
|
54
|
-
|
|
68
|
+
const existing = (globalThis as Record<symbol, unknown>)[NAV_CTX_KEY] as
|
|
69
|
+
| React.Context<NavigationState | null>
|
|
70
|
+
| undefined;
|
|
71
|
+
if (existing !== undefined) return existing;
|
|
55
72
|
// createContext may not exist in the RSC environment
|
|
56
73
|
if (typeof React.createContext === 'function') {
|
|
57
|
-
|
|
74
|
+
const ctx = React.createContext<NavigationState | null>(null);
|
|
75
|
+
(globalThis as Record<symbol, unknown>)[NAV_CTX_KEY] = ctx;
|
|
76
|
+
return ctx;
|
|
58
77
|
}
|
|
59
|
-
return
|
|
78
|
+
return undefined;
|
|
60
79
|
}
|
|
61
80
|
|
|
62
81
|
/**
|
|
@@ -125,23 +144,25 @@ export function getNavigationState(): NavigationState {
|
|
|
125
144
|
|
|
126
145
|
/**
|
|
127
146
|
* Separate context for the in-flight navigation URL. Provided by
|
|
128
|
-
* TransitionRoot (
|
|
147
|
+
* TransitionRoot (urgent useState), consumed by LinkStatusProvider
|
|
129
148
|
* and useNavigationPending.
|
|
130
149
|
*
|
|
131
|
-
*
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
* if they were in separate files, the bundler could duplicate the
|
|
135
|
-
* module-level context variable across chunks.
|
|
150
|
+
* Uses globalThis via Symbol.for for the same reason as NavigationContext
|
|
151
|
+
* above — the bundler duplicates this module across chunks, and module-
|
|
152
|
+
* level variables would create separate context instances.
|
|
136
153
|
*/
|
|
137
|
-
let _pendingContext: React.Context<string | null> | undefined;
|
|
138
154
|
|
|
139
155
|
function getOrCreatePendingContext(): React.Context<string | null> | undefined {
|
|
140
|
-
|
|
156
|
+
const existing = (globalThis as Record<symbol, unknown>)[PENDING_CTX_KEY] as
|
|
157
|
+
| React.Context<string | null>
|
|
158
|
+
| undefined;
|
|
159
|
+
if (existing !== undefined) return existing;
|
|
141
160
|
if (typeof React.createContext === 'function') {
|
|
142
|
-
|
|
161
|
+
const ctx = React.createContext<string | null>(null);
|
|
162
|
+
(globalThis as Record<symbol, unknown>)[PENDING_CTX_KEY] = ctx;
|
|
163
|
+
return ctx;
|
|
143
164
|
}
|
|
144
|
-
return
|
|
165
|
+
return undefined;
|
|
145
166
|
}
|
|
146
167
|
|
|
147
168
|
/**
|