@tanstack/history 0.0.1-beta.193 → 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.
@@ -31,13 +31,16 @@ const stopBlocking = () => {
31
31
  };
32
32
  function createHistory(opts) {
33
33
  let location = opts.getLocation();
34
- let unsub = () => {};
35
34
  let subscribers = new Set();
36
35
  let blockers = [];
37
36
  let queue = [];
38
- const tryFlush = () => {
37
+ const onUpdate = () => {
38
+ location = opts.getLocation();
39
+ subscribers.forEach(subscriber => subscriber());
40
+ };
41
+ const tryUnblock = () => {
39
42
  if (blockers.length) {
40
- blockers[0]?.(tryFlush, () => {
43
+ blockers[0]?.(tryUnblock, () => {
41
44
  blockers = [];
42
45
  stopBlocking();
43
46
  });
@@ -46,42 +49,30 @@ function createHistory(opts) {
46
49
  while (queue.length) {
47
50
  queue.shift()?.();
48
51
  }
49
- if (!opts.subscriber) {
50
- onUpdate();
51
- }
52
+ onUpdate();
52
53
  };
53
54
  const queueTask = task => {
54
55
  queue.push(task);
55
- tryFlush();
56
- };
57
- const onUpdate = () => {
58
- location = opts.getLocation();
59
- subscribers.forEach(subscriber => subscriber());
56
+ tryUnblock();
60
57
  };
61
58
  return {
62
59
  get location() {
63
60
  return location;
64
61
  },
65
62
  subscribe: cb => {
66
- if (subscribers.size === 0) {
67
- unsub = typeof opts.subscriber === 'function' ? opts.subscriber(onUpdate) : () => {};
68
- }
69
63
  subscribers.add(cb);
70
64
  return () => {
71
65
  subscribers.delete(cb);
72
- if (subscribers.size === 0) {
73
- unsub();
74
- }
75
66
  };
76
67
  },
77
68
  push: (path, state) => {
78
- assignKey(state);
69
+ state = assignKey(state);
79
70
  queueTask(() => {
80
71
  opts.pushState(path, state, onUpdate);
81
72
  });
82
73
  },
83
74
  replace: (path, state) => {
84
- assignKey(state);
75
+ state = assignKey(state);
85
76
  queueTask(() => {
86
77
  opts.replaceState(path, state, onUpdate);
87
78
  });
@@ -116,17 +107,17 @@ function createHistory(opts) {
116
107
  }
117
108
  };
118
109
  },
119
- flush: () => opts.flush?.()
110
+ flush: () => opts.flush?.(),
111
+ destroy: () => opts.destroy?.(),
112
+ update: onUpdate
120
113
  };
121
114
  }
122
115
  function assignKey(state) {
116
+ if (!state) {
117
+ state = {};
118
+ }
123
119
  state.key = createRandomKey();
124
- // if (state.__actualLocation) {
125
- // state.__actualLocation.state = {
126
- // ...state.__actualLocation.state,
127
- // key,
128
- // }
129
- // }
120
+ return state;
130
121
  }
131
122
 
132
123
  /**
@@ -202,44 +193,43 @@ function createBrowserHistory(opts) {
202
193
  scheduled = Promise.resolve().then(() => flush());
203
194
  }
204
195
  };
205
- return createHistory({
196
+ const history = createHistory({
206
197
  getLocation,
207
- subscriber: onUpdate => {
208
- window.addEventListener(pushStateEvent, () => {
209
- currentLocation = parseLocation(getHref(), window.history.state);
210
- onUpdate();
211
- });
212
- window.addEventListener(popStateEvent, () => {
213
- currentLocation = parseLocation(getHref(), window.history.state);
214
- onUpdate();
215
- });
216
- var pushState = window.history.pushState;
217
- window.history.pushState = function () {
218
- let res = pushState.apply(history, arguments);
219
- if (tracking) onUpdate();
220
- return res;
221
- };
222
- var replaceState = window.history.replaceState;
223
- window.history.replaceState = function () {
224
- let res = replaceState.apply(history, arguments);
225
- if (tracking) onUpdate();
226
- return res;
227
- };
228
- return () => {
229
- window.history.pushState = pushState;
230
- window.history.replaceState = replaceState;
231
- window.removeEventListener(pushStateEvent, onUpdate);
232
- window.removeEventListener(popStateEvent, onUpdate);
233
- };
234
- },
235
198
  pushState: (path, state, onUpdate) => queueHistoryAction('push', path, state, onUpdate),
236
199
  replaceState: (path, state, onUpdate) => queueHistoryAction('replace', path, state, onUpdate),
237
200
  back: () => window.history.back(),
238
201
  forward: () => window.history.forward(),
239
202
  go: n => window.history.go(n),
240
203
  createHref: path => createHref(path),
241
- flush
204
+ flush,
205
+ destroy: () => {
206
+ window.history.pushState = pushState;
207
+ window.history.replaceState = replaceState;
208
+ window.removeEventListener(pushStateEvent, history.update);
209
+ window.removeEventListener(popStateEvent, history.update);
210
+ }
211
+ });
212
+ window.addEventListener(pushStateEvent, () => {
213
+ currentLocation = parseLocation(getHref(), window.history.state);
214
+ history.update;
242
215
  });
216
+ window.addEventListener(popStateEvent, () => {
217
+ currentLocation = parseLocation(getHref(), window.history.state);
218
+ history.update;
219
+ });
220
+ var pushState = window.history.pushState;
221
+ window.history.pushState = function () {
222
+ let res = pushState.apply(window.history, arguments);
223
+ if (tracking) history.update();
224
+ return res;
225
+ };
226
+ var replaceState = window.history.replaceState;
227
+ window.history.replaceState = function () {
228
+ let res = replaceState.apply(window.history, arguments);
229
+ if (tracking) history.update();
230
+ return res;
231
+ };
232
+ return history;
243
233
  }
244
234
  function createHashHistory() {
245
235
  return createBrowserHistory({
@@ -258,7 +248,6 @@ function createMemoryHistory(opts = {
258
248
  const getLocation = () => parseLocation(entries[index], currentState);
259
249
  return createHistory({
260
250
  getLocation,
261
- subscriber: false,
262
251
  pushState: (path, state) => {
263
252
  currentState = state;
264
253
  entries.push(path);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/index.ts"],"sourcesContent":["// While the public API was clearly inspired by the \"history\" npm package,\n// This implementation attempts to be more lightweight by\n// making assumptions about the way TanStack Router works\n\nexport interface RouterHistory {\n location: HistoryLocation\n subscribe: (cb: () => void) => () => void\n push: (path: string, state?: any) => void\n replace: (path: string, state?: any) => void\n go: (index: number) => void\n back: () => void\n forward: () => void\n createHref: (href: string) => string\n block: (blockerFn: BlockerFn) => () => void\n flush: () => void\n}\n\nexport interface HistoryLocation extends ParsedPath {\n state: HistoryState\n}\n\nexport interface ParsedPath {\n href: string\n pathname: string\n search: string\n hash: string\n}\n\nexport interface HistoryState {\n key: string\n __tempLocation?: HistoryLocation\n __tempKey?: string\n}\n\ntype BlockerFn = (retry: () => void, cancel: () => void) => void\n\nconst pushStateEvent = 'pushstate'\nconst popStateEvent = 'popstate'\nconst beforeUnloadEvent = 'beforeunload'\n\nconst beforeUnloadListener = (event: Event) => {\n event.preventDefault()\n // @ts-ignore\n return (event.returnValue = '')\n}\n\nconst stopBlocking = () => {\n removeEventListener(beforeUnloadEvent, beforeUnloadListener, {\n capture: true,\n })\n}\n\nfunction createHistory(opts: {\n getLocation: () => HistoryLocation\n subscriber: false | ((onUpdate: () => void) => () => void)\n pushState: (path: string, state: any, onUpdate: () => void) => void\n replaceState: (path: string, state: any, onUpdate: () => void) => void\n go: (n: number) => void\n back: () => void\n forward: () => void\n createHref: (path: string) => string\n flush?: () => void\n}): RouterHistory {\n let location = opts.getLocation()\n let unsub = () => {}\n let subscribers = new Set<() => void>()\n let blockers: BlockerFn[] = []\n let queue: (() => void)[] = []\n\n const tryFlush = () => {\n if (blockers.length) {\n blockers[0]?.(tryFlush, () => {\n blockers = []\n stopBlocking()\n })\n return\n }\n\n while (queue.length) {\n queue.shift()?.()\n }\n\n if (!opts.subscriber) {\n onUpdate()\n }\n }\n\n const queueTask = (task: () => void) => {\n queue.push(task)\n tryFlush()\n }\n\n const onUpdate = () => {\n location = opts.getLocation()\n subscribers.forEach((subscriber) => subscriber())\n }\n\n return {\n get location() {\n return location\n },\n subscribe: (cb: () => void) => {\n if (subscribers.size === 0) {\n unsub =\n typeof opts.subscriber === 'function'\n ? opts.subscriber(onUpdate)\n : () => {}\n }\n subscribers.add(cb)\n\n return () => {\n subscribers.delete(cb)\n if (subscribers.size === 0) {\n unsub()\n }\n }\n },\n push: (path: string, state: any) => {\n assignKey(state)\n queueTask(() => {\n opts.pushState(path, state, onUpdate)\n })\n },\n replace: (path: string, state: any) => {\n assignKey(state)\n queueTask(() => {\n opts.replaceState(path, state, onUpdate)\n })\n },\n go: (index) => {\n queueTask(() => {\n opts.go(index)\n })\n },\n back: () => {\n queueTask(() => {\n opts.back()\n })\n },\n forward: () => {\n queueTask(() => {\n opts.forward()\n })\n },\n createHref: (str) => opts.createHref(str),\n block: (cb) => {\n blockers.push(cb)\n\n if (blockers.length === 1) {\n addEventListener(beforeUnloadEvent, beforeUnloadListener, {\n capture: true,\n })\n }\n\n return () => {\n blockers = blockers.filter((b) => b !== cb)\n\n if (!blockers.length) {\n stopBlocking()\n }\n }\n },\n flush: () => opts.flush?.(),\n }\n}\n\nfunction assignKey(state: HistoryState) {\n state.key = createRandomKey()\n // if (state.__actualLocation) {\n // state.__actualLocation.state = {\n // ...state.__actualLocation.state,\n // key,\n // }\n // }\n}\n\n/**\n * Creates a history object that can be used to interact with the browser's\n * navigation. This is a lightweight API wrapping the browser's native methods.\n * It is designed to work with TanStack Router, but could be used as a standalone API as well.\n * IMPORTANT: This API implements history throttling via a microtask to prevent\n * excessive calls to the history API. In some browsers, calling history.pushState or\n * history.replaceState in quick succession can cause the browser to ignore subsequent\n * calls. This API smooths out those differences and ensures that your application\n * state will *eventually* match the browser state. In most cases, this is not a problem,\n * but if you need to ensure that the browser state is up to date, you can use the\n * `history.flush` method to immediately flush all pending state changes to the browser URL.\n * @param opts\n * @param opts.getHref A function that returns the current href (path + search + hash)\n * @param opts.createHref A function that takes a path and returns a href (path + search + hash)\n * @returns A history instance\n */\nexport function createBrowserHistory(opts?: {\n getHref?: () => string\n createHref?: (path: string) => string\n}): RouterHistory {\n const getHref =\n opts?.getHref ??\n (() =>\n `${window.location.pathname}${window.location.search}${window.location.hash}`)\n\n const createHref = opts?.createHref ?? ((path) => path)\n\n let currentLocation = parseLocation(getHref(), window.history.state)\n\n const getLocation = () => currentLocation\n\n let next:\n | undefined\n | {\n // This is the latest location that we were attempting to push/replace\n href: string\n // This is the latest state that we were attempting to push/replace\n state: any\n // This is the latest type that we were attempting to push/replace\n isPush: boolean\n }\n\n // Because we are proactively updating the location\n // in memory before actually updating the browser history,\n // we need to track when we are doing this so we don't\n // notify subscribers twice on the last update.\n let tracking = true\n\n // We need to track the current scheduled update to prevent\n // multiple updates from being scheduled at the same time.\n let scheduled: Promise<void> | undefined\n\n // This function is a wrapper to prevent any of the callback's\n // side effects from causing a subscriber notification\n const untrack = (fn: () => void) => {\n tracking = false\n fn()\n tracking = true\n }\n\n // This function flushes the next update to the browser history\n const flush = () => {\n // Do not notify subscribers about this push/replace call\n untrack(() => {\n if (!next) return\n window.history[next.isPush ? 'pushState' : 'replaceState'](\n next.state,\n '',\n next.href,\n )\n // Reset the nextIsPush flag and clear the scheduled update\n next = undefined\n scheduled = undefined\n })\n }\n\n // This function queues up a call to update the browser history\n const queueHistoryAction = (\n type: 'push' | 'replace',\n path: string,\n state: any,\n onUpdate: () => void,\n ) => {\n const href = createHref(path)\n\n // Update the location in memory\n currentLocation = parseLocation(href, state)\n\n // Keep track of the next location we need to flush to the URL\n next = {\n href,\n state,\n isPush: next?.isPush || type === 'push',\n }\n // Notify subscribers\n onUpdate()\n\n if (!scheduled) {\n // Schedule an update to the browser history\n scheduled = Promise.resolve().then(() => flush())\n }\n }\n\n return createHistory({\n getLocation,\n subscriber: (onUpdate) => {\n window.addEventListener(pushStateEvent, () => {\n currentLocation = parseLocation(getHref(), window.history.state)\n onUpdate()\n })\n window.addEventListener(popStateEvent, () => {\n currentLocation = parseLocation(getHref(), window.history.state)\n onUpdate()\n })\n\n var pushState = window.history.pushState\n window.history.pushState = function () {\n let res = pushState.apply(history, arguments as any)\n if (tracking) onUpdate()\n return res\n }\n var replaceState = window.history.replaceState\n window.history.replaceState = function () {\n let res = replaceState.apply(history, arguments as any)\n if (tracking) onUpdate()\n return res\n }\n\n return () => {\n window.history.pushState = pushState\n window.history.replaceState = replaceState\n window.removeEventListener(pushStateEvent, onUpdate)\n window.removeEventListener(popStateEvent, onUpdate)\n }\n },\n pushState: (path, state, onUpdate) =>\n queueHistoryAction('push', path, state, onUpdate),\n replaceState: (path, state, onUpdate) =>\n queueHistoryAction('replace', path, state, onUpdate),\n back: () => window.history.back(),\n forward: () => window.history.forward(),\n go: (n) => window.history.go(n),\n createHref: (path) => createHref(path),\n flush,\n })\n}\n\nexport function createHashHistory(): RouterHistory {\n return createBrowserHistory({\n getHref: () => window.location.hash.substring(1),\n createHref: (path) => `#${path}`,\n })\n}\n\nexport function createMemoryHistory(\n opts: {\n initialEntries: string[]\n initialIndex?: number\n } = {\n initialEntries: ['/'],\n },\n): RouterHistory {\n const entries = opts.initialEntries\n let index = opts.initialIndex ?? entries.length - 1\n let currentState = {\n key: createRandomKey(),\n } as HistoryState\n\n const getLocation = () => parseLocation(entries[index]!, currentState)\n\n return createHistory({\n getLocation,\n subscriber: false,\n pushState: (path, state) => {\n currentState = state\n entries.push(path)\n index++\n },\n replaceState: (path, state) => {\n currentState = state\n entries[index] = path\n },\n back: () => {\n index--\n },\n forward: () => {\n index = Math.min(index + 1, entries.length - 1)\n },\n go: (n) => window.history.go(n),\n createHref: (path) => path,\n })\n}\n\nfunction parseLocation(href: string, state: HistoryState): HistoryLocation {\n let hashIndex = href.indexOf('#')\n let searchIndex = href.indexOf('?')\n\n return {\n href,\n pathname: href.substring(\n 0,\n hashIndex > 0\n ? searchIndex > 0\n ? Math.min(hashIndex, searchIndex)\n : hashIndex\n : searchIndex > 0\n ? searchIndex\n : href.length,\n ),\n hash: hashIndex > -1 ? href.substring(hashIndex) : '',\n search:\n searchIndex > -1\n ? href.slice(searchIndex, hashIndex === -1 ? undefined : hashIndex)\n : '',\n state: state || {},\n }\n}\n\n// Thanks co-pilot!\nfunction createRandomKey() {\n return (Math.random() + 1).toString(36).substring(7)\n}\n"],"names":["pushStateEvent","popStateEvent","beforeUnloadEvent","beforeUnloadListener","event","preventDefault","returnValue","stopBlocking","removeEventListener","capture","createHistory","opts","location","getLocation","unsub","subscribers","Set","blockers","queue","tryFlush","length","shift","subscriber","onUpdate","queueTask","task","push","forEach","subscribe","cb","size","add","delete","path","state","assignKey","pushState","replace","replaceState","go","index","back","forward","createHref","str","block","addEventListener","filter","b","flush","key","createRandomKey","createBrowserHistory","getHref","window","pathname","search","hash","currentLocation","parseLocation","history","next","tracking","scheduled","untrack","fn","isPush","href","undefined","queueHistoryAction","type","Promise","resolve","then","res","apply","arguments","n","createHashHistory","substring","createMemoryHistory","initialEntries","entries","initialIndex","currentState","Math","min","hashIndex","indexOf","searchIndex","slice","random","toString"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/index.ts"],"sourcesContent":["// While the public API was clearly inspired by the \"history\" npm package,\n// This implementation attempts to be more lightweight by\n// making assumptions about the way TanStack Router works\n\nexport interface RouterHistory {\n location: HistoryLocation\n subscribe: (cb: () => void) => () => void\n push: (path: string, state?: any) => void\n replace: (path: string, state?: any) => void\n go: (index: number) => void\n back: () => void\n forward: () => void\n createHref: (href: string) => string\n block: (blockerFn: BlockerFn) => () => void\n flush: () => void\n destroy: () => void\n update: () => void\n}\n\nexport interface HistoryLocation extends ParsedPath {\n state: HistoryState\n}\n\nexport interface ParsedPath {\n href: string\n pathname: string\n search: string\n hash: string\n}\n\nexport interface HistoryState {\n key: string\n}\n\ntype BlockerFn = (retry: () => void, cancel: () => void) => void\n\nconst pushStateEvent = 'pushstate'\nconst popStateEvent = 'popstate'\nconst beforeUnloadEvent = 'beforeunload'\n\nconst beforeUnloadListener = (event: Event) => {\n event.preventDefault()\n // @ts-ignore\n return (event.returnValue = '')\n}\n\nconst stopBlocking = () => {\n removeEventListener(beforeUnloadEvent, beforeUnloadListener, {\n capture: true,\n })\n}\n\nfunction createHistory(opts: {\n getLocation: () => HistoryLocation\n pushState: (path: string, state: any, onUpdate: () => void) => void\n replaceState: (path: string, state: any, onUpdate: () => void) => void\n go: (n: number) => void\n back: () => void\n forward: () => void\n createHref: (path: string) => string\n flush?: () => void\n destroy?: () => void\n}): RouterHistory {\n let location = opts.getLocation()\n let subscribers = new Set<() => void>()\n let blockers: BlockerFn[] = []\n let queue: (() => void)[] = []\n\n const onUpdate = () => {\n location = opts.getLocation()\n subscribers.forEach((subscriber) => subscriber())\n }\n\n const tryUnblock = () => {\n if (blockers.length) {\n blockers[0]?.(tryUnblock, () => {\n blockers = []\n stopBlocking()\n })\n return\n }\n\n while (queue.length) {\n queue.shift()?.()\n }\n\n onUpdate()\n }\n\n const queueTask = (task: () => void) => {\n queue.push(task)\n tryUnblock()\n }\n\n return {\n get location() {\n return location\n },\n subscribe: (cb: () => void) => {\n subscribers.add(cb)\n\n return () => {\n subscribers.delete(cb)\n }\n },\n push: (path: string, state: any) => {\n state = assignKey(state)\n queueTask(() => {\n opts.pushState(path, state, onUpdate)\n })\n },\n replace: (path: string, state: any) => {\n state = assignKey(state)\n queueTask(() => {\n opts.replaceState(path, state, onUpdate)\n })\n },\n go: (index) => {\n queueTask(() => {\n opts.go(index)\n })\n },\n back: () => {\n queueTask(() => {\n opts.back()\n })\n },\n forward: () => {\n queueTask(() => {\n opts.forward()\n })\n },\n createHref: (str) => opts.createHref(str),\n block: (cb) => {\n blockers.push(cb)\n\n if (blockers.length === 1) {\n addEventListener(beforeUnloadEvent, beforeUnloadListener, {\n capture: true,\n })\n }\n\n return () => {\n blockers = blockers.filter((b) => b !== cb)\n\n if (!blockers.length) {\n stopBlocking()\n }\n }\n },\n flush: () => opts.flush?.(),\n destroy: () => opts.destroy?.(),\n update: onUpdate,\n }\n}\n\nfunction assignKey(state: HistoryState) {\n if (!state) {\n state = {} as HistoryState\n }\n state.key = createRandomKey()\n return state\n}\n\n/**\n * Creates a history object that can be used to interact with the browser's\n * navigation. This is a lightweight API wrapping the browser's native methods.\n * It is designed to work with TanStack Router, but could be used as a standalone API as well.\n * IMPORTANT: This API implements history throttling via a microtask to prevent\n * excessive calls to the history API. In some browsers, calling history.pushState or\n * history.replaceState in quick succession can cause the browser to ignore subsequent\n * calls. This API smooths out those differences and ensures that your application\n * state will *eventually* match the browser state. In most cases, this is not a problem,\n * but if you need to ensure that the browser state is up to date, you can use the\n * `history.flush` method to immediately flush all pending state changes to the browser URL.\n * @param opts\n * @param opts.getHref A function that returns the current href (path + search + hash)\n * @param opts.createHref A function that takes a path and returns a href (path + search + hash)\n * @returns A history instance\n */\nexport function createBrowserHistory(opts?: {\n getHref?: () => string\n createHref?: (path: string) => string\n}): RouterHistory {\n const getHref =\n opts?.getHref ??\n (() =>\n `${window.location.pathname}${window.location.search}${window.location.hash}`)\n\n const createHref = opts?.createHref ?? ((path) => path)\n\n let currentLocation = parseLocation(getHref(), window.history.state)\n\n const getLocation = () => currentLocation\n\n let next:\n | undefined\n | {\n // This is the latest location that we were attempting to push/replace\n href: string\n // This is the latest state that we were attempting to push/replace\n state: any\n // This is the latest type that we were attempting to push/replace\n isPush: boolean\n }\n\n // Because we are proactively updating the location\n // in memory before actually updating the browser history,\n // we need to track when we are doing this so we don't\n // notify subscribers twice on the last update.\n let tracking = true\n\n // We need to track the current scheduled update to prevent\n // multiple updates from being scheduled at the same time.\n let scheduled: Promise<void> | undefined\n\n // This function is a wrapper to prevent any of the callback's\n // side effects from causing a subscriber notification\n const untrack = (fn: () => void) => {\n tracking = false\n fn()\n tracking = true\n }\n\n // This function flushes the next update to the browser history\n const flush = () => {\n // Do not notify subscribers about this push/replace call\n untrack(() => {\n if (!next) return\n window.history[next.isPush ? 'pushState' : 'replaceState'](\n next.state,\n '',\n next.href,\n )\n // Reset the nextIsPush flag and clear the scheduled update\n next = undefined\n scheduled = undefined\n })\n }\n\n // This function queues up a call to update the browser history\n const queueHistoryAction = (\n type: 'push' | 'replace',\n path: string,\n state: any,\n onUpdate: () => void,\n ) => {\n const href = createHref(path)\n\n // Update the location in memory\n currentLocation = parseLocation(href, state)\n\n // Keep track of the next location we need to flush to the URL\n next = {\n href,\n state,\n isPush: next?.isPush || type === 'push',\n }\n // Notify subscribers\n onUpdate()\n\n if (!scheduled) {\n // Schedule an update to the browser history\n scheduled = Promise.resolve().then(() => flush())\n }\n }\n\n const history = createHistory({\n getLocation,\n pushState: (path, state, onUpdate) =>\n queueHistoryAction('push', path, state, onUpdate),\n replaceState: (path, state, onUpdate) =>\n queueHistoryAction('replace', path, state, onUpdate),\n back: () => window.history.back(),\n forward: () => window.history.forward(),\n go: (n) => window.history.go(n),\n createHref: (path) => createHref(path),\n flush,\n destroy: () => {\n window.history.pushState = pushState\n window.history.replaceState = replaceState\n window.removeEventListener(pushStateEvent, history.update)\n window.removeEventListener(popStateEvent, history.update)\n },\n })\n\n window.addEventListener(pushStateEvent, () => {\n currentLocation = parseLocation(getHref(), window.history.state)\n history.update\n })\n window.addEventListener(popStateEvent, () => {\n currentLocation = parseLocation(getHref(), window.history.state)\n history.update\n })\n\n var pushState = window.history.pushState\n window.history.pushState = function () {\n let res = pushState.apply(window.history, arguments as any)\n if (tracking) history.update()\n return res\n }\n var replaceState = window.history.replaceState\n window.history.replaceState = function () {\n let res = replaceState.apply(window.history, arguments as any)\n if (tracking) history.update()\n return res\n }\n\n return history\n}\n\nexport function createHashHistory(): RouterHistory {\n return createBrowserHistory({\n getHref: () => window.location.hash.substring(1),\n createHref: (path) => `#${path}`,\n })\n}\n\nexport function createMemoryHistory(\n opts: {\n initialEntries: string[]\n initialIndex?: number\n } = {\n initialEntries: ['/'],\n },\n): RouterHistory {\n const entries = opts.initialEntries\n let index = opts.initialIndex ?? entries.length - 1\n let currentState = {\n key: createRandomKey(),\n } as HistoryState\n\n const getLocation = () => parseLocation(entries[index]!, currentState)\n\n return createHistory({\n getLocation,\n pushState: (path, state) => {\n currentState = state\n entries.push(path)\n index++\n },\n replaceState: (path, state) => {\n currentState = state\n entries[index] = path\n },\n back: () => {\n index--\n },\n forward: () => {\n index = Math.min(index + 1, entries.length - 1)\n },\n go: (n) => window.history.go(n),\n createHref: (path) => path,\n })\n}\n\nfunction parseLocation(href: string, state: HistoryState): HistoryLocation {\n let hashIndex = href.indexOf('#')\n let searchIndex = href.indexOf('?')\n\n return {\n href,\n pathname: href.substring(\n 0,\n hashIndex > 0\n ? searchIndex > 0\n ? Math.min(hashIndex, searchIndex)\n : hashIndex\n : searchIndex > 0\n ? searchIndex\n : href.length,\n ),\n hash: hashIndex > -1 ? href.substring(hashIndex) : '',\n search:\n searchIndex > -1\n ? href.slice(searchIndex, hashIndex === -1 ? undefined : hashIndex)\n : '',\n state: state || {},\n }\n}\n\n// Thanks co-pilot!\nfunction createRandomKey() {\n return (Math.random() + 1).toString(36).substring(7)\n}\n"],"names":["pushStateEvent","popStateEvent","beforeUnloadEvent","beforeUnloadListener","event","preventDefault","returnValue","stopBlocking","removeEventListener","capture","createHistory","opts","location","getLocation","subscribers","Set","blockers","queue","onUpdate","forEach","subscriber","tryUnblock","length","shift","queueTask","task","push","subscribe","cb","add","delete","path","state","assignKey","pushState","replace","replaceState","go","index","back","forward","createHref","str","block","addEventListener","filter","b","flush","destroy","update","key","createRandomKey","createBrowserHistory","getHref","window","pathname","search","hash","currentLocation","parseLocation","history","next","tracking","scheduled","untrack","fn","isPush","href","undefined","queueHistoryAction","type","Promise","resolve","then","n","res","apply","arguments","createHashHistory","substring","createMemoryHistory","initialEntries","entries","initialIndex","currentState","Math","min","hashIndex","indexOf","searchIndex","slice","random","toString"],"mappings":";;;;;;;;;;;;;;AAAA;AACA;AACA;;AAkCA,MAAMA,cAAc,GAAG,WAAW,CAAA;AAClC,MAAMC,aAAa,GAAG,UAAU,CAAA;AAChC,MAAMC,iBAAiB,GAAG,cAAc,CAAA;AAExC,MAAMC,oBAAoB,GAAIC,KAAY,IAAK;EAC7CA,KAAK,CAACC,cAAc,EAAE,CAAA;AACtB;AACA,EAAA,OAAQD,KAAK,CAACE,WAAW,GAAG,EAAE,CAAA;AAChC,CAAC,CAAA;AAED,MAAMC,YAAY,GAAGA,MAAM;AACzBC,EAAAA,mBAAmB,CAACN,iBAAiB,EAAEC,oBAAoB,EAAE;AAC3DM,IAAAA,OAAO,EAAE,IAAA;AACX,GAAC,CAAC,CAAA;AACJ,CAAC,CAAA;AAED,SAASC,aAAaA,CAACC,IAUtB,EAAiB;AAChB,EAAA,IAAIC,QAAQ,GAAGD,IAAI,CAACE,WAAW,EAAE,CAAA;AACjC,EAAA,IAAIC,WAAW,GAAG,IAAIC,GAAG,EAAc,CAAA;EACvC,IAAIC,QAAqB,GAAG,EAAE,CAAA;EAC9B,IAAIC,KAAqB,GAAG,EAAE,CAAA;EAE9B,MAAMC,QAAQ,GAAGA,MAAM;AACrBN,IAAAA,QAAQ,GAAGD,IAAI,CAACE,WAAW,EAAE,CAAA;IAC7BC,WAAW,CAACK,OAAO,CAAEC,UAAU,IAAKA,UAAU,EAAE,CAAC,CAAA;GAClD,CAAA;EAED,MAAMC,UAAU,GAAGA,MAAM;IACvB,IAAIL,QAAQ,CAACM,MAAM,EAAE;AACnBN,MAAAA,QAAQ,CAAC,CAAC,CAAC,GAAGK,UAAU,EAAE,MAAM;AAC9BL,QAAAA,QAAQ,GAAG,EAAE,CAAA;AACbT,QAAAA,YAAY,EAAE,CAAA;AAChB,OAAC,CAAC,CAAA;AACF,MAAA,OAAA;AACF,KAAA;IAEA,OAAOU,KAAK,CAACK,MAAM,EAAE;AACnBL,MAAAA,KAAK,CAACM,KAAK,EAAE,IAAI,CAAA;AACnB,KAAA;AAEAL,IAAAA,QAAQ,EAAE,CAAA;GACX,CAAA;EAED,MAAMM,SAAS,GAAIC,IAAgB,IAAK;AACtCR,IAAAA,KAAK,CAACS,IAAI,CAACD,IAAI,CAAC,CAAA;AAChBJ,IAAAA,UAAU,EAAE,CAAA;GACb,CAAA;EAED,OAAO;IACL,IAAIT,QAAQA,GAAG;AACb,MAAA,OAAOA,QAAQ,CAAA;KAChB;IACDe,SAAS,EAAGC,EAAc,IAAK;AAC7Bd,MAAAA,WAAW,CAACe,GAAG,CAACD,EAAE,CAAC,CAAA;AAEnB,MAAA,OAAO,MAAM;AACXd,QAAAA,WAAW,CAACgB,MAAM,CAACF,EAAE,CAAC,CAAA;OACvB,CAAA;KACF;AACDF,IAAAA,IAAI,EAAEA,CAACK,IAAY,EAAEC,KAAU,KAAK;AAClCA,MAAAA,KAAK,GAAGC,SAAS,CAACD,KAAK,CAAC,CAAA;AACxBR,MAAAA,SAAS,CAAC,MAAM;QACdb,IAAI,CAACuB,SAAS,CAACH,IAAI,EAAEC,KAAK,EAAEd,QAAQ,CAAC,CAAA;AACvC,OAAC,CAAC,CAAA;KACH;AACDiB,IAAAA,OAAO,EAAEA,CAACJ,IAAY,EAAEC,KAAU,KAAK;AACrCA,MAAAA,KAAK,GAAGC,SAAS,CAACD,KAAK,CAAC,CAAA;AACxBR,MAAAA,SAAS,CAAC,MAAM;QACdb,IAAI,CAACyB,YAAY,CAACL,IAAI,EAAEC,KAAK,EAAEd,QAAQ,CAAC,CAAA;AAC1C,OAAC,CAAC,CAAA;KACH;IACDmB,EAAE,EAAGC,KAAK,IAAK;AACbd,MAAAA,SAAS,CAAC,MAAM;AACdb,QAAAA,IAAI,CAAC0B,EAAE,CAACC,KAAK,CAAC,CAAA;AAChB,OAAC,CAAC,CAAA;KACH;IACDC,IAAI,EAAEA,MAAM;AACVf,MAAAA,SAAS,CAAC,MAAM;QACdb,IAAI,CAAC4B,IAAI,EAAE,CAAA;AACb,OAAC,CAAC,CAAA;KACH;IACDC,OAAO,EAAEA,MAAM;AACbhB,MAAAA,SAAS,CAAC,MAAM;QACdb,IAAI,CAAC6B,OAAO,EAAE,CAAA;AAChB,OAAC,CAAC,CAAA;KACH;IACDC,UAAU,EAAGC,GAAG,IAAK/B,IAAI,CAAC8B,UAAU,CAACC,GAAG,CAAC;IACzCC,KAAK,EAAGf,EAAE,IAAK;AACbZ,MAAAA,QAAQ,CAACU,IAAI,CAACE,EAAE,CAAC,CAAA;AAEjB,MAAA,IAAIZ,QAAQ,CAACM,MAAM,KAAK,CAAC,EAAE;AACzBsB,QAAAA,gBAAgB,CAAC1C,iBAAiB,EAAEC,oBAAoB,EAAE;AACxDM,UAAAA,OAAO,EAAE,IAAA;AACX,SAAC,CAAC,CAAA;AACJ,OAAA;AAEA,MAAA,OAAO,MAAM;QACXO,QAAQ,GAAGA,QAAQ,CAAC6B,MAAM,CAAEC,CAAC,IAAKA,CAAC,KAAKlB,EAAE,CAAC,CAAA;AAE3C,QAAA,IAAI,CAACZ,QAAQ,CAACM,MAAM,EAAE;AACpBf,UAAAA,YAAY,EAAE,CAAA;AAChB,SAAA;OACD,CAAA;KACF;AACDwC,IAAAA,KAAK,EAAEA,MAAMpC,IAAI,CAACoC,KAAK,IAAI;AAC3BC,IAAAA,OAAO,EAAEA,MAAMrC,IAAI,CAACqC,OAAO,IAAI;AAC/BC,IAAAA,MAAM,EAAE/B,QAAAA;GACT,CAAA;AACH,CAAA;AAEA,SAASe,SAASA,CAACD,KAAmB,EAAE;EACtC,IAAI,CAACA,KAAK,EAAE;IACVA,KAAK,GAAG,EAAkB,CAAA;AAC5B,GAAA;AACAA,EAAAA,KAAK,CAACkB,GAAG,GAAGC,eAAe,EAAE,CAAA;AAC7B,EAAA,OAAOnB,KAAK,CAAA;AACd,CAAA;;AAEA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACO,SAASoB,oBAAoBA,CAACzC,IAGpC,EAAiB;EAChB,MAAM0C,OAAO,GACX1C,IAAI,EAAE0C,OAAO,KACZ,MACE,CAAEC,EAAAA,MAAM,CAAC1C,QAAQ,CAAC2C,QAAS,GAAED,MAAM,CAAC1C,QAAQ,CAAC4C,MAAO,CAAA,EAAEF,MAAM,CAAC1C,QAAQ,CAAC6C,IAAK,CAAA,CAAC,CAAC,CAAA;EAElF,MAAMhB,UAAU,GAAG9B,IAAI,EAAE8B,UAAU,KAAMV,IAAI,IAAKA,IAAI,CAAC,CAAA;AAEvD,EAAA,IAAI2B,eAAe,GAAGC,aAAa,CAACN,OAAO,EAAE,EAAEC,MAAM,CAACM,OAAO,CAAC5B,KAAK,CAAC,CAAA;AAEpE,EAAA,MAAMnB,WAAW,GAAGA,MAAM6C,eAAe,CAAA;AAEzC,EAAA,IAAIG,IASC,CAAA;;AAEL;AACA;AACA;AACA;EACA,IAAIC,QAAQ,GAAG,IAAI,CAAA;;AAEnB;AACA;AACA,EAAA,IAAIC,SAAoC,CAAA;;AAExC;AACA;EACA,MAAMC,OAAO,GAAIC,EAAc,IAAK;AAClCH,IAAAA,QAAQ,GAAG,KAAK,CAAA;AAChBG,IAAAA,EAAE,EAAE,CAAA;AACJH,IAAAA,QAAQ,GAAG,IAAI,CAAA;GAChB,CAAA;;AAED;EACA,MAAMf,KAAK,GAAGA,MAAM;AAClB;AACAiB,IAAAA,OAAO,CAAC,MAAM;MACZ,IAAI,CAACH,IAAI,EAAE,OAAA;MACXP,MAAM,CAACM,OAAO,CAACC,IAAI,CAACK,MAAM,GAAG,WAAW,GAAG,cAAc,CAAC,CACxDL,IAAI,CAAC7B,KAAK,EACV,EAAE,EACF6B,IAAI,CAACM,IACP,CAAC,CAAA;AACD;AACAN,MAAAA,IAAI,GAAGO,SAAS,CAAA;AAChBL,MAAAA,SAAS,GAAGK,SAAS,CAAA;AACvB,KAAC,CAAC,CAAA;GACH,CAAA;;AAED;EACA,MAAMC,kBAAkB,GAAGA,CACzBC,IAAwB,EACxBvC,IAAY,EACZC,KAAU,EACVd,QAAoB,KACjB;AACH,IAAA,MAAMiD,IAAI,GAAG1B,UAAU,CAACV,IAAI,CAAC,CAAA;;AAE7B;AACA2B,IAAAA,eAAe,GAAGC,aAAa,CAACQ,IAAI,EAAEnC,KAAK,CAAC,CAAA;;AAE5C;AACA6B,IAAAA,IAAI,GAAG;MACLM,IAAI;MACJnC,KAAK;AACLkC,MAAAA,MAAM,EAAEL,IAAI,EAAEK,MAAM,IAAII,IAAI,KAAK,MAAA;KAClC,CAAA;AACD;AACApD,IAAAA,QAAQ,EAAE,CAAA;IAEV,IAAI,CAAC6C,SAAS,EAAE;AACd;AACAA,MAAAA,SAAS,GAAGQ,OAAO,CAACC,OAAO,EAAE,CAACC,IAAI,CAAC,MAAM1B,KAAK,EAAE,CAAC,CAAA;AACnD,KAAA;GACD,CAAA;EAED,MAAMa,OAAO,GAAGlD,aAAa,CAAC;IAC5BG,WAAW;AACXqB,IAAAA,SAAS,EAAEA,CAACH,IAAI,EAAEC,KAAK,EAAEd,QAAQ,KAC/BmD,kBAAkB,CAAC,MAAM,EAAEtC,IAAI,EAAEC,KAAK,EAAEd,QAAQ,CAAC;AACnDkB,IAAAA,YAAY,EAAEA,CAACL,IAAI,EAAEC,KAAK,EAAEd,QAAQ,KAClCmD,kBAAkB,CAAC,SAAS,EAAEtC,IAAI,EAAEC,KAAK,EAAEd,QAAQ,CAAC;IACtDqB,IAAI,EAAEA,MAAMe,MAAM,CAACM,OAAO,CAACrB,IAAI,EAAE;IACjCC,OAAO,EAAEA,MAAMc,MAAM,CAACM,OAAO,CAACpB,OAAO,EAAE;IACvCH,EAAE,EAAGqC,CAAC,IAAKpB,MAAM,CAACM,OAAO,CAACvB,EAAE,CAACqC,CAAC,CAAC;AAC/BjC,IAAAA,UAAU,EAAGV,IAAI,IAAKU,UAAU,CAACV,IAAI,CAAC;IACtCgB,KAAK;IACLC,OAAO,EAAEA,MAAM;AACbM,MAAAA,MAAM,CAACM,OAAO,CAAC1B,SAAS,GAAGA,SAAS,CAAA;AACpCoB,MAAAA,MAAM,CAACM,OAAO,CAACxB,YAAY,GAAGA,YAAY,CAAA;MAC1CkB,MAAM,CAAC9C,mBAAmB,CAACR,cAAc,EAAE4D,OAAO,CAACX,MAAM,CAAC,CAAA;MAC1DK,MAAM,CAAC9C,mBAAmB,CAACP,aAAa,EAAE2D,OAAO,CAACX,MAAM,CAAC,CAAA;AAC3D,KAAA;AACF,GAAC,CAAC,CAAA;AAEFK,EAAAA,MAAM,CAACV,gBAAgB,CAAC5C,cAAc,EAAE,MAAM;AAC5C0D,IAAAA,eAAe,GAAGC,aAAa,CAACN,OAAO,EAAE,EAAEC,MAAM,CAACM,OAAO,CAAC5B,KAAK,CAAC,CAAA;AAChE4B,IAAAA,OAAO,CAACX,MAAM,CAAA;AAChB,GAAC,CAAC,CAAA;AACFK,EAAAA,MAAM,CAACV,gBAAgB,CAAC3C,aAAa,EAAE,MAAM;AAC3CyD,IAAAA,eAAe,GAAGC,aAAa,CAACN,OAAO,EAAE,EAAEC,MAAM,CAACM,OAAO,CAAC5B,KAAK,CAAC,CAAA;AAChE4B,IAAAA,OAAO,CAACX,MAAM,CAAA;AAChB,GAAC,CAAC,CAAA;AAEF,EAAA,IAAIf,SAAS,GAAGoB,MAAM,CAACM,OAAO,CAAC1B,SAAS,CAAA;AACxCoB,EAAAA,MAAM,CAACM,OAAO,CAAC1B,SAAS,GAAG,YAAY;IACrC,IAAIyC,GAAG,GAAGzC,SAAS,CAAC0C,KAAK,CAACtB,MAAM,CAACM,OAAO,EAAEiB,SAAgB,CAAC,CAAA;AAC3D,IAAA,IAAIf,QAAQ,EAAEF,OAAO,CAACX,MAAM,EAAE,CAAA;AAC9B,IAAA,OAAO0B,GAAG,CAAA;GACX,CAAA;AACD,EAAA,IAAIvC,YAAY,GAAGkB,MAAM,CAACM,OAAO,CAACxB,YAAY,CAAA;AAC9CkB,EAAAA,MAAM,CAACM,OAAO,CAACxB,YAAY,GAAG,YAAY;IACxC,IAAIuC,GAAG,GAAGvC,YAAY,CAACwC,KAAK,CAACtB,MAAM,CAACM,OAAO,EAAEiB,SAAgB,CAAC,CAAA;AAC9D,IAAA,IAAIf,QAAQ,EAAEF,OAAO,CAACX,MAAM,EAAE,CAAA;AAC9B,IAAA,OAAO0B,GAAG,CAAA;GACX,CAAA;AAED,EAAA,OAAOf,OAAO,CAAA;AAChB,CAAA;AAEO,SAASkB,iBAAiBA,GAAkB;AACjD,EAAA,OAAO1B,oBAAoB,CAAC;AAC1BC,IAAAA,OAAO,EAAEA,MAAMC,MAAM,CAAC1C,QAAQ,CAAC6C,IAAI,CAACsB,SAAS,CAAC,CAAC,CAAC;AAChDtC,IAAAA,UAAU,EAAGV,IAAI,IAAM,CAAA,CAAA,EAAGA,IAAK,CAAA,CAAA;AACjC,GAAC,CAAC,CAAA;AACJ,CAAA;AAEO,SAASiD,mBAAmBA,CACjCrE,IAGC,GAAG;EACFsE,cAAc,EAAE,CAAC,GAAG,CAAA;AACtB,CAAC,EACc;AACf,EAAA,MAAMC,OAAO,GAAGvE,IAAI,CAACsE,cAAc,CAAA;EACnC,IAAI3C,KAAK,GAAG3B,IAAI,CAACwE,YAAY,IAAID,OAAO,CAAC5D,MAAM,GAAG,CAAC,CAAA;AACnD,EAAA,IAAI8D,YAAY,GAAG;IACjBlC,GAAG,EAAEC,eAAe,EAAC;GACN,CAAA;AAEjB,EAAA,MAAMtC,WAAW,GAAGA,MAAM8C,aAAa,CAACuB,OAAO,CAAC5C,KAAK,CAAC,EAAG8C,YAAY,CAAC,CAAA;AAEtE,EAAA,OAAO1E,aAAa,CAAC;IACnBG,WAAW;AACXqB,IAAAA,SAAS,EAAEA,CAACH,IAAI,EAAEC,KAAK,KAAK;AAC1BoD,MAAAA,YAAY,GAAGpD,KAAK,CAAA;AACpBkD,MAAAA,OAAO,CAACxD,IAAI,CAACK,IAAI,CAAC,CAAA;AAClBO,MAAAA,KAAK,EAAE,CAAA;KACR;AACDF,IAAAA,YAAY,EAAEA,CAACL,IAAI,EAAEC,KAAK,KAAK;AAC7BoD,MAAAA,YAAY,GAAGpD,KAAK,CAAA;AACpBkD,MAAAA,OAAO,CAAC5C,KAAK,CAAC,GAAGP,IAAI,CAAA;KACtB;IACDQ,IAAI,EAAEA,MAAM;AACVD,MAAAA,KAAK,EAAE,CAAA;KACR;IACDE,OAAO,EAAEA,MAAM;AACbF,MAAAA,KAAK,GAAG+C,IAAI,CAACC,GAAG,CAAChD,KAAK,GAAG,CAAC,EAAE4C,OAAO,CAAC5D,MAAM,GAAG,CAAC,CAAC,CAAA;KAChD;IACDe,EAAE,EAAGqC,CAAC,IAAKpB,MAAM,CAACM,OAAO,CAACvB,EAAE,CAACqC,CAAC,CAAC;IAC/BjC,UAAU,EAAGV,IAAI,IAAKA,IAAAA;AACxB,GAAC,CAAC,CAAA;AACJ,CAAA;AAEA,SAAS4B,aAAaA,CAACQ,IAAY,EAAEnC,KAAmB,EAAmB;AACzE,EAAA,IAAIuD,SAAS,GAAGpB,IAAI,CAACqB,OAAO,CAAC,GAAG,CAAC,CAAA;AACjC,EAAA,IAAIC,WAAW,GAAGtB,IAAI,CAACqB,OAAO,CAAC,GAAG,CAAC,CAAA;EAEnC,OAAO;IACLrB,IAAI;AACJZ,IAAAA,QAAQ,EAAEY,IAAI,CAACY,SAAS,CACtB,CAAC,EACDQ,SAAS,GAAG,CAAC,GACTE,WAAW,GAAG,CAAC,GACbJ,IAAI,CAACC,GAAG,CAACC,SAAS,EAAEE,WAAW,CAAC,GAChCF,SAAS,GACXE,WAAW,GAAG,CAAC,GACfA,WAAW,GACXtB,IAAI,CAAC7C,MACX,CAAC;AACDmC,IAAAA,IAAI,EAAE8B,SAAS,GAAG,CAAC,CAAC,GAAGpB,IAAI,CAACY,SAAS,CAACQ,SAAS,CAAC,GAAG,EAAE;IACrD/B,MAAM,EACJiC,WAAW,GAAG,CAAC,CAAC,GACZtB,IAAI,CAACuB,KAAK,CAACD,WAAW,EAAEF,SAAS,KAAK,CAAC,CAAC,GAAGnB,SAAS,GAAGmB,SAAS,CAAC,GACjE,EAAE;IACRvD,KAAK,EAAEA,KAAK,IAAI,EAAC;GAClB,CAAA;AACH,CAAA;;AAEA;AACA,SAASmB,eAAeA,GAAG;AACzB,EAAA,OAAO,CAACkC,IAAI,CAACM,MAAM,EAAE,GAAG,CAAC,EAAEC,QAAQ,CAAC,EAAE,CAAC,CAACb,SAAS,CAAC,CAAC,CAAC,CAAA;AACtD;;;;;;"}
@@ -27,13 +27,16 @@ const stopBlocking = () => {
27
27
  };
28
28
  function createHistory(opts) {
29
29
  let location = opts.getLocation();
30
- let unsub = () => {};
31
30
  let subscribers = new Set();
32
31
  let blockers = [];
33
32
  let queue = [];
34
- const tryFlush = () => {
33
+ const onUpdate = () => {
34
+ location = opts.getLocation();
35
+ subscribers.forEach(subscriber => subscriber());
36
+ };
37
+ const tryUnblock = () => {
35
38
  if (blockers.length) {
36
- blockers[0]?.(tryFlush, () => {
39
+ blockers[0]?.(tryUnblock, () => {
37
40
  blockers = [];
38
41
  stopBlocking();
39
42
  });
@@ -42,42 +45,30 @@ function createHistory(opts) {
42
45
  while (queue.length) {
43
46
  queue.shift()?.();
44
47
  }
45
- if (!opts.subscriber) {
46
- onUpdate();
47
- }
48
+ onUpdate();
48
49
  };
49
50
  const queueTask = task => {
50
51
  queue.push(task);
51
- tryFlush();
52
- };
53
- const onUpdate = () => {
54
- location = opts.getLocation();
55
- subscribers.forEach(subscriber => subscriber());
52
+ tryUnblock();
56
53
  };
57
54
  return {
58
55
  get location() {
59
56
  return location;
60
57
  },
61
58
  subscribe: cb => {
62
- if (subscribers.size === 0) {
63
- unsub = typeof opts.subscriber === 'function' ? opts.subscriber(onUpdate) : () => {};
64
- }
65
59
  subscribers.add(cb);
66
60
  return () => {
67
61
  subscribers.delete(cb);
68
- if (subscribers.size === 0) {
69
- unsub();
70
- }
71
62
  };
72
63
  },
73
64
  push: (path, state) => {
74
- assignKey(state);
65
+ state = assignKey(state);
75
66
  queueTask(() => {
76
67
  opts.pushState(path, state, onUpdate);
77
68
  });
78
69
  },
79
70
  replace: (path, state) => {
80
- assignKey(state);
71
+ state = assignKey(state);
81
72
  queueTask(() => {
82
73
  opts.replaceState(path, state, onUpdate);
83
74
  });
@@ -112,17 +103,17 @@ function createHistory(opts) {
112
103
  }
113
104
  };
114
105
  },
115
- flush: () => opts.flush?.()
106
+ flush: () => opts.flush?.(),
107
+ destroy: () => opts.destroy?.(),
108
+ update: onUpdate
116
109
  };
117
110
  }
118
111
  function assignKey(state) {
112
+ if (!state) {
113
+ state = {};
114
+ }
119
115
  state.key = createRandomKey();
120
- // if (state.__actualLocation) {
121
- // state.__actualLocation.state = {
122
- // ...state.__actualLocation.state,
123
- // key,
124
- // }
125
- // }
116
+ return state;
126
117
  }
127
118
 
128
119
  /**
@@ -198,44 +189,43 @@ function createBrowserHistory(opts) {
198
189
  scheduled = Promise.resolve().then(() => flush());
199
190
  }
200
191
  };
201
- return createHistory({
192
+ const history = createHistory({
202
193
  getLocation,
203
- subscriber: onUpdate => {
204
- window.addEventListener(pushStateEvent, () => {
205
- currentLocation = parseLocation(getHref(), window.history.state);
206
- onUpdate();
207
- });
208
- window.addEventListener(popStateEvent, () => {
209
- currentLocation = parseLocation(getHref(), window.history.state);
210
- onUpdate();
211
- });
212
- var pushState = window.history.pushState;
213
- window.history.pushState = function () {
214
- let res = pushState.apply(history, arguments);
215
- if (tracking) onUpdate();
216
- return res;
217
- };
218
- var replaceState = window.history.replaceState;
219
- window.history.replaceState = function () {
220
- let res = replaceState.apply(history, arguments);
221
- if (tracking) onUpdate();
222
- return res;
223
- };
224
- return () => {
225
- window.history.pushState = pushState;
226
- window.history.replaceState = replaceState;
227
- window.removeEventListener(pushStateEvent, onUpdate);
228
- window.removeEventListener(popStateEvent, onUpdate);
229
- };
230
- },
231
194
  pushState: (path, state, onUpdate) => queueHistoryAction('push', path, state, onUpdate),
232
195
  replaceState: (path, state, onUpdate) => queueHistoryAction('replace', path, state, onUpdate),
233
196
  back: () => window.history.back(),
234
197
  forward: () => window.history.forward(),
235
198
  go: n => window.history.go(n),
236
199
  createHref: path => createHref(path),
237
- flush
200
+ flush,
201
+ destroy: () => {
202
+ window.history.pushState = pushState;
203
+ window.history.replaceState = replaceState;
204
+ window.removeEventListener(pushStateEvent, history.update);
205
+ window.removeEventListener(popStateEvent, history.update);
206
+ }
207
+ });
208
+ window.addEventListener(pushStateEvent, () => {
209
+ currentLocation = parseLocation(getHref(), window.history.state);
210
+ history.update;
238
211
  });
212
+ window.addEventListener(popStateEvent, () => {
213
+ currentLocation = parseLocation(getHref(), window.history.state);
214
+ history.update;
215
+ });
216
+ var pushState = window.history.pushState;
217
+ window.history.pushState = function () {
218
+ let res = pushState.apply(window.history, arguments);
219
+ if (tracking) history.update();
220
+ return res;
221
+ };
222
+ var replaceState = window.history.replaceState;
223
+ window.history.replaceState = function () {
224
+ let res = replaceState.apply(window.history, arguments);
225
+ if (tracking) history.update();
226
+ return res;
227
+ };
228
+ return history;
239
229
  }
240
230
  function createHashHistory() {
241
231
  return createBrowserHistory({
@@ -254,7 +244,6 @@ function createMemoryHistory(opts = {
254
244
  const getLocation = () => parseLocation(entries[index], currentState);
255
245
  return createHistory({
256
246
  getLocation,
257
- subscriber: false,
258
247
  pushState: (path, state) => {
259
248
  currentState = state;
260
249
  entries.push(path);
@@ -1 +1 @@
1
- {"version":3,"file":"index.js","sources":["../../src/index.ts"],"sourcesContent":["// While the public API was clearly inspired by the \"history\" npm package,\n// This implementation attempts to be more lightweight by\n// making assumptions about the way TanStack Router works\n\nexport interface RouterHistory {\n location: HistoryLocation\n subscribe: (cb: () => void) => () => void\n push: (path: string, state?: any) => void\n replace: (path: string, state?: any) => void\n go: (index: number) => void\n back: () => void\n forward: () => void\n createHref: (href: string) => string\n block: (blockerFn: BlockerFn) => () => void\n flush: () => void\n}\n\nexport interface HistoryLocation extends ParsedPath {\n state: HistoryState\n}\n\nexport interface ParsedPath {\n href: string\n pathname: string\n search: string\n hash: string\n}\n\nexport interface HistoryState {\n key: string\n __tempLocation?: HistoryLocation\n __tempKey?: string\n}\n\ntype BlockerFn = (retry: () => void, cancel: () => void) => void\n\nconst pushStateEvent = 'pushstate'\nconst popStateEvent = 'popstate'\nconst beforeUnloadEvent = 'beforeunload'\n\nconst beforeUnloadListener = (event: Event) => {\n event.preventDefault()\n // @ts-ignore\n return (event.returnValue = '')\n}\n\nconst stopBlocking = () => {\n removeEventListener(beforeUnloadEvent, beforeUnloadListener, {\n capture: true,\n })\n}\n\nfunction createHistory(opts: {\n getLocation: () => HistoryLocation\n subscriber: false | ((onUpdate: () => void) => () => void)\n pushState: (path: string, state: any, onUpdate: () => void) => void\n replaceState: (path: string, state: any, onUpdate: () => void) => void\n go: (n: number) => void\n back: () => void\n forward: () => void\n createHref: (path: string) => string\n flush?: () => void\n}): RouterHistory {\n let location = opts.getLocation()\n let unsub = () => {}\n let subscribers = new Set<() => void>()\n let blockers: BlockerFn[] = []\n let queue: (() => void)[] = []\n\n const tryFlush = () => {\n if (blockers.length) {\n blockers[0]?.(tryFlush, () => {\n blockers = []\n stopBlocking()\n })\n return\n }\n\n while (queue.length) {\n queue.shift()?.()\n }\n\n if (!opts.subscriber) {\n onUpdate()\n }\n }\n\n const queueTask = (task: () => void) => {\n queue.push(task)\n tryFlush()\n }\n\n const onUpdate = () => {\n location = opts.getLocation()\n subscribers.forEach((subscriber) => subscriber())\n }\n\n return {\n get location() {\n return location\n },\n subscribe: (cb: () => void) => {\n if (subscribers.size === 0) {\n unsub =\n typeof opts.subscriber === 'function'\n ? opts.subscriber(onUpdate)\n : () => {}\n }\n subscribers.add(cb)\n\n return () => {\n subscribers.delete(cb)\n if (subscribers.size === 0) {\n unsub()\n }\n }\n },\n push: (path: string, state: any) => {\n assignKey(state)\n queueTask(() => {\n opts.pushState(path, state, onUpdate)\n })\n },\n replace: (path: string, state: any) => {\n assignKey(state)\n queueTask(() => {\n opts.replaceState(path, state, onUpdate)\n })\n },\n go: (index) => {\n queueTask(() => {\n opts.go(index)\n })\n },\n back: () => {\n queueTask(() => {\n opts.back()\n })\n },\n forward: () => {\n queueTask(() => {\n opts.forward()\n })\n },\n createHref: (str) => opts.createHref(str),\n block: (cb) => {\n blockers.push(cb)\n\n if (blockers.length === 1) {\n addEventListener(beforeUnloadEvent, beforeUnloadListener, {\n capture: true,\n })\n }\n\n return () => {\n blockers = blockers.filter((b) => b !== cb)\n\n if (!blockers.length) {\n stopBlocking()\n }\n }\n },\n flush: () => opts.flush?.(),\n }\n}\n\nfunction assignKey(state: HistoryState) {\n state.key = createRandomKey()\n // if (state.__actualLocation) {\n // state.__actualLocation.state = {\n // ...state.__actualLocation.state,\n // key,\n // }\n // }\n}\n\n/**\n * Creates a history object that can be used to interact with the browser's\n * navigation. This is a lightweight API wrapping the browser's native methods.\n * It is designed to work with TanStack Router, but could be used as a standalone API as well.\n * IMPORTANT: This API implements history throttling via a microtask to prevent\n * excessive calls to the history API. In some browsers, calling history.pushState or\n * history.replaceState in quick succession can cause the browser to ignore subsequent\n * calls. This API smooths out those differences and ensures that your application\n * state will *eventually* match the browser state. In most cases, this is not a problem,\n * but if you need to ensure that the browser state is up to date, you can use the\n * `history.flush` method to immediately flush all pending state changes to the browser URL.\n * @param opts\n * @param opts.getHref A function that returns the current href (path + search + hash)\n * @param opts.createHref A function that takes a path and returns a href (path + search + hash)\n * @returns A history instance\n */\nexport function createBrowserHistory(opts?: {\n getHref?: () => string\n createHref?: (path: string) => string\n}): RouterHistory {\n const getHref =\n opts?.getHref ??\n (() =>\n `${window.location.pathname}${window.location.search}${window.location.hash}`)\n\n const createHref = opts?.createHref ?? ((path) => path)\n\n let currentLocation = parseLocation(getHref(), window.history.state)\n\n const getLocation = () => currentLocation\n\n let next:\n | undefined\n | {\n // This is the latest location that we were attempting to push/replace\n href: string\n // This is the latest state that we were attempting to push/replace\n state: any\n // This is the latest type that we were attempting to push/replace\n isPush: boolean\n }\n\n // Because we are proactively updating the location\n // in memory before actually updating the browser history,\n // we need to track when we are doing this so we don't\n // notify subscribers twice on the last update.\n let tracking = true\n\n // We need to track the current scheduled update to prevent\n // multiple updates from being scheduled at the same time.\n let scheduled: Promise<void> | undefined\n\n // This function is a wrapper to prevent any of the callback's\n // side effects from causing a subscriber notification\n const untrack = (fn: () => void) => {\n tracking = false\n fn()\n tracking = true\n }\n\n // This function flushes the next update to the browser history\n const flush = () => {\n // Do not notify subscribers about this push/replace call\n untrack(() => {\n if (!next) return\n window.history[next.isPush ? 'pushState' : 'replaceState'](\n next.state,\n '',\n next.href,\n )\n // Reset the nextIsPush flag and clear the scheduled update\n next = undefined\n scheduled = undefined\n })\n }\n\n // This function queues up a call to update the browser history\n const queueHistoryAction = (\n type: 'push' | 'replace',\n path: string,\n state: any,\n onUpdate: () => void,\n ) => {\n const href = createHref(path)\n\n // Update the location in memory\n currentLocation = parseLocation(href, state)\n\n // Keep track of the next location we need to flush to the URL\n next = {\n href,\n state,\n isPush: next?.isPush || type === 'push',\n }\n // Notify subscribers\n onUpdate()\n\n if (!scheduled) {\n // Schedule an update to the browser history\n scheduled = Promise.resolve().then(() => flush())\n }\n }\n\n return createHistory({\n getLocation,\n subscriber: (onUpdate) => {\n window.addEventListener(pushStateEvent, () => {\n currentLocation = parseLocation(getHref(), window.history.state)\n onUpdate()\n })\n window.addEventListener(popStateEvent, () => {\n currentLocation = parseLocation(getHref(), window.history.state)\n onUpdate()\n })\n\n var pushState = window.history.pushState\n window.history.pushState = function () {\n let res = pushState.apply(history, arguments as any)\n if (tracking) onUpdate()\n return res\n }\n var replaceState = window.history.replaceState\n window.history.replaceState = function () {\n let res = replaceState.apply(history, arguments as any)\n if (tracking) onUpdate()\n return res\n }\n\n return () => {\n window.history.pushState = pushState\n window.history.replaceState = replaceState\n window.removeEventListener(pushStateEvent, onUpdate)\n window.removeEventListener(popStateEvent, onUpdate)\n }\n },\n pushState: (path, state, onUpdate) =>\n queueHistoryAction('push', path, state, onUpdate),\n replaceState: (path, state, onUpdate) =>\n queueHistoryAction('replace', path, state, onUpdate),\n back: () => window.history.back(),\n forward: () => window.history.forward(),\n go: (n) => window.history.go(n),\n createHref: (path) => createHref(path),\n flush,\n })\n}\n\nexport function createHashHistory(): RouterHistory {\n return createBrowserHistory({\n getHref: () => window.location.hash.substring(1),\n createHref: (path) => `#${path}`,\n })\n}\n\nexport function createMemoryHistory(\n opts: {\n initialEntries: string[]\n initialIndex?: number\n } = {\n initialEntries: ['/'],\n },\n): RouterHistory {\n const entries = opts.initialEntries\n let index = opts.initialIndex ?? entries.length - 1\n let currentState = {\n key: createRandomKey(),\n } as HistoryState\n\n const getLocation = () => parseLocation(entries[index]!, currentState)\n\n return createHistory({\n getLocation,\n subscriber: false,\n pushState: (path, state) => {\n currentState = state\n entries.push(path)\n index++\n },\n replaceState: (path, state) => {\n currentState = state\n entries[index] = path\n },\n back: () => {\n index--\n },\n forward: () => {\n index = Math.min(index + 1, entries.length - 1)\n },\n go: (n) => window.history.go(n),\n createHref: (path) => path,\n })\n}\n\nfunction parseLocation(href: string, state: HistoryState): HistoryLocation {\n let hashIndex = href.indexOf('#')\n let searchIndex = href.indexOf('?')\n\n return {\n href,\n pathname: href.substring(\n 0,\n hashIndex > 0\n ? searchIndex > 0\n ? Math.min(hashIndex, searchIndex)\n : hashIndex\n : searchIndex > 0\n ? searchIndex\n : href.length,\n ),\n hash: hashIndex > -1 ? href.substring(hashIndex) : '',\n search:\n searchIndex > -1\n ? href.slice(searchIndex, hashIndex === -1 ? undefined : hashIndex)\n : '',\n state: state || {},\n }\n}\n\n// Thanks co-pilot!\nfunction createRandomKey() {\n return (Math.random() + 1).toString(36).substring(7)\n}\n"],"names":["pushStateEvent","popStateEvent","beforeUnloadEvent","beforeUnloadListener","event","preventDefault","returnValue","stopBlocking","removeEventListener","capture","createHistory","opts","location","getLocation","unsub","subscribers","Set","blockers","queue","tryFlush","length","shift","subscriber","onUpdate","queueTask","task","push","forEach","subscribe","cb","size","add","delete","path","state","assignKey","pushState","replace","replaceState","go","index","back","forward","createHref","str","block","addEventListener","filter","b","flush","key","createRandomKey","createBrowserHistory","getHref","window","pathname","search","hash","currentLocation","parseLocation","history","next","tracking","scheduled","untrack","fn","isPush","href","undefined","queueHistoryAction","type","Promise","resolve","then","res","apply","arguments","n","createHashHistory","substring","createMemoryHistory","initialEntries","entries","initialIndex","currentState","Math","min","hashIndex","indexOf","searchIndex","slice","random","toString"],"mappings":"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"}
1
+ {"version":3,"file":"index.js","sources":["../../src/index.ts"],"sourcesContent":["// While the public API was clearly inspired by the \"history\" npm package,\n// This implementation attempts to be more lightweight by\n// making assumptions about the way TanStack Router works\n\nexport interface RouterHistory {\n location: HistoryLocation\n subscribe: (cb: () => void) => () => void\n push: (path: string, state?: any) => void\n replace: (path: string, state?: any) => void\n go: (index: number) => void\n back: () => void\n forward: () => void\n createHref: (href: string) => string\n block: (blockerFn: BlockerFn) => () => void\n flush: () => void\n destroy: () => void\n update: () => void\n}\n\nexport interface HistoryLocation extends ParsedPath {\n state: HistoryState\n}\n\nexport interface ParsedPath {\n href: string\n pathname: string\n search: string\n hash: string\n}\n\nexport interface HistoryState {\n key: string\n}\n\ntype BlockerFn = (retry: () => void, cancel: () => void) => void\n\nconst pushStateEvent = 'pushstate'\nconst popStateEvent = 'popstate'\nconst beforeUnloadEvent = 'beforeunload'\n\nconst beforeUnloadListener = (event: Event) => {\n event.preventDefault()\n // @ts-ignore\n return (event.returnValue = '')\n}\n\nconst stopBlocking = () => {\n removeEventListener(beforeUnloadEvent, beforeUnloadListener, {\n capture: true,\n })\n}\n\nfunction createHistory(opts: {\n getLocation: () => HistoryLocation\n pushState: (path: string, state: any, onUpdate: () => void) => void\n replaceState: (path: string, state: any, onUpdate: () => void) => void\n go: (n: number) => void\n back: () => void\n forward: () => void\n createHref: (path: string) => string\n flush?: () => void\n destroy?: () => void\n}): RouterHistory {\n let location = opts.getLocation()\n let subscribers = new Set<() => void>()\n let blockers: BlockerFn[] = []\n let queue: (() => void)[] = []\n\n const onUpdate = () => {\n location = opts.getLocation()\n subscribers.forEach((subscriber) => subscriber())\n }\n\n const tryUnblock = () => {\n if (blockers.length) {\n blockers[0]?.(tryUnblock, () => {\n blockers = []\n stopBlocking()\n })\n return\n }\n\n while (queue.length) {\n queue.shift()?.()\n }\n\n onUpdate()\n }\n\n const queueTask = (task: () => void) => {\n queue.push(task)\n tryUnblock()\n }\n\n return {\n get location() {\n return location\n },\n subscribe: (cb: () => void) => {\n subscribers.add(cb)\n\n return () => {\n subscribers.delete(cb)\n }\n },\n push: (path: string, state: any) => {\n state = assignKey(state)\n queueTask(() => {\n opts.pushState(path, state, onUpdate)\n })\n },\n replace: (path: string, state: any) => {\n state = assignKey(state)\n queueTask(() => {\n opts.replaceState(path, state, onUpdate)\n })\n },\n go: (index) => {\n queueTask(() => {\n opts.go(index)\n })\n },\n back: () => {\n queueTask(() => {\n opts.back()\n })\n },\n forward: () => {\n queueTask(() => {\n opts.forward()\n })\n },\n createHref: (str) => opts.createHref(str),\n block: (cb) => {\n blockers.push(cb)\n\n if (blockers.length === 1) {\n addEventListener(beforeUnloadEvent, beforeUnloadListener, {\n capture: true,\n })\n }\n\n return () => {\n blockers = blockers.filter((b) => b !== cb)\n\n if (!blockers.length) {\n stopBlocking()\n }\n }\n },\n flush: () => opts.flush?.(),\n destroy: () => opts.destroy?.(),\n update: onUpdate,\n }\n}\n\nfunction assignKey(state: HistoryState) {\n if (!state) {\n state = {} as HistoryState\n }\n state.key = createRandomKey()\n return state\n}\n\n/**\n * Creates a history object that can be used to interact with the browser's\n * navigation. This is a lightweight API wrapping the browser's native methods.\n * It is designed to work with TanStack Router, but could be used as a standalone API as well.\n * IMPORTANT: This API implements history throttling via a microtask to prevent\n * excessive calls to the history API. In some browsers, calling history.pushState or\n * history.replaceState in quick succession can cause the browser to ignore subsequent\n * calls. This API smooths out those differences and ensures that your application\n * state will *eventually* match the browser state. In most cases, this is not a problem,\n * but if you need to ensure that the browser state is up to date, you can use the\n * `history.flush` method to immediately flush all pending state changes to the browser URL.\n * @param opts\n * @param opts.getHref A function that returns the current href (path + search + hash)\n * @param opts.createHref A function that takes a path and returns a href (path + search + hash)\n * @returns A history instance\n */\nexport function createBrowserHistory(opts?: {\n getHref?: () => string\n createHref?: (path: string) => string\n}): RouterHistory {\n const getHref =\n opts?.getHref ??\n (() =>\n `${window.location.pathname}${window.location.search}${window.location.hash}`)\n\n const createHref = opts?.createHref ?? ((path) => path)\n\n let currentLocation = parseLocation(getHref(), window.history.state)\n\n const getLocation = () => currentLocation\n\n let next:\n | undefined\n | {\n // This is the latest location that we were attempting to push/replace\n href: string\n // This is the latest state that we were attempting to push/replace\n state: any\n // This is the latest type that we were attempting to push/replace\n isPush: boolean\n }\n\n // Because we are proactively updating the location\n // in memory before actually updating the browser history,\n // we need to track when we are doing this so we don't\n // notify subscribers twice on the last update.\n let tracking = true\n\n // We need to track the current scheduled update to prevent\n // multiple updates from being scheduled at the same time.\n let scheduled: Promise<void> | undefined\n\n // This function is a wrapper to prevent any of the callback's\n // side effects from causing a subscriber notification\n const untrack = (fn: () => void) => {\n tracking = false\n fn()\n tracking = true\n }\n\n // This function flushes the next update to the browser history\n const flush = () => {\n // Do not notify subscribers about this push/replace call\n untrack(() => {\n if (!next) return\n window.history[next.isPush ? 'pushState' : 'replaceState'](\n next.state,\n '',\n next.href,\n )\n // Reset the nextIsPush flag and clear the scheduled update\n next = undefined\n scheduled = undefined\n })\n }\n\n // This function queues up a call to update the browser history\n const queueHistoryAction = (\n type: 'push' | 'replace',\n path: string,\n state: any,\n onUpdate: () => void,\n ) => {\n const href = createHref(path)\n\n // Update the location in memory\n currentLocation = parseLocation(href, state)\n\n // Keep track of the next location we need to flush to the URL\n next = {\n href,\n state,\n isPush: next?.isPush || type === 'push',\n }\n // Notify subscribers\n onUpdate()\n\n if (!scheduled) {\n // Schedule an update to the browser history\n scheduled = Promise.resolve().then(() => flush())\n }\n }\n\n const history = createHistory({\n getLocation,\n pushState: (path, state, onUpdate) =>\n queueHistoryAction('push', path, state, onUpdate),\n replaceState: (path, state, onUpdate) =>\n queueHistoryAction('replace', path, state, onUpdate),\n back: () => window.history.back(),\n forward: () => window.history.forward(),\n go: (n) => window.history.go(n),\n createHref: (path) => createHref(path),\n flush,\n destroy: () => {\n window.history.pushState = pushState\n window.history.replaceState = replaceState\n window.removeEventListener(pushStateEvent, history.update)\n window.removeEventListener(popStateEvent, history.update)\n },\n })\n\n window.addEventListener(pushStateEvent, () => {\n currentLocation = parseLocation(getHref(), window.history.state)\n history.update\n })\n window.addEventListener(popStateEvent, () => {\n currentLocation = parseLocation(getHref(), window.history.state)\n history.update\n })\n\n var pushState = window.history.pushState\n window.history.pushState = function () {\n let res = pushState.apply(window.history, arguments as any)\n if (tracking) history.update()\n return res\n }\n var replaceState = window.history.replaceState\n window.history.replaceState = function () {\n let res = replaceState.apply(window.history, arguments as any)\n if (tracking) history.update()\n return res\n }\n\n return history\n}\n\nexport function createHashHistory(): RouterHistory {\n return createBrowserHistory({\n getHref: () => window.location.hash.substring(1),\n createHref: (path) => `#${path}`,\n })\n}\n\nexport function createMemoryHistory(\n opts: {\n initialEntries: string[]\n initialIndex?: number\n } = {\n initialEntries: ['/'],\n },\n): RouterHistory {\n const entries = opts.initialEntries\n let index = opts.initialIndex ?? entries.length - 1\n let currentState = {\n key: createRandomKey(),\n } as HistoryState\n\n const getLocation = () => parseLocation(entries[index]!, currentState)\n\n return createHistory({\n getLocation,\n pushState: (path, state) => {\n currentState = state\n entries.push(path)\n index++\n },\n replaceState: (path, state) => {\n currentState = state\n entries[index] = path\n },\n back: () => {\n index--\n },\n forward: () => {\n index = Math.min(index + 1, entries.length - 1)\n },\n go: (n) => window.history.go(n),\n createHref: (path) => path,\n })\n}\n\nfunction parseLocation(href: string, state: HistoryState): HistoryLocation {\n let hashIndex = href.indexOf('#')\n let searchIndex = href.indexOf('?')\n\n return {\n href,\n pathname: href.substring(\n 0,\n hashIndex > 0\n ? searchIndex > 0\n ? Math.min(hashIndex, searchIndex)\n : hashIndex\n : searchIndex > 0\n ? searchIndex\n : href.length,\n ),\n hash: hashIndex > -1 ? href.substring(hashIndex) : '',\n search:\n searchIndex > -1\n ? href.slice(searchIndex, hashIndex === -1 ? undefined : hashIndex)\n : '',\n state: state || {},\n }\n}\n\n// Thanks co-pilot!\nfunction createRandomKey() {\n return (Math.random() + 1).toString(36).substring(7)\n}\n"],"names":["pushStateEvent","popStateEvent","beforeUnloadEvent","beforeUnloadListener","event","preventDefault","returnValue","stopBlocking","removeEventListener","capture","createHistory","opts","location","getLocation","subscribers","Set","blockers","queue","onUpdate","forEach","subscriber","tryUnblock","length","shift","queueTask","task","push","subscribe","cb","add","delete","path","state","assignKey","pushState","replace","replaceState","go","index","back","forward","createHref","str","block","addEventListener","filter","b","flush","destroy","update","key","createRandomKey","createBrowserHistory","getHref","window","pathname","search","hash","currentLocation","parseLocation","history","next","tracking","scheduled","untrack","fn","isPush","href","undefined","queueHistoryAction","type","Promise","resolve","then","n","res","apply","arguments","createHashHistory","substring","createMemoryHistory","initialEntries","entries","initialIndex","currentState","Math","min","hashIndex","indexOf","searchIndex","slice","random","toString"],"mappings":"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"}
@@ -4024,7 +4024,7 @@ var drawChart = (function (exports) {
4024
4024
  </script>
4025
4025
  <script>
4026
4026
  /*<!--*/
4027
- const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.production.js","children":[{"name":"packages/history/src/index.ts","uid":"7fc4-863"}]}],"isRoot":true},"nodeParts":{"7fc4-863":{"renderedLength":9309,"gzipLength":2670,"brotliLength":0,"mainUid":"7fc4-862"}},"nodeMetas":{"7fc4-862":{"id":"/packages/history/src/index.ts","moduleParts":{"index.production.js":"7fc4-863"},"imported":[],"importedBy":[],"isEntry":true}},"env":{"rollup":"2.79.1"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
4027
+ const data = {"version":2,"tree":{"name":"root","children":[{"name":"index.production.js","children":[{"name":"packages/history/src/index.ts","uid":"3286-1"}]}],"isRoot":true},"nodeParts":{"3286-1":{"renderedLength":8931,"gzipLength":2601,"brotliLength":0,"mainUid":"3286-0"}},"nodeMetas":{"3286-0":{"id":"/packages/history/src/index.ts","moduleParts":{"index.production.js":"3286-1"},"imported":[],"importedBy":[],"isEntry":true}},"env":{"rollup":"2.79.1"},"options":{"gzip":true,"brotli":false,"sourcemap":false}};
4028
4028
 
4029
4029
  const run = () => {
4030
4030
  const width = window.innerWidth;
@@ -8,7 +8,7 @@
8
8
  "children": [
9
9
  {
10
10
  "name": "packages/history/src/index.ts",
11
- "uid": "7fc4-865"
11
+ "uid": "3286-3"
12
12
  }
13
13
  ]
14
14
  }
@@ -16,18 +16,18 @@
16
16
  "isRoot": true
17
17
  },
18
18
  "nodeParts": {
19
- "7fc4-865": {
20
- "renderedLength": 9309,
21
- "gzipLength": 2670,
19
+ "3286-3": {
20
+ "renderedLength": 8931,
21
+ "gzipLength": 2601,
22
22
  "brotliLength": 0,
23
- "mainUid": "7fc4-864"
23
+ "mainUid": "3286-2"
24
24
  }
25
25
  },
26
26
  "nodeMetas": {
27
- "7fc4-864": {
27
+ "3286-2": {
28
28
  "id": "/packages/history/src/index.ts",
29
29
  "moduleParts": {
30
- "index.production.js": "7fc4-865"
30
+ "index.production.js": "3286-3"
31
31
  },
32
32
  "imported": [],
33
33
  "importedBy": [],
@@ -19,6 +19,8 @@ interface RouterHistory {
19
19
  createHref: (href: string) => string;
20
20
  block: (blockerFn: BlockerFn) => () => void;
21
21
  flush: () => void;
22
+ destroy: () => void;
23
+ update: () => void;
22
24
  }
23
25
  interface HistoryLocation extends ParsedPath {
24
26
  state: HistoryState;
@@ -31,8 +33,6 @@ interface ParsedPath {
31
33
  }
32
34
  interface HistoryState {
33
35
  key: string;
34
- __tempLocation?: HistoryLocation;
35
- __tempKey?: string;
36
36
  }
37
37
  type BlockerFn = (retry: () => void, cancel: () => void) => void;
38
38
  /**
@@ -33,13 +33,16 @@
33
33
  };
34
34
  function createHistory(opts) {
35
35
  let location = opts.getLocation();
36
- let unsub = () => {};
37
36
  let subscribers = new Set();
38
37
  let blockers = [];
39
38
  let queue = [];
40
- const tryFlush = () => {
39
+ const onUpdate = () => {
40
+ location = opts.getLocation();
41
+ subscribers.forEach(subscriber => subscriber());
42
+ };
43
+ const tryUnblock = () => {
41
44
  if (blockers.length) {
42
- blockers[0]?.(tryFlush, () => {
45
+ blockers[0]?.(tryUnblock, () => {
43
46
  blockers = [];
44
47
  stopBlocking();
45
48
  });
@@ -48,42 +51,30 @@
48
51
  while (queue.length) {
49
52
  queue.shift()?.();
50
53
  }
51
- if (!opts.subscriber) {
52
- onUpdate();
53
- }
54
+ onUpdate();
54
55
  };
55
56
  const queueTask = task => {
56
57
  queue.push(task);
57
- tryFlush();
58
- };
59
- const onUpdate = () => {
60
- location = opts.getLocation();
61
- subscribers.forEach(subscriber => subscriber());
58
+ tryUnblock();
62
59
  };
63
60
  return {
64
61
  get location() {
65
62
  return location;
66
63
  },
67
64
  subscribe: cb => {
68
- if (subscribers.size === 0) {
69
- unsub = typeof opts.subscriber === 'function' ? opts.subscriber(onUpdate) : () => {};
70
- }
71
65
  subscribers.add(cb);
72
66
  return () => {
73
67
  subscribers.delete(cb);
74
- if (subscribers.size === 0) {
75
- unsub();
76
- }
77
68
  };
78
69
  },
79
70
  push: (path, state) => {
80
- assignKey(state);
71
+ state = assignKey(state);
81
72
  queueTask(() => {
82
73
  opts.pushState(path, state, onUpdate);
83
74
  });
84
75
  },
85
76
  replace: (path, state) => {
86
- assignKey(state);
77
+ state = assignKey(state);
87
78
  queueTask(() => {
88
79
  opts.replaceState(path, state, onUpdate);
89
80
  });
@@ -118,17 +109,17 @@
118
109
  }
119
110
  };
120
111
  },
121
- flush: () => opts.flush?.()
112
+ flush: () => opts.flush?.(),
113
+ destroy: () => opts.destroy?.(),
114
+ update: onUpdate
122
115
  };
123
116
  }
124
117
  function assignKey(state) {
118
+ if (!state) {
119
+ state = {};
120
+ }
125
121
  state.key = createRandomKey();
126
- // if (state.__actualLocation) {
127
- // state.__actualLocation.state = {
128
- // ...state.__actualLocation.state,
129
- // key,
130
- // }
131
- // }
122
+ return state;
132
123
  }
133
124
 
134
125
  /**
@@ -204,44 +195,43 @@
204
195
  scheduled = Promise.resolve().then(() => flush());
205
196
  }
206
197
  };
207
- return createHistory({
198
+ const history = createHistory({
208
199
  getLocation,
209
- subscriber: onUpdate => {
210
- window.addEventListener(pushStateEvent, () => {
211
- currentLocation = parseLocation(getHref(), window.history.state);
212
- onUpdate();
213
- });
214
- window.addEventListener(popStateEvent, () => {
215
- currentLocation = parseLocation(getHref(), window.history.state);
216
- onUpdate();
217
- });
218
- var pushState = window.history.pushState;
219
- window.history.pushState = function () {
220
- let res = pushState.apply(history, arguments);
221
- if (tracking) onUpdate();
222
- return res;
223
- };
224
- var replaceState = window.history.replaceState;
225
- window.history.replaceState = function () {
226
- let res = replaceState.apply(history, arguments);
227
- if (tracking) onUpdate();
228
- return res;
229
- };
230
- return () => {
231
- window.history.pushState = pushState;
232
- window.history.replaceState = replaceState;
233
- window.removeEventListener(pushStateEvent, onUpdate);
234
- window.removeEventListener(popStateEvent, onUpdate);
235
- };
236
- },
237
200
  pushState: (path, state, onUpdate) => queueHistoryAction('push', path, state, onUpdate),
238
201
  replaceState: (path, state, onUpdate) => queueHistoryAction('replace', path, state, onUpdate),
239
202
  back: () => window.history.back(),
240
203
  forward: () => window.history.forward(),
241
204
  go: n => window.history.go(n),
242
205
  createHref: path => createHref(path),
243
- flush
206
+ flush,
207
+ destroy: () => {
208
+ window.history.pushState = pushState;
209
+ window.history.replaceState = replaceState;
210
+ window.removeEventListener(pushStateEvent, history.update);
211
+ window.removeEventListener(popStateEvent, history.update);
212
+ }
213
+ });
214
+ window.addEventListener(pushStateEvent, () => {
215
+ currentLocation = parseLocation(getHref(), window.history.state);
216
+ history.update;
244
217
  });
218
+ window.addEventListener(popStateEvent, () => {
219
+ currentLocation = parseLocation(getHref(), window.history.state);
220
+ history.update;
221
+ });
222
+ var pushState = window.history.pushState;
223
+ window.history.pushState = function () {
224
+ let res = pushState.apply(window.history, arguments);
225
+ if (tracking) history.update();
226
+ return res;
227
+ };
228
+ var replaceState = window.history.replaceState;
229
+ window.history.replaceState = function () {
230
+ let res = replaceState.apply(window.history, arguments);
231
+ if (tracking) history.update();
232
+ return res;
233
+ };
234
+ return history;
245
235
  }
246
236
  function createHashHistory() {
247
237
  return createBrowserHistory({
@@ -260,7 +250,6 @@
260
250
  const getLocation = () => parseLocation(entries[index], currentState);
261
251
  return createHistory({
262
252
  getLocation,
263
- subscriber: false,
264
253
  pushState: (path, state) => {
265
254
  currentState = state;
266
255
  entries.push(path);
@@ -1 +1 @@
1
- {"version":3,"file":"index.development.js","sources":["../../src/index.ts"],"sourcesContent":["// While the public API was clearly inspired by the \"history\" npm package,\n// This implementation attempts to be more lightweight by\n// making assumptions about the way TanStack Router works\n\nexport interface RouterHistory {\n location: HistoryLocation\n subscribe: (cb: () => void) => () => void\n push: (path: string, state?: any) => void\n replace: (path: string, state?: any) => void\n go: (index: number) => void\n back: () => void\n forward: () => void\n createHref: (href: string) => string\n block: (blockerFn: BlockerFn) => () => void\n flush: () => void\n}\n\nexport interface HistoryLocation extends ParsedPath {\n state: HistoryState\n}\n\nexport interface ParsedPath {\n href: string\n pathname: string\n search: string\n hash: string\n}\n\nexport interface HistoryState {\n key: string\n __tempLocation?: HistoryLocation\n __tempKey?: string\n}\n\ntype BlockerFn = (retry: () => void, cancel: () => void) => void\n\nconst pushStateEvent = 'pushstate'\nconst popStateEvent = 'popstate'\nconst beforeUnloadEvent = 'beforeunload'\n\nconst beforeUnloadListener = (event: Event) => {\n event.preventDefault()\n // @ts-ignore\n return (event.returnValue = '')\n}\n\nconst stopBlocking = () => {\n removeEventListener(beforeUnloadEvent, beforeUnloadListener, {\n capture: true,\n })\n}\n\nfunction createHistory(opts: {\n getLocation: () => HistoryLocation\n subscriber: false | ((onUpdate: () => void) => () => void)\n pushState: (path: string, state: any, onUpdate: () => void) => void\n replaceState: (path: string, state: any, onUpdate: () => void) => void\n go: (n: number) => void\n back: () => void\n forward: () => void\n createHref: (path: string) => string\n flush?: () => void\n}): RouterHistory {\n let location = opts.getLocation()\n let unsub = () => {}\n let subscribers = new Set<() => void>()\n let blockers: BlockerFn[] = []\n let queue: (() => void)[] = []\n\n const tryFlush = () => {\n if (blockers.length) {\n blockers[0]?.(tryFlush, () => {\n blockers = []\n stopBlocking()\n })\n return\n }\n\n while (queue.length) {\n queue.shift()?.()\n }\n\n if (!opts.subscriber) {\n onUpdate()\n }\n }\n\n const queueTask = (task: () => void) => {\n queue.push(task)\n tryFlush()\n }\n\n const onUpdate = () => {\n location = opts.getLocation()\n subscribers.forEach((subscriber) => subscriber())\n }\n\n return {\n get location() {\n return location\n },\n subscribe: (cb: () => void) => {\n if (subscribers.size === 0) {\n unsub =\n typeof opts.subscriber === 'function'\n ? opts.subscriber(onUpdate)\n : () => {}\n }\n subscribers.add(cb)\n\n return () => {\n subscribers.delete(cb)\n if (subscribers.size === 0) {\n unsub()\n }\n }\n },\n push: (path: string, state: any) => {\n assignKey(state)\n queueTask(() => {\n opts.pushState(path, state, onUpdate)\n })\n },\n replace: (path: string, state: any) => {\n assignKey(state)\n queueTask(() => {\n opts.replaceState(path, state, onUpdate)\n })\n },\n go: (index) => {\n queueTask(() => {\n opts.go(index)\n })\n },\n back: () => {\n queueTask(() => {\n opts.back()\n })\n },\n forward: () => {\n queueTask(() => {\n opts.forward()\n })\n },\n createHref: (str) => opts.createHref(str),\n block: (cb) => {\n blockers.push(cb)\n\n if (blockers.length === 1) {\n addEventListener(beforeUnloadEvent, beforeUnloadListener, {\n capture: true,\n })\n }\n\n return () => {\n blockers = blockers.filter((b) => b !== cb)\n\n if (!blockers.length) {\n stopBlocking()\n }\n }\n },\n flush: () => opts.flush?.(),\n }\n}\n\nfunction assignKey(state: HistoryState) {\n state.key = createRandomKey()\n // if (state.__actualLocation) {\n // state.__actualLocation.state = {\n // ...state.__actualLocation.state,\n // key,\n // }\n // }\n}\n\n/**\n * Creates a history object that can be used to interact with the browser's\n * navigation. This is a lightweight API wrapping the browser's native methods.\n * It is designed to work with TanStack Router, but could be used as a standalone API as well.\n * IMPORTANT: This API implements history throttling via a microtask to prevent\n * excessive calls to the history API. In some browsers, calling history.pushState or\n * history.replaceState in quick succession can cause the browser to ignore subsequent\n * calls. This API smooths out those differences and ensures that your application\n * state will *eventually* match the browser state. In most cases, this is not a problem,\n * but if you need to ensure that the browser state is up to date, you can use the\n * `history.flush` method to immediately flush all pending state changes to the browser URL.\n * @param opts\n * @param opts.getHref A function that returns the current href (path + search + hash)\n * @param opts.createHref A function that takes a path and returns a href (path + search + hash)\n * @returns A history instance\n */\nexport function createBrowserHistory(opts?: {\n getHref?: () => string\n createHref?: (path: string) => string\n}): RouterHistory {\n const getHref =\n opts?.getHref ??\n (() =>\n `${window.location.pathname}${window.location.search}${window.location.hash}`)\n\n const createHref = opts?.createHref ?? ((path) => path)\n\n let currentLocation = parseLocation(getHref(), window.history.state)\n\n const getLocation = () => currentLocation\n\n let next:\n | undefined\n | {\n // This is the latest location that we were attempting to push/replace\n href: string\n // This is the latest state that we were attempting to push/replace\n state: any\n // This is the latest type that we were attempting to push/replace\n isPush: boolean\n }\n\n // Because we are proactively updating the location\n // in memory before actually updating the browser history,\n // we need to track when we are doing this so we don't\n // notify subscribers twice on the last update.\n let tracking = true\n\n // We need to track the current scheduled update to prevent\n // multiple updates from being scheduled at the same time.\n let scheduled: Promise<void> | undefined\n\n // This function is a wrapper to prevent any of the callback's\n // side effects from causing a subscriber notification\n const untrack = (fn: () => void) => {\n tracking = false\n fn()\n tracking = true\n }\n\n // This function flushes the next update to the browser history\n const flush = () => {\n // Do not notify subscribers about this push/replace call\n untrack(() => {\n if (!next) return\n window.history[next.isPush ? 'pushState' : 'replaceState'](\n next.state,\n '',\n next.href,\n )\n // Reset the nextIsPush flag and clear the scheduled update\n next = undefined\n scheduled = undefined\n })\n }\n\n // This function queues up a call to update the browser history\n const queueHistoryAction = (\n type: 'push' | 'replace',\n path: string,\n state: any,\n onUpdate: () => void,\n ) => {\n const href = createHref(path)\n\n // Update the location in memory\n currentLocation = parseLocation(href, state)\n\n // Keep track of the next location we need to flush to the URL\n next = {\n href,\n state,\n isPush: next?.isPush || type === 'push',\n }\n // Notify subscribers\n onUpdate()\n\n if (!scheduled) {\n // Schedule an update to the browser history\n scheduled = Promise.resolve().then(() => flush())\n }\n }\n\n return createHistory({\n getLocation,\n subscriber: (onUpdate) => {\n window.addEventListener(pushStateEvent, () => {\n currentLocation = parseLocation(getHref(), window.history.state)\n onUpdate()\n })\n window.addEventListener(popStateEvent, () => {\n currentLocation = parseLocation(getHref(), window.history.state)\n onUpdate()\n })\n\n var pushState = window.history.pushState\n window.history.pushState = function () {\n let res = pushState.apply(history, arguments as any)\n if (tracking) onUpdate()\n return res\n }\n var replaceState = window.history.replaceState\n window.history.replaceState = function () {\n let res = replaceState.apply(history, arguments as any)\n if (tracking) onUpdate()\n return res\n }\n\n return () => {\n window.history.pushState = pushState\n window.history.replaceState = replaceState\n window.removeEventListener(pushStateEvent, onUpdate)\n window.removeEventListener(popStateEvent, onUpdate)\n }\n },\n pushState: (path, state, onUpdate) =>\n queueHistoryAction('push', path, state, onUpdate),\n replaceState: (path, state, onUpdate) =>\n queueHistoryAction('replace', path, state, onUpdate),\n back: () => window.history.back(),\n forward: () => window.history.forward(),\n go: (n) => window.history.go(n),\n createHref: (path) => createHref(path),\n flush,\n })\n}\n\nexport function createHashHistory(): RouterHistory {\n return createBrowserHistory({\n getHref: () => window.location.hash.substring(1),\n createHref: (path) => `#${path}`,\n })\n}\n\nexport function createMemoryHistory(\n opts: {\n initialEntries: string[]\n initialIndex?: number\n } = {\n initialEntries: ['/'],\n },\n): RouterHistory {\n const entries = opts.initialEntries\n let index = opts.initialIndex ?? entries.length - 1\n let currentState = {\n key: createRandomKey(),\n } as HistoryState\n\n const getLocation = () => parseLocation(entries[index]!, currentState)\n\n return createHistory({\n getLocation,\n subscriber: false,\n pushState: (path, state) => {\n currentState = state\n entries.push(path)\n index++\n },\n replaceState: (path, state) => {\n currentState = state\n entries[index] = path\n },\n back: () => {\n index--\n },\n forward: () => {\n index = Math.min(index + 1, entries.length - 1)\n },\n go: (n) => window.history.go(n),\n createHref: (path) => path,\n })\n}\n\nfunction parseLocation(href: string, state: HistoryState): HistoryLocation {\n let hashIndex = href.indexOf('#')\n let searchIndex = href.indexOf('?')\n\n return {\n href,\n pathname: href.substring(\n 0,\n hashIndex > 0\n ? searchIndex > 0\n ? Math.min(hashIndex, searchIndex)\n : hashIndex\n : searchIndex > 0\n ? searchIndex\n : href.length,\n ),\n hash: hashIndex > -1 ? href.substring(hashIndex) : '',\n search:\n searchIndex > -1\n ? href.slice(searchIndex, hashIndex === -1 ? undefined : hashIndex)\n : '',\n state: state || {},\n }\n}\n\n// Thanks co-pilot!\nfunction createRandomKey() {\n return (Math.random() + 1).toString(36).substring(7)\n}\n"],"names":["pushStateEvent","popStateEvent","beforeUnloadEvent","beforeUnloadListener","event","preventDefault","returnValue","stopBlocking","removeEventListener","capture","createHistory","opts","location","getLocation","unsub","subscribers","Set","blockers","queue","tryFlush","length","shift","subscriber","onUpdate","queueTask","task","push","forEach","subscribe","cb","size","add","delete","path","state","assignKey","pushState","replace","replaceState","go","index","back","forward","createHref","str","block","addEventListener","filter","b","flush","key","createRandomKey","createBrowserHistory","getHref","window","pathname","search","hash","currentLocation","parseLocation","history","next","tracking","scheduled","untrack","fn","isPush","href","undefined","queueHistoryAction","type","Promise","resolve","then","res","apply","arguments","n","createHashHistory","substring","createMemoryHistory","initialEntries","entries","initialIndex","currentState","Math","min","hashIndex","indexOf","searchIndex","slice","random","toString"],"mappings":"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"}
1
+ {"version":3,"file":"index.development.js","sources":["../../src/index.ts"],"sourcesContent":["// While the public API was clearly inspired by the \"history\" npm package,\n// This implementation attempts to be more lightweight by\n// making assumptions about the way TanStack Router works\n\nexport interface RouterHistory {\n location: HistoryLocation\n subscribe: (cb: () => void) => () => void\n push: (path: string, state?: any) => void\n replace: (path: string, state?: any) => void\n go: (index: number) => void\n back: () => void\n forward: () => void\n createHref: (href: string) => string\n block: (blockerFn: BlockerFn) => () => void\n flush: () => void\n destroy: () => void\n update: () => void\n}\n\nexport interface HistoryLocation extends ParsedPath {\n state: HistoryState\n}\n\nexport interface ParsedPath {\n href: string\n pathname: string\n search: string\n hash: string\n}\n\nexport interface HistoryState {\n key: string\n}\n\ntype BlockerFn = (retry: () => void, cancel: () => void) => void\n\nconst pushStateEvent = 'pushstate'\nconst popStateEvent = 'popstate'\nconst beforeUnloadEvent = 'beforeunload'\n\nconst beforeUnloadListener = (event: Event) => {\n event.preventDefault()\n // @ts-ignore\n return (event.returnValue = '')\n}\n\nconst stopBlocking = () => {\n removeEventListener(beforeUnloadEvent, beforeUnloadListener, {\n capture: true,\n })\n}\n\nfunction createHistory(opts: {\n getLocation: () => HistoryLocation\n pushState: (path: string, state: any, onUpdate: () => void) => void\n replaceState: (path: string, state: any, onUpdate: () => void) => void\n go: (n: number) => void\n back: () => void\n forward: () => void\n createHref: (path: string) => string\n flush?: () => void\n destroy?: () => void\n}): RouterHistory {\n let location = opts.getLocation()\n let subscribers = new Set<() => void>()\n let blockers: BlockerFn[] = []\n let queue: (() => void)[] = []\n\n const onUpdate = () => {\n location = opts.getLocation()\n subscribers.forEach((subscriber) => subscriber())\n }\n\n const tryUnblock = () => {\n if (blockers.length) {\n blockers[0]?.(tryUnblock, () => {\n blockers = []\n stopBlocking()\n })\n return\n }\n\n while (queue.length) {\n queue.shift()?.()\n }\n\n onUpdate()\n }\n\n const queueTask = (task: () => void) => {\n queue.push(task)\n tryUnblock()\n }\n\n return {\n get location() {\n return location\n },\n subscribe: (cb: () => void) => {\n subscribers.add(cb)\n\n return () => {\n subscribers.delete(cb)\n }\n },\n push: (path: string, state: any) => {\n state = assignKey(state)\n queueTask(() => {\n opts.pushState(path, state, onUpdate)\n })\n },\n replace: (path: string, state: any) => {\n state = assignKey(state)\n queueTask(() => {\n opts.replaceState(path, state, onUpdate)\n })\n },\n go: (index) => {\n queueTask(() => {\n opts.go(index)\n })\n },\n back: () => {\n queueTask(() => {\n opts.back()\n })\n },\n forward: () => {\n queueTask(() => {\n opts.forward()\n })\n },\n createHref: (str) => opts.createHref(str),\n block: (cb) => {\n blockers.push(cb)\n\n if (blockers.length === 1) {\n addEventListener(beforeUnloadEvent, beforeUnloadListener, {\n capture: true,\n })\n }\n\n return () => {\n blockers = blockers.filter((b) => b !== cb)\n\n if (!blockers.length) {\n stopBlocking()\n }\n }\n },\n flush: () => opts.flush?.(),\n destroy: () => opts.destroy?.(),\n update: onUpdate,\n }\n}\n\nfunction assignKey(state: HistoryState) {\n if (!state) {\n state = {} as HistoryState\n }\n state.key = createRandomKey()\n return state\n}\n\n/**\n * Creates a history object that can be used to interact with the browser's\n * navigation. This is a lightweight API wrapping the browser's native methods.\n * It is designed to work with TanStack Router, but could be used as a standalone API as well.\n * IMPORTANT: This API implements history throttling via a microtask to prevent\n * excessive calls to the history API. In some browsers, calling history.pushState or\n * history.replaceState in quick succession can cause the browser to ignore subsequent\n * calls. This API smooths out those differences and ensures that your application\n * state will *eventually* match the browser state. In most cases, this is not a problem,\n * but if you need to ensure that the browser state is up to date, you can use the\n * `history.flush` method to immediately flush all pending state changes to the browser URL.\n * @param opts\n * @param opts.getHref A function that returns the current href (path + search + hash)\n * @param opts.createHref A function that takes a path and returns a href (path + search + hash)\n * @returns A history instance\n */\nexport function createBrowserHistory(opts?: {\n getHref?: () => string\n createHref?: (path: string) => string\n}): RouterHistory {\n const getHref =\n opts?.getHref ??\n (() =>\n `${window.location.pathname}${window.location.search}${window.location.hash}`)\n\n const createHref = opts?.createHref ?? ((path) => path)\n\n let currentLocation = parseLocation(getHref(), window.history.state)\n\n const getLocation = () => currentLocation\n\n let next:\n | undefined\n | {\n // This is the latest location that we were attempting to push/replace\n href: string\n // This is the latest state that we were attempting to push/replace\n state: any\n // This is the latest type that we were attempting to push/replace\n isPush: boolean\n }\n\n // Because we are proactively updating the location\n // in memory before actually updating the browser history,\n // we need to track when we are doing this so we don't\n // notify subscribers twice on the last update.\n let tracking = true\n\n // We need to track the current scheduled update to prevent\n // multiple updates from being scheduled at the same time.\n let scheduled: Promise<void> | undefined\n\n // This function is a wrapper to prevent any of the callback's\n // side effects from causing a subscriber notification\n const untrack = (fn: () => void) => {\n tracking = false\n fn()\n tracking = true\n }\n\n // This function flushes the next update to the browser history\n const flush = () => {\n // Do not notify subscribers about this push/replace call\n untrack(() => {\n if (!next) return\n window.history[next.isPush ? 'pushState' : 'replaceState'](\n next.state,\n '',\n next.href,\n )\n // Reset the nextIsPush flag and clear the scheduled update\n next = undefined\n scheduled = undefined\n })\n }\n\n // This function queues up a call to update the browser history\n const queueHistoryAction = (\n type: 'push' | 'replace',\n path: string,\n state: any,\n onUpdate: () => void,\n ) => {\n const href = createHref(path)\n\n // Update the location in memory\n currentLocation = parseLocation(href, state)\n\n // Keep track of the next location we need to flush to the URL\n next = {\n href,\n state,\n isPush: next?.isPush || type === 'push',\n }\n // Notify subscribers\n onUpdate()\n\n if (!scheduled) {\n // Schedule an update to the browser history\n scheduled = Promise.resolve().then(() => flush())\n }\n }\n\n const history = createHistory({\n getLocation,\n pushState: (path, state, onUpdate) =>\n queueHistoryAction('push', path, state, onUpdate),\n replaceState: (path, state, onUpdate) =>\n queueHistoryAction('replace', path, state, onUpdate),\n back: () => window.history.back(),\n forward: () => window.history.forward(),\n go: (n) => window.history.go(n),\n createHref: (path) => createHref(path),\n flush,\n destroy: () => {\n window.history.pushState = pushState\n window.history.replaceState = replaceState\n window.removeEventListener(pushStateEvent, history.update)\n window.removeEventListener(popStateEvent, history.update)\n },\n })\n\n window.addEventListener(pushStateEvent, () => {\n currentLocation = parseLocation(getHref(), window.history.state)\n history.update\n })\n window.addEventListener(popStateEvent, () => {\n currentLocation = parseLocation(getHref(), window.history.state)\n history.update\n })\n\n var pushState = window.history.pushState\n window.history.pushState = function () {\n let res = pushState.apply(window.history, arguments as any)\n if (tracking) history.update()\n return res\n }\n var replaceState = window.history.replaceState\n window.history.replaceState = function () {\n let res = replaceState.apply(window.history, arguments as any)\n if (tracking) history.update()\n return res\n }\n\n return history\n}\n\nexport function createHashHistory(): RouterHistory {\n return createBrowserHistory({\n getHref: () => window.location.hash.substring(1),\n createHref: (path) => `#${path}`,\n })\n}\n\nexport function createMemoryHistory(\n opts: {\n initialEntries: string[]\n initialIndex?: number\n } = {\n initialEntries: ['/'],\n },\n): RouterHistory {\n const entries = opts.initialEntries\n let index = opts.initialIndex ?? entries.length - 1\n let currentState = {\n key: createRandomKey(),\n } as HistoryState\n\n const getLocation = () => parseLocation(entries[index]!, currentState)\n\n return createHistory({\n getLocation,\n pushState: (path, state) => {\n currentState = state\n entries.push(path)\n index++\n },\n replaceState: (path, state) => {\n currentState = state\n entries[index] = path\n },\n back: () => {\n index--\n },\n forward: () => {\n index = Math.min(index + 1, entries.length - 1)\n },\n go: (n) => window.history.go(n),\n createHref: (path) => path,\n })\n}\n\nfunction parseLocation(href: string, state: HistoryState): HistoryLocation {\n let hashIndex = href.indexOf('#')\n let searchIndex = href.indexOf('?')\n\n return {\n href,\n pathname: href.substring(\n 0,\n hashIndex > 0\n ? searchIndex > 0\n ? Math.min(hashIndex, searchIndex)\n : hashIndex\n : searchIndex > 0\n ? searchIndex\n : href.length,\n ),\n hash: hashIndex > -1 ? href.substring(hashIndex) : '',\n search:\n searchIndex > -1\n ? href.slice(searchIndex, hashIndex === -1 ? undefined : hashIndex)\n : '',\n state: state || {},\n }\n}\n\n// Thanks co-pilot!\nfunction createRandomKey() {\n return (Math.random() + 1).toString(36).substring(7)\n}\n"],"names":["pushStateEvent","popStateEvent","beforeUnloadEvent","beforeUnloadListener","event","preventDefault","returnValue","stopBlocking","removeEventListener","capture","createHistory","opts","location","getLocation","subscribers","Set","blockers","queue","onUpdate","forEach","subscriber","tryUnblock","length","shift","queueTask","task","push","subscribe","cb","add","delete","path","state","assignKey","pushState","replace","replaceState","go","index","back","forward","createHref","str","block","addEventListener","filter","b","flush","destroy","update","key","createRandomKey","createBrowserHistory","getHref","window","pathname","search","hash","currentLocation","parseLocation","history","next","tracking","scheduled","untrack","fn","isPush","href","undefined","queueHistoryAction","type","Promise","resolve","then","n","res","apply","arguments","createHashHistory","substring","createMemoryHistory","initialEntries","entries","initialIndex","currentState","Math","min","hashIndex","indexOf","searchIndex","slice","random","toString"],"mappings":"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"}
@@ -8,5 +8,5 @@
8
8
  *
9
9
  * @license MIT
10
10
  */
11
- !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).TanStackHistory={})}(this,(function(e){"use strict";const t="pushstate",r="popstate",n="beforeunload",o=e=>(e.preventDefault(),e.returnValue=""),i=()=>{removeEventListener(n,o,{capture:!0})};function s(e){let t=e.getLocation(),r=()=>{},s=new Set,c=[],h=[];const u=()=>{if(c.length)c[0]?.(u,(()=>{c=[],i()}));else{for(;h.length;)h.shift()?.();e.subscriber||f()}},d=e=>{h.push(e),u()},f=()=>{t=e.getLocation(),s.forEach((e=>e()))};return{get location(){return t},subscribe:t=>(0===s.size&&(r="function"==typeof e.subscriber?e.subscriber(f):()=>{}),s.add(t),()=>{s.delete(t),0===s.size&&r()}),push:(t,r)=>{a(r),d((()=>{e.pushState(t,r,f)}))},replace:(t,r)=>{a(r),d((()=>{e.replaceState(t,r,f)}))},go:t=>{d((()=>{e.go(t)}))},back:()=>{d((()=>{e.back()}))},forward:()=>{d((()=>{e.forward()}))},createHref:t=>e.createHref(t),block:e=>(c.push(e),1===c.length&&addEventListener(n,o,{capture:!0}),()=>{c=c.filter((t=>t!==e)),c.length||i()}),flush:()=>e.flush?.()}}function a(e){e.key=u()}function c(e){const n=e?.getHref??(()=>`${window.location.pathname}${window.location.search}${window.location.hash}`),o=e?.createHref??(e=>e);let i=h(n(),window.history.state);let a,c,u=!0;const d=()=>{u=!1,(()=>{a&&(window.history[a.isPush?"pushState":"replaceState"](a.state,"",a.href),a=void 0,c=void 0)})(),u=!0},f=(e,t,r,n)=>{const s=o(t);i=h(s,r),a={href:s,state:r,isPush:a?.isPush||"push"===e},n(),c||(c=Promise.resolve().then((()=>d())))};return s({getLocation:()=>i,subscriber:e=>{window.addEventListener(t,(()=>{i=h(n(),window.history.state),e()})),window.addEventListener(r,(()=>{i=h(n(),window.history.state),e()}));var o=window.history.pushState;window.history.pushState=function(){let t=o.apply(history,arguments);return u&&e(),t};var s=window.history.replaceState;return window.history.replaceState=function(){let t=s.apply(history,arguments);return u&&e(),t},()=>{window.history.pushState=o,window.history.replaceState=s,window.removeEventListener(t,e),window.removeEventListener(r,e)}},pushState:(e,t,r)=>f("push",e,t,r),replaceState:(e,t,r)=>f("replace",e,t,r),back:()=>window.history.back(),forward:()=>window.history.forward(),go:e=>window.history.go(e),createHref:e=>o(e),flush:d})}function h(e,t){let r=e.indexOf("#"),n=e.indexOf("?");return{href:e,pathname:e.substring(0,r>0?n>0?Math.min(r,n):r:n>0?n:e.length),hash:r>-1?e.substring(r):"",search:n>-1?e.slice(n,-1===r?void 0:r):"",state:t||{}}}function u(){return(Math.random()+1).toString(36).substring(7)}e.createBrowserHistory=c,e.createHashHistory=function(){return c({getHref:()=>window.location.hash.substring(1),createHref:e=>`#${e}`})},e.createMemoryHistory=function(e={initialEntries:["/"]}){const t=e.initialEntries;let r=e.initialIndex??t.length-1,n={key:u()};return s({getLocation:()=>h(t[r],n),subscriber:!1,pushState:(e,o)=>{n=o,t.push(e),r++},replaceState:(e,o)=>{n=o,t[r]=e},back:()=>{r--},forward:()=>{r=Math.min(r+1,t.length-1)},go:e=>window.history.go(e),createHref:e=>e})},Object.defineProperty(e,"__esModule",{value:!0})}));
11
+ !function(e,t){"object"==typeof exports&&"undefined"!=typeof module?t(exports):"function"==typeof define&&define.amd?define(["exports"],t):t((e="undefined"!=typeof globalThis?globalThis:e||self).TanStackHistory={})}(this,(function(e){"use strict";const t="pushstate",o="popstate",n="beforeunload",r=e=>(e.preventDefault(),e.returnValue=""),i=()=>{removeEventListener(n,r,{capture:!0})};function a(e){let t=e.getLocation(),o=new Set,a=[],d=[];const h=()=>{t=e.getLocation(),o.forEach((e=>e()))},u=()=>{if(a.length)a[0]?.(u,(()=>{a=[],i()}));else{for(;d.length;)d.shift()?.();h()}},c=e=>{d.push(e),u()};return{get location(){return t},subscribe:e=>(o.add(e),()=>{o.delete(e)}),push:(t,o)=>{o=s(o),c((()=>{e.pushState(t,o,h)}))},replace:(t,o)=>{o=s(o),c((()=>{e.replaceState(t,o,h)}))},go:t=>{c((()=>{e.go(t)}))},back:()=>{c((()=>{e.back()}))},forward:()=>{c((()=>{e.forward()}))},createHref:t=>e.createHref(t),block:e=>(a.push(e),1===a.length&&addEventListener(n,r,{capture:!0}),()=>{a=a.filter((t=>t!==e)),a.length||i()}),flush:()=>e.flush?.(),destroy:()=>e.destroy?.(),update:h}}function s(e){return e||(e={}),e.key=u(),e}function d(e){const n=e?.getHref??(()=>`${window.location.pathname}${window.location.search}${window.location.hash}`),r=e?.createHref??(e=>e);let i=h(n(),window.history.state);let s,d,u=!0;const c=()=>{u=!1,(()=>{s&&(window.history[s.isPush?"pushState":"replaceState"](s.state,"",s.href),s=void 0,d=void 0)})(),u=!0},w=(e,t,o,n)=>{const a=r(t);i=h(a,o),s={href:a,state:o,isPush:s?.isPush||"push"===e},n(),d||(d=Promise.resolve().then((()=>c())))},l=a({getLocation:()=>i,pushState:(e,t,o)=>w("push",e,t,o),replaceState:(e,t,o)=>w("replace",e,t,o),back:()=>window.history.back(),forward:()=>window.history.forward(),go:e=>window.history.go(e),createHref:e=>r(e),flush:c,destroy:()=>{window.history.pushState=f,window.history.replaceState=p,window.removeEventListener(t,l.update),window.removeEventListener(o,l.update)}});window.addEventListener(t,(()=>{i=h(n(),window.history.state),l.update})),window.addEventListener(o,(()=>{i=h(n(),window.history.state),l.update}));var f=window.history.pushState;window.history.pushState=function(){let e=f.apply(window.history,arguments);return u&&l.update(),e};var p=window.history.replaceState;return window.history.replaceState=function(){let e=p.apply(window.history,arguments);return u&&l.update(),e},l}function h(e,t){let o=e.indexOf("#"),n=e.indexOf("?");return{href:e,pathname:e.substring(0,o>0?n>0?Math.min(o,n):o:n>0?n:e.length),hash:o>-1?e.substring(o):"",search:n>-1?e.slice(n,-1===o?void 0:o):"",state:t||{}}}function u(){return(Math.random()+1).toString(36).substring(7)}e.createBrowserHistory=d,e.createHashHistory=function(){return d({getHref:()=>window.location.hash.substring(1),createHref:e=>`#${e}`})},e.createMemoryHistory=function(e={initialEntries:["/"]}){const t=e.initialEntries;let o=e.initialIndex??t.length-1,n={key:u()};return a({getLocation:()=>h(t[o],n),pushState:(e,r)=>{n=r,t.push(e),o++},replaceState:(e,r)=>{n=r,t[o]=e},back:()=>{o--},forward:()=>{o=Math.min(o+1,t.length-1)},go:e=>window.history.go(e),createHref:e=>e})},Object.defineProperty(e,"__esModule",{value:!0})}));
12
12
  //# sourceMappingURL=index.production.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"index.production.js","sources":["../../src/index.ts"],"sourcesContent":["// While the public API was clearly inspired by the \"history\" npm package,\n// This implementation attempts to be more lightweight by\n// making assumptions about the way TanStack Router works\n\nexport interface RouterHistory {\n location: HistoryLocation\n subscribe: (cb: () => void) => () => void\n push: (path: string, state?: any) => void\n replace: (path: string, state?: any) => void\n go: (index: number) => void\n back: () => void\n forward: () => void\n createHref: (href: string) => string\n block: (blockerFn: BlockerFn) => () => void\n flush: () => void\n}\n\nexport interface HistoryLocation extends ParsedPath {\n state: HistoryState\n}\n\nexport interface ParsedPath {\n href: string\n pathname: string\n search: string\n hash: string\n}\n\nexport interface HistoryState {\n key: string\n __tempLocation?: HistoryLocation\n __tempKey?: string\n}\n\ntype BlockerFn = (retry: () => void, cancel: () => void) => void\n\nconst pushStateEvent = 'pushstate'\nconst popStateEvent = 'popstate'\nconst beforeUnloadEvent = 'beforeunload'\n\nconst beforeUnloadListener = (event: Event) => {\n event.preventDefault()\n // @ts-ignore\n return (event.returnValue = '')\n}\n\nconst stopBlocking = () => {\n removeEventListener(beforeUnloadEvent, beforeUnloadListener, {\n capture: true,\n })\n}\n\nfunction createHistory(opts: {\n getLocation: () => HistoryLocation\n subscriber: false | ((onUpdate: () => void) => () => void)\n pushState: (path: string, state: any, onUpdate: () => void) => void\n replaceState: (path: string, state: any, onUpdate: () => void) => void\n go: (n: number) => void\n back: () => void\n forward: () => void\n createHref: (path: string) => string\n flush?: () => void\n}): RouterHistory {\n let location = opts.getLocation()\n let unsub = () => {}\n let subscribers = new Set<() => void>()\n let blockers: BlockerFn[] = []\n let queue: (() => void)[] = []\n\n const tryFlush = () => {\n if (blockers.length) {\n blockers[0]?.(tryFlush, () => {\n blockers = []\n stopBlocking()\n })\n return\n }\n\n while (queue.length) {\n queue.shift()?.()\n }\n\n if (!opts.subscriber) {\n onUpdate()\n }\n }\n\n const queueTask = (task: () => void) => {\n queue.push(task)\n tryFlush()\n }\n\n const onUpdate = () => {\n location = opts.getLocation()\n subscribers.forEach((subscriber) => subscriber())\n }\n\n return {\n get location() {\n return location\n },\n subscribe: (cb: () => void) => {\n if (subscribers.size === 0) {\n unsub =\n typeof opts.subscriber === 'function'\n ? opts.subscriber(onUpdate)\n : () => {}\n }\n subscribers.add(cb)\n\n return () => {\n subscribers.delete(cb)\n if (subscribers.size === 0) {\n unsub()\n }\n }\n },\n push: (path: string, state: any) => {\n assignKey(state)\n queueTask(() => {\n opts.pushState(path, state, onUpdate)\n })\n },\n replace: (path: string, state: any) => {\n assignKey(state)\n queueTask(() => {\n opts.replaceState(path, state, onUpdate)\n })\n },\n go: (index) => {\n queueTask(() => {\n opts.go(index)\n })\n },\n back: () => {\n queueTask(() => {\n opts.back()\n })\n },\n forward: () => {\n queueTask(() => {\n opts.forward()\n })\n },\n createHref: (str) => opts.createHref(str),\n block: (cb) => {\n blockers.push(cb)\n\n if (blockers.length === 1) {\n addEventListener(beforeUnloadEvent, beforeUnloadListener, {\n capture: true,\n })\n }\n\n return () => {\n blockers = blockers.filter((b) => b !== cb)\n\n if (!blockers.length) {\n stopBlocking()\n }\n }\n },\n flush: () => opts.flush?.(),\n }\n}\n\nfunction assignKey(state: HistoryState) {\n state.key = createRandomKey()\n // if (state.__actualLocation) {\n // state.__actualLocation.state = {\n // ...state.__actualLocation.state,\n // key,\n // }\n // }\n}\n\n/**\n * Creates a history object that can be used to interact with the browser's\n * navigation. This is a lightweight API wrapping the browser's native methods.\n * It is designed to work with TanStack Router, but could be used as a standalone API as well.\n * IMPORTANT: This API implements history throttling via a microtask to prevent\n * excessive calls to the history API. In some browsers, calling history.pushState or\n * history.replaceState in quick succession can cause the browser to ignore subsequent\n * calls. This API smooths out those differences and ensures that your application\n * state will *eventually* match the browser state. In most cases, this is not a problem,\n * but if you need to ensure that the browser state is up to date, you can use the\n * `history.flush` method to immediately flush all pending state changes to the browser URL.\n * @param opts\n * @param opts.getHref A function that returns the current href (path + search + hash)\n * @param opts.createHref A function that takes a path and returns a href (path + search + hash)\n * @returns A history instance\n */\nexport function createBrowserHistory(opts?: {\n getHref?: () => string\n createHref?: (path: string) => string\n}): RouterHistory {\n const getHref =\n opts?.getHref ??\n (() =>\n `${window.location.pathname}${window.location.search}${window.location.hash}`)\n\n const createHref = opts?.createHref ?? ((path) => path)\n\n let currentLocation = parseLocation(getHref(), window.history.state)\n\n const getLocation = () => currentLocation\n\n let next:\n | undefined\n | {\n // This is the latest location that we were attempting to push/replace\n href: string\n // This is the latest state that we were attempting to push/replace\n state: any\n // This is the latest type that we were attempting to push/replace\n isPush: boolean\n }\n\n // Because we are proactively updating the location\n // in memory before actually updating the browser history,\n // we need to track when we are doing this so we don't\n // notify subscribers twice on the last update.\n let tracking = true\n\n // We need to track the current scheduled update to prevent\n // multiple updates from being scheduled at the same time.\n let scheduled: Promise<void> | undefined\n\n // This function is a wrapper to prevent any of the callback's\n // side effects from causing a subscriber notification\n const untrack = (fn: () => void) => {\n tracking = false\n fn()\n tracking = true\n }\n\n // This function flushes the next update to the browser history\n const flush = () => {\n // Do not notify subscribers about this push/replace call\n untrack(() => {\n if (!next) return\n window.history[next.isPush ? 'pushState' : 'replaceState'](\n next.state,\n '',\n next.href,\n )\n // Reset the nextIsPush flag and clear the scheduled update\n next = undefined\n scheduled = undefined\n })\n }\n\n // This function queues up a call to update the browser history\n const queueHistoryAction = (\n type: 'push' | 'replace',\n path: string,\n state: any,\n onUpdate: () => void,\n ) => {\n const href = createHref(path)\n\n // Update the location in memory\n currentLocation = parseLocation(href, state)\n\n // Keep track of the next location we need to flush to the URL\n next = {\n href,\n state,\n isPush: next?.isPush || type === 'push',\n }\n // Notify subscribers\n onUpdate()\n\n if (!scheduled) {\n // Schedule an update to the browser history\n scheduled = Promise.resolve().then(() => flush())\n }\n }\n\n return createHistory({\n getLocation,\n subscriber: (onUpdate) => {\n window.addEventListener(pushStateEvent, () => {\n currentLocation = parseLocation(getHref(), window.history.state)\n onUpdate()\n })\n window.addEventListener(popStateEvent, () => {\n currentLocation = parseLocation(getHref(), window.history.state)\n onUpdate()\n })\n\n var pushState = window.history.pushState\n window.history.pushState = function () {\n let res = pushState.apply(history, arguments as any)\n if (tracking) onUpdate()\n return res\n }\n var replaceState = window.history.replaceState\n window.history.replaceState = function () {\n let res = replaceState.apply(history, arguments as any)\n if (tracking) onUpdate()\n return res\n }\n\n return () => {\n window.history.pushState = pushState\n window.history.replaceState = replaceState\n window.removeEventListener(pushStateEvent, onUpdate)\n window.removeEventListener(popStateEvent, onUpdate)\n }\n },\n pushState: (path, state, onUpdate) =>\n queueHistoryAction('push', path, state, onUpdate),\n replaceState: (path, state, onUpdate) =>\n queueHistoryAction('replace', path, state, onUpdate),\n back: () => window.history.back(),\n forward: () => window.history.forward(),\n go: (n) => window.history.go(n),\n createHref: (path) => createHref(path),\n flush,\n })\n}\n\nexport function createHashHistory(): RouterHistory {\n return createBrowserHistory({\n getHref: () => window.location.hash.substring(1),\n createHref: (path) => `#${path}`,\n })\n}\n\nexport function createMemoryHistory(\n opts: {\n initialEntries: string[]\n initialIndex?: number\n } = {\n initialEntries: ['/'],\n },\n): RouterHistory {\n const entries = opts.initialEntries\n let index = opts.initialIndex ?? entries.length - 1\n let currentState = {\n key: createRandomKey(),\n } as HistoryState\n\n const getLocation = () => parseLocation(entries[index]!, currentState)\n\n return createHistory({\n getLocation,\n subscriber: false,\n pushState: (path, state) => {\n currentState = state\n entries.push(path)\n index++\n },\n replaceState: (path, state) => {\n currentState = state\n entries[index] = path\n },\n back: () => {\n index--\n },\n forward: () => {\n index = Math.min(index + 1, entries.length - 1)\n },\n go: (n) => window.history.go(n),\n createHref: (path) => path,\n })\n}\n\nfunction parseLocation(href: string, state: HistoryState): HistoryLocation {\n let hashIndex = href.indexOf('#')\n let searchIndex = href.indexOf('?')\n\n return {\n href,\n pathname: href.substring(\n 0,\n hashIndex > 0\n ? searchIndex > 0\n ? Math.min(hashIndex, searchIndex)\n : hashIndex\n : searchIndex > 0\n ? searchIndex\n : href.length,\n ),\n hash: hashIndex > -1 ? href.substring(hashIndex) : '',\n search:\n searchIndex > -1\n ? href.slice(searchIndex, hashIndex === -1 ? undefined : hashIndex)\n : '',\n state: state || {},\n }\n}\n\n// Thanks co-pilot!\nfunction createRandomKey() {\n return (Math.random() + 1).toString(36).substring(7)\n}\n"],"names":["pushStateEvent","popStateEvent","beforeUnloadEvent","beforeUnloadListener","event","preventDefault","returnValue","stopBlocking","removeEventListener","capture","createHistory","opts","location","getLocation","unsub","subscribers","Set","blockers","queue","tryFlush","length","shift","subscriber","onUpdate","queueTask","task","push","forEach","subscribe","cb","size","add","delete","path","state","assignKey","pushState","replace","replaceState","go","index","back","forward","createHref","str","block","addEventListener","filter","b","flush","key","createRandomKey","createBrowserHistory","getHref","window","pathname","search","hash","currentLocation","parseLocation","history","next","scheduled","tracking","isPush","href","undefined","fn","queueHistoryAction","type","Promise","resolve","then","res","apply","arguments","n","hashIndex","indexOf","searchIndex","substring","Math","min","slice","random","toString","initialEntries","entries","initialIndex","currentState"],"mappings":"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"}
1
+ {"version":3,"file":"index.production.js","sources":["../../src/index.ts"],"sourcesContent":["// While the public API was clearly inspired by the \"history\" npm package,\n// This implementation attempts to be more lightweight by\n// making assumptions about the way TanStack Router works\n\nexport interface RouterHistory {\n location: HistoryLocation\n subscribe: (cb: () => void) => () => void\n push: (path: string, state?: any) => void\n replace: (path: string, state?: any) => void\n go: (index: number) => void\n back: () => void\n forward: () => void\n createHref: (href: string) => string\n block: (blockerFn: BlockerFn) => () => void\n flush: () => void\n destroy: () => void\n update: () => void\n}\n\nexport interface HistoryLocation extends ParsedPath {\n state: HistoryState\n}\n\nexport interface ParsedPath {\n href: string\n pathname: string\n search: string\n hash: string\n}\n\nexport interface HistoryState {\n key: string\n}\n\ntype BlockerFn = (retry: () => void, cancel: () => void) => void\n\nconst pushStateEvent = 'pushstate'\nconst popStateEvent = 'popstate'\nconst beforeUnloadEvent = 'beforeunload'\n\nconst beforeUnloadListener = (event: Event) => {\n event.preventDefault()\n // @ts-ignore\n return (event.returnValue = '')\n}\n\nconst stopBlocking = () => {\n removeEventListener(beforeUnloadEvent, beforeUnloadListener, {\n capture: true,\n })\n}\n\nfunction createHistory(opts: {\n getLocation: () => HistoryLocation\n pushState: (path: string, state: any, onUpdate: () => void) => void\n replaceState: (path: string, state: any, onUpdate: () => void) => void\n go: (n: number) => void\n back: () => void\n forward: () => void\n createHref: (path: string) => string\n flush?: () => void\n destroy?: () => void\n}): RouterHistory {\n let location = opts.getLocation()\n let subscribers = new Set<() => void>()\n let blockers: BlockerFn[] = []\n let queue: (() => void)[] = []\n\n const onUpdate = () => {\n location = opts.getLocation()\n subscribers.forEach((subscriber) => subscriber())\n }\n\n const tryUnblock = () => {\n if (blockers.length) {\n blockers[0]?.(tryUnblock, () => {\n blockers = []\n stopBlocking()\n })\n return\n }\n\n while (queue.length) {\n queue.shift()?.()\n }\n\n onUpdate()\n }\n\n const queueTask = (task: () => void) => {\n queue.push(task)\n tryUnblock()\n }\n\n return {\n get location() {\n return location\n },\n subscribe: (cb: () => void) => {\n subscribers.add(cb)\n\n return () => {\n subscribers.delete(cb)\n }\n },\n push: (path: string, state: any) => {\n state = assignKey(state)\n queueTask(() => {\n opts.pushState(path, state, onUpdate)\n })\n },\n replace: (path: string, state: any) => {\n state = assignKey(state)\n queueTask(() => {\n opts.replaceState(path, state, onUpdate)\n })\n },\n go: (index) => {\n queueTask(() => {\n opts.go(index)\n })\n },\n back: () => {\n queueTask(() => {\n opts.back()\n })\n },\n forward: () => {\n queueTask(() => {\n opts.forward()\n })\n },\n createHref: (str) => opts.createHref(str),\n block: (cb) => {\n blockers.push(cb)\n\n if (blockers.length === 1) {\n addEventListener(beforeUnloadEvent, beforeUnloadListener, {\n capture: true,\n })\n }\n\n return () => {\n blockers = blockers.filter((b) => b !== cb)\n\n if (!blockers.length) {\n stopBlocking()\n }\n }\n },\n flush: () => opts.flush?.(),\n destroy: () => opts.destroy?.(),\n update: onUpdate,\n }\n}\n\nfunction assignKey(state: HistoryState) {\n if (!state) {\n state = {} as HistoryState\n }\n state.key = createRandomKey()\n return state\n}\n\n/**\n * Creates a history object that can be used to interact with the browser's\n * navigation. This is a lightweight API wrapping the browser's native methods.\n * It is designed to work with TanStack Router, but could be used as a standalone API as well.\n * IMPORTANT: This API implements history throttling via a microtask to prevent\n * excessive calls to the history API. In some browsers, calling history.pushState or\n * history.replaceState in quick succession can cause the browser to ignore subsequent\n * calls. This API smooths out those differences and ensures that your application\n * state will *eventually* match the browser state. In most cases, this is not a problem,\n * but if you need to ensure that the browser state is up to date, you can use the\n * `history.flush` method to immediately flush all pending state changes to the browser URL.\n * @param opts\n * @param opts.getHref A function that returns the current href (path + search + hash)\n * @param opts.createHref A function that takes a path and returns a href (path + search + hash)\n * @returns A history instance\n */\nexport function createBrowserHistory(opts?: {\n getHref?: () => string\n createHref?: (path: string) => string\n}): RouterHistory {\n const getHref =\n opts?.getHref ??\n (() =>\n `${window.location.pathname}${window.location.search}${window.location.hash}`)\n\n const createHref = opts?.createHref ?? ((path) => path)\n\n let currentLocation = parseLocation(getHref(), window.history.state)\n\n const getLocation = () => currentLocation\n\n let next:\n | undefined\n | {\n // This is the latest location that we were attempting to push/replace\n href: string\n // This is the latest state that we were attempting to push/replace\n state: any\n // This is the latest type that we were attempting to push/replace\n isPush: boolean\n }\n\n // Because we are proactively updating the location\n // in memory before actually updating the browser history,\n // we need to track when we are doing this so we don't\n // notify subscribers twice on the last update.\n let tracking = true\n\n // We need to track the current scheduled update to prevent\n // multiple updates from being scheduled at the same time.\n let scheduled: Promise<void> | undefined\n\n // This function is a wrapper to prevent any of the callback's\n // side effects from causing a subscriber notification\n const untrack = (fn: () => void) => {\n tracking = false\n fn()\n tracking = true\n }\n\n // This function flushes the next update to the browser history\n const flush = () => {\n // Do not notify subscribers about this push/replace call\n untrack(() => {\n if (!next) return\n window.history[next.isPush ? 'pushState' : 'replaceState'](\n next.state,\n '',\n next.href,\n )\n // Reset the nextIsPush flag and clear the scheduled update\n next = undefined\n scheduled = undefined\n })\n }\n\n // This function queues up a call to update the browser history\n const queueHistoryAction = (\n type: 'push' | 'replace',\n path: string,\n state: any,\n onUpdate: () => void,\n ) => {\n const href = createHref(path)\n\n // Update the location in memory\n currentLocation = parseLocation(href, state)\n\n // Keep track of the next location we need to flush to the URL\n next = {\n href,\n state,\n isPush: next?.isPush || type === 'push',\n }\n // Notify subscribers\n onUpdate()\n\n if (!scheduled) {\n // Schedule an update to the browser history\n scheduled = Promise.resolve().then(() => flush())\n }\n }\n\n const history = createHistory({\n getLocation,\n pushState: (path, state, onUpdate) =>\n queueHistoryAction('push', path, state, onUpdate),\n replaceState: (path, state, onUpdate) =>\n queueHistoryAction('replace', path, state, onUpdate),\n back: () => window.history.back(),\n forward: () => window.history.forward(),\n go: (n) => window.history.go(n),\n createHref: (path) => createHref(path),\n flush,\n destroy: () => {\n window.history.pushState = pushState\n window.history.replaceState = replaceState\n window.removeEventListener(pushStateEvent, history.update)\n window.removeEventListener(popStateEvent, history.update)\n },\n })\n\n window.addEventListener(pushStateEvent, () => {\n currentLocation = parseLocation(getHref(), window.history.state)\n history.update\n })\n window.addEventListener(popStateEvent, () => {\n currentLocation = parseLocation(getHref(), window.history.state)\n history.update\n })\n\n var pushState = window.history.pushState\n window.history.pushState = function () {\n let res = pushState.apply(window.history, arguments as any)\n if (tracking) history.update()\n return res\n }\n var replaceState = window.history.replaceState\n window.history.replaceState = function () {\n let res = replaceState.apply(window.history, arguments as any)\n if (tracking) history.update()\n return res\n }\n\n return history\n}\n\nexport function createHashHistory(): RouterHistory {\n return createBrowserHistory({\n getHref: () => window.location.hash.substring(1),\n createHref: (path) => `#${path}`,\n })\n}\n\nexport function createMemoryHistory(\n opts: {\n initialEntries: string[]\n initialIndex?: number\n } = {\n initialEntries: ['/'],\n },\n): RouterHistory {\n const entries = opts.initialEntries\n let index = opts.initialIndex ?? entries.length - 1\n let currentState = {\n key: createRandomKey(),\n } as HistoryState\n\n const getLocation = () => parseLocation(entries[index]!, currentState)\n\n return createHistory({\n getLocation,\n pushState: (path, state) => {\n currentState = state\n entries.push(path)\n index++\n },\n replaceState: (path, state) => {\n currentState = state\n entries[index] = path\n },\n back: () => {\n index--\n },\n forward: () => {\n index = Math.min(index + 1, entries.length - 1)\n },\n go: (n) => window.history.go(n),\n createHref: (path) => path,\n })\n}\n\nfunction parseLocation(href: string, state: HistoryState): HistoryLocation {\n let hashIndex = href.indexOf('#')\n let searchIndex = href.indexOf('?')\n\n return {\n href,\n pathname: href.substring(\n 0,\n hashIndex > 0\n ? searchIndex > 0\n ? Math.min(hashIndex, searchIndex)\n : hashIndex\n : searchIndex > 0\n ? searchIndex\n : href.length,\n ),\n hash: hashIndex > -1 ? href.substring(hashIndex) : '',\n search:\n searchIndex > -1\n ? href.slice(searchIndex, hashIndex === -1 ? undefined : hashIndex)\n : '',\n state: state || {},\n }\n}\n\n// Thanks co-pilot!\nfunction createRandomKey() {\n return (Math.random() + 1).toString(36).substring(7)\n}\n"],"names":["pushStateEvent","popStateEvent","beforeUnloadEvent","beforeUnloadListener","event","preventDefault","returnValue","stopBlocking","removeEventListener","capture","createHistory","opts","location","getLocation","subscribers","Set","blockers","queue","onUpdate","forEach","subscriber","tryUnblock","length","shift","queueTask","task","push","subscribe","cb","add","delete","path","state","assignKey","pushState","replace","replaceState","go","index","back","forward","createHref","str","block","addEventListener","filter","b","flush","destroy","update","key","createRandomKey","createBrowserHistory","getHref","window","pathname","search","hash","currentLocation","parseLocation","history","next","scheduled","tracking","isPush","href","undefined","fn","queueHistoryAction","type","Promise","resolve","then","n","res","apply","arguments","hashIndex","indexOf","searchIndex","substring","Math","min","slice","random","toString","initialEntries","entries","initialIndex","currentState"],"mappings":"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"}
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@tanstack/history",
3
3
  "author": "Tanner Linsley",
4
- "version": "0.0.1-beta.193",
4
+ "version": "0.0.1-beta.197",
5
5
  "license": "MIT",
6
6
  "repository": "tanstack/history",
7
7
  "homepage": "https://tanstack.com",
package/src/index.ts CHANGED
@@ -13,6 +13,8 @@ export interface RouterHistory {
13
13
  createHref: (href: string) => string
14
14
  block: (blockerFn: BlockerFn) => () => void
15
15
  flush: () => void
16
+ destroy: () => void
17
+ update: () => void
16
18
  }
17
19
 
18
20
  export interface HistoryLocation extends ParsedPath {
@@ -28,8 +30,6 @@ export interface ParsedPath {
28
30
 
29
31
  export interface HistoryState {
30
32
  key: string
31
- __tempLocation?: HistoryLocation
32
- __tempKey?: string
33
33
  }
34
34
 
35
35
  type BlockerFn = (retry: () => void, cancel: () => void) => void
@@ -52,7 +52,6 @@ const stopBlocking = () => {
52
52
 
53
53
  function createHistory(opts: {
54
54
  getLocation: () => HistoryLocation
55
- subscriber: false | ((onUpdate: () => void) => () => void)
56
55
  pushState: (path: string, state: any, onUpdate: () => void) => void
57
56
  replaceState: (path: string, state: any, onUpdate: () => void) => void
58
57
  go: (n: number) => void
@@ -60,16 +59,21 @@ function createHistory(opts: {
60
59
  forward: () => void
61
60
  createHref: (path: string) => string
62
61
  flush?: () => void
62
+ destroy?: () => void
63
63
  }): RouterHistory {
64
64
  let location = opts.getLocation()
65
- let unsub = () => {}
66
65
  let subscribers = new Set<() => void>()
67
66
  let blockers: BlockerFn[] = []
68
67
  let queue: (() => void)[] = []
69
68
 
70
- const tryFlush = () => {
69
+ const onUpdate = () => {
70
+ location = opts.getLocation()
71
+ subscribers.forEach((subscriber) => subscriber())
72
+ }
73
+
74
+ const tryUnblock = () => {
71
75
  if (blockers.length) {
72
- blockers[0]?.(tryFlush, () => {
76
+ blockers[0]?.(tryUnblock, () => {
73
77
  blockers = []
74
78
  stopBlocking()
75
79
  })
@@ -80,19 +84,12 @@ function createHistory(opts: {
80
84
  queue.shift()?.()
81
85
  }
82
86
 
83
- if (!opts.subscriber) {
84
- onUpdate()
85
- }
87
+ onUpdate()
86
88
  }
87
89
 
88
90
  const queueTask = (task: () => void) => {
89
91
  queue.push(task)
90
- tryFlush()
91
- }
92
-
93
- const onUpdate = () => {
94
- location = opts.getLocation()
95
- subscribers.forEach((subscriber) => subscriber())
92
+ tryUnblock()
96
93
  }
97
94
 
98
95
  return {
@@ -100,29 +97,20 @@ function createHistory(opts: {
100
97
  return location
101
98
  },
102
99
  subscribe: (cb: () => void) => {
103
- if (subscribers.size === 0) {
104
- unsub =
105
- typeof opts.subscriber === 'function'
106
- ? opts.subscriber(onUpdate)
107
- : () => {}
108
- }
109
100
  subscribers.add(cb)
110
101
 
111
102
  return () => {
112
103
  subscribers.delete(cb)
113
- if (subscribers.size === 0) {
114
- unsub()
115
- }
116
104
  }
117
105
  },
118
106
  push: (path: string, state: any) => {
119
- assignKey(state)
107
+ state = assignKey(state)
120
108
  queueTask(() => {
121
109
  opts.pushState(path, state, onUpdate)
122
110
  })
123
111
  },
124
112
  replace: (path: string, state: any) => {
125
- assignKey(state)
113
+ state = assignKey(state)
126
114
  queueTask(() => {
127
115
  opts.replaceState(path, state, onUpdate)
128
116
  })
@@ -161,17 +149,17 @@ function createHistory(opts: {
161
149
  }
162
150
  },
163
151
  flush: () => opts.flush?.(),
152
+ destroy: () => opts.destroy?.(),
153
+ update: onUpdate,
164
154
  }
165
155
  }
166
156
 
167
157
  function assignKey(state: HistoryState) {
158
+ if (!state) {
159
+ state = {} as HistoryState
160
+ }
168
161
  state.key = createRandomKey()
169
- // if (state.__actualLocation) {
170
- // state.__actualLocation.state = {
171
- // ...state.__actualLocation.state,
172
- // key,
173
- // }
174
- // }
162
+ return state
175
163
  }
176
164
 
177
165
  /**
@@ -277,38 +265,8 @@ export function createBrowserHistory(opts?: {
277
265
  }
278
266
  }
279
267
 
280
- return createHistory({
268
+ const history = createHistory({
281
269
  getLocation,
282
- subscriber: (onUpdate) => {
283
- window.addEventListener(pushStateEvent, () => {
284
- currentLocation = parseLocation(getHref(), window.history.state)
285
- onUpdate()
286
- })
287
- window.addEventListener(popStateEvent, () => {
288
- currentLocation = parseLocation(getHref(), window.history.state)
289
- onUpdate()
290
- })
291
-
292
- var pushState = window.history.pushState
293
- window.history.pushState = function () {
294
- let res = pushState.apply(history, arguments as any)
295
- if (tracking) onUpdate()
296
- return res
297
- }
298
- var replaceState = window.history.replaceState
299
- window.history.replaceState = function () {
300
- let res = replaceState.apply(history, arguments as any)
301
- if (tracking) onUpdate()
302
- return res
303
- }
304
-
305
- return () => {
306
- window.history.pushState = pushState
307
- window.history.replaceState = replaceState
308
- window.removeEventListener(pushStateEvent, onUpdate)
309
- window.removeEventListener(popStateEvent, onUpdate)
310
- }
311
- },
312
270
  pushState: (path, state, onUpdate) =>
313
271
  queueHistoryAction('push', path, state, onUpdate),
314
272
  replaceState: (path, state, onUpdate) =>
@@ -318,7 +276,37 @@ export function createBrowserHistory(opts?: {
318
276
  go: (n) => window.history.go(n),
319
277
  createHref: (path) => createHref(path),
320
278
  flush,
279
+ destroy: () => {
280
+ window.history.pushState = pushState
281
+ window.history.replaceState = replaceState
282
+ window.removeEventListener(pushStateEvent, history.update)
283
+ window.removeEventListener(popStateEvent, history.update)
284
+ },
285
+ })
286
+
287
+ window.addEventListener(pushStateEvent, () => {
288
+ currentLocation = parseLocation(getHref(), window.history.state)
289
+ history.update
290
+ })
291
+ window.addEventListener(popStateEvent, () => {
292
+ currentLocation = parseLocation(getHref(), window.history.state)
293
+ history.update
321
294
  })
295
+
296
+ var pushState = window.history.pushState
297
+ window.history.pushState = function () {
298
+ let res = pushState.apply(window.history, arguments as any)
299
+ if (tracking) history.update()
300
+ return res
301
+ }
302
+ var replaceState = window.history.replaceState
303
+ window.history.replaceState = function () {
304
+ let res = replaceState.apply(window.history, arguments as any)
305
+ if (tracking) history.update()
306
+ return res
307
+ }
308
+
309
+ return history
322
310
  }
323
311
 
324
312
  export function createHashHistory(): RouterHistory {
@@ -346,7 +334,6 @@ export function createMemoryHistory(
346
334
 
347
335
  return createHistory({
348
336
  getLocation,
349
- subscriber: false,
350
337
  pushState: (path, state) => {
351
338
  currentState = state
352
339
  entries.push(path)