Compare commits
8 Commits
Author | SHA1 | Date | |
---|---|---|---|
ab5298c5a0 | |||
c74c4e78a6 | |||
fa8ec78c1c | |||
bd943726eb | |||
4e7bcfd48d | |||
8492192e72 | |||
90466ff2b6 | |||
fb974c3a0f |
24
changelog.md
24
changelog.md
@ -1,5 +1,29 @@
|
||||
# Changelog
|
||||
|
||||
## 2024-10-06 - 1.3.0 - feat(smartrouter)
|
||||
Add destroy method to SmartRouter class.
|
||||
|
||||
- Introduced a destroy method to the SmartRouter class for cleaning up event listeners and route references.
|
||||
- Refactored popstate event listener to be removable, improving resource management and preventing memory leaks.
|
||||
|
||||
## 2024-10-06 - 1.2.1 - fix(core)
|
||||
Ensure stability and performance improvements
|
||||
|
||||
- Improves platform compatibility for modern web applications.
|
||||
- Enhances stability of the routing logic within SmartRouter class.
|
||||
|
||||
## 2024-10-06 - 1.2.0 - feat(core)
|
||||
Add support for base paths and sub-routers.
|
||||
|
||||
- Added basePath feature to SmartRouter for handling base paths.
|
||||
- Introduced createSubRouter method to create a sub-router with a specific prefix.
|
||||
|
||||
## 2024-10-06 - 1.1.1 - fix(core)
|
||||
Remove SelectionDimension functionality
|
||||
|
||||
- Removed SelectionDimension class and references
|
||||
- Deleted smartrouter.classes.selectiondimension.ts and related imports
|
||||
|
||||
## 2024-10-06 - 1.1.0 - feat(core)
|
||||
Add selection dimensions and route removal functionality
|
||||
|
||||
|
@ -1,6 +1,6 @@
|
||||
{
|
||||
"name": "@push.rocks/smartrouter",
|
||||
"version": "1.1.0",
|
||||
"version": "1.3.0",
|
||||
"private": false,
|
||||
"description": "A JavaScript library providing routing capabilities for web applications.",
|
||||
"main": "dist_ts/index.js",
|
||||
|
@ -3,6 +3,6 @@
|
||||
*/
|
||||
export const commitinfo = {
|
||||
name: '@push.rocks/smartrouter',
|
||||
version: '1.1.0',
|
||||
version: '1.3.0',
|
||||
description: 'A JavaScript library providing routing capabilities for web applications.'
|
||||
}
|
||||
|
@ -1,50 +0,0 @@
|
||||
import * as plugins from './smartrouter.plugins.js';
|
||||
|
||||
export interface ISelectionOption<T = any> {
|
||||
key: string;
|
||||
detail: T;
|
||||
selected?: boolean;
|
||||
action: () => Promise<T>;
|
||||
}
|
||||
|
||||
export class SelectionDimension<T = any> {
|
||||
/**
|
||||
* the key of the selection dimension
|
||||
*/
|
||||
public dimensionKey: string;
|
||||
/**
|
||||
* the level of the selection dimension
|
||||
* a higher level is execution later than a lower level
|
||||
* during catchup phase
|
||||
*/
|
||||
public dimensionLevel: number;
|
||||
public dimensionPeers: SelectionDimension<T>[] = [];
|
||||
public selectionOptions: ISelectionOption<T>[] = [];
|
||||
|
||||
public selectionOptionSubject = new plugins.smartrx.rxjs.Subject<ISelectionOption<T>[]>();
|
||||
|
||||
public async emitSelectionOptions () {
|
||||
const selectionOptions = this.selectionOptions.map((selectionOptionArg): ISelectionOption => {
|
||||
return {
|
||||
key: selectionOptionArg.key,
|
||||
detail: selectionOptionArg.detail,
|
||||
action: async () => {
|
||||
this.updateSelection(selectionOptionArg);
|
||||
return await selectionOptionArg.action();
|
||||
},
|
||||
}
|
||||
});
|
||||
this.selectionOptionSubject.next(selectionOptions);
|
||||
}
|
||||
|
||||
public async updateSelection (selectionOptionArg: ISelectionOption<T>) {
|
||||
for (const selectionOption of this.selectionOptions) {
|
||||
if (selectionOption.key === selectionOptionArg.key) {
|
||||
selectionOption.selected = true;
|
||||
} else {
|
||||
selectionOption.selected = false;
|
||||
}
|
||||
}
|
||||
this.emitSelectionOptions();
|
||||
}
|
||||
}
|
@ -1,7 +1,6 @@
|
||||
import * as plugins from './smartrouter.plugins.js';
|
||||
|
||||
import { QueryParams } from './smartrouter.classes.queryparams.js';
|
||||
import { type ISelectionOption, SelectionDimension } from './smartrouter.classes.selectiondimension.js';
|
||||
|
||||
const routeLog = (message: string) => {
|
||||
console.log(`%c[Router]%c ${message}`, 'color: rgb(255, 105, 100);', 'color: inherit');
|
||||
@ -37,31 +36,54 @@ export class SmartRouter {
|
||||
handler: THandlerFunction;
|
||||
}> = [];
|
||||
|
||||
/**
|
||||
* base path for this router
|
||||
*/
|
||||
private basePath: string;
|
||||
|
||||
/**
|
||||
* Reference to the event listener function for cleanup
|
||||
*/
|
||||
private popstateListener: (event: PopStateEvent) => void;
|
||||
|
||||
/**
|
||||
* Creates an instance of Router.
|
||||
*/
|
||||
constructor(optionsArg: IRouterOptions) {
|
||||
constructor(optionsArg: IRouterOptions, basePath: string = '') {
|
||||
// lets set the router options
|
||||
this.options = {
|
||||
...this.options,
|
||||
...optionsArg,
|
||||
};
|
||||
this.basePath = basePath;
|
||||
|
||||
// lets subscribe to route changes
|
||||
window.addEventListener('popstate', (popStateEventArg) => {
|
||||
this.popstateListener = (popStateEventArg) => {
|
||||
popStateEventArg.preventDefault();
|
||||
this._handleRouteState();
|
||||
});
|
||||
};
|
||||
window.addEventListener('popstate', this.popstateListener);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a sub-router with a specific prefix
|
||||
* @param {string} subPath
|
||||
* @param {IRouterOptions} [options]
|
||||
*/
|
||||
public createSubRouter(subPath: string, options?: IRouterOptions): SmartRouter {
|
||||
const newBasePath = `${this.basePath}${subPath}`;
|
||||
return new SmartRouter({ ...this.options, ...options }, newBasePath);
|
||||
}
|
||||
|
||||
/**
|
||||
* Push route state to history stack
|
||||
*/
|
||||
public async pushUrl(url: string = '/', state: any = {}) {
|
||||
if (url !== window.location.pathname) {
|
||||
window.history.pushState(state, window.document.title, url);
|
||||
const fullUrl = `${this.basePath}${url}`;
|
||||
if (fullUrl !== window.location.pathname) {
|
||||
window.history.pushState(state, window.document.title, fullUrl);
|
||||
} else {
|
||||
window.history.replaceState(state, window.document.title, url);
|
||||
window.history.replaceState(state, window.document.title, fullUrl);
|
||||
}
|
||||
await this._handleRouteState();
|
||||
}
|
||||
@ -72,8 +94,9 @@ export class SmartRouter {
|
||||
* @param {function} handlerArg
|
||||
*/
|
||||
public on(routeArg: string, handlerArg: THandlerFunction) {
|
||||
const fullRoute = `${this.basePath}${routeArg}`;
|
||||
const routeObject = {
|
||||
matchFunction: plugins.pathToRegExp.match(routeArg),
|
||||
matchFunction: plugins.pathToRegExp.match(fullRoute),
|
||||
handler: handlerArg,
|
||||
};
|
||||
this.routes.push(routeObject);
|
||||
@ -103,18 +126,13 @@ export class SmartRouter {
|
||||
}
|
||||
}
|
||||
|
||||
public selectionDimensionsMap = new plugins.lik.ObjectMap<SelectionDimension>();
|
||||
public async createSelectionDimension(optionsArg: {
|
||||
routeArg: string,
|
||||
keyArg: string,
|
||||
options: ISelectionOption[],
|
||||
peers?: SelectionDimension[],
|
||||
}) {
|
||||
const selectionDimension = new SelectionDimension();
|
||||
selectionDimension.dimensionKey = optionsArg.keyArg;
|
||||
selectionDimension.dimensionPeers = optionsArg.peers;
|
||||
selectionDimension.selectionOptions = optionsArg.options;
|
||||
await this.selectionDimensionsMap.findOneAndRemove(async dimensionArg => dimensionArg.dimensionKey === optionsArg.keyArg);
|
||||
this.selectionDimensionsMap.addMappedUnique(optionsArg.keyArg, selectionDimension);
|
||||
/**
|
||||
* Destroy the router instance, removing all external references
|
||||
*/
|
||||
public destroy() {
|
||||
// Remove the event listener for popstate
|
||||
window.removeEventListener('popstate', this.popstateListener);
|
||||
// Clear all routes
|
||||
this.routes = [];
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user