@tanstack/router-core 0.0.1-beta.195 → 0.0.1-beta.197
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/build/cjs/index.js +7 -4
- package/build/cjs/index.js.map +1 -1
- package/build/cjs/router.js +1 -1
- package/build/cjs/router.js.map +1 -1
- package/build/esm/index.js +3 -284
- package/build/esm/index.js.map +1 -1
- package/build/stats-html.html +1 -1
- package/build/stats-react.json +194 -189
- package/build/types/index.d.ts +1 -1
- package/build/types/router.d.ts +7 -1
- package/build/umd/index.development.js +2094 -2095
- package/build/umd/index.development.js.map +1 -1
- package/build/umd/index.production.js +21 -11
- package/build/umd/index.production.js.map +1 -1
- package/package.json +2 -1
- package/src/index.ts +1 -1
- package/src/router.ts +14 -7
- package/build/cjs/history.js +0 -301
- package/build/cjs/history.js.map +0 -1
- package/build/types/history.d.ts +0 -53
- package/src/history.ts +0 -398
package/build/esm/index.js
CHANGED
|
@@ -8,294 +8,13 @@
|
|
|
8
8
|
*
|
|
9
9
|
* @license MIT
|
|
10
10
|
*/
|
|
11
|
+
import { createMemoryHistory, createBrowserHistory } from '@tanstack/history';
|
|
12
|
+
export * from '@tanstack/history';
|
|
11
13
|
import invariant from 'tiny-invariant';
|
|
12
14
|
export { default as invariant } from 'tiny-invariant';
|
|
13
15
|
export { default as warning } from 'tiny-warning';
|
|
14
16
|
import { Store } from '@tanstack/store';
|
|
15
17
|
|
|
16
|
-
// While the public API was clearly inspired by the "history" npm package,
|
|
17
|
-
// This implementation attempts to be more lightweight by
|
|
18
|
-
// making assumptions about the way TanStack Router works
|
|
19
|
-
|
|
20
|
-
const pushStateEvent = 'pushstate';
|
|
21
|
-
const popStateEvent = 'popstate';
|
|
22
|
-
const beforeUnloadEvent = 'beforeunload';
|
|
23
|
-
const beforeUnloadListener = event => {
|
|
24
|
-
event.preventDefault();
|
|
25
|
-
// @ts-ignore
|
|
26
|
-
return event.returnValue = '';
|
|
27
|
-
};
|
|
28
|
-
const stopBlocking = () => {
|
|
29
|
-
removeEventListener(beforeUnloadEvent, beforeUnloadListener, {
|
|
30
|
-
capture: true
|
|
31
|
-
});
|
|
32
|
-
};
|
|
33
|
-
function createHistory(opts) {
|
|
34
|
-
let location = opts.getLocation();
|
|
35
|
-
let unsub = () => {};
|
|
36
|
-
let subscribers = new Set();
|
|
37
|
-
let blockers = [];
|
|
38
|
-
let queue = [];
|
|
39
|
-
const tryFlush = () => {
|
|
40
|
-
if (blockers.length) {
|
|
41
|
-
blockers[0]?.(tryFlush, () => {
|
|
42
|
-
blockers = [];
|
|
43
|
-
stopBlocking();
|
|
44
|
-
});
|
|
45
|
-
return;
|
|
46
|
-
}
|
|
47
|
-
while (queue.length) {
|
|
48
|
-
queue.shift()?.();
|
|
49
|
-
}
|
|
50
|
-
if (!opts.subscriber) {
|
|
51
|
-
onUpdate();
|
|
52
|
-
}
|
|
53
|
-
};
|
|
54
|
-
const queueTask = task => {
|
|
55
|
-
queue.push(task);
|
|
56
|
-
tryFlush();
|
|
57
|
-
};
|
|
58
|
-
const onUpdate = () => {
|
|
59
|
-
location = opts.getLocation();
|
|
60
|
-
subscribers.forEach(subscriber => subscriber());
|
|
61
|
-
};
|
|
62
|
-
return {
|
|
63
|
-
get location() {
|
|
64
|
-
return location;
|
|
65
|
-
},
|
|
66
|
-
subscribe: cb => {
|
|
67
|
-
if (subscribers.size === 0) {
|
|
68
|
-
unsub = typeof opts.subscriber === 'function' ? opts.subscriber(onUpdate) : () => {};
|
|
69
|
-
}
|
|
70
|
-
subscribers.add(cb);
|
|
71
|
-
return () => {
|
|
72
|
-
subscribers.delete(cb);
|
|
73
|
-
if (subscribers.size === 0) {
|
|
74
|
-
unsub();
|
|
75
|
-
}
|
|
76
|
-
};
|
|
77
|
-
},
|
|
78
|
-
push: (path, state) => {
|
|
79
|
-
assignKey(state);
|
|
80
|
-
queueTask(() => {
|
|
81
|
-
opts.pushState(path, state, onUpdate);
|
|
82
|
-
});
|
|
83
|
-
},
|
|
84
|
-
replace: (path, state) => {
|
|
85
|
-
assignKey(state);
|
|
86
|
-
queueTask(() => {
|
|
87
|
-
opts.replaceState(path, state, onUpdate);
|
|
88
|
-
});
|
|
89
|
-
},
|
|
90
|
-
go: index => {
|
|
91
|
-
queueTask(() => {
|
|
92
|
-
opts.go(index);
|
|
93
|
-
});
|
|
94
|
-
},
|
|
95
|
-
back: () => {
|
|
96
|
-
queueTask(() => {
|
|
97
|
-
opts.back();
|
|
98
|
-
});
|
|
99
|
-
},
|
|
100
|
-
forward: () => {
|
|
101
|
-
queueTask(() => {
|
|
102
|
-
opts.forward();
|
|
103
|
-
});
|
|
104
|
-
},
|
|
105
|
-
createHref: str => opts.createHref(str),
|
|
106
|
-
block: cb => {
|
|
107
|
-
blockers.push(cb);
|
|
108
|
-
if (blockers.length === 1) {
|
|
109
|
-
addEventListener(beforeUnloadEvent, beforeUnloadListener, {
|
|
110
|
-
capture: true
|
|
111
|
-
});
|
|
112
|
-
}
|
|
113
|
-
return () => {
|
|
114
|
-
blockers = blockers.filter(b => b !== cb);
|
|
115
|
-
if (!blockers.length) {
|
|
116
|
-
stopBlocking();
|
|
117
|
-
}
|
|
118
|
-
};
|
|
119
|
-
},
|
|
120
|
-
flush: () => opts.flush?.()
|
|
121
|
-
};
|
|
122
|
-
}
|
|
123
|
-
function assignKey(state) {
|
|
124
|
-
state.key = createRandomKey();
|
|
125
|
-
// if (state.__actualLocation) {
|
|
126
|
-
// state.__actualLocation.state = {
|
|
127
|
-
// ...state.__actualLocation.state,
|
|
128
|
-
// key,
|
|
129
|
-
// }
|
|
130
|
-
// }
|
|
131
|
-
}
|
|
132
|
-
|
|
133
|
-
/**
|
|
134
|
-
* Creates a history object that can be used to interact with the browser's
|
|
135
|
-
* navigation. This is a lightweight API wrapping the browser's native methods.
|
|
136
|
-
* It is designed to work with TanStack Router, but could be used as a standalone API as well.
|
|
137
|
-
* IMPORTANT: This API implements history throttling via a microtask to prevent
|
|
138
|
-
* excessive calls to the history API. In some browsers, calling history.pushState or
|
|
139
|
-
* history.replaceState in quick succession can cause the browser to ignore subsequent
|
|
140
|
-
* calls. This API smooths out those differences and ensures that your application
|
|
141
|
-
* state will *eventually* match the browser state. In most cases, this is not a problem,
|
|
142
|
-
* but if you need to ensure that the browser state is up to date, you can use the
|
|
143
|
-
* `history.flush` method to immediately flush all pending state changes to the browser URL.
|
|
144
|
-
* @param opts
|
|
145
|
-
* @param opts.getHref A function that returns the current href (path + search + hash)
|
|
146
|
-
* @param opts.createHref A function that takes a path and returns a href (path + search + hash)
|
|
147
|
-
* @returns A history instance
|
|
148
|
-
*/
|
|
149
|
-
function createBrowserHistory(opts) {
|
|
150
|
-
const getHref = opts?.getHref ?? (() => `${window.location.pathname}${window.location.search}${window.location.hash}`);
|
|
151
|
-
const createHref = opts?.createHref ?? (path => path);
|
|
152
|
-
let currentLocation = parseLocation(getHref(), window.history.state);
|
|
153
|
-
const getLocation = () => currentLocation;
|
|
154
|
-
let next;
|
|
155
|
-
|
|
156
|
-
// Because we are proactively updating the location
|
|
157
|
-
// in memory before actually updating the browser history,
|
|
158
|
-
// we need to track when we are doing this so we don't
|
|
159
|
-
// notify subscribers twice on the last update.
|
|
160
|
-
let tracking = true;
|
|
161
|
-
|
|
162
|
-
// We need to track the current scheduled update to prevent
|
|
163
|
-
// multiple updates from being scheduled at the same time.
|
|
164
|
-
let scheduled;
|
|
165
|
-
|
|
166
|
-
// This function is a wrapper to prevent any of the callback's
|
|
167
|
-
// side effects from causing a subscriber notification
|
|
168
|
-
const untrack = fn => {
|
|
169
|
-
tracking = false;
|
|
170
|
-
fn();
|
|
171
|
-
tracking = true;
|
|
172
|
-
};
|
|
173
|
-
|
|
174
|
-
// This function flushes the next update to the browser history
|
|
175
|
-
const flush = () => {
|
|
176
|
-
// Do not notify subscribers about this push/replace call
|
|
177
|
-
untrack(() => {
|
|
178
|
-
if (!next) return;
|
|
179
|
-
window.history[next.isPush ? 'pushState' : 'replaceState'](next.state, '', next.href);
|
|
180
|
-
// Reset the nextIsPush flag and clear the scheduled update
|
|
181
|
-
next = undefined;
|
|
182
|
-
scheduled = undefined;
|
|
183
|
-
});
|
|
184
|
-
};
|
|
185
|
-
|
|
186
|
-
// This function queues up a call to update the browser history
|
|
187
|
-
const queueHistoryAction = (type, path, state, onUpdate) => {
|
|
188
|
-
const href = createHref(path);
|
|
189
|
-
|
|
190
|
-
// Update the location in memory
|
|
191
|
-
currentLocation = parseLocation(href, state);
|
|
192
|
-
|
|
193
|
-
// Keep track of the next location we need to flush to the URL
|
|
194
|
-
next = {
|
|
195
|
-
href,
|
|
196
|
-
state,
|
|
197
|
-
isPush: next?.isPush || type === 'push'
|
|
198
|
-
};
|
|
199
|
-
// Notify subscribers
|
|
200
|
-
onUpdate();
|
|
201
|
-
if (!scheduled) {
|
|
202
|
-
// Schedule an update to the browser history
|
|
203
|
-
scheduled = Promise.resolve().then(() => flush());
|
|
204
|
-
}
|
|
205
|
-
};
|
|
206
|
-
return createHistory({
|
|
207
|
-
getLocation,
|
|
208
|
-
subscriber: onUpdate => {
|
|
209
|
-
window.addEventListener(pushStateEvent, () => {
|
|
210
|
-
currentLocation = parseLocation(getHref(), window.history.state);
|
|
211
|
-
onUpdate();
|
|
212
|
-
});
|
|
213
|
-
window.addEventListener(popStateEvent, () => {
|
|
214
|
-
currentLocation = parseLocation(getHref(), window.history.state);
|
|
215
|
-
onUpdate();
|
|
216
|
-
});
|
|
217
|
-
var pushState = window.history.pushState;
|
|
218
|
-
window.history.pushState = function () {
|
|
219
|
-
let res = pushState.apply(history, arguments);
|
|
220
|
-
if (tracking) onUpdate();
|
|
221
|
-
return res;
|
|
222
|
-
};
|
|
223
|
-
var replaceState = window.history.replaceState;
|
|
224
|
-
window.history.replaceState = function () {
|
|
225
|
-
let res = replaceState.apply(history, arguments);
|
|
226
|
-
if (tracking) onUpdate();
|
|
227
|
-
return res;
|
|
228
|
-
};
|
|
229
|
-
return () => {
|
|
230
|
-
window.history.pushState = pushState;
|
|
231
|
-
window.history.replaceState = replaceState;
|
|
232
|
-
window.removeEventListener(pushStateEvent, onUpdate);
|
|
233
|
-
window.removeEventListener(popStateEvent, onUpdate);
|
|
234
|
-
};
|
|
235
|
-
},
|
|
236
|
-
pushState: (path, state, onUpdate) => queueHistoryAction('push', path, state, onUpdate),
|
|
237
|
-
replaceState: (path, state, onUpdate) => queueHistoryAction('replace', path, state, onUpdate),
|
|
238
|
-
back: () => window.history.back(),
|
|
239
|
-
forward: () => window.history.forward(),
|
|
240
|
-
go: n => window.history.go(n),
|
|
241
|
-
createHref: path => createHref(path),
|
|
242
|
-
flush
|
|
243
|
-
});
|
|
244
|
-
}
|
|
245
|
-
function createHashHistory() {
|
|
246
|
-
return createBrowserHistory({
|
|
247
|
-
getHref: () => window.location.hash.substring(1),
|
|
248
|
-
createHref: path => `#${path}`
|
|
249
|
-
});
|
|
250
|
-
}
|
|
251
|
-
function createMemoryHistory(opts = {
|
|
252
|
-
initialEntries: ['/']
|
|
253
|
-
}) {
|
|
254
|
-
const entries = opts.initialEntries;
|
|
255
|
-
let index = opts.initialIndex ?? entries.length - 1;
|
|
256
|
-
let currentState = {
|
|
257
|
-
key: createRandomKey()
|
|
258
|
-
};
|
|
259
|
-
const getLocation = () => parseLocation(entries[index], currentState);
|
|
260
|
-
return createHistory({
|
|
261
|
-
getLocation,
|
|
262
|
-
subscriber: false,
|
|
263
|
-
pushState: (path, state) => {
|
|
264
|
-
currentState = state;
|
|
265
|
-
entries.push(path);
|
|
266
|
-
index++;
|
|
267
|
-
},
|
|
268
|
-
replaceState: (path, state) => {
|
|
269
|
-
currentState = state;
|
|
270
|
-
entries[index] = path;
|
|
271
|
-
},
|
|
272
|
-
back: () => {
|
|
273
|
-
index--;
|
|
274
|
-
},
|
|
275
|
-
forward: () => {
|
|
276
|
-
index = Math.min(index + 1, entries.length - 1);
|
|
277
|
-
},
|
|
278
|
-
go: n => window.history.go(n),
|
|
279
|
-
createHref: path => path
|
|
280
|
-
});
|
|
281
|
-
}
|
|
282
|
-
function parseLocation(href, state) {
|
|
283
|
-
let hashIndex = href.indexOf('#');
|
|
284
|
-
let searchIndex = href.indexOf('?');
|
|
285
|
-
return {
|
|
286
|
-
href,
|
|
287
|
-
pathname: href.substring(0, hashIndex > 0 ? searchIndex > 0 ? Math.min(hashIndex, searchIndex) : hashIndex : searchIndex > 0 ? searchIndex : href.length),
|
|
288
|
-
hash: hashIndex > -1 ? href.substring(hashIndex) : '',
|
|
289
|
-
search: searchIndex > -1 ? href.slice(searchIndex, hashIndex === -1 ? undefined : hashIndex) : '',
|
|
290
|
-
state: state || {}
|
|
291
|
-
};
|
|
292
|
-
}
|
|
293
|
-
|
|
294
|
-
// Thanks co-pilot!
|
|
295
|
-
function createRandomKey() {
|
|
296
|
-
return (Math.random() + 1).toString(36).substring(7);
|
|
297
|
-
}
|
|
298
|
-
|
|
299
18
|
// export type Expand<T> = T
|
|
300
19
|
|
|
301
20
|
// type Compute<T> = { [K in keyof T]: T[K] } | never
|
|
@@ -2187,5 +1906,5 @@ function isDehydratedDeferred(obj) {
|
|
|
2187
1906
|
return typeof obj === 'object' && obj !== null && !(obj instanceof Promise) && !obj.then && '__deferredState' in obj;
|
|
2188
1907
|
}
|
|
2189
1908
|
|
|
2190
|
-
export { FileRoute, PathParamError, RootRoute, Route, Router, RouterContext, SearchParamError, cleanPath, componentTypes,
|
|
1909
|
+
export { FileRoute, PathParamError, RootRoute, Route, Router, RouterContext, SearchParamError, cleanPath, componentTypes, createRouteMask, decode, defaultParseSearch, defaultStringifySearch, defer, encode, functionalUpdate, interpolatePath, isDehydratedDeferred, isMatchInvalid, isPlainObject, isRedirect, joinPaths, last, lazyFn, matchByPath, matchPathname, parsePathname, parseSearchWith, partialDeepEqual, pick, redirect, replaceEqualDeep, resolvePath, restoreScrollPositions, rootRouteId, stringifySearchWith, trimPath, trimPathLeft, trimPathRight, watchScrollPositions };
|
|
2191
1910
|
//# sourceMappingURL=index.js.map
|