Advertisement
Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- class GraphRouter {
- constructor(state) {
- this.vertices = {};
- this.sortedVerticies = [];
- this.visitedVerticies = [];
- }
- addNode(path, dependencies, resolve) {
- const vertex = {
- name: path.split('/').pop(),
- path,
- edges: dependencies,
- resolve,
- };
- this.vertices[path] = vertex;
- }
- _visitForSort(vertex) {
- if (this.visitedVerticies[vertex.path] === 2) return;
- if (this.visitedVerticies[vertex.path] === 1) throw new Error(`CYCLE FOUND AT ${vertex}`);
- this.visitedVerticies[vertex.path] = 1;
- vertex.edges.length && vertex.edges.map((v) => this._visitForSort(this.vertices[v]));
- this.visitedVerticies[vertex.path] = 2;
- this.sortedVerticies.push(vertex);
- }
- sort() {
- // Reverse topological sort
- this.sortedVerticies = [];
- this.visitedVerticies = [];
- const vertices = Object.values(this.vertices);
- while (vertices.length > 0) {
- this._visitForSort(vertices.shift());
- }
- }
- _sortIfNotSorted() {
- if (Object.keys(this.vertices).length > this.sortedVerticies.length) {
- this.sort();
- }
- }
- get order() {
- this._sortIfNotSorted();
- return this.sortedVerticies;
- }
- next() {
- this._sortIfNotSorted();
- }
- goTo(route) {
- this._sortIfNotSorted();
- const verticies = this.sortedVerticies;
- let curr = verticies.shift();
- while (curr.path !== route) {
- console.log('Visiting', curr.path);
- curr.resolve('some render root', {internet: true}, () => {});
- curr = verticies.shift();
- }
- console.log('Visiting', curr.path);
- curr.resolve('some render root', {internet: true}, () => {});
- }
- _findRouteIndex(route) {
- this._sortIfNotSorted();
- return this.sortedVerticies.findIndex(route);
- }
- }
- const router = new GraphRouter();
- const internetDeps = [];
- const tvDeps = ['/tv-internet/internet'];
- const phoneDeps = ['/tv-internet/tv'];
- const tvInterenetDeps =
- ['/tv-internet/internet', '/tv-internet/tv', '/tv-internet/phone', '/sign-up'];
- const doneDeps = ['/tv-internet', '/promotions', '/sign-up'];
- const resolveNow = (_, __, resolve) => resolve(true);
- router.addNode('/tv-internet/internet', internetDeps, (div, state, resolve) => {
- if (state.internet) {
- return resolve();
- } else {
- div.innerHTML = `<div> internet </div>`
- }
- });
- router.addNode('/tv-internet/tv', tvDeps, resolveNow);
- router.addNode('/tv-internet/phone', phoneDeps, resolveNow);
- router.addNode('/tv-internet', tvInterenetDeps, resolveNow);
- router.addNode('/promotions', ['/sign-up'], resolveNow);
- router.addNode('/sign-up', [], resolveNow);
- router.addNode('/done', doneDeps, resolveNow)
- console.log(router.order.map((v) => v.path));
- router.goTo('/promotions');
- /*
- [ '/tv-internet/internet',
- '/tv-internet/tv',
- '/tv-internet/phone',
- '/sign-up',
- '/tv-internet',
- '/promotions',
- '/done' ]
- Visiting /tv-internet/internet
- Visiting /tv-internet/tv
- Visiting /tv-internet/phone
- Visiting /sign-up
- Visiting /tv-internet
- Visiting /promotions
- */
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement