Description | ||
---|---|---|
ngrx-ducks | Easy but explicit handling for Redux actions embracing OCP. |
Description | ||
---|---|---|
rxjs-operators | Helpful operators for RxJS |
Tool visualizing actions, reducers & effects in your Angular app
License: GNU Lesser General Public License v3.0
Description | ||
---|---|---|
ngrx-ducks | Easy but explicit handling for Redux actions embracing OCP. |
Description | ||
---|---|---|
rxjs-operators | Helpful operators for RxJS |
Use data that we currently read and put it into a structure being used to render the graph
const nodes = new vis.DataSet([{
id: 1,
level: 0,
label: "Compnent A"
},
{
id: 2,
level: 0,
label: "Component B"
},
{
id: 3,
level: 1,
label: "triggers"
},
{
id: 4,
level: 2,
label: "Reducer A"
},
{
id: 5,
level: 2,
label: "Effect A"
},
{
id: 6,
level: 3,
label: "dispatches"
},
{
id: 7,
level: 4,
label: "Effect A Action A"
},
{
id: 8,
level: 4,
label: "Effect A Action B"
}
]);
// create an array with edges
const edges = new vis.DataSet([{
from: 1,
to: 3,
arrows: "to"
},
{
from: 2,
to: 3,
arrows: "to"
},
{
from: 3,
to: 4,
arrows: "to"
},
{
from: 3,
to: 5,
arrows: "to"
},
{
from: 5,
to: 6,
arrows: "to"
},
{
from: 6,
to: 7,
arrows: "to"
},
{
from: 6,
to: 8,
arrows: "to"
},
]);
// create a network
const container = document.getElementById("mynetwork");
const data = {
nodes: nodes,
edges: edges
};
const options = {
edges: {
smooth: {
type: 'cubicBezier',
roundness: 0.4
}
},
layout: {
hierarchical: {
direction: "LR"
}
},
physics: false
};
const network = new vis.Network(container, data, options);
I am getting this error when I run ngrx-vis -p ./apps/client/tsconfig.app.json
C:\Projects\bnpl-front-end\node_modules\@ts-morph\common\node_modules\typescript\lib\typescript.js:112935
ts.Debug.assert(!!(moduleSymbol.flags & 1536 /* Module */));
^
TypeError: Cannot read properties of undefined (reading 'flags')
at addIndirectUsers (C:\Projects\bnpl-front-end\node_modules\@ts-morph\common\node_modules\typescript\lib\typescript.js:112935:49)
at addIndirectUsers (C:\Projects\bnpl-front-end\node_modules\@ts-morph\common\node_modules\typescript\lib\typescript.js:112941:29)
at addIndirectUsers (C:\Projects\bnpl-front-end\node_modules\@ts-morph\common\node_modules\typescript\lib\typescript.js:112941:29)
at addIndirectUsers (C:\Projects\bnpl-front-end\node_modules\@ts-morph\common\node_modules\typescript\lib\typescript.js:112941:29)
at addIndirectUsers (C:\Projects\bnpl-front-end\node_modules\@ts-morph\common\node_modules\typescript\lib\typescript.js:112941:29)
at addIndirectUsers (C:\Projects\bnpl-front-end\node_modules\@ts-morph\common\node_modules\typescript\lib\typescript.js:112941:29)
at addIndirectUsers (C:\Projects\bnpl-front-end\node_modules\@ts-morph\common\node_modules\typescript\lib\typescript.js:112941:29)
at handleNamespaceImport (C:\Projects\bnpl-front-end\node_modules\@ts-morph\common\node_modules\typescript\lib\typescript.js:112914:25)
at handleDirectImports (C:\Projects\bnpl-front-end\node_modules\@ts-morph\common\node_modules\typescript\lib\typescript.js:112879:37)
at getImportersForExport (C:\Projects\bnpl-front-end\node_modules\@ts-morph\common\node_modules\typescript\lib\typescript.js:112828:13)
Node.js v18.10.0
The application which I am trying to analyze is part of a Nx workspace, this is my package.json
:
"devDependencies": {
"@angular-devkit/build-angular": "14.2.7",
"@angular-eslint/eslint-plugin": "14.0.4",
"@angular-eslint/eslint-plugin-template": "14.0.4",
"@angular-eslint/template-parser": "14.0.4",
"@angular/cli": "~14.2.0",
"@angular/compiler-cli": "14.2.8",
"@angular/language-service": "14.2.8",
"@ngrx/eslint-plugin": "14.1.0",
"@ngrx/schematics": "14.0.0",
"@ngrx/store-devtools": "14.0.0",
"@nrwl/angular": "15.0.3",
"@nrwl/cli": "15.0.3",
"@nrwl/cypress": "15.0.3",
"@nrwl/eslint-plugin-nx": "15.0.3",
"@nrwl/jest": "15.0.3",
"@nrwl/linter": "15.0.3",
"@nrwl/workspace": "15.0.3",
"@types/jest": "28.1.8",
"@types/lodash": "^4.14.186",
"@types/node": "16.11.7",
"@types/uuid": "^9.0.0",
"@typescript-eslint/eslint-plugin": "5.36.1",
"@typescript-eslint/parser": "5.36.1",
"cypress": "^10.7.0",
"eslint": "8.15.0",
"eslint-config-prettier": "8.1.0",
"eslint-plugin-cypress": "2.10.3",
"eslint-plugin-rxjs": "5.0.2",
"eslint-plugin-rxjs-angular": "2.0.0",
"husky": "8.0.1",
"jasmine-marbles": "0.9.1",
"jest": "28.1.3",
"jest-environment-jsdom": "28.1.1",
"jest-preset-angular": "12.2.2",
"ng-packagr": "14.2.2",
"ngrx-vis": "^0.1.24",
"nx": "15.0.3",
"postcss": "8.4.5",
"postcss-import": "14.1.0",
"postcss-preset-env": "7.5.0",
"postcss-url": "10.1.3",
"prettier": "2.6.2",
"prettier-plugin-organize-imports": "3.0.3",
"pretty-quick": "3.1.3",
"ts-jest": "28.0.8",
"ts-node": "10.9.1",
"typescript": "4.8.4"
},
"dependencies": {
"@angular/animations": "14.2.8",
"@angular/cdk": "14.2.6",
"@angular/common": "14.2.8",
"@angular/compiler": "14.2.8",
"@angular/core": "14.2.8",
"@angular/forms": "14.2.8",
"@angular/material": "14.2.6",
"@angular/material-date-fns-adapter": "14.2.6",
"@angular/platform-browser": "14.2.8",
"@angular/platform-browser-dynamic": "14.2.8",
"@angular/router": "14.2.8",
"@ngneat/transloco": "4.1.0",
"@ngrx/component-store": "14.0.0",
"@ngrx/effects": "14.0.0",
"@ngrx/entity": "14.0.0",
"@ngrx/router-store": "14.0.0",
"@ngrx/store": "14.0.0",
"@nx-tools/container-metadata": "4.0.1",
"@nx-tools/nx-container": "4.0.1",
"angular-google-tag-manager": "^1.6.1",
"bootstrap": "5.1.3",
"chart.js": "3.9.1",
"date-fns": "^2.29.3",
"deepmerge": "4.2.2",
"filestack-js": "3.25.0",
"ibantools": "4.1.6",
"keen-slider": "6.8.5",
"lodash": "4.17.21",
"ngrx-store-localstorage": "14.0.0",
"ngx-device-detector": "4.0.1",
"ngx-iban": "14.0.0",
"ngx-mask": "14.2.3",
"ngx-pagination": "6.0.2",
"primeicons": "6.0.1",
"primeng": "14.1.2",
"rxjs": "~7.5.0",
"stripe": "^11.11.0",
"stylelint": "14.9.1",
"stylelint-config-twbs-bootstrap": "4.0.0",
"tslib": "2.3.0",
"uuid": "^9.0.0",
"zone.js": "0.11.4"
}
Action and file names could be rather long. The graph drawing algorithm directly places the action and origin-file on the same row lane by lane. However the labels may overlap and become unreadable. The workaround is to manually pull one of the nodes slightly up or down. This may be something the tool could to while generating the graph.
Inject data being read by vis.js into an index.html
to render the graph.
The index.html
is stored in a folder ngrx-vis/
html > body > #ngrx-actions-graph + vis.js + graph-data
Thanks for making this tool!
I have some selectors in a facade that currently aren't being used (small use case I know) but it might be good to show them attached to the facade like in the bottom example vs detached. Or perhaps mark that they're unused?
This is how it's used:
export class SourceFacade {
emissionCount$ = this.store.select(Selectors.selectEmissionCount);
}
First of all, thank you very much for this project.
I have found the same error in two projects (one private and the other opensource). The opensource project code is here: https://github.com/Caballerog/ngrx-pokedex/tree/ngrx-part3
I have followed the installation and configuration steps as described in README and my output is as follows:
[carlos@carlos-lenovo ngrx-pokedex]$ npm run ngrx-vis
> [email protected] ngrx-vis /home/carlos/www/github/caballerog/ngrx-pokedex
> ngrx-vis -p ./tsconfig.app.json
/home/carlos/www/github/caballerog/ngrx-pokedex/node_modules/ngrx-vis/utils/ngrx.js:3
var m = typeof Symbol === "function" && o[Symbol.iterator];
^
TypeError: object null is not iterable (cannot read property Symbol(Symbol.iterator))
at __read (/home/carlos/www/github/caballerog/ngrx-pokedex/node_modules/ngrx-vis/utils/ngrx.js:3:46)
at Object.segmentAction (/home/carlos/www/github/caballerog/ngrx-pokedex/node_modules/ngrx-vis/utils/ngrx.js:39:14)
at /home/carlos/www/github/caballerog/ngrx-pokedex/node_modules/ngrx-vis/core/ngrx-vanilla-inspector.js:41:198
at Array.map (<anonymous>)
at NgRxVanillaInspector.findActions (/home/carlos/www/github/caballerog/ngrx-pokedex/node_modules/ngrx-vis/core/ngrx-vanilla-inspector.js:41:14)
at /home/carlos/www/github/caballerog/ngrx-pokedex/node_modules/ngrx-vis/core/ngrx-vanilla-inspector.js:34:61
at Array.flatMap (<anonymous>)
at NgRxVanillaInspector.inspect (/home/carlos/www/github/caballerog/ngrx-pokedex/node_modules/ngrx-vis/core/ngrx-vanilla-inspector.js:34:22)
at Object.<anonymous> (/home/carlos/www/github/caballerog/ngrx-pokedex/node_modules/ngrx-vis/index.js:20:32)
at Module._compile (internal/modules/cjs/loader.js:956:30)
Node version:
node -v
v12.13.0
Thanks!
If no tsconfig is passed to the program it should look up the default paths in Angular CLI or Nx projects.
It could read the path from the angular.json
.
This issue collects some graphs NgRx Vis printed out that make me having a deeper look in the code base of the respective NgRx project.
Often I really find a code or a modelling issue.
The action below is handled by an effect but has no continuation.
It is not used.
No dispatcher is found.
The reason is that the action is remapped
in a stream and the reference is lost.
NgRx Vis cannot track the reference any more.
I don't consider this being a bug yet since remapping the action is not needed in this case
// Current
this.service.load().pipe(
map(entity => loadBook({book: entity})),
tap(action => store.dispatch(action))
// ...
)
// Better
this.service.load().pipe(
tap(entity => store.dispatch(loadBook({book: entity})))
// ...
)
The graph below looks a bit confusing first. Having a look in the codebase, you will see that the error handling is done in a separate effect that is called by other effects.
This graph shows up multiple times for that project. This is an indicator to create an effect being responsible for error handling.
Hi !
I noticed that in the ngrx-example-app folder, you are missing the configuration file angular.json
.
Therefore, it is impossible to use commands such as ng serve
.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
๐ Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. ๐๐๐
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google โค๏ธ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.