UNPKG

ngx-foresight

Version:

<p align="center"> <img src="https://akshykhade.github.io/ngx-foresight/logo.svg" width="305px"> </p> <br/> <p align="center"> <a href="https://www.npmjs.com/package/ngx-foresight"> <img src="https://img.shields.io/npm/v/ngx-foresight.svg?style=fo

216 lines (208 loc) 8.31 kB
import * as i0 from '@angular/core'; import { Injectable, inject, Directive, Input } from '@angular/core'; import * as i1 from '@angular/router'; import { PRIMARY_OUTLET, Router, RouterPreloader } from '@angular/router'; import { ForesightManager } from 'js.foresight'; import { EMPTY } from 'rxjs'; // Using a global registry so we can keep it populated across lazy-loaded // modules with different parent injectors which create instance of the registry. const globalRegistry = []; class PrefetchRegistry { router; trees = globalRegistry; constructor(router) { this.router = router; } add(tree) { this.trees.push(tree); } shouldPrefetch(url) { const tree = this.router.parseUrl(url); return this.trees.some(containsTree.bind(null, tree)); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PrefetchRegistry, deps: [{ token: i1.Router }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PrefetchRegistry, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: PrefetchRegistry, decorators: [{ type: Injectable, args: [{ providedIn: 'root' }] }], ctorParameters: () => [{ type: i1.Router }] }); function containsQueryParams(container, containee) { // TODO: This does not handle array params correctly. return (Object.keys(containee).length <= Object.keys(container).length && Object.keys(containee).every((key) => containee[key] === container[key])); } function containsTree(containee, container) { return (containsQueryParams(container.queryParams, containee.queryParams) && containsSegmentGroup(container.root, containee.root, containee.root.segments)); } function containsSegmentGroup(container, containee, containeePaths) { if (container.segments.length > containeePaths.length) { const current = container.segments.slice(0, containeePaths.length); if (!equalPath(current, containeePaths)) return false; if (containee.hasChildren()) return false; return true; } else if (container.segments.length === containeePaths.length) { if (!equalPath(container.segments, containeePaths)) return false; if (!containee.hasChildren()) return true; for (const c in containee.children) { if (!container.children[c]) break; if (containsSegmentGroup(container.children[c], containee.children[c], containee.children[c].segments)) return true; } return false; } else { const current = containeePaths.slice(0, container.segments.length); const next = containeePaths.slice(container.segments.length); if (!equalPath(container.segments, current)) return false; if (!container.children[PRIMARY_OUTLET]) return false; return containsSegmentGroup(container.children[PRIMARY_OUTLET], containee, next); } } function equalPath(as, bs) { if (as.length !== bs.length) return false; return as.every((a, i) => a.path === bs[i].path || a.path.startsWith(':') || bs[i].path.startsWith(':')); } class ForesightjsDirective { elementRef; router = inject(Router); registry = inject(PrefetchRegistry); preloader = inject(RouterPreloader); routerLink = ''; href = ''; name = undefined; unregisterRef = () => { }; constructor(elementRef) { this.elementRef = elementRef; } ngOnInit() { const { unregister } = ForesightManager.instance.register({ element: this.elementRef.nativeElement, name: this.name, callback: () => { if (!this.routerLink && !this.href) { return; } const tree = this.router.parseUrl(this.routerLink || this.href); this.registry.add(tree); this.preloader.preload().subscribe(() => void 0); }, }); this.unregisterRef = unregister; } ngOnDestroy() { this.unregisterRef(); } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ForesightjsDirective, deps: [{ token: i0.ElementRef }], target: i0.ɵɵFactoryTarget.Directive }); static ɵdir = i0.ɵɵngDeclareDirective({ minVersion: "14.0.0", version: "18.2.13", type: ForesightjsDirective, isStandalone: true, selector: "[foresightjs],[registerForesight]", inputs: { routerLink: "routerLink", href: "href", name: ["registerForesight", "name"] }, ngImport: i0 }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ForesightjsDirective, decorators: [{ type: Directive, args: [{ selector: '[foresightjs],[registerForesight]', standalone: true, }] }], ctorParameters: () => [{ type: i0.ElementRef }], propDecorators: { routerLink: [{ type: Input }], href: [{ type: Input }], name: [{ type: Input, args: ['registerForesight'] }] } }); const findPath = (config, route) => { config = config.slice(); const parent = new Map(); const visited = new Set(); while (config.length) { const el = config.shift(); if (!el) { continue; } visited.add(el); if (el === route) break; let children = el.children || []; const current = el._loadedRoutes || []; for (const route of current) { if (route && route.children) { children = children.concat(route.children); } } children.forEach((r) => { if (visited.has(r)) return; parent.set(r, el); config.push(r); }); } let path = ''; let current = route; while (current) { if (isPrimaryRoute(current)) { path = `/${current.path}${path}`; } else { path = `/(${current.outlet}:${current.path}${path})`; } current = parent.get(current); } // For routes with empty paths (the resulted string will look like `///section/sub-section`) return path.replace(/[\/]+/, '/'); }; function isPrimaryRoute(route) { return route.outlet === PRIMARY_OUTLET || !route.outlet; } class ForesightjsStrategy { registry; router; loading = new Set(); constructor(registry, router) { this.registry = registry; this.router = router; } preload(route, load) { if (this.loading.has(route)) { // Don't preload the same route twice return EMPTY; } // Prevent from preloading if (route.data && route.data['preload'] === false) { return EMPTY; } const fullPath = findPath(this.router.config, route); if (this.registry.shouldPrefetch(fullPath)) { this.loading.add(route); return load(); } return EMPTY; } static ɵfac = i0.ɵɵngDeclareFactory({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ForesightjsStrategy, deps: [{ token: PrefetchRegistry }, { token: i1.Router }], target: i0.ɵɵFactoryTarget.Injectable }); static ɵprov = i0.ɵɵngDeclareInjectable({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ForesightjsStrategy, providedIn: 'root' }); } i0.ɵɵngDeclareClassMetadata({ minVersion: "12.0.0", version: "18.2.13", ngImport: i0, type: ForesightjsStrategy, decorators: [{ type: Injectable, args: [{ providedIn: 'root', }] }], ctorParameters: () => [{ type: PrefetchRegistry }, { type: i1.Router }] }); /* * Public API Surface of ngx-foresight */ /** * Generated bundle index. Do not edit. */ export { ForesightjsDirective, ForesightjsStrategy }; //# sourceMappingURL=ngx-foresight.mjs.map