@real-router/memory-plugin 0.1.3 → 0.2.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/cjs/index.d.ts +11 -1
- package/dist/cjs/index.d.ts.map +1 -1
- package/dist/cjs/index.js +1 -1
- package/dist/cjs/index.js.map +1 -1
- package/dist/esm/index.d.mts +11 -1
- package/dist/esm/index.d.mts.map +1 -1
- package/dist/esm/index.mjs +1 -1
- package/dist/esm/index.mjs.map +1 -1
- package/package.json +5 -4
- package/src/index.ts +11 -1
- package/src/plugin.ts +30 -1
- package/src/types.ts +7 -0
package/dist/cjs/index.d.ts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { PluginFactory } from "@real-router/core";
|
|
2
2
|
|
|
3
3
|
//#region src/types.d.ts
|
|
4
|
+
type MemoryDirection = "back" | "forward" | "navigate";
|
|
5
|
+
interface MemoryContext {
|
|
6
|
+
direction: MemoryDirection;
|
|
7
|
+
historyIndex: number;
|
|
8
|
+
}
|
|
4
9
|
interface MemoryPluginOptions {
|
|
5
10
|
maxHistoryLength?: number;
|
|
6
11
|
}
|
|
@@ -9,6 +14,11 @@ interface MemoryPluginOptions {
|
|
|
9
14
|
declare function memoryPluginFactory(options?: MemoryPluginOptions): PluginFactory;
|
|
10
15
|
//#endregion
|
|
11
16
|
//#region src/index.d.ts
|
|
17
|
+
declare module "@real-router/types" {
|
|
18
|
+
interface StateContext {
|
|
19
|
+
memory?: MemoryContext;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
12
22
|
declare module "@real-router/core" {
|
|
13
23
|
interface Router {
|
|
14
24
|
back: () => void;
|
|
@@ -19,5 +29,5 @@ declare module "@real-router/core" {
|
|
|
19
29
|
}
|
|
20
30
|
} //# sourceMappingURL=index.d.ts.map
|
|
21
31
|
//#endregion
|
|
22
|
-
export { type MemoryPluginOptions, memoryPluginFactory };
|
|
32
|
+
export { type MemoryContext, type MemoryDirection, type MemoryPluginOptions, memoryPluginFactory };
|
|
23
33
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/cjs/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/types.ts","../../src/factory.ts","../../src/index.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.d.ts","names":[],"sources":["../../src/types.ts","../../src/factory.ts","../../src/index.ts"],"mappings":";;;KAEY,eAAA;AAAA,UAEK,aAAA;EACf,SAAA,EAAW,eAAA;EACX,YAAA;AAAA;AAAA,UAGe,mBAAA;EACf,gBAAA;AAAA;;;iBCHc,mBAAA,CACd,OAAA,GAAS,mBAAA,GACR,aAAA;;;;YCAS,YAAA;IACR,MAAA,GAJa,aAAA;EAAA;AAAA;AAAA;EAAA,UASL,MAAA;IACR,IAAA;IACA,OAAA;IACA,EAAA,GAAK,KAAA;IACL,SAAA;IACA,YAAA;EAAA;AAAA"}
|
package/dist/cjs/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@real-router/core/api`);var t=class{#e;#t;#n=[];#r;#i=-1;#
|
|
1
|
+
Object.defineProperty(exports,Symbol.toStringTag,{value:`Module`});let e=require(`@real-router/core/api`);var t=class{#e;#t;#n=[];#r;#i;#a=-1;#o=!1;#s=`navigate`;#c=0;constructor(e,t,n){this.#e=e,this.#t=n.maxHistoryLength??1e3,this.#i=t.claimContextNamespace(`memory`),this.#r=t.extendRouter({back:()=>{this.#l(-1)},forward:()=>{this.#l(1)},go:e=>{this.#l(e)},canGoBack:()=>this.#a>0,canGoForward:()=>this.#a<this.#n.length-1})}getPlugin(){return{onTransitionSuccess:(e,t,n)=>{if(this.#o){this.#i.write(e,Object.freeze({direction:this.#s,historyIndex:this.#a}));return}let r={name:e.name,params:e.params,path:e.path};if(n.replace&&this.#a>=0)this.#n[this.#a]=r;else if(this.#n.splice(this.#a+1),this.#n.push(r),this.#a=this.#n.length-1,this.#t>0&&this.#n.length>this.#t){let e=this.#n.length-this.#t;this.#n.splice(0,e),this.#a=Math.max(0,this.#a-e)}this.#i.write(e,Object.freeze({direction:`navigate`,historyIndex:this.#a}))},onStop:()=>{this.#u()},teardown:()=>{this.#r(),this.#i.release(),this.#u()}}}#l(e){if(e===0)return;let t=this.#a+e;if(t<0||t>=this.#n.length)return;let n=this.#n[t],r=this.#e.getState();if(n.path===r?.path){this.#a=t;return}let i=this.#a,a=++this.#c;this.#s=e>0?`forward`:`back`,this.#o=!0,this.#a=t,this.#e.navigate(n.name,n.params,{replace:!0}).catch(()=>{this.#c===a&&(this.#a=i)}).finally(()=>{this.#c===a&&(this.#o=!1)})}#u(){this.#n.length=0,this.#a=-1}};function n(n={}){if(n.maxHistoryLength!==void 0&&(typeof n.maxHistoryLength!=`number`||n.maxHistoryLength<0))throw TypeError(`[memory-plugin] Invalid maxHistoryLength: expected non-negative number, got ${String(n.maxHistoryLength)}.`);let r=Object.freeze({...n});return n=>new t(n,(0,e.getPluginApi)(n),r).getPlugin()}exports.memoryPluginFactory=n;
|
|
2
2
|
//# sourceMappingURL=index.js.map
|
package/dist/cjs/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":["#router","#maxHistory","#entries","#removeExtensions","#go","#index","#navigatingFromHistory","#clear","#goGeneration"],"sources":["../../src/plugin.ts","../../src/factory.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"index.js","names":["#router","#maxHistory","#entries","#removeExtensions","#claim","#go","#index","#navigatingFromHistory","#pendingDirection","#clear","#goGeneration"],"sources":["../../src/plugin.ts","../../src/factory.ts"],"sourcesContent":["import type {\n HistoryEntry,\n MemoryContext,\n MemoryDirection,\n MemoryPluginOptions,\n} from \"./types\";\nimport type {\n NavigationOptions,\n Plugin,\n Router,\n State,\n} from \"@real-router/core\";\nimport type { PluginApi } from \"@real-router/core/api\";\n\nconst DEFAULT_MAX_HISTORY = 1000;\n\nexport class MemoryPlugin {\n readonly #router: Router;\n readonly #maxHistory: number;\n readonly #entries: HistoryEntry[] = [];\n readonly #removeExtensions: () => void;\n readonly #claim: {\n write: (state: State, value: MemoryContext) => void;\n release: () => void;\n };\n #index = -1;\n #navigatingFromHistory = false;\n #pendingDirection: MemoryDirection = \"navigate\";\n #goGeneration = 0;\n\n constructor(router: Router, api: PluginApi, options: MemoryPluginOptions) {\n this.#router = router;\n this.#maxHistory = options.maxHistoryLength ?? DEFAULT_MAX_HISTORY;\n this.#claim = api.claimContextNamespace(\"memory\");\n\n this.#removeExtensions = api.extendRouter({\n back: () => {\n this.#go(-1);\n },\n forward: () => {\n this.#go(1);\n },\n go: (delta: number) => {\n this.#go(delta);\n },\n canGoBack: () => this.#index > 0,\n canGoForward: () => this.#index < this.#entries.length - 1,\n });\n }\n\n getPlugin(): Plugin {\n return {\n onTransitionSuccess: (\n toState: State,\n _fromState: State | undefined,\n opts: NavigationOptions,\n ) => {\n if (this.#navigatingFromHistory) {\n this.#claim.write(\n toState,\n Object.freeze({\n direction: this.#pendingDirection,\n historyIndex: this.#index,\n }),\n );\n\n return;\n }\n\n const entry: HistoryEntry = {\n name: toState.name,\n params: toState.params,\n path: toState.path,\n };\n\n if (opts.replace && this.#index >= 0) {\n this.#entries[this.#index] = entry;\n } else {\n this.#entries.splice(this.#index + 1);\n this.#entries.push(entry);\n this.#index = this.#entries.length - 1;\n\n if (this.#maxHistory > 0 && this.#entries.length > this.#maxHistory) {\n const overflow = this.#entries.length - this.#maxHistory;\n\n this.#entries.splice(0, overflow);\n this.#index = Math.max(0, this.#index - overflow);\n }\n }\n\n this.#claim.write(\n toState,\n Object.freeze({\n direction: \"navigate\" as const,\n historyIndex: this.#index,\n }),\n );\n },\n\n onStop: () => {\n this.#clear();\n },\n\n teardown: () => {\n this.#removeExtensions();\n this.#claim.release();\n this.#clear();\n },\n };\n }\n\n #go(delta: number): void {\n if (delta === 0) {\n return;\n }\n\n const targetIndex = this.#index + delta;\n\n if (targetIndex < 0 || targetIndex >= this.#entries.length) {\n return;\n }\n\n const entry = this.#entries[targetIndex];\n const currentState = this.#router.getState();\n\n if (entry.path === currentState?.path) {\n this.#index = targetIndex;\n\n return;\n }\n\n const previousIndex = this.#index;\n const generation = ++this.#goGeneration;\n\n this.#pendingDirection = delta > 0 ? \"forward\" : \"back\";\n this.#navigatingFromHistory = true;\n this.#index = targetIndex;\n\n void this.#router\n .navigate(entry.name, entry.params, { replace: true })\n .catch(() => {\n if (this.#goGeneration === generation) {\n this.#index = previousIndex;\n }\n })\n .finally(() => {\n if (this.#goGeneration === generation) {\n this.#navigatingFromHistory = false;\n }\n });\n }\n\n #clear(): void {\n this.#entries.length = 0;\n this.#index = -1;\n }\n}\n","import { getPluginApi } from \"@real-router/core/api\";\n\nimport { MemoryPlugin } from \"./plugin\";\n\nimport type { MemoryPluginOptions } from \"./types\";\nimport type { PluginFactory, Plugin, Router } from \"@real-router/core\";\n\nexport function memoryPluginFactory(\n options: MemoryPluginOptions = {},\n): PluginFactory {\n if (\n options.maxHistoryLength !== undefined &&\n (typeof options.maxHistoryLength !== \"number\" ||\n options.maxHistoryLength < 0)\n ) {\n throw new TypeError(\n `[memory-plugin] Invalid maxHistoryLength: expected non-negative number, got ${String(options.maxHistoryLength)}.`,\n );\n }\n\n const frozenOptions: MemoryPluginOptions = Object.freeze({ ...options });\n\n return (router): Plugin => {\n const api = getPluginApi(router);\n const plugin = new MemoryPlugin(router as Router, api, frozenOptions);\n\n return plugin.getPlugin();\n };\n}\n"],"mappings":"0GAgBA,IAAa,EAAb,KAA0B,CACxB,GACA,GACA,GAAoC,EAAE,CACtC,GACA,GAIA,GAAS,GACT,GAAyB,GACzB,GAAqC,WACrC,GAAgB,EAEhB,YAAY,EAAgB,EAAgB,EAA8B,CACxE,MAAA,EAAe,EACf,MAAA,EAAmB,EAAQ,kBAAoB,IAC/C,MAAA,EAAc,EAAI,sBAAsB,SAAS,CAEjD,MAAA,EAAyB,EAAI,aAAa,CACxC,SAAY,CACV,MAAA,EAAS,GAAG,EAEd,YAAe,CACb,MAAA,EAAS,EAAE,EAEb,GAAK,GAAkB,CACrB,MAAA,EAAS,EAAM,EAEjB,cAAiB,MAAA,EAAc,EAC/B,iBAAoB,MAAA,EAAc,MAAA,EAAc,OAAS,EAC1D,CAAC,CAGJ,WAAoB,CAClB,MAAO,CACL,qBACE,EACA,EACA,IACG,CACH,GAAI,MAAA,EAA6B,CAC/B,MAAA,EAAY,MACV,EACA,OAAO,OAAO,CACZ,UAAW,MAAA,EACX,aAAc,MAAA,EACf,CAAC,CACH,CAED,OAGF,IAAM,EAAsB,CAC1B,KAAM,EAAQ,KACd,OAAQ,EAAQ,OAChB,KAAM,EAAQ,KACf,CAED,GAAI,EAAK,SAAW,MAAA,GAAe,EACjC,MAAA,EAAc,MAAA,GAAe,UAE7B,MAAA,EAAc,OAAO,MAAA,EAAc,EAAE,CACrC,MAAA,EAAc,KAAK,EAAM,CACzB,MAAA,EAAc,MAAA,EAAc,OAAS,EAEjC,MAAA,EAAmB,GAAK,MAAA,EAAc,OAAS,MAAA,EAAkB,CACnE,IAAM,EAAW,MAAA,EAAc,OAAS,MAAA,EAExC,MAAA,EAAc,OAAO,EAAG,EAAS,CACjC,MAAA,EAAc,KAAK,IAAI,EAAG,MAAA,EAAc,EAAS,CAIrD,MAAA,EAAY,MACV,EACA,OAAO,OAAO,CACZ,UAAW,WACX,aAAc,MAAA,EACf,CAAC,CACH,EAGH,WAAc,CACZ,MAAA,GAAa,EAGf,aAAgB,CACd,MAAA,GAAwB,CACxB,MAAA,EAAY,SAAS,CACrB,MAAA,GAAa,EAEhB,CAGH,GAAI,EAAqB,CACvB,GAAI,IAAU,EACZ,OAGF,IAAM,EAAc,MAAA,EAAc,EAElC,GAAI,EAAc,GAAK,GAAe,MAAA,EAAc,OAClD,OAGF,IAAM,EAAQ,MAAA,EAAc,GACtB,EAAe,MAAA,EAAa,UAAU,CAE5C,GAAI,EAAM,OAAS,GAAc,KAAM,CACrC,MAAA,EAAc,EAEd,OAGF,IAAM,EAAgB,MAAA,EAChB,EAAa,EAAE,MAAA,EAErB,MAAA,EAAyB,EAAQ,EAAI,UAAY,OACjD,MAAA,EAA8B,GAC9B,MAAA,EAAc,EAET,MAAA,EACF,SAAS,EAAM,KAAM,EAAM,OAAQ,CAAE,QAAS,GAAM,CAAC,CACrD,UAAY,CACP,MAAA,IAAuB,IACzB,MAAA,EAAc,IAEhB,CACD,YAAc,CACT,MAAA,IAAuB,IACzB,MAAA,EAA8B,KAEhC,CAGN,IAAe,CACb,MAAA,EAAc,OAAS,EACvB,MAAA,EAAc,KCnJlB,SAAgB,EACd,EAA+B,EAAE,CAClB,CACf,GACE,EAAQ,mBAAqB,IAAA,KAC5B,OAAO,EAAQ,kBAAqB,UACnC,EAAQ,iBAAmB,GAE7B,MAAU,UACR,+EAA+E,OAAO,EAAQ,iBAAiB,CAAC,GACjH,CAGH,IAAM,EAAqC,OAAO,OAAO,CAAE,GAAG,EAAS,CAAC,CAExE,MAAQ,IAES,IAAI,EAAa,GAAA,EAAA,EAAA,cADP,EAAO,CACuB,EAAc,CAEvD,WAAW"}
|
package/dist/esm/index.d.mts
CHANGED
|
@@ -1,6 +1,11 @@
|
|
|
1
1
|
import { PluginFactory } from "@real-router/core";
|
|
2
2
|
|
|
3
3
|
//#region src/types.d.ts
|
|
4
|
+
type MemoryDirection = "back" | "forward" | "navigate";
|
|
5
|
+
interface MemoryContext {
|
|
6
|
+
direction: MemoryDirection;
|
|
7
|
+
historyIndex: number;
|
|
8
|
+
}
|
|
4
9
|
interface MemoryPluginOptions {
|
|
5
10
|
maxHistoryLength?: number;
|
|
6
11
|
}
|
|
@@ -9,6 +14,11 @@ interface MemoryPluginOptions {
|
|
|
9
14
|
declare function memoryPluginFactory(options?: MemoryPluginOptions): PluginFactory;
|
|
10
15
|
//#endregion
|
|
11
16
|
//#region src/index.d.ts
|
|
17
|
+
declare module "@real-router/types" {
|
|
18
|
+
interface StateContext {
|
|
19
|
+
memory?: MemoryContext;
|
|
20
|
+
}
|
|
21
|
+
}
|
|
12
22
|
declare module "@real-router/core" {
|
|
13
23
|
interface Router {
|
|
14
24
|
back: () => void;
|
|
@@ -19,5 +29,5 @@ declare module "@real-router/core" {
|
|
|
19
29
|
}
|
|
20
30
|
} //# sourceMappingURL=index.d.ts.map
|
|
21
31
|
//#endregion
|
|
22
|
-
export { type MemoryPluginOptions, memoryPluginFactory };
|
|
32
|
+
export { type MemoryContext, type MemoryDirection, type MemoryPluginOptions, memoryPluginFactory };
|
|
23
33
|
//# sourceMappingURL=index.d.mts.map
|
package/dist/esm/index.d.mts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/types.ts","../../src/factory.ts","../../src/index.ts"],"mappings":";;;
|
|
1
|
+
{"version":3,"file":"index.d.mts","names":[],"sources":["../../src/types.ts","../../src/factory.ts","../../src/index.ts"],"mappings":";;;KAEY,eAAA;AAAA,UAEK,aAAA;EACf,SAAA,EAAW,eAAA;EACX,YAAA;AAAA;AAAA,UAGe,mBAAA;EACf,gBAAA;AAAA;;;iBCHc,mBAAA,CACd,OAAA,GAAS,mBAAA,GACR,aAAA;;;;YCAS,YAAA;IACR,MAAA,GAJa,aAAA;EAAA;AAAA;AAAA;EAAA,UASL,MAAA;IACR,IAAA;IACA,OAAA;IACA,EAAA,GAAK,KAAA;IACL,SAAA;IACA,YAAA;EAAA;AAAA"}
|
package/dist/esm/index.mjs
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
import{getPluginApi as e}from"@real-router/core/api";var t=class{#e;#t;#n=[];#r;#i=-1;#
|
|
1
|
+
import{getPluginApi as e}from"@real-router/core/api";var t=class{#e;#t;#n=[];#r;#i;#a=-1;#o=!1;#s=`navigate`;#c=0;constructor(e,t,n){this.#e=e,this.#t=n.maxHistoryLength??1e3,this.#i=t.claimContextNamespace(`memory`),this.#r=t.extendRouter({back:()=>{this.#l(-1)},forward:()=>{this.#l(1)},go:e=>{this.#l(e)},canGoBack:()=>this.#a>0,canGoForward:()=>this.#a<this.#n.length-1})}getPlugin(){return{onTransitionSuccess:(e,t,n)=>{if(this.#o){this.#i.write(e,Object.freeze({direction:this.#s,historyIndex:this.#a}));return}let r={name:e.name,params:e.params,path:e.path};if(n.replace&&this.#a>=0)this.#n[this.#a]=r;else if(this.#n.splice(this.#a+1),this.#n.push(r),this.#a=this.#n.length-1,this.#t>0&&this.#n.length>this.#t){let e=this.#n.length-this.#t;this.#n.splice(0,e),this.#a=Math.max(0,this.#a-e)}this.#i.write(e,Object.freeze({direction:`navigate`,historyIndex:this.#a}))},onStop:()=>{this.#u()},teardown:()=>{this.#r(),this.#i.release(),this.#u()}}}#l(e){if(e===0)return;let t=this.#a+e;if(t<0||t>=this.#n.length)return;let n=this.#n[t],r=this.#e.getState();if(n.path===r?.path){this.#a=t;return}let i=this.#a,a=++this.#c;this.#s=e>0?`forward`:`back`,this.#o=!0,this.#a=t,this.#e.navigate(n.name,n.params,{replace:!0}).catch(()=>{this.#c===a&&(this.#a=i)}).finally(()=>{this.#c===a&&(this.#o=!1)})}#u(){this.#n.length=0,this.#a=-1}};function n(n={}){if(n.maxHistoryLength!==void 0&&(typeof n.maxHistoryLength!=`number`||n.maxHistoryLength<0))throw TypeError(`[memory-plugin] Invalid maxHistoryLength: expected non-negative number, got ${String(n.maxHistoryLength)}.`);let r=Object.freeze({...n});return n=>new t(n,e(n),r).getPlugin()}export{n as memoryPluginFactory};
|
|
2
2
|
//# sourceMappingURL=index.mjs.map
|
package/dist/esm/index.mjs.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.mjs","names":["#router","#maxHistory","#entries","#removeExtensions","#go","#index","#navigatingFromHistory","#clear","#goGeneration"],"sources":["../../src/plugin.ts","../../src/factory.ts"],"sourcesContent":["import type {
|
|
1
|
+
{"version":3,"file":"index.mjs","names":["#router","#maxHistory","#entries","#removeExtensions","#claim","#go","#index","#navigatingFromHistory","#pendingDirection","#clear","#goGeneration"],"sources":["../../src/plugin.ts","../../src/factory.ts"],"sourcesContent":["import type {\n HistoryEntry,\n MemoryContext,\n MemoryDirection,\n MemoryPluginOptions,\n} from \"./types\";\nimport type {\n NavigationOptions,\n Plugin,\n Router,\n State,\n} from \"@real-router/core\";\nimport type { PluginApi } from \"@real-router/core/api\";\n\nconst DEFAULT_MAX_HISTORY = 1000;\n\nexport class MemoryPlugin {\n readonly #router: Router;\n readonly #maxHistory: number;\n readonly #entries: HistoryEntry[] = [];\n readonly #removeExtensions: () => void;\n readonly #claim: {\n write: (state: State, value: MemoryContext) => void;\n release: () => void;\n };\n #index = -1;\n #navigatingFromHistory = false;\n #pendingDirection: MemoryDirection = \"navigate\";\n #goGeneration = 0;\n\n constructor(router: Router, api: PluginApi, options: MemoryPluginOptions) {\n this.#router = router;\n this.#maxHistory = options.maxHistoryLength ?? DEFAULT_MAX_HISTORY;\n this.#claim = api.claimContextNamespace(\"memory\");\n\n this.#removeExtensions = api.extendRouter({\n back: () => {\n this.#go(-1);\n },\n forward: () => {\n this.#go(1);\n },\n go: (delta: number) => {\n this.#go(delta);\n },\n canGoBack: () => this.#index > 0,\n canGoForward: () => this.#index < this.#entries.length - 1,\n });\n }\n\n getPlugin(): Plugin {\n return {\n onTransitionSuccess: (\n toState: State,\n _fromState: State | undefined,\n opts: NavigationOptions,\n ) => {\n if (this.#navigatingFromHistory) {\n this.#claim.write(\n toState,\n Object.freeze({\n direction: this.#pendingDirection,\n historyIndex: this.#index,\n }),\n );\n\n return;\n }\n\n const entry: HistoryEntry = {\n name: toState.name,\n params: toState.params,\n path: toState.path,\n };\n\n if (opts.replace && this.#index >= 0) {\n this.#entries[this.#index] = entry;\n } else {\n this.#entries.splice(this.#index + 1);\n this.#entries.push(entry);\n this.#index = this.#entries.length - 1;\n\n if (this.#maxHistory > 0 && this.#entries.length > this.#maxHistory) {\n const overflow = this.#entries.length - this.#maxHistory;\n\n this.#entries.splice(0, overflow);\n this.#index = Math.max(0, this.#index - overflow);\n }\n }\n\n this.#claim.write(\n toState,\n Object.freeze({\n direction: \"navigate\" as const,\n historyIndex: this.#index,\n }),\n );\n },\n\n onStop: () => {\n this.#clear();\n },\n\n teardown: () => {\n this.#removeExtensions();\n this.#claim.release();\n this.#clear();\n },\n };\n }\n\n #go(delta: number): void {\n if (delta === 0) {\n return;\n }\n\n const targetIndex = this.#index + delta;\n\n if (targetIndex < 0 || targetIndex >= this.#entries.length) {\n return;\n }\n\n const entry = this.#entries[targetIndex];\n const currentState = this.#router.getState();\n\n if (entry.path === currentState?.path) {\n this.#index = targetIndex;\n\n return;\n }\n\n const previousIndex = this.#index;\n const generation = ++this.#goGeneration;\n\n this.#pendingDirection = delta > 0 ? \"forward\" : \"back\";\n this.#navigatingFromHistory = true;\n this.#index = targetIndex;\n\n void this.#router\n .navigate(entry.name, entry.params, { replace: true })\n .catch(() => {\n if (this.#goGeneration === generation) {\n this.#index = previousIndex;\n }\n })\n .finally(() => {\n if (this.#goGeneration === generation) {\n this.#navigatingFromHistory = false;\n }\n });\n }\n\n #clear(): void {\n this.#entries.length = 0;\n this.#index = -1;\n }\n}\n","import { getPluginApi } from \"@real-router/core/api\";\n\nimport { MemoryPlugin } from \"./plugin\";\n\nimport type { MemoryPluginOptions } from \"./types\";\nimport type { PluginFactory, Plugin, Router } from \"@real-router/core\";\n\nexport function memoryPluginFactory(\n options: MemoryPluginOptions = {},\n): PluginFactory {\n if (\n options.maxHistoryLength !== undefined &&\n (typeof options.maxHistoryLength !== \"number\" ||\n options.maxHistoryLength < 0)\n ) {\n throw new TypeError(\n `[memory-plugin] Invalid maxHistoryLength: expected non-negative number, got ${String(options.maxHistoryLength)}.`,\n );\n }\n\n const frozenOptions: MemoryPluginOptions = Object.freeze({ ...options });\n\n return (router): Plugin => {\n const api = getPluginApi(router);\n const plugin = new MemoryPlugin(router as Router, api, frozenOptions);\n\n return plugin.getPlugin();\n };\n}\n"],"mappings":"qDAgBA,IAAa,EAAb,KAA0B,CACxB,GACA,GACA,GAAoC,EAAE,CACtC,GACA,GAIA,GAAS,GACT,GAAyB,GACzB,GAAqC,WACrC,GAAgB,EAEhB,YAAY,EAAgB,EAAgB,EAA8B,CACxE,MAAA,EAAe,EACf,MAAA,EAAmB,EAAQ,kBAAoB,IAC/C,MAAA,EAAc,EAAI,sBAAsB,SAAS,CAEjD,MAAA,EAAyB,EAAI,aAAa,CACxC,SAAY,CACV,MAAA,EAAS,GAAG,EAEd,YAAe,CACb,MAAA,EAAS,EAAE,EAEb,GAAK,GAAkB,CACrB,MAAA,EAAS,EAAM,EAEjB,cAAiB,MAAA,EAAc,EAC/B,iBAAoB,MAAA,EAAc,MAAA,EAAc,OAAS,EAC1D,CAAC,CAGJ,WAAoB,CAClB,MAAO,CACL,qBACE,EACA,EACA,IACG,CACH,GAAI,MAAA,EAA6B,CAC/B,MAAA,EAAY,MACV,EACA,OAAO,OAAO,CACZ,UAAW,MAAA,EACX,aAAc,MAAA,EACf,CAAC,CACH,CAED,OAGF,IAAM,EAAsB,CAC1B,KAAM,EAAQ,KACd,OAAQ,EAAQ,OAChB,KAAM,EAAQ,KACf,CAED,GAAI,EAAK,SAAW,MAAA,GAAe,EACjC,MAAA,EAAc,MAAA,GAAe,UAE7B,MAAA,EAAc,OAAO,MAAA,EAAc,EAAE,CACrC,MAAA,EAAc,KAAK,EAAM,CACzB,MAAA,EAAc,MAAA,EAAc,OAAS,EAEjC,MAAA,EAAmB,GAAK,MAAA,EAAc,OAAS,MAAA,EAAkB,CACnE,IAAM,EAAW,MAAA,EAAc,OAAS,MAAA,EAExC,MAAA,EAAc,OAAO,EAAG,EAAS,CACjC,MAAA,EAAc,KAAK,IAAI,EAAG,MAAA,EAAc,EAAS,CAIrD,MAAA,EAAY,MACV,EACA,OAAO,OAAO,CACZ,UAAW,WACX,aAAc,MAAA,EACf,CAAC,CACH,EAGH,WAAc,CACZ,MAAA,GAAa,EAGf,aAAgB,CACd,MAAA,GAAwB,CACxB,MAAA,EAAY,SAAS,CACrB,MAAA,GAAa,EAEhB,CAGH,GAAI,EAAqB,CACvB,GAAI,IAAU,EACZ,OAGF,IAAM,EAAc,MAAA,EAAc,EAElC,GAAI,EAAc,GAAK,GAAe,MAAA,EAAc,OAClD,OAGF,IAAM,EAAQ,MAAA,EAAc,GACtB,EAAe,MAAA,EAAa,UAAU,CAE5C,GAAI,EAAM,OAAS,GAAc,KAAM,CACrC,MAAA,EAAc,EAEd,OAGF,IAAM,EAAgB,MAAA,EAChB,EAAa,EAAE,MAAA,EAErB,MAAA,EAAyB,EAAQ,EAAI,UAAY,OACjD,MAAA,EAA8B,GAC9B,MAAA,EAAc,EAET,MAAA,EACF,SAAS,EAAM,KAAM,EAAM,OAAQ,CAAE,QAAS,GAAM,CAAC,CACrD,UAAY,CACP,MAAA,IAAuB,IACzB,MAAA,EAAc,IAEhB,CACD,YAAc,CACT,MAAA,IAAuB,IACzB,MAAA,EAA8B,KAEhC,CAGN,IAAe,CACb,MAAA,EAAc,OAAS,EACvB,MAAA,EAAc,KCnJlB,SAAgB,EACd,EAA+B,EAAE,CAClB,CACf,GACE,EAAQ,mBAAqB,IAAA,KAC5B,OAAO,EAAQ,kBAAqB,UACnC,EAAQ,iBAAmB,GAE7B,MAAU,UACR,+EAA+E,OAAO,EAAQ,iBAAiB,CAAC,GACjH,CAGH,IAAM,EAAqC,OAAO,OAAO,CAAE,GAAG,EAAS,CAAC,CAExE,MAAQ,IAES,IAAI,EAAa,EADpB,EAAa,EAAO,CACuB,EAAc,CAEvD,WAAW"}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@real-router/memory-plugin",
|
|
3
|
-
"version": "0.1
|
|
3
|
+
"version": "0.2.1",
|
|
4
4
|
"type": "commonjs",
|
|
5
5
|
"description": "In-memory history engine for Real-Router — non-browser environments and benchmarks",
|
|
6
6
|
"main": "./dist/cjs/index.js",
|
|
@@ -8,6 +8,7 @@
|
|
|
8
8
|
"types": "./dist/esm/index.d.mts",
|
|
9
9
|
"exports": {
|
|
10
10
|
".": {
|
|
11
|
+
"@real-router/internal-source": "./src/index.ts",
|
|
11
12
|
"types": {
|
|
12
13
|
"import": "./dist/esm/index.d.mts",
|
|
13
14
|
"require": "./dist/cjs/index.d.ts"
|
|
@@ -44,7 +45,8 @@
|
|
|
44
45
|
"homepage": "https://github.com/greydragon888/real-router",
|
|
45
46
|
"sideEffects": false,
|
|
46
47
|
"dependencies": {
|
|
47
|
-
"@real-router/core": "^0.
|
|
48
|
+
"@real-router/core": "^0.48.0",
|
|
49
|
+
"@real-router/types": "^0.34.0"
|
|
48
50
|
},
|
|
49
51
|
"scripts": {
|
|
50
52
|
"test": "vitest",
|
|
@@ -53,7 +55,6 @@
|
|
|
53
55
|
"type-check": "tsc --noEmit",
|
|
54
56
|
"lint": "eslint --cache --ext .ts src/ tests/ --fix --max-warnings 0",
|
|
55
57
|
"lint:package": "publint",
|
|
56
|
-
"lint:types": "attw --pack ."
|
|
57
|
-
"build:dist-only": "tsdown --config-loader unrun"
|
|
58
|
+
"lint:types": "attw --pack ."
|
|
58
59
|
}
|
|
59
60
|
}
|
package/src/index.ts
CHANGED
|
@@ -1,6 +1,16 @@
|
|
|
1
1
|
export { memoryPluginFactory } from "./factory";
|
|
2
2
|
|
|
3
|
-
export type {
|
|
3
|
+
export type {
|
|
4
|
+
MemoryPluginOptions,
|
|
5
|
+
MemoryContext,
|
|
6
|
+
MemoryDirection,
|
|
7
|
+
} from "./types";
|
|
8
|
+
|
|
9
|
+
declare module "@real-router/types" {
|
|
10
|
+
interface StateContext {
|
|
11
|
+
memory?: import("./types").MemoryContext;
|
|
12
|
+
}
|
|
13
|
+
}
|
|
4
14
|
|
|
5
15
|
declare module "@real-router/core" {
|
|
6
16
|
interface Router {
|
package/src/plugin.ts
CHANGED
|
@@ -1,4 +1,9 @@
|
|
|
1
|
-
import type {
|
|
1
|
+
import type {
|
|
2
|
+
HistoryEntry,
|
|
3
|
+
MemoryContext,
|
|
4
|
+
MemoryDirection,
|
|
5
|
+
MemoryPluginOptions,
|
|
6
|
+
} from "./types";
|
|
2
7
|
import type {
|
|
3
8
|
NavigationOptions,
|
|
4
9
|
Plugin,
|
|
@@ -14,13 +19,19 @@ export class MemoryPlugin {
|
|
|
14
19
|
readonly #maxHistory: number;
|
|
15
20
|
readonly #entries: HistoryEntry[] = [];
|
|
16
21
|
readonly #removeExtensions: () => void;
|
|
22
|
+
readonly #claim: {
|
|
23
|
+
write: (state: State, value: MemoryContext) => void;
|
|
24
|
+
release: () => void;
|
|
25
|
+
};
|
|
17
26
|
#index = -1;
|
|
18
27
|
#navigatingFromHistory = false;
|
|
28
|
+
#pendingDirection: MemoryDirection = "navigate";
|
|
19
29
|
#goGeneration = 0;
|
|
20
30
|
|
|
21
31
|
constructor(router: Router, api: PluginApi, options: MemoryPluginOptions) {
|
|
22
32
|
this.#router = router;
|
|
23
33
|
this.#maxHistory = options.maxHistoryLength ?? DEFAULT_MAX_HISTORY;
|
|
34
|
+
this.#claim = api.claimContextNamespace("memory");
|
|
24
35
|
|
|
25
36
|
this.#removeExtensions = api.extendRouter({
|
|
26
37
|
back: () => {
|
|
@@ -45,6 +56,14 @@ export class MemoryPlugin {
|
|
|
45
56
|
opts: NavigationOptions,
|
|
46
57
|
) => {
|
|
47
58
|
if (this.#navigatingFromHistory) {
|
|
59
|
+
this.#claim.write(
|
|
60
|
+
toState,
|
|
61
|
+
Object.freeze({
|
|
62
|
+
direction: this.#pendingDirection,
|
|
63
|
+
historyIndex: this.#index,
|
|
64
|
+
}),
|
|
65
|
+
);
|
|
66
|
+
|
|
48
67
|
return;
|
|
49
68
|
}
|
|
50
69
|
|
|
@@ -68,6 +87,14 @@ export class MemoryPlugin {
|
|
|
68
87
|
this.#index = Math.max(0, this.#index - overflow);
|
|
69
88
|
}
|
|
70
89
|
}
|
|
90
|
+
|
|
91
|
+
this.#claim.write(
|
|
92
|
+
toState,
|
|
93
|
+
Object.freeze({
|
|
94
|
+
direction: "navigate" as const,
|
|
95
|
+
historyIndex: this.#index,
|
|
96
|
+
}),
|
|
97
|
+
);
|
|
71
98
|
},
|
|
72
99
|
|
|
73
100
|
onStop: () => {
|
|
@@ -76,6 +103,7 @@ export class MemoryPlugin {
|
|
|
76
103
|
|
|
77
104
|
teardown: () => {
|
|
78
105
|
this.#removeExtensions();
|
|
106
|
+
this.#claim.release();
|
|
79
107
|
this.#clear();
|
|
80
108
|
},
|
|
81
109
|
};
|
|
@@ -104,6 +132,7 @@ export class MemoryPlugin {
|
|
|
104
132
|
const previousIndex = this.#index;
|
|
105
133
|
const generation = ++this.#goGeneration;
|
|
106
134
|
|
|
135
|
+
this.#pendingDirection = delta > 0 ? "forward" : "back";
|
|
107
136
|
this.#navigatingFromHistory = true;
|
|
108
137
|
this.#index = targetIndex;
|
|
109
138
|
|
package/src/types.ts
CHANGED
|
@@ -1,5 +1,12 @@
|
|
|
1
1
|
import type { Params } from "@real-router/core";
|
|
2
2
|
|
|
3
|
+
export type MemoryDirection = "back" | "forward" | "navigate";
|
|
4
|
+
|
|
5
|
+
export interface MemoryContext {
|
|
6
|
+
direction: MemoryDirection;
|
|
7
|
+
historyIndex: number;
|
|
8
|
+
}
|
|
9
|
+
|
|
3
10
|
export interface MemoryPluginOptions {
|
|
4
11
|
maxHistoryLength?: number;
|
|
5
12
|
}
|