@timber-js/app 0.1.42 → 0.1.44
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/dist/client/index.js
CHANGED
|
@@ -99,12 +99,28 @@ function useLinkStatus() {
|
|
|
99
99
|
* The context is created lazily to avoid calling createContext at module
|
|
100
100
|
* level. In the RSC environment, React.createContext doesn't exist —
|
|
101
101
|
* calling it at import time would crash the server.
|
|
102
|
+
*
|
|
103
|
+
* IMPORTANT: Context instances are stored on globalThis, NOT in module-
|
|
104
|
+
* level variables. The RSC client bundler duplicates this module across
|
|
105
|
+
* the browser-entry chunk (index) and client-reference chunk (shared-app)
|
|
106
|
+
* because both entry graphs import it. Module-level variables would create
|
|
107
|
+
* separate singleton instances per chunk — the provider in TransitionRoot
|
|
108
|
+
* (index chunk) would use context A while the consumer in LinkStatusProvider
|
|
109
|
+
* (shared-app chunk) reads from context B. globalThis guarantees a single
|
|
110
|
+
* instance regardless of how many times the module is duplicated.
|
|
111
|
+
*
|
|
112
|
+
* See design/19-client-navigation.md §"Singleton Context Guarantee"
|
|
102
113
|
*/
|
|
103
|
-
var
|
|
114
|
+
var NAV_CTX_KEY = Symbol.for("__timber_nav_ctx");
|
|
115
|
+
var PENDING_CTX_KEY = Symbol.for("__timber_pending_nav_ctx");
|
|
104
116
|
function getOrCreateContext() {
|
|
105
|
-
|
|
106
|
-
if (
|
|
107
|
-
|
|
117
|
+
const existing = globalThis[NAV_CTX_KEY];
|
|
118
|
+
if (existing !== void 0) return existing;
|
|
119
|
+
if (typeof React.createContext === "function") {
|
|
120
|
+
const ctx = React.createContext(null);
|
|
121
|
+
globalThis[NAV_CTX_KEY] = ctx;
|
|
122
|
+
return ctx;
|
|
123
|
+
}
|
|
108
124
|
}
|
|
109
125
|
/**
|
|
110
126
|
* Read the navigation context. Returns null during SSR (no provider)
|
|
@@ -129,40 +145,50 @@ function NavigationProvider({ value, children }) {
|
|
|
129
145
|
return createElement(ctx.Provider, { value }, children);
|
|
130
146
|
}
|
|
131
147
|
/**
|
|
132
|
-
*
|
|
133
|
-
*
|
|
134
|
-
*
|
|
148
|
+
* Navigation state communicated between the router and renderRoot.
|
|
149
|
+
*
|
|
150
|
+
* The router calls setNavigationState() before renderRoot(). The
|
|
151
|
+
* renderRoot callback reads via getNavigationState() to create the
|
|
152
|
+
* NavigationProvider with the correct params/pathname.
|
|
135
153
|
*
|
|
136
154
|
* This is NOT used by hooks directly — hooks read from React context.
|
|
137
|
-
*
|
|
138
|
-
* (
|
|
155
|
+
*
|
|
156
|
+
* Stored on globalThis (like the context instances above) because the
|
|
157
|
+
* router lives in the shared-app chunk while renderRoot lives in the
|
|
158
|
+
* index chunk. Module-level variables would be separate per chunk.
|
|
139
159
|
*/
|
|
140
|
-
var
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
160
|
+
var NAV_STATE_KEY = Symbol.for("__timber_nav_state");
|
|
161
|
+
function _getNavStateStore() {
|
|
162
|
+
const g = globalThis;
|
|
163
|
+
if (!g[NAV_STATE_KEY]) g[NAV_STATE_KEY] = { current: {
|
|
164
|
+
params: {},
|
|
165
|
+
pathname: "/"
|
|
166
|
+
} };
|
|
167
|
+
return g[NAV_STATE_KEY];
|
|
168
|
+
}
|
|
144
169
|
function setNavigationState(state) {
|
|
145
|
-
|
|
170
|
+
_getNavStateStore().current = state;
|
|
146
171
|
}
|
|
147
172
|
function getNavigationState() {
|
|
148
|
-
return
|
|
173
|
+
return _getNavStateStore().current;
|
|
149
174
|
}
|
|
150
175
|
/**
|
|
151
176
|
* Separate context for the in-flight navigation URL. Provided by
|
|
152
|
-
* TransitionRoot (
|
|
177
|
+
* TransitionRoot (urgent useState), consumed by LinkStatusProvider
|
|
153
178
|
* and useNavigationPending.
|
|
154
179
|
*
|
|
155
|
-
*
|
|
156
|
-
*
|
|
157
|
-
*
|
|
158
|
-
* if they were in separate files, the bundler could duplicate the
|
|
159
|
-
* module-level context variable across chunks.
|
|
180
|
+
* Uses globalThis via Symbol.for for the same reason as NavigationContext
|
|
181
|
+
* above — the bundler duplicates this module across chunks, and module-
|
|
182
|
+
* level variables would create separate context instances.
|
|
160
183
|
*/
|
|
161
|
-
var _pendingContext;
|
|
162
184
|
function getOrCreatePendingContext() {
|
|
163
|
-
|
|
164
|
-
if (
|
|
165
|
-
|
|
185
|
+
const existing = globalThis[PENDING_CTX_KEY];
|
|
186
|
+
if (existing !== void 0) return existing;
|
|
187
|
+
if (typeof React.createContext === "function") {
|
|
188
|
+
const ctx = React.createContext(null);
|
|
189
|
+
globalThis[PENDING_CTX_KEY] = ctx;
|
|
190
|
+
return ctx;
|
|
191
|
+
}
|
|
166
192
|
}
|
|
167
193
|
/**
|
|
168
194
|
* Read the pending navigation URL from context.
|