@buildwithdarsh/historyjs 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
package/README.md ADDED
@@ -0,0 +1,250 @@
1
+ # HistoryJS
2
+
3
+ A modern, typed, framework-agnostic wrapper over the browser History API. The 2026 successor to [browserstate/history.js](https://github.com/browserstate/history.js/).
4
+
5
+ [![npm](https://img.shields.io/badge/npm-v1.0.0-bf5af2)](https://www.npmjs.com/package/@buildwithdarsh/historyjs)
6
+ [![bundle](https://img.shields.io/badge/gzipped-~3KB-2997ff)](#)
7
+ [![license](https://img.shields.io/badge/license-MIT-30d158)](LICENSE)
8
+ [![types](https://img.shields.io/badge/TypeScript-first-2997ff)](#)
9
+
10
+ The original `history.js` shipped in 2010 to paper over the HTML4/HTML5 split. Every browser worth supporting today implements `pushState`/`popstate` natively, so this rewrite drops the HTML4 fallback, the jQuery/MooTools/Prototype adapters, and the global `History` namespace — and gives you what apps actually want now: typed entries, async navigation guards, query helpers, route matching, link interception, and a virtual stack.
11
+
12
+ ## Install
13
+
14
+ ```bash
15
+ npm install @buildwithdarsh/historyjs
16
+ # or
17
+ pnpm add @buildwithdarsh/historyjs
18
+ # or
19
+ yarn add @buildwithdarsh/historyjs
20
+ ```
21
+
22
+ Or via CDN:
23
+
24
+ ```html
25
+ <script src="https://unpkg.com/@buildwithdarsh/historyjs"></script>
26
+ ```
27
+
28
+ ## Quick start
29
+
30
+ ```ts
31
+ import { getHistory } from '@buildwithdarsh/historyjs';
32
+
33
+ type AppState = { view: 'home' | 'profile'; userId?: string };
34
+
35
+ const history = getHistory<AppState>();
36
+
37
+ history.subscribe((event) => {
38
+ console.log(event.type, '→', event.to.location.pathname, event.to.state);
39
+ });
40
+
41
+ await history.push('/profile/42', { state: { view: 'profile', userId: '42' } });
42
+ history.back();
43
+ ```
44
+
45
+ ## Why a rewrite?
46
+
47
+ | Original `history.js` (2010) | `@buildwithdarsh/historyjs` (2026) |
48
+ | ----------------------------------------- | ----------------------------------- |
49
+ | HTML4 hashchange fallback | Native History API only |
50
+ | jQuery / MooTools / Prototype adapters | Zero dependencies |
51
+ | Global `History` namespace, untyped state | TypeScript-first, generic state |
52
+ | Event-name strings (`statechange`) | Typed `NavigationEvent` callbacks |
53
+ | No navigation guards | Async guards with cancellation |
54
+ | Manual query/hash building | `setQuery`, `setHash`, `getQuery` |
55
+ | No routing primitives | Built-in pattern matcher |
56
+ | Manual `<a>` interception | `interceptLinks(history)` |
57
+ | Manual scroll handling | Built-in scroll restoration |
58
+
59
+ ## Core concepts
60
+
61
+ ### Entries
62
+
63
+ Every navigation produces a typed `HistoryEntry<TState>`:
64
+
65
+ ```ts
66
+ {
67
+ id: string; // stable, survives reload
68
+ state: TState | null; // your typed state
69
+ title: string;
70
+ location: { pathname, search, hash, href, origin };
71
+ index: number; // monotonic
72
+ timestamp: number; // Date.now() at navigation
73
+ }
74
+ ```
75
+
76
+ ### Navigation
77
+
78
+ ```ts
79
+ await history.push('/path', { state: {...}, title: 'New title' });
80
+ await history.replace('/path');
81
+ history.back(); // or history.back(2)
82
+ history.forward();
83
+ history.go(-3);
84
+ history.reload();
85
+ ```
86
+
87
+ `push` and `replace` are async because guards may be async. They resolve to `true` if the navigation completed, `false` if it was cancelled.
88
+
89
+ ### Listeners
90
+
91
+ ```ts
92
+ const unsubscribe = history.subscribe((event) => {
93
+ // event.type: 'push' | 'replace' | 'pop'
94
+ // event.direction: 'forward' | 'backward' | 'none'
95
+ // event.from / event.to: HistoryEntry
96
+ // event.isPopState: true if triggered by browser back/forward
97
+ });
98
+
99
+ unsubscribe();
100
+ ```
101
+
102
+ ### Guards
103
+
104
+ Guards run before every navigation. Return `false` to cancel.
105
+
106
+ ```ts
107
+ history.addGuard(async (event) => {
108
+ if (event.to.location.pathname.startsWith('/admin')) {
109
+ return await checkAuth();
110
+ }
111
+ });
112
+
113
+ // Or just prompt the user:
114
+ history.block('You have unsaved changes — leave anyway?');
115
+ ```
116
+
117
+ For pop navigations, a cancelled guard attempts to push the user back via `history.go(delta)`.
118
+
119
+ ### Query helpers
120
+
121
+ ```ts
122
+ history.setQuery({ page: 2, q: 'hello' }); // patch params
123
+ history.setQuery({ page: null }); // remove a key
124
+ history.getQuery('page'); // '2'
125
+ history.searchParams; // URLSearchParams (read-only)
126
+ ```
127
+
128
+ Or use the standalone helpers:
129
+
130
+ ```ts
131
+ import { parseQuery, stringifyQuery, mergeQuery } from '@buildwithdarsh/historyjs';
132
+ ```
133
+
134
+ ### Route matching
135
+
136
+ ```ts
137
+ import { matchPattern, buildPath } from '@buildwithdarsh/historyjs';
138
+
139
+ history.matches<{ id: string }>('/users/:id');
140
+ // → { pattern: '/users/:id', path: '/users/42', params: { id: '42' } }
141
+
142
+ buildPath('/users/:id', { id: 42 });
143
+ // → '/users/42'
144
+ ```
145
+
146
+ Supported syntax:
147
+ - `:name` — named param, matches a single segment
148
+ - `:name?` — optional segment
149
+ - `:name*` — splat, matches the rest including slashes
150
+
151
+ ### Link interception
152
+
153
+ One call hijacks every same-origin `<a>` click. Modifier-clicks, off-origin links, download links, and links with `target` pass through unchanged.
154
+
155
+ ```ts
156
+ import { interceptLinks } from '@buildwithdarsh/historyjs';
157
+
158
+ const off = interceptLinks(history);
159
+ // Optional config:
160
+ interceptLinks(history, {
161
+ selector: 'a[data-spa]',
162
+ root: document.getElementById('app'),
163
+ sameOriginOnly: true,
164
+ });
165
+ ```
166
+
167
+ ### Virtual stack
168
+
169
+ `history.entries` is an in-memory snapshot of every entry the manager has visited — great for breadcrumbs, history menus, or analytics.
170
+
171
+ ```ts
172
+ history.entries.forEach((entry) => {
173
+ console.log(entry.index, entry.location.href, entry.timestamp);
174
+ });
175
+ ```
176
+
177
+ ### Metrics
178
+
179
+ ```ts
180
+ history.metrics; // { pushes, replaces, pops, cancelled }
181
+ ```
182
+
183
+ ### Scroll restoration
184
+
185
+ Enabled by default on pop navigations. To opt out:
186
+
187
+ ```ts
188
+ const history = getHistory({ restoreScrollOnPop: false });
189
+ ```
190
+
191
+ The library sets `history.scrollRestoration = 'manual'` by default — pass `scrollRestoration: 'auto'` or `false` to opt out.
192
+
193
+ ### Singleton vs. instance
194
+
195
+ `getHistory()` is a lazy singleton — convenient for app code. For tests or iframes, instantiate directly:
196
+
197
+ ```ts
198
+ import { HistoryManager } from '@buildwithdarsh/historyjs';
199
+ const history = new HistoryManager({ window: iframe.contentWindow! });
200
+ ```
201
+
202
+ ## React example
203
+
204
+ ```tsx
205
+ import { useEffect, useState, useSyncExternalStore } from 'react';
206
+ import { getHistory } from '@buildwithdarsh/historyjs';
207
+
208
+ const history = getHistory<{ page: string }>();
209
+
210
+ export function useHistoryEntry() {
211
+ return useSyncExternalStore(
212
+ (cb) => history.subscribe(cb),
213
+ () => history.entry,
214
+ );
215
+ }
216
+ ```
217
+
218
+ ## Demo
219
+
220
+ A full live playground (the page in `example/index.html`) is deployed at the project URL — push, replace, back/forward, query patching, route matching, guards, link interception, virtual stack, and a real-time event log are all wired up.
221
+
222
+ To run locally:
223
+
224
+ ```bash
225
+ npm install
226
+ npm run build
227
+ npx serve example
228
+ ```
229
+
230
+ ## Development
231
+
232
+ ```bash
233
+ npm install
234
+ npm run typecheck # tsc --noEmit
235
+ npm test # vitest run
236
+ npm run build # rollup → dist/
237
+ npm run dev # rollup --watch
238
+ ```
239
+
240
+ ## Publishing
241
+
242
+ ```bash
243
+ npm publish --access public
244
+ ```
245
+
246
+ The `prepublishOnly` script runs typecheck, tests, and the rollup build.
247
+
248
+ ## License
249
+
250
+ MIT
@@ -0,0 +1,216 @@
1
+ type NavigationType = 'push' | 'replace' | 'pop';
2
+ type NavigationDirection = 'forward' | 'backward' | 'none';
3
+ interface HistoryLocation {
4
+ pathname: string;
5
+ search: string;
6
+ hash: string;
7
+ href: string;
8
+ origin: string;
9
+ }
10
+ interface HistoryEntry<TState = unknown> {
11
+ /** Stable id assigned per entry — survives reload of the same entry. */
12
+ id: string;
13
+ /** Application state attached to the entry. */
14
+ state: TState | null;
15
+ /** Document title at the time of navigation. */
16
+ title: string;
17
+ /** Snapshot of the URL parts. */
18
+ location: HistoryLocation;
19
+ /** Monotonic index relative to library initialization (best-effort). */
20
+ index: number;
21
+ /** Wall-clock timestamp the entry was visited. */
22
+ timestamp: number;
23
+ }
24
+ interface NavigationEvent<TState = unknown> {
25
+ type: NavigationType;
26
+ direction: NavigationDirection;
27
+ from: HistoryEntry<TState> | null;
28
+ to: HistoryEntry<TState>;
29
+ /** Truthy when triggered by browser back/forward, false for programmatic. */
30
+ isPopState: boolean;
31
+ }
32
+ type Listener<TState = unknown> = (event: NavigationEvent<TState>) => void;
33
+ type Unsubscribe = () => void;
34
+ /** Return false (or a Promise resolving to false) to cancel a navigation. */
35
+ type NavigationGuard<TState = unknown> = (event: NavigationEvent<TState>) => boolean | void | Promise<boolean | void>;
36
+ interface NavigateOptions<TState = unknown> {
37
+ state?: TState | null;
38
+ title?: string;
39
+ /** Use replaceState instead of pushState. */
40
+ replace?: boolean;
41
+ /** Skip guards — useful for programmatic redirects from inside a guard. */
42
+ force?: boolean;
43
+ /** Scroll to top after navigation. Default: true for push, false for replace. */
44
+ scrollToTop?: boolean;
45
+ }
46
+ interface HistoryManagerOptions {
47
+ /** Override window — useful for testing or iframe scenarios. */
48
+ window?: Window;
49
+ /** Control native `history.scrollRestoration`. Defaults to 'manual'. */
50
+ scrollRestoration?: 'auto' | 'manual' | false;
51
+ /** Restore scroll position on pop navigations. Defaults to true. */
52
+ restoreScrollOnPop?: boolean;
53
+ /** Max entries to retain in the in-memory stack. Defaults to 100. */
54
+ maxStackSize?: number;
55
+ }
56
+ type QueryValue = string | number | boolean | null | undefined;
57
+ type QueryInput = Record<string, QueryValue | QueryValue[]>;
58
+ interface RouteMatch<TParams extends Record<string, string> = Record<string, string>> {
59
+ pattern: string;
60
+ path: string;
61
+ params: TParams;
62
+ }
63
+ interface LinkInterceptorOptions {
64
+ /** CSS selector to limit which anchors are intercepted. Default: 'a[href]'. */
65
+ selector?: string;
66
+ /** Root element to attach the listener to. Default: document. */
67
+ root?: Document | HTMLElement;
68
+ /** Skip anchors whose `target` is set (e.g. _blank). Default: true. */
69
+ respectTarget?: boolean;
70
+ /** Skip anchors that point off-origin. Default: true. */
71
+ sameOriginOnly?: boolean;
72
+ /** Skip download links. Default: true. */
73
+ skipDownloads?: boolean;
74
+ }
75
+
76
+ declare class HistoryManager<TState = unknown> {
77
+ /** @internal — exposed for the link interceptor. Do not rely on this. */
78
+ readonly _win: Window;
79
+ private readonly history;
80
+ private readonly listeners;
81
+ private readonly guards;
82
+ private readonly restoreScrollOnPop;
83
+ private readonly maxStackSize;
84
+ private stack;
85
+ private current;
86
+ private indexCounter;
87
+ private destroyed;
88
+ private readonly onPopState;
89
+ /** Cumulative counts since construction — useful for live demos and debugging. */
90
+ readonly metrics: {
91
+ pushes: number;
92
+ replaces: number;
93
+ pops: number;
94
+ cancelled: number;
95
+ };
96
+ constructor(options?: HistoryManagerOptions);
97
+ /** The currently active entry. */
98
+ get entry(): HistoryEntry<TState>;
99
+ /** Current application state — shorthand for `manager.entry.state`. */
100
+ get state(): TState | null;
101
+ /** Current location object. */
102
+ get location(): HistoryLocation;
103
+ /** Total entries in the session history (delegates to `window.history.length`). */
104
+ get length(): number;
105
+ /** Snapshot of the in-memory entry stack, oldest first. */
106
+ get entries(): readonly HistoryEntry<TState>[];
107
+ /** True if we believe we can move back in history. Best-effort. */
108
+ get canGoBack(): boolean;
109
+ /** Subscribe to navigation events. Returns an unsubscribe function. */
110
+ subscribe(listener: Listener<TState>): Unsubscribe;
111
+ /**
112
+ * Register a navigation guard. Return `false` to cancel a navigation.
113
+ * Guards run for push, replace, and pop. For pop, a cancelled guard will
114
+ * attempt to restore the previous URL via `history.go`.
115
+ */
116
+ addGuard(guard: NavigationGuard<TState>): Unsubscribe;
117
+ /**
118
+ * Convenience: confirm-prompt blocker. Returns a teardown function.
119
+ * Pass a string for `window.confirm`, or a function returning a string/boolean/Promise.
120
+ */
121
+ block(message: string | ((event: NavigationEvent<TState>) => string | boolean | Promise<string | boolean>)): Unsubscribe;
122
+ /** Resolve a promise on the next navigation event. */
123
+ waitFor(): Promise<NavigationEvent<TState>>;
124
+ /** Push a new entry. */
125
+ push(url: string | URL, options?: NavigateOptions<TState>): Promise<boolean>;
126
+ /** Replace the current entry. */
127
+ replace(url: string | URL, options?: NavigateOptions<TState>): Promise<boolean>;
128
+ /** Go back N entries. */
129
+ back(n?: number): void;
130
+ /** Go forward N entries. */
131
+ forward(n?: number): void;
132
+ /** Jump by a signed delta — negative = back, positive = forward. */
133
+ go(delta: number): void;
134
+ /** Reload the current URL (full page reload). */
135
+ reload(): void;
136
+ /**
137
+ * Update state on the current entry in place without changing the URL.
138
+ */
139
+ updateState(updater: TState | ((prev: TState | null) => TState | null)): void;
140
+ /** Current query string parsed into a URLSearchParams (read-only — clone before mutating). */
141
+ get searchParams(): URLSearchParams;
142
+ /** Read a single query value from the current URL. */
143
+ getQuery(key: string): string | null;
144
+ /**
145
+ * Replace-navigate to the same path with a patched query string.
146
+ * `undefined` and `null` values remove the key.
147
+ */
148
+ setQuery(patch: QueryInput, options?: NavigateOptions<TState>): Promise<boolean>;
149
+ /** Replace-navigate to the same path with the hash updated. */
150
+ setHash(hash: string, options?: NavigateOptions<TState>): Promise<boolean>;
151
+ /** Match the current pathname against a route pattern. */
152
+ matches<TParams extends Record<string, string> = Record<string, string>>(pattern: string): RouteMatch<TParams> | null;
153
+ /** Tear down listeners. Call when your app unmounts. */
154
+ destroy(): void;
155
+ private adoptOrCreateInitialEntry;
156
+ private writeRaw;
157
+ private runGuards;
158
+ private emit;
159
+ private pushToStack;
160
+ private navigate;
161
+ private handlePop;
162
+ }
163
+
164
+ /**
165
+ * Intercept clicks on `<a>` elements and route them through the HistoryManager.
166
+ * Modifier-clicks (cmd/ctrl/shift/alt), middle/right clicks, off-origin links,
167
+ * download links, and links with a `target` are passed through to the browser.
168
+ */
169
+ declare function interceptLinks(history: HistoryManager, options?: LinkInterceptorOptions): Unsubscribe;
170
+
171
+ interface CompiledPattern {
172
+ regex: RegExp;
173
+ keys: string[];
174
+ }
175
+ /**
176
+ * Compile a route pattern into a regex.
177
+ *
178
+ * Supported syntax:
179
+ * - `/users/:id` — named param, matches a single segment
180
+ * - `/files/:path*` — splat, matches the rest including slashes
181
+ * - `/posts/:slug?` — optional segment
182
+ * - `/static/path` — literal
183
+ */
184
+ declare function compilePattern(pattern: string): CompiledPattern;
185
+ /** Match a pathname against a pattern. Returns the params object or null. */
186
+ declare function matchPattern<TParams extends Record<string, string> = Record<string, string>>(pattern: string, pathname: string): RouteMatch<TParams> | null;
187
+ /** Build a URL from a pattern and params: `('/users/:id', { id: '42' })` → `'/users/42'`. */
188
+ declare function buildPath(pattern: string, params: Record<string, string | number>): string;
189
+
190
+ /** Parse a query string into a plain object. Arrays are produced when a key appears multiple times. */
191
+ declare function parseQuery(search: string): Record<string, string | string[]>;
192
+ /** Serialize an object into a leading-`?` query string. Returns '' for empty objects. */
193
+ declare function stringifyQuery(input: QueryInput): string;
194
+ /** Merge new params into an existing query string (undefined/null removes the key). */
195
+ declare function mergeQuery(currentSearch: string, patch: QueryInput): string;
196
+ /** Read a single query value from a search string. Returns the first value if the key repeats. */
197
+ declare function getQueryValue(search: string, key: string): string | null;
198
+ declare function hasQueryKey(search: string, key: string): boolean;
199
+
200
+ /**
201
+ * Lazy singleton — convenient for app code that just wants "the" history.
202
+ * Pass options the first time to configure. Subsequent calls ignore options.
203
+ * Use `new HistoryManager()` directly if you need multiple instances.
204
+ */
205
+ declare function getHistory<TState = unknown>(options?: HistoryManagerOptions): HistoryManager<TState>;
206
+ /** Reset the singleton — primarily for tests. */
207
+ declare function resetHistorySingleton(): void;
208
+ /** Default export — the same `getHistory` used as a callable, with helpers attached. */
209
+ declare const defaultExport: typeof getHistory & {
210
+ HistoryManager: typeof HistoryManager;
211
+ getHistory: typeof getHistory;
212
+ resetHistorySingleton: typeof resetHistorySingleton;
213
+ };
214
+
215
+ export { HistoryManager, buildPath, compilePattern, defaultExport as default, getHistory, getQueryValue, hasQueryKey, interceptLinks, matchPattern, mergeQuery, parseQuery, resetHistorySingleton, stringifyQuery };
216
+ export type { HistoryEntry, HistoryLocation, HistoryManagerOptions, LinkInterceptorOptions, Listener, NavigateOptions, NavigationDirection, NavigationEvent, NavigationGuard, NavigationType, QueryInput, QueryValue, RouteMatch, Unsubscribe };
@@ -0,0 +1,2 @@
1
+ const t=new Map;function s(s){const n=t.get(s);if(n)return n;const i=[],e="^"+(s.endsWith("/")&&s.length>1?s.slice(0,-1):s).split("/").map(t=>{if(""===t)return"";if(t.startsWith(":")){let s=t.slice(1),n=!1,e=!1;return s.endsWith("?")?(n=!0,s=s.slice(0,-1)):s.endsWith("*")&&(e=!0,s=s.slice(0,-1)),i.push(s),e?"(.*)":n?"?([^/]+)?":"([^/]+)"}return t.replace(/[.+*?^${}()|[\]\\]/g,"\\$&")}).join("/")+"/?$",r={regex:new RegExp(e),keys:i};return t.set(s,r),r}function n(t,n){const{regex:i,keys:e}=s(t),r=i.exec(n);if(!r)return null;const o={};return e.forEach((t,s)=>{const n=r[s+1];void 0!==n&&(o[t]=decodeURIComponent(n))}),{pattern:t,path:n,params:o}}function i(t,s){return t.replace(/:([A-Za-z_][\w]*)([?*])?/g,(t,n)=>{const i=s[n];return null==i?"":encodeURIComponent(String(i))})}function e(t){const s={},n=new URLSearchParams(t.startsWith("?")?t.slice(1):t);for(const[t,i]of n.entries())if(t in s){const n=s[t];s[t]=Array.isArray(n)?[...n,i]:[n,i]}else s[t]=i;return s}function r(t){const s=new URLSearchParams;for(const[n,i]of Object.entries(t))if(null!=i)if(Array.isArray(i))for(const t of i)null!=t&&s.append(n,String(t));else s.set(n,String(i));const n=s.toString();return n?`?${n}`:""}function o(t,s){const n=new URLSearchParams(t.startsWith("?")?t.slice(1):t);for(const[t,i]of Object.entries(s))if(null==i)n.delete(t);else if(Array.isArray(i)){n.delete(t);for(const s of i)null!=s&&n.append(t,String(s))}else n.set(t,String(i));const i=n.toString();return i?`?${i}`:""}function h(t,s){return new URLSearchParams(t.startsWith("?")?t.slice(1):t).get(s)}function a(t,s){return new URLSearchParams(t.startsWith("?")?t.slice(1):t).has(s)}const c="__hjs__";function u(t){return"object"==typeof(s=t)&&null!==s&&c in s?{user:t.user,meta:t[c]}:{user:t??null,meta:null};var s}function f(t){const{pathname:s,search:n,hash:i,href:e,origin:r}=t.location;return{pathname:s,search:n,hash:i,href:e,origin:r}}function l(t){const s=new URL(t);return{pathname:s.pathname,search:s.search,hash:s.hash,href:s.href,origin:s.origin}}let p=0;function d(){p+=1;const t=Math.random().toString(36).slice(2,8);return`hjs_${Date.now().toString(36)}_${p.toString(36)}_${t}`}class w{constructor(t={}){this.listeners=new Set,this.guards=new Set,this.stack=[],this.indexCounter=0,this.destroyed=!1,this.metrics={pushes:0,replaces:0,pops:0,cancelled:0};const s=t.window??("undefined"!=typeof window?window:void 0);if(!s)throw new Error("HistoryManager requires a window. Pass `options.window` when running outside the browser.");this.t=s,this.history=s.history,this.restoreScrollOnPop=t.restoreScrollOnPop??!0,this.maxStackSize=t.maxStackSize??100,!1!==t.scrollRestoration&&"scrollRestoration"in s.history&&(this.history.scrollRestoration=t.scrollRestoration??"manual"),this.current=this.adoptOrCreateInitialEntry(),this.stack.push(this.current),this.onPopState=t=>{this.handlePop(t)},this.t.addEventListener("popstate",this.onPopState)}get entry(){return this.current}get state(){return this.current.state}get location(){return this.current.location}get length(){return this.history.length}get entries(){return this.stack}get canGoBack(){return this.current.index>0}subscribe(t){return this.listeners.add(t),()=>{this.listeners.delete(t)}}addGuard(t){return this.guards.add(t),()=>{this.guards.delete(t)}}block(t){return this.addGuard(async s=>{const n="function"==typeof t?await t(s):t;return!1!==n&&(!0===n||this.t.confirm(n))})}waitFor(){return new Promise(t=>{const s=this.subscribe(n=>{s(),t(n)})})}push(t,s={}){return this.navigate(t,{...s,replace:!1})}replace(t,s={}){return this.navigate(t,{...s,replace:!0})}back(t=1){this.history.go(-Math.abs(t))}forward(t=1){this.history.go(Math.abs(t))}go(t){this.history.go(t)}reload(){this.t.location.reload()}updateState(t){const s="function"==typeof t?t(this.current.state):t;this.current={...this.current,state:s??null},this.writeRaw(this.current,!0)}get searchParams(){return new URLSearchParams(this.current.location.search)}getQuery(t){return this.searchParams.get(t)}setQuery(t,s={}){const n=o(this.current.location.search,t);return this.replace(this.current.location.pathname+n+this.current.location.hash,s)}setHash(t,s={}){const n=""===t||t.startsWith("#")?t:`#${t}`;return this.replace(this.current.location.pathname+this.current.location.search+n,s)}matches(t){return n(t,this.current.location.pathname)}destroy(){this.destroyed||(this.destroyed=!0,this.t.removeEventListener("popstate",this.onPopState),this.listeners.clear(),this.guards.clear())}adoptOrCreateInitialEntry(){const t=this.history.state,{user:s,meta:n}=u(t),i=n?.index??this.indexCounter;this.indexCounter=i+1;const e={id:n?.id??d(),state:s,title:this.t.document.title,location:f(this.t),index:i,timestamp:Date.now()};return n||this.writeRaw(e,!0),e}writeRaw(t,s){const n=(i=t.state,e={id:t.id,index:t.index,scroll:{x:this.t.scrollX,y:this.t.scrollY}},{[c]:e,user:i});var i,e;this.history[s?"replaceState":"pushState"](n,t.title,t.location.href)}async runGuards(t){for(const s of Array.from(this.guards))if(!1===await s(t))return!1;return!0}emit(t){for(const s of Array.from(this.listeners))try{s(t)}catch(t){console.error("[HistoryJS] listener threw:",t)}}pushToStack(t,s){s?this.stack[this.stack.length-1]=t:(this.stack.push(t),this.stack.length>this.maxStackSize&&this.stack.splice(0,this.stack.length-this.maxStackSize))}async navigate(t,s){const n=s.replace??!1,i=(r=this.t.location.href,(e=t)instanceof URL?e.toString():new URL(e,r).toString());var e,r;const o=s.title??this.t.document.title,h=n?this.current.index:this.indexCounter+1,a={id:d(),state:s.state??null,title:o,location:l(i),index:h,timestamp:Date.now()},c={type:n?"replace":"push",direction:"none",from:this.current,to:a,isPopState:!1};return s.force||await this.runGuards(c)?(this.indexCounter=h,this.current=a,o&&this.t.document.title!==o&&(this.t.document.title=o),this.writeRaw(a,n),this.pushToStack(a,n),n?this.metrics.replaces+=1:this.metrics.pushes+=1,(s.scrollToTop??!n)&&"function"==typeof this.t.scrollTo&&this.t.scrollTo(0,0),this.emit(c),!0):(this.metrics.cancelled+=1,!1)}async handlePop(t){const{user:s,meta:n}=u(t.state),i=this.current.index,e=n?.index??i,r=e>i?"forward":e<i?"backward":"none",o={id:n?.id??d(),state:s,title:this.t.document.title,location:f(this.t),index:e,timestamp:Date.now()},h={type:"pop",direction:r,from:this.current,to:o,isPopState:!0};if(!await this.runGuards(h)){this.metrics.cancelled+=1;const t=i-e;return void(0!==t&&this.history.go(t))}this.current=o,this.indexCounter=Math.max(this.indexCounter,e),this.metrics.pops+=1,this.restoreScrollOnPop&&n?.scroll&&this.t.scrollTo(n.scroll.x,n.scroll.y),this.emit(h)}}function y(t,s={}){const n=function(t){return t.t}(t),i=s.root??n.document,e=s.selector??"a[href]",r=s.respectTarget??!0,o=s.sameOriginOnly??!0,h=s.skipDownloads??!0,a=s=>{if(s.defaultPrevented)return;if(void 0!==s.button&&0!==s.button)return;if(s.metaKey||s.ctrlKey||s.shiftKey||s.altKey)return;const i=s.target;if(!i||!i.closest)return;const a=i.closest(e);if(!a)return;if(r&&a.target&&"_self"!==a.target)return;if(h&&a.hasAttribute("download"))return;const c=a.getAttribute("href");if(!c)return;if(/^[a-z][a-z0-9+.-]*:/i.test(c)&&!/^https?:/i.test(c))return;const u=new URL(a.href,n.location.href);o&&u.origin!==n.location.origin||(s.preventDefault(),t.push(u.pathname+u.search+u.hash))};return i.addEventListener("click",a),()=>i.removeEventListener("click",a)}let g=null;function m(t){return g||(g=new w(t)),g}function S(){g?.destroy(),g=null}const R=Object.assign(m,{HistoryManager:w,getHistory:m,resetHistorySingleton:S});export{w as HistoryManager,i as buildPath,s as compilePattern,R as default,m as getHistory,h as getQueryValue,a as hasQueryKey,y as interceptLinks,n as matchPattern,o as mergeQuery,e as parseQuery,S as resetHistorySingleton,r as stringifyQuery};
2
+ //# sourceMappingURL=history.esm.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.esm.js","sources":["../src/matcher.ts","../src/query.ts","../src/utils.ts","../src/manager.ts","../src/links.ts","../src/index.ts"],"sourcesContent":[null,null,null,null,null,null],"names":["cache","Map","compilePattern","pattern","cached","get","keys","source","endsWith","length","slice","split","map","seg","startsWith","body","optional","splat","push","replace","join","compiled","regex","RegExp","set","matchPattern","pathname","match","exec","params","forEach","key","i","value","undefined","decodeURIComponent","path","buildPath","_match","encodeURIComponent","String","parseQuery","search","out","URLSearchParams","entries","existing","Array","isArray","stringifyQuery","input","raw","Object","v","append","s","toString","mergeQuery","currentSearch","patch","delete","getQueryValue","hasQueryKey","has","HJS_KEY","unwrapState","user","meta","locationOf","win","hash","href","origin","location","parseLocation","u","URL","idCounter","makeId","rand","Math","random","Date","now","HistoryManager","constructor","options","this","listeners","Set","guards","stack","indexCounter","destroyed","metrics","pushes","replaces","pops","cancelled","window","Error","_win","history","restoreScrollOnPop","maxStackSize","scrollRestoration","current","adoptOrCreateInitialEntry","onPopState","event","handlePop","addEventListener","entry","state","canGoBack","index","subscribe","listener","add","addGuard","guard","block","message","async","resolved","confirm","waitFor","Promise","resolve","off","url","navigate","back","n","go","abs","forward","delta","reload","updateState","updater","next","writeRaw","searchParams","getQuery","setQuery","nextSearch","setHash","normalized","matches","destroy","removeEventListener","clear","id","title","document","timestamp","wrapped","scroll","x","scrollX","y","scrollY","runGuards","from","emit","err","console","error","pushToStack","splice","base","nextIndex","type","direction","to","isPopState","force","scrollToTop","scrollTo","rawEvent","prevIndex","max","interceptLinks","getWindow","root","selector","respectTarget","sameOriginOnly","skipDownloads","onClick","defaultPrevented","button","metaKey","ctrlKey","shiftKey","altKey","target","closest","anchor","hasAttribute","getAttribute","test","preventDefault","singleton","getHistory","resetHistorySingleton","defaultExport","assign"],"mappings":"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"}
@@ -0,0 +1,2 @@
1
+ !function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).History={})}(this,function(t){"use strict";const e=new Map;function n(t){const n=e.get(t);if(n)return n;const s=[],i="^"+(t.endsWith("/")&&t.length>1?t.slice(0,-1):t).split("/").map(t=>{if(""===t)return"";if(t.startsWith(":")){let e=t.slice(1),n=!1,i=!1;return e.endsWith("?")?(n=!0,e=e.slice(0,-1)):e.endsWith("*")&&(i=!0,e=e.slice(0,-1)),s.push(e),i?"(.*)":n?"?([^/]+)?":"([^/]+)"}return t.replace(/[.+*?^${}()|[\]\\]/g,"\\$&")}).join("/")+"/?$",r={regex:new RegExp(i),keys:s};return e.set(t,r),r}function s(t,e){const{regex:s,keys:i}=n(t),r=s.exec(e);if(!r)return null;const o={};return i.forEach((t,e)=>{const n=r[e+1];void 0!==n&&(o[t]=decodeURIComponent(n))}),{pattern:t,path:e,params:o}}function i(t,e){const n=new URLSearchParams(t.startsWith("?")?t.slice(1):t);for(const[t,s]of Object.entries(e))if(null==s)n.delete(t);else if(Array.isArray(s)){n.delete(t);for(const e of s)null!=e&&n.append(t,String(e))}else n.set(t,String(s));const s=n.toString();return s?`?${s}`:""}const r="__hjs__";function o(t){return"object"==typeof(e=t)&&null!==e&&r in e?{user:t.user,meta:t[r]}:{user:t??null,meta:null};var e}function h(t){const{pathname:e,search:n,hash:s,href:i,origin:r}=t.location;return{pathname:e,search:n,hash:s,href:i,origin:r}}function a(t){const e=new URL(t);return{pathname:e.pathname,search:e.search,hash:e.hash,href:e.href,origin:e.origin}}let c=0;function u(){c+=1;const t=Math.random().toString(36).slice(2,8);return`hjs_${Date.now().toString(36)}_${c.toString(36)}_${t}`}class f{constructor(t={}){this.listeners=new Set,this.guards=new Set,this.stack=[],this.indexCounter=0,this.destroyed=!1,this.metrics={pushes:0,replaces:0,pops:0,cancelled:0};const e=t.window??("undefined"!=typeof window?window:void 0);if(!e)throw new Error("HistoryManager requires a window. Pass `options.window` when running outside the browser.");this.t=e,this.history=e.history,this.restoreScrollOnPop=t.restoreScrollOnPop??!0,this.maxStackSize=t.maxStackSize??100,!1!==t.scrollRestoration&&"scrollRestoration"in e.history&&(this.history.scrollRestoration=t.scrollRestoration??"manual"),this.current=this.adoptOrCreateInitialEntry(),this.stack.push(this.current),this.onPopState=t=>{this.handlePop(t)},this.t.addEventListener("popstate",this.onPopState)}get entry(){return this.current}get state(){return this.current.state}get location(){return this.current.location}get length(){return this.history.length}get entries(){return this.stack}get canGoBack(){return this.current.index>0}subscribe(t){return this.listeners.add(t),()=>{this.listeners.delete(t)}}addGuard(t){return this.guards.add(t),()=>{this.guards.delete(t)}}block(t){return this.addGuard(async e=>{const n="function"==typeof t?await t(e):t;return!1!==n&&(!0===n||this.t.confirm(n))})}waitFor(){return new Promise(t=>{const e=this.subscribe(n=>{e(),t(n)})})}push(t,e={}){return this.navigate(t,{...e,replace:!1})}replace(t,e={}){return this.navigate(t,{...e,replace:!0})}back(t=1){this.history.go(-Math.abs(t))}forward(t=1){this.history.go(Math.abs(t))}go(t){this.history.go(t)}reload(){this.t.location.reload()}updateState(t){const e="function"==typeof t?t(this.current.state):t;this.current={...this.current,state:e??null},this.writeRaw(this.current,!0)}get searchParams(){return new URLSearchParams(this.current.location.search)}getQuery(t){return this.searchParams.get(t)}setQuery(t,e={}){const n=i(this.current.location.search,t);return this.replace(this.current.location.pathname+n+this.current.location.hash,e)}setHash(t,e={}){const n=""===t||t.startsWith("#")?t:`#${t}`;return this.replace(this.current.location.pathname+this.current.location.search+n,e)}matches(t){return s(t,this.current.location.pathname)}destroy(){this.destroyed||(this.destroyed=!0,this.t.removeEventListener("popstate",this.onPopState),this.listeners.clear(),this.guards.clear())}adoptOrCreateInitialEntry(){const t=this.history.state,{user:e,meta:n}=o(t),s=n?.index??this.indexCounter;this.indexCounter=s+1;const i={id:n?.id??u(),state:e,title:this.t.document.title,location:h(this.t),index:s,timestamp:Date.now()};return n||this.writeRaw(i,!0),i}writeRaw(t,e){const n=(s=t.state,i={id:t.id,index:t.index,scroll:{x:this.t.scrollX,y:this.t.scrollY}},{[r]:i,user:s});var s,i;this.history[e?"replaceState":"pushState"](n,t.title,t.location.href)}async runGuards(t){for(const e of Array.from(this.guards))if(!1===await e(t))return!1;return!0}emit(t){for(const e of Array.from(this.listeners))try{e(t)}catch(t){console.error("[HistoryJS] listener threw:",t)}}pushToStack(t,e){e?this.stack[this.stack.length-1]=t:(this.stack.push(t),this.stack.length>this.maxStackSize&&this.stack.splice(0,this.stack.length-this.maxStackSize))}async navigate(t,e){const n=e.replace??!1,s=(r=this.t.location.href,(i=t)instanceof URL?i.toString():new URL(i,r).toString());var i,r;const o=e.title??this.t.document.title,h=n?this.current.index:this.indexCounter+1,c={id:u(),state:e.state??null,title:o,location:a(s),index:h,timestamp:Date.now()},f={type:n?"replace":"push",direction:"none",from:this.current,to:c,isPopState:!1};return e.force||await this.runGuards(f)?(this.indexCounter=h,this.current=c,o&&this.t.document.title!==o&&(this.t.document.title=o),this.writeRaw(c,n),this.pushToStack(c,n),n?this.metrics.replaces+=1:this.metrics.pushes+=1,(e.scrollToTop??!n)&&"function"==typeof this.t.scrollTo&&this.t.scrollTo(0,0),this.emit(f),!0):(this.metrics.cancelled+=1,!1)}async handlePop(t){const{user:e,meta:n}=o(t.state),s=this.current.index,i=n?.index??s,r=i>s?"forward":i<s?"backward":"none",a={id:n?.id??u(),state:e,title:this.t.document.title,location:h(this.t),index:i,timestamp:Date.now()},c={type:"pop",direction:r,from:this.current,to:a,isPopState:!0};if(!await this.runGuards(c)){this.metrics.cancelled+=1;const t=s-i;return void(0!==t&&this.history.go(t))}this.current=a,this.indexCounter=Math.max(this.indexCounter,i),this.metrics.pops+=1,this.restoreScrollOnPop&&n?.scroll&&this.t.scrollTo(n.scroll.x,n.scroll.y),this.emit(c)}}let l=null;function p(t){return l||(l=new f(t)),l}function d(){l?.destroy(),l=null}const w=Object.assign(p,{HistoryManager:f,getHistory:p,resetHistorySingleton:d});t.HistoryManager=f,t.buildPath=function(t,e){return t.replace(/:([A-Za-z_][\w]*)([?*])?/g,(t,n)=>{const s=e[n];return null==s?"":encodeURIComponent(String(s))})},t.compilePattern=n,t.default=w,t.getHistory=p,t.getQueryValue=function(t,e){return new URLSearchParams(t.startsWith("?")?t.slice(1):t).get(e)},t.hasQueryKey=function(t,e){return new URLSearchParams(t.startsWith("?")?t.slice(1):t).has(e)},t.interceptLinks=function(t,e={}){const n=function(t){return t.t}(t),s=e.root??n.document,i=e.selector??"a[href]",r=e.respectTarget??!0,o=e.sameOriginOnly??!0,h=e.skipDownloads??!0,a=e=>{if(e.defaultPrevented)return;if(void 0!==e.button&&0!==e.button)return;if(e.metaKey||e.ctrlKey||e.shiftKey||e.altKey)return;const s=e.target;if(!s||!s.closest)return;const a=s.closest(i);if(!a)return;if(r&&a.target&&"_self"!==a.target)return;if(h&&a.hasAttribute("download"))return;const c=a.getAttribute("href");if(!c)return;if(/^[a-z][a-z0-9+.-]*:/i.test(c)&&!/^https?:/i.test(c))return;const u=new URL(a.href,n.location.href);o&&u.origin!==n.location.origin||(e.preventDefault(),t.push(u.pathname+u.search+u.hash))};return s.addEventListener("click",a),()=>s.removeEventListener("click",a)},t.matchPattern=s,t.mergeQuery=i,t.parseQuery=function(t){const e={},n=new URLSearchParams(t.startsWith("?")?t.slice(1):t);for(const[t,s]of n.entries())if(t in e){const n=e[t];e[t]=Array.isArray(n)?[...n,s]:[n,s]}else e[t]=s;return e},t.resetHistorySingleton=d,t.stringifyQuery=function(t){const e=new URLSearchParams;for(const[n,s]of Object.entries(t))if(null!=s)if(Array.isArray(s))for(const t of s)null!=t&&e.append(n,String(t));else e.set(n,String(s));const n=e.toString();return n?`?${n}`:""},Object.defineProperty(t,"i",{value:!0})});
2
+ //# sourceMappingURL=history.umd.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"history.umd.js","sources":["../src/matcher.ts","../src/query.ts","../src/utils.ts","../src/manager.ts","../src/index.ts","../src/links.ts"],"sourcesContent":[null,null,null,null,null,null],"names":["cache","Map","compilePattern","pattern","cached","get","keys","source","endsWith","length","slice","split","map","seg","startsWith","body","optional","splat","push","replace","join","compiled","regex","RegExp","set","matchPattern","pathname","match","exec","params","forEach","key","i","value","undefined","decodeURIComponent","path","mergeQuery","currentSearch","patch","URLSearchParams","Object","entries","delete","Array","isArray","v","append","String","s","toString","HJS_KEY","unwrapState","raw","user","meta","locationOf","win","search","hash","href","origin","location","parseLocation","u","URL","idCounter","makeId","rand","Math","random","Date","now","HistoryManager","constructor","options","this","listeners","Set","guards","stack","indexCounter","destroyed","metrics","pushes","replaces","pops","cancelled","window","Error","_win","history","restoreScrollOnPop","maxStackSize","scrollRestoration","current","adoptOrCreateInitialEntry","onPopState","event","handlePop","addEventListener","entry","state","canGoBack","index","subscribe","listener","add","addGuard","guard","block","message","async","resolved","confirm","waitFor","Promise","resolve","off","url","navigate","back","n","go","abs","forward","delta","reload","updateState","updater","next","writeRaw","searchParams","getQuery","setQuery","nextSearch","setHash","normalized","matches","destroy","removeEventListener","clear","id","title","document","timestamp","wrapped","scroll","x","scrollX","y","scrollY","runGuards","from","emit","err","console","error","pushToStack","splice","base","input","nextIndex","type","direction","to","isPopState","force","scrollToTop","scrollTo","rawEvent","prevIndex","max","singleton","getHistory","resetHistorySingleton","defaultExport","assign","_match","encodeURIComponent","has","getWindow","root","selector","respectTarget","sameOriginOnly","skipDownloads","onClick","defaultPrevented","button","metaKey","ctrlKey","shiftKey","altKey","target","closest","anchor","hasAttribute","getAttribute","test","preventDefault","out","existing"],"mappings":"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"}
package/package.json ADDED
@@ -0,0 +1,64 @@
1
+ {
2
+ "name": "@buildwithdarsh/historyjs",
3
+ "version": "1.0.0",
4
+ "description": "A modern, typed, framework-agnostic wrapper over the History API — typed entries, guards, query helpers, route matching, link interception, and a virtual stack. The 2026 successor to history.js.",
5
+ "main": "dist/history.umd.js",
6
+ "module": "dist/history.esm.js",
7
+ "types": "dist/history.d.ts",
8
+ "unpkg": "dist/history.umd.js",
9
+ "jsdelivr": "dist/history.umd.js",
10
+ "exports": {
11
+ ".": {
12
+ "types": "./dist/history.d.ts",
13
+ "import": "./dist/history.esm.js",
14
+ "require": "./dist/history.umd.js"
15
+ }
16
+ },
17
+ "files": [
18
+ "dist/history.umd.js",
19
+ "dist/history.umd.js.map",
20
+ "dist/history.esm.js",
21
+ "dist/history.esm.js.map",
22
+ "dist/history.d.ts",
23
+ "README.md",
24
+ "LICENSE"
25
+ ],
26
+ "publishConfig": {
27
+ "access": "public"
28
+ },
29
+ "scripts": {
30
+ "build": "rollup -c && rm -rf example/dist && cp -r dist example/dist",
31
+ "typecheck": "tsc --noEmit",
32
+ "test": "vitest run",
33
+ "test:watch": "vitest",
34
+ "dev": "rollup -c -w",
35
+ "prepublishOnly": "npm run typecheck && npm run test && npm run build"
36
+ },
37
+ "keywords": [
38
+ "history",
39
+ "historyjs",
40
+ "pushState",
41
+ "popstate",
42
+ "router",
43
+ "spa",
44
+ "navigation",
45
+ "url",
46
+ "query-string",
47
+ "route-matcher",
48
+ "typescript"
49
+ ],
50
+ "author": "Darsh Gupta",
51
+ "license": "MIT",
52
+ "type": "module",
53
+ "sideEffects": false,
54
+ "devDependencies": {
55
+ "@rollup/plugin-terser": "^1.0.0",
56
+ "@rollup/plugin-typescript": "^12.1.2",
57
+ "happy-dom": "^15.0.0",
58
+ "rollup": "^4.34.8",
59
+ "rollup-plugin-dts": "^6.1.1",
60
+ "tslib": "^2.8.1",
61
+ "typescript": "^5.7.3",
62
+ "vitest": "^2.1.0"
63
+ }
64
+ }