├── .gitignore
├── .npmignore
├── .publishrc
├── .travis.yml
├── .vscode
└── settings.json
├── CONTRIBUTING.md
├── ISSUE_TEMPLATE.md
├── LICENSE
├── PULL_REQUEST_TEMPLATE.md
├── README.md
├── gulpfile.js
├── index.html
├── media
├── 1.png
├── 2.png
└── 3.png
├── package.json
├── server.js
├── src
├── actions
│ ├── app_actions.ts
│ ├── bindings_actions.ts
│ ├── logger_actions.ts
│ └── settings_actions.ts
├── components
│ ├── binding_explorer.tsx
│ ├── binding_props_explorer.tsx
│ ├── kernel_explorer.tsx
│ ├── log_details.tsx
│ ├── menu.tsx
│ ├── panel.tsx
│ ├── playground.tsx
│ ├── request_log.tsx
│ ├── request_tree.tsx
│ ├── settings.tsx
│ └── tip.tsx
├── config
│ └── routes.tsx
├── constants
│ ├── action_types.ts
│ └── json_tree_theme.ts
├── containers
│ ├── layout
│ │ └── layout.tsx
│ └── pages
│ │ ├── bindings_page.tsx
│ │ ├── logger_page.tsx
│ │ ├── playground_page.tsx
│ │ └── settings_page.tsx
├── core
│ ├── default_settings.ts
│ ├── logger.ts
│ ├── selectable_kernel.ts
│ └── selectable_log_entry.ts
├── interfaces
│ ├── globals.d.ts
│ └── interfaces.ts
├── main.tsx
├── reducers
│ ├── app_reducer.ts
│ ├── log_reducer.ts
│ └── setting_reducer.ts
└── utils
│ └── utils.ts
├── style
├── scrollbar.css
├── site.css
└── tree.css
├── test
└── stubs.ts
├── tsconfig.json
├── tslint.json
└── typings.json
/.gitignore:
--------------------------------------------------------------------------------
1 | # Logs
2 | logs
3 | *.log
4 | npm-debug.log*
5 |
6 | # Runtime data
7 | pids
8 | *.pid
9 | *.seed
10 |
11 | # Directory for instrumented libs generated by jscoverage/JSCover
12 | lib-cov
13 |
14 | # Coverage directory used by tools like istanbul
15 | coverage
16 |
17 | # Grunt intermediate storage (http://gruntjs.com/creating-plugins#storing-task-files)
18 | .grunt
19 |
20 | # node-waf configuration
21 | .lock-wscript
22 |
23 | # Compiled binary addons (http://nodejs.org/api/addons.html)
24 | build/Release
25 |
26 | # Dependency directory
27 | node_modules
28 | typings
29 |
30 | # build
31 | temp
32 | bundle
33 | lib
34 | node_modulestypings
35 |
36 | # Optional npm cache directory
37 | .npm
38 |
39 | # Optional REPL history
40 | .node_repl_history
41 |
42 | .typingsrc
--------------------------------------------------------------------------------
/.npmignore:
--------------------------------------------------------------------------------
1 | src
2 | test
3 | typings
4 | bundle
5 | build
6 | coverage
7 | docs
8 | wiki
9 | gulpfile.js
10 | bower.json
11 | karma.conf.js
12 | tsconfig.json
13 | typings.json
14 | CONTRIBUTING.md
15 | ISSUE_TEMPLATE.md
16 | PULL_REQUEST_TEMPLATE.md
17 | tslint.json
18 | wallaby.js
19 | .travis.yml
20 | .gitignore
21 | .vscode
22 | .publishrc
23 | type_definitions
24 |
--------------------------------------------------------------------------------
/.publishrc:
--------------------------------------------------------------------------------
1 | {
2 | "validations": {
3 | "vulnerableDependencies": true,
4 | "uncommittedChanges": true,
5 | "untrackedFiles": true,
6 | "sensitiveData": true,
7 | "branch": "master",
8 | "gitTag": true
9 | },
10 | "confirm": true,
11 | "publishTag": "latest",
12 | "prePublishScript": "npm test"
13 | }
--------------------------------------------------------------------------------
/.travis.yml:
--------------------------------------------------------------------------------
1 | language: node_js
2 | node_js:
3 | - 'stable'
4 | - '5.4.1'
5 | - '5.4.0'
6 | - '5.3.0'
7 | - '5.2.0'
8 | - '5.1.1'
9 | before_install:
10 | - npm install -g typings
11 | - typings install
12 |
--------------------------------------------------------------------------------
/.vscode/settings.json:
--------------------------------------------------------------------------------
1 | // Place your settings in this file to overwrite default and user settings.
2 | {
3 | "files.exclude": {
4 | "**/.git": true,
5 | "**/.svn": true,
6 | "**/.DS_Store": true,
7 | "temp": true
8 | }
9 | }
--------------------------------------------------------------------------------
/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Contributing to Inversify
2 |
3 | ## Setup
4 |
5 | 1 - Clone your fork of the repository:
6 | ```
7 | $ git clone https://github.com/YOUR_USERNAME/inversify-devtools.git
8 | ```
9 |
10 | 2 - Install typings:
11 | ```
12 | $ npm install -g typings
13 | ```
14 |
15 | 3 - Install type definitions:
16 | ```
17 | $ typings install
18 | ```
19 |
20 | 4 - Install npm dependencies:
21 | ```
22 | $ npm install
23 | ```
24 |
25 | 5 - Run build process
26 | ```
27 | $ gulp
28 | ```
29 |
30 | ## Guidelines
31 |
32 | - Please try to [combine multiple commits before pushing](http://stackoverflow.com/questions/6934752/combining-multiple-commits-before-pushing-in-git)
33 |
34 | - Please use `TDD` when fixing bugs. This means that you should write a unit test that fails because it reproduces the issue,
35 | then fix the issue finally run the test to ensure that the issue has been resolved. This helps us to prevent fixed bugs from
36 | happening again in the future.
37 |
38 | - Please keep the test coverage at 100%. Write additional unit test if necessary
39 |
40 | - Please create an issue before sending a PR ff your it is going to change the public interface of InversifyJS or it
41 | includes significant architecture changes.
42 |
43 | - Feel free to ask for help from other members of the InversifyJS team via the chat / mailing list or github issues.
--------------------------------------------------------------------------------
/ISSUE_TEMPLATE.md:
--------------------------------------------------------------------------------
1 | PLEASE DO NOT REPORT THE ISSUE HERE!
2 |
3 | PLEASE USE THE INVERSIFYJS REPO INSTEAD YOU CAN FIND THE REPO AT:
4 |
5 | https://github.com/inversify/InversifyJS/issues
6 |
7 | YOU CAN ALSO FIND US ON GITTER AT:
8 |
9 | https://gitter.im/inversify/InversifyJS
10 |
11 | THANKS!
12 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | The MIT License (MIT)
2 |
3 | Copyright (c) 2016 Remo H. Jansen
4 |
5 | Permission is hereby granted, free of charge, to any person obtaining a copy
6 | of this software and associated documentation files (the "Software"), to deal
7 | in the Software without restriction, including without limitation the rights
8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9 | copies of the Software, and to permit persons to whom the Software is
10 | furnished to do so, subject to the following conditions:
11 |
12 | The above copyright notice and this permission notice shall be included in all
13 | copies or substantial portions of the Software.
14 |
15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21 | SOFTWARE.
22 |
--------------------------------------------------------------------------------
/PULL_REQUEST_TEMPLATE.md:
--------------------------------------------------------------------------------
1 |
2 |
3 | ## Description
4 |
5 |
6 | ## Related Issue
7 |
8 |
9 |
10 |
11 |
12 | ## Motivation and Context
13 |
14 |
15 | ## How Has This Been Tested?
16 |
17 |
18 |
19 |
20 | ## Types of changes
21 |
22 | - [ ] Bug fix (non-breaking change which fixes an issue)
23 | - [ ] New feature (non-breaking change which adds functionality)
24 | - [ ] Breaking change (fix or feature that would cause existing functionality to change)
25 |
26 | ## Checklist:
27 |
28 |
29 | - [ ] My code follows the code style of this project.
30 | - [ ] My change requires a change to the documentation.
31 | - [ ] I have updated the documentation accordingly.
32 | - [ ] My change requires a change to the type definitions.
33 | - [ ] I have updated the type definitions accordingly.
34 | - [ ] I have read the **CONTRIBUTING** document.
35 | - [ ] I have added tests to cover my changes.
36 | - [ ] All new and existing tests passed.
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # inversify-devtools
2 |
3 | [](https://gitter.im/inversify/InversifyJS?utm_source=badge&utm_medium=badge&utm_campaign=pr-badge&utm_content=badge)
4 | [](https://travis-ci.org/inversify/devtools)
5 | [](http://badge.fury.io/js/inversify-devtools)
6 | [](https://david-dm.org/inversify/devtools#info=dependencies)
7 | [](https://david-dm.org/inversify/devtools/#info=devDependencies)
8 | [](https://david-dm.org/inversify/devtools/#info=peerDependenciess)
9 | [](https://snyk.io/test/github/inversify/devtools)
10 |
11 | [](https://nodei.co/npm/inversify-devtools/)
12 | [](https://nodei.co/npm/inversify-devtools/)
13 |
14 | A React/Redux application that powers the InversifyJS browser development tools.
15 |
16 | 
17 | 
18 | 
19 |
20 | You can use this project to add features to the suported browsers extensions.
21 |
22 | ### How to use this project?
23 |
24 | > NOTE: this project contains a web applicaiton used to power the browser extensions. If you are an InverisfyJS user looking for a browser extension you should visit the extension projects:
25 | > - [inversify-chrome-devtools](https://github.com/inversify/inversify-chrome-devtools)
26 |
27 | To use this project you must install it using npm:
28 |
29 | ```
30 | $ npm install --save inversify-devtools
31 | $ npm install --save-dev inversify-dts
32 | ```
33 | You can use the `connectKernel` function to connect an instance of the `Kernel` class to the devtools:
34 |
35 | ```ts
36 | ///
37 |
38 | import render from "inversify-devtools";
39 | import { Kernel } from "inversify";
40 |
41 | let containerId = "root";
42 | let connectKernel = render(containerId);
43 | let kernel = new Kernel();
44 | connectKernel(kernel);
45 | ```
46 |
47 | ### License
48 | License under the MIT License (MIT)
49 |
50 | Copyright © 2015 [Remo H. Jansen](http://www.remojansen.com)
51 |
52 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software
53 | and associated documentation files (the "Software"), to deal in the Software without restriction,
54 | including without limitation the rights to use, copy, modify, merge, publish, distribute,
55 | sublicense, and/or sell copies of the Software, and to permit persons to whom the Software
56 | is furnished to do so, subject to the following conditions:
57 |
58 | The above copyright notice and this permission notice shall be included in all copies or
59 | substantial portions of the Software.
60 |
61 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED,
62 | INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
63 | PURPOSE AND NONINFRINGEMENT.
64 |
65 | IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR
66 | OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
67 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
68 |
--------------------------------------------------------------------------------
/gulpfile.js:
--------------------------------------------------------------------------------
1 | "use strict";
2 |
3 | //******************************************************************************
4 | //* DEPENDENCIES
5 | //******************************************************************************
6 |
7 | var gulp = require("gulp"),
8 | tslint = require("gulp-tslint"),
9 | tsc = require("gulp-typescript"),
10 | runSequence = require("run-sequence"),
11 | browserify = require("browserify"),
12 | source = require("vinyl-source-stream"),
13 | buffer = require("vinyl-buffer");
14 |
15 | //******************************************************************************
16 | //* LINT ALL
17 | //******************************************************************************
18 | gulp.task("lint", function() {
19 |
20 | var config = { emitError: (process.env.CI) ? true : false };
21 |
22 | return gulp.src([
23 | "src/**/**.ts",
24 | "test/**/**.test.ts"
25 | ])
26 | .pipe(tslint())
27 | .pipe(tslint.report("verbose", config));
28 | });
29 |
30 | //******************************************************************************
31 | //* BUILD SOURCE
32 | //******************************************************************************
33 | var tsLibProject = tsc.createProject("tsconfig.json");
34 |
35 | gulp.task("build", function() {
36 | return gulp.src([
37 | "typings/index.d.ts",
38 | "node_modules/immutable/dist/immutable.d.ts",
39 | "node_modules/redux-bootstrap/type_definitions/redux-bootstrap/redux-bootstrap.d.ts",
40 | "node_modules/inversify/type_definitions/inversify/inversify.d.ts",
41 | "node_modules/inversify-dts/inversify-logger-middleware/inversify-logger-middleware.d.ts",
42 | "src/interfaces/interfaces.d.ts",
43 | "src/**/**.ts",
44 | "src/**/**.tsx"
45 | ])
46 | .pipe(tsc(tsLibProject))
47 | .on("error", function (err) {
48 | process.exit(1);
49 | })
50 | .js.pipe(gulp.dest("lib/"));
51 | });
52 |
53 | //******************************************************************************
54 | //* BUNDLE SOURCE
55 | //******************************************************************************
56 | gulp.task("bundle", function() {
57 |
58 | var mainFilePath = "lib/main.js";
59 | var outputFolder = "bundle";
60 | var outputFileName = "app.js";
61 |
62 | var bundler = browserify({
63 | debug: true
64 | });
65 |
66 | // TS compiler options are in tsconfig.json file
67 | return bundler.add(mainFilePath)
68 | .bundle()
69 | .pipe(source(outputFileName))
70 | .pipe(buffer())
71 | .pipe(gulp.dest(outputFolder));
72 | });
73 |
74 | //******************************************************************************
75 | //* TASK GROUPS
76 | //******************************************************************************
77 | gulp.task("default", function (cb) {
78 | runSequence(
79 | "lint",
80 | "build",
81 | "bundle",
82 | cb);
83 | });
84 |
--------------------------------------------------------------------------------
/index.html:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 | InversifyJS DevTools
8 |
9 |
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/media/1.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/inversify/inversify-devtools/6eb09c726bcf6f1f86f97df7dfc532d23418e44c/media/1.png
--------------------------------------------------------------------------------
/media/2.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/inversify/inversify-devtools/6eb09c726bcf6f1f86f97df7dfc532d23418e44c/media/2.png
--------------------------------------------------------------------------------
/media/3.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/inversify/inversify-devtools/6eb09c726bcf6f1f86f97df7dfc532d23418e44c/media/3.png
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "inversify-devtools",
3 | "version": "1.0.0",
4 | "description": "inversify-devtools",
5 | "main": "lib/main.js",
6 | "scripts": {
7 | "test": "gulp",
8 | "publish-please": "publish-please",
9 | "prepublish": "publish-please guard"
10 | },
11 | "repository": {
12 | "type": "git",
13 | "url": "git+https://github.com/inversify/inversify-devtools.git"
14 | },
15 | "keywords": [
16 | "redux",
17 | "react",
18 | "example"
19 | ],
20 | "author": "Remo H. Jansen ",
21 | "license": "MIT",
22 | "bugs": {
23 | "url": "https://github.com/inversify/inversify-devtools/issues"
24 | },
25 | "homepage": "https://github.com/inversify/inversify-devtools#readme",
26 | "dependencies": {
27 | "bootstrap": "^3.3.6",
28 | "font-awesome": "^4.6.1",
29 | "inversify-logger-middleware": "^1.0.0-rc.3",
30 | "react": "^15.0.1",
31 | "react-dom": "^15.0.1",
32 | "react-json-tree": "^0.7.4",
33 | "react-redux": "^4.4.5",
34 | "react-router": "^2.3.0",
35 | "react-router-redux": "^4.0.4",
36 | "redux": "^3.5.2",
37 | "redux-bootstrap": "^1.0.0-rc.1",
38 | "redux-immutable": "^3.0.6",
39 | "redux-thunk": "^2.0.1",
40 | "redux-devtools": "^3.2.0",
41 | "redux-devtools-dock-monitor": "^1.1.1",
42 | "redux-devtools-log-monitor": "^1.0.11",
43 | "redux-logger": "^2.6.1"
44 | },
45 | "devDependencies": {
46 | "browserify": "^13.0.0",
47 | "envify": "^3.4.1",
48 | "gulp": "^3.9.1",
49 | "gulp-tslint": "^5.0.0",
50 | "gulp-typescript": "^2.13.0",
51 | "inversify": "^2.0.0-rc.5",
52 | "inversify-dts": "^1.6.0",
53 | "publish-please": "^2.1.4",
54 | "reflect-metadata": "^0.1.3",
55 | "run-sequence": "^1.1.5",
56 | "tslint": "^3.8.1",
57 | "vinyl-buffer": "^1.0.0",
58 | "vinyl-source-stream": "^1.1.0"
59 | }
60 | }
61 |
--------------------------------------------------------------------------------
/server.js:
--------------------------------------------------------------------------------
1 | var bootstrap = require("redux-bootstrap");
2 | var routes = require("./config/routes");
3 |
4 | var result = bootstrap({
5 | container: "root",
6 | createHistory: createMemoryHistory,
7 | initialState: {},
8 | middlewares: [thunk],
9 | reducers: getReducers(),
10 | render: () => {}, // skip first render, we navigate first
11 | routes: getRoutes()
12 | });
13 |
14 | result.history.push("/users");
15 | result.output = renderToStaticMarkup(result.root);
--------------------------------------------------------------------------------
/src/actions/app_actions.ts:
--------------------------------------------------------------------------------
1 | import { getLogger } from "../core/logger";
2 | import { makeActionCreator } from "../utils/utils";
3 | import ACTION_TYPES from "../constants/action_types";
4 | import loggerActions from "./logger_actions";
5 | import SelectableKernel from "../core/selectable_kernel";
6 |
7 | let resize = makeActionCreator(ACTION_TYPES.RESIZE, "width", "height");
8 | let appInitSuccess = makeActionCreator(ACTION_TYPES.APP_INIT_SUCCESS, "__inversifyDevtools__");
9 | let kernelConnectSucess = makeActionCreator(ACTION_TYPES.KERNEL_CONNECT_SUCCESS, "kernel");
10 | let initSettings = makeActionCreator(ACTION_TYPES.APP_SETTINGS_SUCCESS, "settings");
11 |
12 | function appInitAsync() {
13 | return function(dispatch: Redux.Dispatch) {
14 |
15 | let __inversifyDevtools__ = function(kernel: inversify.interfaces.Kernel) {
16 | let logger = getLogger(loggerActions.addLogEntry, initSettings, dispatch);
17 | kernel.applyMiddleware(logger);
18 | let selectableKernel = new SelectableKernel(kernel);
19 | dispatch(kernelConnectSucess(selectableKernel));
20 | };
21 |
22 | dispatch(appInitSuccess(__inversifyDevtools__));
23 |
24 | };
25 | }
26 |
27 | export { appInitAsync, appInitSuccess, resize};
28 |
--------------------------------------------------------------------------------
/src/actions/bindings_actions.ts:
--------------------------------------------------------------------------------
1 | import { makeActionCreator } from "../utils/utils";
2 | import ACTION_TYPES from "../constants/action_types";
3 |
4 | let selectKernel = makeActionCreator(ACTION_TYPES.SELECT_KERNEL, "kernel");
5 | let selectBinding = makeActionCreator(ACTION_TYPES.SELECT_BINDING, "keyVal", "kernelGuid");
6 |
7 | let bindingsActions = {
8 | selectKernel,
9 | selectBinding
10 | };
11 |
12 | export default bindingsActions;
13 |
--------------------------------------------------------------------------------
/src/actions/logger_actions.ts:
--------------------------------------------------------------------------------
1 | import { makeActionCreator } from "../utils/utils";
2 | import ACTION_TYPES from "../constants/action_types";
3 |
4 | let addLogEntry = makeActionCreator(ACTION_TYPES.ADD_LOG_ENTRY, "entry", "logSize");
5 | let selectRequest = makeActionCreator(ACTION_TYPES.SELECT_LOG_ENTRY, "entry");
6 | let filterRequests = makeActionCreator(ACTION_TYPES.FILTER_LOG_ENTRIES, "filterBy");
7 | let clearRequests = makeActionCreator(ACTION_TYPES.CLEAR_LOG);
8 |
9 | let loggerActions = {
10 | addLogEntry,
11 | selectRequest,
12 | filterRequests,
13 | clearRequests
14 | };
15 |
16 | export default loggerActions;
17 |
--------------------------------------------------------------------------------
/src/actions/settings_actions.ts:
--------------------------------------------------------------------------------
1 | import { makeActionCreator } from "../utils/utils";
2 | import ACTION_TYPES from "../constants/action_types";
3 | import interfaces from "../interfaces/interfaces";
4 |
5 | let saveSettingsSuccess = makeActionCreator(ACTION_TYPES.SAVE_SETTINGS_SUCCESS, "settings");
6 | let saveSettingsError = makeActionCreator(ACTION_TYPES.SAVE_SETTINGS_ERROR, "exception");
7 |
8 | let saveSettingsAsync = function (settings: interfaces.UserSettings) {
9 | try {
10 | window.localStorage.setItem("inversify_settings", JSON.stringify(settings));
11 | return saveSettingsSuccess(settings);
12 | } catch (e) {
13 | return saveSettingsError(e);
14 | }
15 | };
16 |
17 | let settingsActions = {
18 | saveSettingsAsync
19 | };
20 |
21 | export default settingsActions;
22 |
--------------------------------------------------------------------------------
/src/components/binding_explorer.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { Link } from "react-router";
3 | import Panel from "./panel";
4 | import Tip from "./tip";
5 |
6 | class BindingExplorer extends React.Component {
7 |
8 | public constructor(props: any) {
9 | super(props);
10 | }
11 |
12 | public render() {
13 | return (
14 |
15 | {this._renderTip()}
16 | {this._renderBindings(this.props.dictionary)}
17 |
18 | );
19 | }
20 |
21 | private _renderTip() {
22 | if (this.props.dictionary.length === 0) {
23 | return (
24 |
25 | Click on one of the kernels on the kernel panel (left) to see its binding!
26 |
27 | );
28 | } else {
29 | return (
30 |
31 | Services with more than one implementation are displayed in yellow.
32 | Remember to add some metadata and constraints to avoid ambiguous match exceptions!
33 |
34 | );
35 | }
36 | }
37 |
38 | private _handleClick(keyVal: any) {
39 | this.props.selectBinding(keyVal, this.props.kernelGuid);
40 | }
41 |
42 | private _renderClass(length: number) {
43 | return (length > 1) ? "request requestBox warningBox" : "request requestBox defaultBox";
44 | }
45 |
46 | private _renderBindings(dictionary: any[]): JSX.Element[] {
47 | return dictionary.map((keyVal: any, id: number) => {
48 | return (
49 | { this._handleClick(keyVal); }}>
51 |
52 |
53 |
IMPLEMENTATIONS: {keyVal.value.length}
54 | {keyVal.serviceIdentifier.toString()}
55 |
56 |
57 |
58 | );
59 | });
60 | }
61 |
62 | }
63 |
64 | export default BindingExplorer;
65 |
--------------------------------------------------------------------------------
/src/components/binding_props_explorer.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { Link } from "react-router";
3 | import Panel from "./panel";
4 | import JSONTree from "react-json-tree";
5 | import theme from "../constants/json_tree_theme";
6 | import Tip from "./tip";
7 | import { formatBindings } from "../utils/utils";
8 |
9 | class BindingPropsExplorer extends React.Component {
10 |
11 | public constructor(props: any) {
12 | super(props);
13 | }
14 |
15 | public render() {
16 | return (
17 |
18 | {this._render()}
19 |
20 | );
21 | }
22 |
23 | private _render() {
24 | if (this.props.bindings.length > 0) {
25 | let bindings = formatBindings(this.props.bindings);
26 | return (
27 |
32 | );
33 | } else {
34 | return (
35 |
36 | Click on one of the services on the services panel (left) to see its binding!
37 |
38 | );
39 | }
40 | }
41 |
42 | }
43 |
44 | export default BindingPropsExplorer;
45 |
--------------------------------------------------------------------------------
/src/components/kernel_explorer.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { Link } from "react-router";
3 | import Panel from "./panel";
4 | import interfaces from "../interfaces/interfaces";
5 | import Tip from "./tip";
6 |
7 | const dir = {
8 | close: "▹",
9 | open: "▿"
10 | };
11 |
12 | class KernelExplorer extends React.Component {
13 |
14 | public constructor(props: any) {
15 | super(props);
16 | }
17 |
18 | public render() {
19 | return (
20 |
21 | {this._render()}
22 |
23 | );
24 | }
25 |
26 | private _render() {
27 | if (this.props.kernels.length > 0) {
28 | let kernels = this._renderKernels(this.props.kernels);
29 | return {kernels}
;
30 | } else {
31 | return
32 | No Kernels found! Use global
33 | __inversifyDevtools__
34 | to connect a kernel.
35 | ;
36 | }
37 | }
38 |
39 | private _handleClick(kernel: interfaces.SelectableKernel) {
40 | this.props.selectKernel(kernel);
41 | }
42 |
43 | private _renderKernels(kernels: interfaces.SelectableKernel[]) {
44 | return kernels.map((kernel: interfaces.SelectableKernel, id: number) => {
45 | return (
46 | { this._handleClick(kernel); }}>
47 |
48 |
GUID: {kernel.details.guid}
49 | Kernel
50 |
51 |
52 | );
53 | });
54 | }
55 |
56 | }
57 |
58 | export default KernelExplorer;
59 |
--------------------------------------------------------------------------------
/src/components/log_details.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import Panel from "./panel";
3 | import JSONTree from "react-json-tree";
4 | import theme from "../constants/json_tree_theme";
5 | import interfaces from "../interfaces/interfaces";
6 | import Tip from "./tip";
7 | import { formatBindings } from "../utils/utils";
8 |
9 | class LogDetails extends React.Component {
10 |
11 | public constructor(props: any) {
12 | super(props);
13 | }
14 |
15 | public render() {
16 | return (
17 |
18 | {this.props.entry ? this._renderEntry(this.props.entry) : this._renderTip() }
19 |
20 | );
21 | }
22 |
23 | private _renderTip() {
24 | return (
25 | Click on one of the requests on the request log to see its details!
26 | );
27 | }
28 |
29 | private _formatRequest(request: inversify.interfaces.Request) {
30 | request.bindings = formatBindings(request.bindings);
31 | request.childRequests = request.childRequests.map((childRequest: inversify.interfaces.Request) => {
32 | return this._formatRequest(childRequest);
33 | });
34 | return request;
35 | }
36 |
37 | private _renderEntry(entry: interfaces.SelectableLogEntry) {
38 |
39 | if (entry.details.error) {
40 |
41 | let stack = entry.details.exception.stack.split(" at ")
42 | .map((s: string, index: number) => {
43 | if (index === 0) {
44 | return (
45 |
46 |
47 | {`${s}`}
48 |
49 | );
50 | } else {
51 | return (
52 |
53 | {`at ${s}`}
54 |
55 | );
56 | }
57 | });
58 |
59 | return (
60 |
61 |
62 | {stack}
63 |
64 |
69 |
70 | );
71 |
72 | } else {
73 | entry.details.rootRequest = this._formatRequest(entry.details.rootRequest);
74 | return (
75 |
80 | );
81 | }
82 | }
83 |
84 | }
85 |
86 | export default LogDetails;
87 |
--------------------------------------------------------------------------------
/src/components/menu.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { Link } from "react-router";
3 |
4 | class Menu extends React.Component {
5 |
6 | public constructor(props: any) {
7 | super(props);
8 | }
9 |
10 | public render() {
11 | return (
12 |
13 |
14 |
15 |
16 |
17 |
18 |
19 |
20 |
21 |
22 |
23 |
24 | /* TEMP HIDE CLASS */
25 |
26 |
27 |
28 |
29 |
30 |
31 |
32 |
33 |
34 |
35 |
36 | );
37 | }
38 | }
39 |
40 | export default Menu;
41 |
--------------------------------------------------------------------------------
/src/components/panel.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { Link } from "react-router";
3 |
4 | class Panel extends React.Component {
5 |
6 | public constructor(props: any) {
7 | super(props);
8 | }
9 |
10 | public render() {
11 | let rowSize = 12;
12 | let columnSize: number = this.props.columnSize;
13 | let size = (100 / (rowSize / columnSize)).toFixed(2) + "%";
14 | return (
15 |
16 |
17 |
{this.props.subtitle}
18 | {this.props.title}
19 |
20 | {this.props.children}
21 |
22 | );
23 | }
24 | }
25 |
26 | export default Panel;
27 |
--------------------------------------------------------------------------------
/src/components/playground.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { Link } from "react-router";
3 | import Panel from "./panel";
4 |
5 | class Playground extends React.Component {
6 |
7 | public constructor(props: any) {
8 | super(props);
9 | }
10 |
11 | public render() {
12 | return (
13 |
15 |
16 |
17 |
18 | The playground is a sandbox. You can write some code here to try InversifyJS
19 | without having to set up the a real development environment.
20 |
21 |
22 |
23 | );
24 | }
25 |
26 | }
27 |
28 | export default Playground;
29 |
--------------------------------------------------------------------------------
/src/components/request_log.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import Panel from "./panel";
3 | import interfaces from "../interfaces/interfaces";
4 | import Tip from "./tip";
5 |
6 | class RequestLog extends React.Component {
7 |
8 | public constructor(props: any) {
9 | super(props);
10 | }
11 |
12 | public render() {
13 |
14 | return (
15 |
16 | {this._render()}
17 |
18 | );
19 |
20 | }
21 |
22 | private _render() {
23 | if (this.props.log.size > 0) {
24 | let entries = this.props.log.map((entry: interfaces.SelectableLogEntry, i: number) => {
25 | return this._renderEntry(entry, i);
26 | });
27 | return (
28 |
50 | );
51 | } else {
52 | return Awaiting requests. Ensure that at least one kernel instance is connected. ;
53 | }
54 | }
55 |
56 | private _onClearHandler() {
57 | this.props.clearRequests();
58 | }
59 |
60 | private _onFilterHandler(filterBy: string) {
61 | this.props.filterRequests(filterBy);
62 | }
63 |
64 | private _renderResult(entry: interfaces.SelectableLogEntry) {
65 | return entry.details.error ? entry.details.exception.message : entry.details.results[0].constructor.name;
66 | }
67 |
68 | private _renderTime(entry: interfaces.SelectableLogEntry) {
69 | return entry.details.error ? `ERROR!` : `SUCCESS: ${entry.details.time} ms`;
70 | }
71 |
72 | private _handleClick(entry: interfaces.SelectableLogEntry) {
73 | this.props.selectRequest(entry);
74 | }
75 |
76 | private _renderEntry(entry: interfaces.SelectableLogEntry, id: number) {
77 |
78 | // set box color based on status
79 | let classes = `request requestBox ${entry.details.error ? "errorBox" : "successBox"}`;
80 |
81 | // hide based on filter
82 | let filterByErrorAndEntryIsNotAnError = (this.props.filter === "ERROR" && entry.details.error === false);
83 | let filterBySuccessAndEntryIsAnError = (this.props.filter === "SUCCESS" && entry.details.error === true);
84 | if (filterByErrorAndEntryIsNotAnError || filterBySuccessAndEntryIsAnError) {
85 | classes = "hide";
86 | }
87 |
88 | return (
89 | { this._handleClick(entry); }}>
90 |
91 |
{this._renderTime(entry)}
92 | {entry.details.serviceIdentifier} {"\u279e"} {this._renderResult(entry)}
93 |
94 |
95 | );
96 | }
97 |
98 | }
99 |
100 | export default RequestLog;
101 |
--------------------------------------------------------------------------------
/src/components/request_tree.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import Panel from "./panel";
3 | import interfaces from "../interfaces/interfaces";
4 | import Tip from "./tip";
5 |
6 | class RequestTree extends React.Component {
7 |
8 | public constructor(props: any) {
9 | super(props);
10 | }
11 |
12 | public render() {
13 | return (
14 |
16 |
17 | {this._render()}
18 |
19 | );
20 | }
21 |
22 | private _render() {
23 | let entry = this.props.entry;
24 | if (entry) {
25 | if (entry.details.error) {
26 | return this._renderError();
27 | } else {
28 | return (
29 |
30 | {this._renderTree(entry)}
31 |
32 | );
33 | }
34 | } else {
35 | return this._renderTip();
36 | }
37 | }
38 |
39 | private _renderTip() {
40 | return (
41 | Click on one of the requests on the request log to see its details!
42 | );
43 | }
44 |
45 | private _renderError() {
46 | return (
47 |
48 |
49 | The composition tree cannot be displayed due to an error during the
50 | resolution process. Please refer to the request details panel to
51 | find out more information.
52 |
53 | );
54 | }
55 |
56 | private _renderTree(entry: interfaces.SelectableLogEntry) {
57 | let rootRequest = entry.details.rootRequest;
58 | return (
59 |
60 |
61 |
62 | {this._renderNode(rootRequest)}
63 | {this._renderLeaf(rootRequest.childRequests)}
64 |
65 |
66 |
67 | );
68 | }
69 |
70 | private _renderNode(request: inversify.interfaces.Request) {
71 | let result: any = request.bindings[0].implementationType;
72 | return {request.serviceIdentifier} {"\u279e"} {result.name} ;
73 | }
74 |
75 | private _renderLeaf(childRequests: inversify.interfaces.Request[]): JSX.Element {
76 | if (childRequests.length === 0) {
77 | return ;
78 | }
79 | return (
80 |
81 | {childRequests.map((childRequest: inversify.interfaces.Request) => {
82 | return (
83 |
84 | {this._renderNode(childRequest)}
85 | {this._renderLeaf(childRequest.childRequests)}
86 |
87 | );
88 | })}
89 |
90 | );
91 | }
92 |
93 | }
94 |
95 | export default RequestTree;
96 |
--------------------------------------------------------------------------------
/src/components/settings.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { Link } from "react-router";
3 | import Panel from "./panel";
4 | import getDefaultSettings from "../core/default_settings";
5 |
6 | class SettingsEditor extends React.Component {
7 |
8 | public constructor(props: any) {
9 | super(props);
10 | this.state = {
11 | size: props.settings.size
12 | };
13 | }
14 |
15 | public render() {
16 | return (
17 |
18 |
19 |
20 | Maximun Log Size:
21 | { this._handleChange("size", e.target.value); }} />
26 |
27 |
Save Changes
29 |
30 |
31 | );
32 | }
33 |
34 | private _handleChange(property: string, value: any) {
35 | let update: any = {};
36 | update[property] = value;
37 | this.setState(update);
38 | }
39 |
40 | private _handleSaveClick() {
41 | let settings = getDefaultSettings();
42 | settings.size = parseInt(this.state.size, null);
43 | this.props.saveSettingsAsync(settings);
44 | }
45 |
46 | }
47 |
48 | export default SettingsEditor;
49 |
--------------------------------------------------------------------------------
/src/components/tip.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 |
3 | class Tip extends React.Component {
4 |
5 | public constructor(props: any) {
6 | super(props);
7 | }
8 |
9 | public render() {
10 | return (
11 |
12 |
13 | {this.props.children}
14 |
15 | );
16 | }
17 |
18 | }
19 |
20 | export default Tip;
21 |
--------------------------------------------------------------------------------
/src/config/routes.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { IndexRoute, Route } from "react-router";
3 | import AppLayout from "../containers/layout/layout";
4 | import LoggerPage from "../containers/pages/logger_page";
5 | import BindingsPage from "../containers/pages/bindings_page";
6 | import SettingsPage from "../containers/pages/settings_page";
7 | import PlaygroundPage from "../containers/pages/playground_page";
8 |
9 | let routes = (
10 |
11 |
12 |
13 |
14 |
15 |
16 |
17 | );
18 |
19 | export default routes;
20 |
--------------------------------------------------------------------------------
/src/constants/action_types.ts:
--------------------------------------------------------------------------------
1 | const ACTION_TYPES = {
2 | ADD_LOG_ENTRY: "ADD_LOG_ENTRY",
3 | APP_INIT_SUCCESS: "APP_INIT_SUCCESS",
4 | APP_SETTINGS_SUCCESS: "APP_SETTINGS_SUCCESS",
5 | CLEAR_LOG: "CLEAR_LOG",
6 | FILTER_LOG_ENTRIES: "FILTER_LOG_ENTRIES",
7 | KERNEL_CONNECT_SUCCESS: "KERNEL_CONNECT_SUCCESS",
8 | RESIZE: "RESIZE",
9 | SAVE_SETTINGS_ERROR: "SAVE_SETTINGS_ERROR",
10 | SAVE_SETTINGS_SUCCESS: "SAVE_SETTINGS_SUCCESS",
11 | SELECT_BINDING: "SELECT_BINDING",
12 | SELECT_KERNEL: "SELECT_KERNEL",
13 | SELECT_LOG_ENTRY: "SELECT_LOG_ENTRY"
14 | };
15 |
16 | export default ACTION_TYPES;
17 |
--------------------------------------------------------------------------------
/src/constants/json_tree_theme.ts:
--------------------------------------------------------------------------------
1 | const theme = {
2 | author: "wimer hazenberg (http://www.monokai.nl)",
3 | base00: "#272822",
4 | base01: "#383830",
5 | base02: "#49483e",
6 | base03: "#75715e",
7 | base04: "#a59f85",
8 | base05: "#f8f8f2",
9 | base06: "#f5f4f1",
10 | base07: "#f9f8f5",
11 | base08: "#f92672",
12 | base09: "#fd971f",
13 | base0A: "#f4bf75",
14 | base0B: "#a6e22e",
15 | base0C: "#a1efe4",
16 | base0D: "#66d9ef",
17 | base0E: "#ae81ff",
18 | base0F: "#cc6633",
19 | scheme: "monokai",
20 | };
21 |
22 | export default theme;
23 |
--------------------------------------------------------------------------------
/src/containers/layout/layout.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import Menu from "../../components/menu";
3 | import { bindActionCreators } from "redux";
4 | import { connect } from "react-redux";
5 | import * as appActions from "../../actions/app_actions";
6 |
7 | const menuWidthPx = 53;
8 |
9 | function mapStateToPropsReposPage(state: any) {
10 | return {
11 | app: state.get("app")
12 | };
13 | }
14 |
15 | function mapDispatchToPropsReposPage(dispatch: Redux.Dispatch) {
16 | return { actions : bindActionCreators(appActions, dispatch) };
17 | }
18 |
19 | class AppLayout extends React.Component {
20 |
21 | public constructor(props: any) {
22 | super(props);
23 | }
24 |
25 | public render() {
26 | let page = this.props.location.pathname.split("/").join("");
27 | let style = {
28 | height: this.props.app.get("windowHeight"),
29 | width: (this.props.app.get("windowWidth") - menuWidthPx)
30 | };
31 | return (
32 |
33 |
34 |
35 | {this.props.children}
36 |
37 |
38 | );
39 | }
40 |
41 | public componentWillMount() {
42 | this.props.actions.appInitAsync();
43 | }
44 |
45 | public componentDidMount() {
46 | window.addEventListener("resize", (e) => { this._handleResize(); } );
47 | }
48 |
49 | public componentWillUnmount() {
50 | window.removeEventListener("resize", (e) => { this._handleResize(); });
51 | }
52 |
53 | private _handleResize() {
54 | this.props.actions.resize(window.innerWidth, window.innerHeight);
55 | }
56 |
57 | }
58 |
59 | export default connect(mapStateToPropsReposPage, mapDispatchToPropsReposPage)(AppLayout);
60 |
--------------------------------------------------------------------------------
/src/containers/pages/bindings_page.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { bindActionCreators } from "redux";
3 | import { connect } from "react-redux";
4 | import bindingsActions from "../../actions/bindings_actions";
5 | import KernelExplorer from "../../components/kernel_explorer";
6 | import BindingExplorer from "../../components/binding_explorer";
7 | import BindingPropsExplorer from "../../components/binding_props_explorer";
8 | import interfaces from "../../interfaces/interfaces";
9 |
10 | function mapStateToPropsReposPage(state: any) {
11 | return {
12 | app: state.get("app")
13 | };
14 | }
15 |
16 | function mapDispatchToPropsReposPage(dispatch: Redux.Dispatch) {
17 | return { actions : bindActionCreators(bindingsActions, dispatch) };
18 | }
19 |
20 | class BindingsPage extends React.Component {
21 | public render() {
22 |
23 | let kernels = this.props.app.get("kernels").toJSON();
24 | let selectedKernel: interfaces.SelectableKernel = kernels.filter((kernel: interfaces.SelectableKernel) => {
25 | return kernel.selected === true;
26 | })[0];
27 |
28 | let dictionary: any[] = [];
29 | let valuesOfSelectedKey: any = [];
30 | if (selectedKernel) {
31 | let _details: any = selectedKernel.details;
32 | dictionary = (_details._bindingDictionary._dictionary);
33 | let selectedKeyVal = dictionary.filter((keyVal: any) => {
34 | return keyVal.selected === true;
35 | })[0];
36 | valuesOfSelectedKey = selectedKeyVal ? selectedKeyVal.value : [];
37 | }
38 |
39 | let selectedKernelGuid = selectedKernel ? selectedKernel.details.guid : "";
40 |
41 | return (
42 |
43 |
46 |
47 |
51 |
52 |
54 |
55 |
56 | );
57 |
58 | }
59 | }
60 |
61 | export default connect(mapStateToPropsReposPage, mapDispatchToPropsReposPage)(BindingsPage);
62 |
--------------------------------------------------------------------------------
/src/containers/pages/logger_page.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { bindActionCreators } from "redux";
3 | import { connect } from "react-redux";
4 | import RequestLog from "../../components/request_log";
5 | import RequestTree from "../../components/request_tree";
6 | import LogDetails from "../../components/log_details";
7 | import loggerActions from "../../actions/logger_actions";
8 | import interfaces from "../../interfaces/interfaces";
9 |
10 | function mapStateToPropsReposPage(state: any) {
11 | return {
12 | app: state.get("app"),
13 | log: state.get("log")
14 | };
15 | }
16 |
17 | function mapDispatchToPropsReposPage(dispatch: Redux.Dispatch) {
18 | return { actions : bindActionCreators(loggerActions, dispatch) };
19 | }
20 |
21 | class LoggerPage extends React.Component {
22 | public render() {
23 |
24 | let entries: any = this.props.log.get("entries");
25 |
26 | let selectedEntry = entries.filter((entry: interfaces.SelectableLogEntry) => {
27 | return entry.selected === true;
28 | }).toJSON()[0];
29 |
30 | return (
31 |
32 |
33 |
38 |
39 |
40 |
41 |
42 |
43 | );
44 | }
45 | }
46 |
47 | export default connect(mapStateToPropsReposPage, mapDispatchToPropsReposPage)(LoggerPage);
48 |
--------------------------------------------------------------------------------
/src/containers/pages/playground_page.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { bindActionCreators } from "redux";
3 | import { connect } from "react-redux";
4 | import loggerActions from "../../actions/logger_actions";
5 | import Playground from "../../components/playground";
6 |
7 | function mapStateToPropsReposPage(state: any) {
8 | return {
9 | app: state.get("app")
10 | };
11 | }
12 |
13 | function mapDispatchToPropsReposPage(dispatch: Redux.Dispatch) {
14 | return { actions : bindActionCreators(loggerActions, dispatch) };
15 | }
16 |
17 | class PlaygroundPage extends React.Component {
18 | public render() {
19 | return (
20 |
21 | );
22 | }
23 | }
24 |
25 | export default connect(mapStateToPropsReposPage, mapDispatchToPropsReposPage)(PlaygroundPage);
26 |
--------------------------------------------------------------------------------
/src/containers/pages/settings_page.tsx:
--------------------------------------------------------------------------------
1 | import * as React from "react";
2 | import { bindActionCreators } from "redux";
3 | import { connect } from "react-redux";
4 | import loggerActions from "../../actions/logger_actions";
5 | import settingsActions from "../../actions/settings_actions";
6 | import SettingsEditor from "../../components/settings";
7 | import { combineActionsGroups } from "../../utils/utils";
8 |
9 | let actions = combineActionsGroups(loggerActions, settingsActions);
10 |
11 | function mapStateToPropsReposPage(state: any) {
12 | return {
13 | app: state.get("app"),
14 | settings: state.get("settings")
15 | };
16 | }
17 |
18 | function mapDispatchToPropsReposPage(dispatch: Redux.Dispatch) {
19 | return { actions : bindActionCreators(actions, dispatch) };
20 | }
21 |
22 | class SettingsPage extends React.Component {
23 | public render() {
24 | return (
25 |
28 | );
29 | }
30 | }
31 |
32 | export default connect(mapStateToPropsReposPage, mapDispatchToPropsReposPage)(SettingsPage);
33 |
--------------------------------------------------------------------------------
/src/core/default_settings.ts:
--------------------------------------------------------------------------------
1 | import interfaces from "../interfaces/interfaces";
2 |
3 | function getDefaultSettings () {
4 | let defaultSettings: interfaces.UserSettings = {
5 | request: {
6 | bindings: {
7 | activated: false,
8 | cache: false,
9 | constraint: false,
10 | dynamicValue: false,
11 | factory: false,
12 | implementationType: true,
13 | onActivation: false,
14 | provider: false,
15 | scope: true,
16 | serviceIdentifier: true,
17 | type: true
18 | },
19 | serviceIdentifier: true,
20 | target: {
21 | metadata: true,
22 | name: false,
23 | serviceIdentifier: false
24 | }
25 | },
26 | size: 20,
27 | time: true
28 | };
29 | return defaultSettings;
30 | }
31 |
32 | export default getDefaultSettings;
33 |
--------------------------------------------------------------------------------
/src/core/logger.ts:
--------------------------------------------------------------------------------
1 | import { makeLoggerMiddleware } from "inversify-logger-middleware";
2 | import SelectableLogEntry from "./selectable_log_entry";
3 | import getDefaultSettings from "./default_settings";
4 | import interfaces from "../interfaces/interfaces";
5 |
6 | function getSettings() {
7 |
8 | let settings: any = window.localStorage.getItem("inversify_settings");
9 |
10 | if (settings === null) {
11 | settings = getDefaultSettings();
12 | window.localStorage.setItem("inversify_settings", JSON.stringify(settings));
13 | } else {
14 | settings = JSON.parse(settings);
15 | }
16 |
17 | return settings;
18 |
19 | }
20 |
21 | function getLogger(
22 | addLogEntry: (entry: interfaces.SelectableLogEntry, logSize: number) => void,
23 | initSettings: (settings: interfaces.UserSettings) => void,
24 | dispatch: Redux.Dispatch
25 | ): inversify.interfaces.Middleware {
26 |
27 | let settings = getSettings();
28 |
29 | dispatch(initSettings(settings));
30 |
31 | let reduxRenderer = function(entry: inversifyLoggerMiddleware.interfaces.LogEntry) {
32 | dispatch(addLogEntry(new SelectableLogEntry(entry), getSettings().size));
33 | };
34 |
35 | let middleware = makeLoggerMiddleware(settings, reduxRenderer);
36 | return middleware;
37 | }
38 |
39 | export { getLogger };
40 |
--------------------------------------------------------------------------------
/src/core/selectable_kernel.ts:
--------------------------------------------------------------------------------
1 | import interfaces from "../interfaces/interfaces";
2 |
3 | class SelectableKernel implements interfaces.Selectable {
4 |
5 | public details: inversify.interfaces.Kernel;
6 | public selected: boolean;
7 |
8 | public constructor(details: inversify.interfaces.Kernel) {
9 | this.details = details;
10 | this.selected = false;
11 | }
12 | }
13 |
14 | export default SelectableKernel;
15 |
--------------------------------------------------------------------------------
/src/core/selectable_log_entry.ts:
--------------------------------------------------------------------------------
1 | import interfaces from "../interfaces/interfaces";
2 |
3 | class SelectableLogEntry implements interfaces.Selectable, interfaces.Displayable {
4 |
5 | public details: inversifyLoggerMiddleware.interfaces.LogEntry;
6 | public selected: boolean;
7 | public guid: string;
8 | public visible: boolean;
9 |
10 | public constructor(details: inversifyLoggerMiddleware.interfaces.LogEntry) {
11 | this.details = details;
12 | this.selected = false;
13 | this.visible = false;
14 | }
15 | }
16 |
17 | export default SelectableLogEntry;
18 |
--------------------------------------------------------------------------------
/src/interfaces/globals.d.ts:
--------------------------------------------------------------------------------
1 | declare module "react-json-tree" {
2 | let JSONTree: any;
3 | export default JSONTree;
4 | }
5 |
--------------------------------------------------------------------------------
/src/interfaces/interfaces.ts:
--------------------------------------------------------------------------------
1 |
2 | namespace interfaces {
3 |
4 | export interface UserSettings extends inversifyLoggerMiddleware.interfaces.LoggerSettings {
5 | size: number;
6 | }
7 |
8 | export interface Selectable {
9 | selected: boolean;
10 | }
11 |
12 | export interface Displayable {
13 | visible: boolean;
14 | }
15 |
16 | export interface SelectableKernel extends Selectable {
17 | details: inversify.interfaces.Kernel;
18 | selected: boolean;
19 | }
20 |
21 | export interface SelectableLogEntry extends Selectable, Displayable {
22 | details: inversifyLoggerMiddleware.interfaces.LogEntry;
23 | selected: boolean;
24 | visible: boolean;
25 | }
26 |
27 | }
28 |
29 | export default interfaces;
30 |
--------------------------------------------------------------------------------
/src/main.tsx:
--------------------------------------------------------------------------------
1 | import thunk from "redux-thunk";
2 | import { bootstrap } from "redux-bootstrap";
3 | import routes from "./config/routes";
4 | import appReducer from "./reducers/app_reducer";
5 | import logReducer from "./reducers/log_reducer";
6 | import settingReducer from "./reducers/setting_reducer";
7 |
8 | function render(container: string) {
9 |
10 | let result = bootstrap({
11 | container: container,
12 | initialState: {},
13 | middlewares: [thunk],
14 | reducers: {
15 | app: appReducer,
16 | log: logReducer,
17 | settings: settingReducer
18 | },
19 | routes: routes
20 | });
21 | let state = result.store.getState();
22 | let connectKernel: (kernel: inversify.interfaces.Kernel) => void = state.get("app").get("__inversifyDevtools__");
23 | return connectKernel;
24 |
25 | }
26 |
27 | export default render;
28 |
--------------------------------------------------------------------------------
/src/reducers/app_reducer.ts:
--------------------------------------------------------------------------------
1 | import * as Immutable from "immutable";
2 | import ACTION_TYPES from "../constants/action_types";
3 | import interfaces from "../interfaces/interfaces";
4 |
5 | const defaultState = Immutable.fromJS({
6 | __inversifyDevtools__: null,
7 | kernels: [],
8 | windowHeight: window.innerHeight,
9 | windowWidth: window.innerWidth
10 | });
11 |
12 | function initAppSuccess(previousState: any, action: any) {
13 | return previousState.set("__inversifyDevtools__", action.__inversifyDevtools__);
14 | }
15 |
16 | function resize(previousState: any, action: any) {
17 | return previousState.withMutations((ctx: any) => {
18 | ctx.set("windowWidth", action.width).set("windowHeight", action.height);
19 | });
20 | }
21 |
22 | function kernelConnectSucess(previousState: any, action: any) {
23 | let kernels = previousState.get("kernels");
24 | let dictionary = (action.kernel.details)._bindingDictionary._dictionary;
25 | dictionary.forEach((keyValPair: inversify.interfaces.KeyValuePair) => {
26 | (keyValPair).selected = false;
27 | });
28 | let updatedKernels = kernels.push(action.kernel);
29 | return previousState.set("kernels", updatedKernels);
30 | }
31 |
32 | function selectKernel(previousState: any, action: any) {
33 | let kernels = previousState.get("kernels");
34 | let updatedKernels = kernels.map((kernel: interfaces.SelectableKernel) => {
35 | kernel.selected = (kernel.details.guid === action.kernel.details.guid);
36 | return kernel;
37 | });
38 | return previousState.set("kernels", updatedKernels);
39 | }
40 |
41 | function selectBinding(previousState: any, action: any) {
42 | let kernels = previousState.get("kernels");
43 | let updatedKernels = kernels.map((kernel: interfaces.SelectableKernel) => {
44 | if (kernel.details.guid === action.kernelGuid) {
45 | let dictionary = (kernel.details)._bindingDictionary._dictionary;
46 | dictionary = dictionary.map((keyValPair: inversify.interfaces.KeyValuePair) => {
47 | (keyValPair).selected = (keyValPair.guid === action.keyVal.guid);
48 | return keyValPair;
49 | });
50 | }
51 | return kernel;
52 | });
53 | return previousState.set("kernels", updatedKernels);
54 | }
55 |
56 | const appReducer: Redux.Reducer = (previousState: any = defaultState, action: any) => {
57 | switch (action.type) {
58 | case ACTION_TYPES.RESIZE:
59 | return resize(previousState, action);
60 | case ACTION_TYPES.APP_INIT_SUCCESS:
61 | return initAppSuccess(previousState, action);
62 | case ACTION_TYPES.KERNEL_CONNECT_SUCCESS:
63 | return kernelConnectSucess(previousState, action);
64 | case ACTION_TYPES.SELECT_KERNEL:
65 | return selectKernel(previousState, action);
66 | case ACTION_TYPES.SELECT_BINDING:
67 | return selectBinding(previousState, action);
68 | default:
69 | return previousState;
70 | }
71 | };
72 |
73 | export default appReducer;
74 |
--------------------------------------------------------------------------------
/src/reducers/log_reducer.ts:
--------------------------------------------------------------------------------
1 | import * as Immutable from "immutable";
2 | import ACTION_TYPES from "../constants/action_types";
3 | import interfaces from "../interfaces/interfaces";
4 |
5 | const defaultWindowState = Immutable.fromJS({
6 | entries: [],
7 | filter: "ALL"
8 | });
9 |
10 | function addLogEntry(previousState: any, action: any) {
11 | let entries = previousState.get("entries");
12 | if (entries.size === action.logSize) {
13 | let indexToRemove = 0;
14 | let numberToRemove = 1;
15 | entries = entries.splice(indexToRemove, numberToRemove);
16 | }
17 | let updatedEntries = entries.push(action.entry);
18 | return previousState.set("entries", updatedEntries);
19 | }
20 |
21 | function selectLogEntry(previousState: any, action: any) {
22 | let entries = previousState.get("entries");
23 | let updatedEntries = entries.map((entry: interfaces.SelectableLogEntry) => {
24 | entry.selected = (entry.details.guid === action.entry.details.guid);
25 | return entry;
26 | });
27 | return previousState.set("entries", updatedEntries);
28 | }
29 |
30 | function filterEntries(previousState: any, action: any) {
31 | return previousState.set("filter", action.filterBy);
32 | }
33 |
34 | function clearEntries(previousState: any) {
35 | let emptyLog = Immutable.fromJS([]);
36 | return previousState.set("entries", emptyLog);
37 | }
38 |
39 | const logReducer: Redux.Reducer = (previousState: any = defaultWindowState, action: any) => {
40 | switch (action.type) {
41 | case ACTION_TYPES.ADD_LOG_ENTRY:
42 | return addLogEntry(previousState, action);
43 | case ACTION_TYPES.SELECT_LOG_ENTRY:
44 | return selectLogEntry(previousState, action);
45 | case ACTION_TYPES.CLEAR_LOG:
46 | return clearEntries(previousState);
47 | case ACTION_TYPES.FILTER_LOG_ENTRIES:
48 | return filterEntries(previousState, action);
49 | default:
50 | return previousState;
51 | }
52 | };
53 |
54 | export default logReducer;
55 |
--------------------------------------------------------------------------------
/src/reducers/setting_reducer.ts:
--------------------------------------------------------------------------------
1 | import * as Immutable from "immutable";
2 | import ACTION_TYPES from "../constants/action_types";
3 | import interfaces from "../interfaces/interfaces";
4 | import getDefaultSettings from "../core/default_settings";
5 |
6 | const defaultState = Immutable.fromJS({
7 | settings: getDefaultSettings()
8 | });
9 |
10 | function initSettingsSuccess(previousState: any, action: any) {
11 | return previousState.set("settings", action.settings);
12 | }
13 |
14 | function saveSettingsSuccess(previousState: any, action: any) {
15 | return previousState.set("settings", action.settings);
16 | }
17 |
18 | function saveSettingsError(previousState: any, action: any) {
19 | console.log("TODO!");
20 | }
21 |
22 | const settingReducer: Redux.Reducer = (previousState: any = defaultState, action: any) => {
23 | switch (action.type) {
24 | case ACTION_TYPES.APP_SETTINGS_SUCCESS:
25 | return initSettingsSuccess(previousState, action);
26 | case ACTION_TYPES.SAVE_SETTINGS_SUCCESS:
27 | return saveSettingsSuccess(previousState, action);
28 | case ACTION_TYPES.SAVE_SETTINGS_ERROR:
29 | return saveSettingsError(previousState, action);
30 | default:
31 | return previousState;
32 | }
33 | };
34 |
35 | export default settingReducer;
36 |
--------------------------------------------------------------------------------
/src/utils/utils.ts:
--------------------------------------------------------------------------------
1 |
2 | import { scopeFormatter, bindingTypeFormatter } from "inversify-logger-middleware";
3 |
4 | function makeActionCreator(type: string, ...argNames: string[]) {
5 | return function(...args: any[]) {
6 | let action: any = { type : type };
7 | argNames.forEach((arg, index) => {
8 | let argName: string = argNames[index];
9 | let argValue: any = args[index];
10 | action[argName] = argValue;
11 | });
12 | return action;
13 | };
14 | }
15 |
16 | function combineActionsGroups(...actionGroups: any[]) {
17 | let mixing: any = {};
18 | actionGroups.forEach((actionGroup: any) => {
19 | Object.keys(actionGroup).forEach((key: string) => {
20 | if (mixing[key] !== undefined) {
21 | throw new Error("Mixing cannot be applied due to duplicated key!");
22 | } else {
23 | mixing[key] = actionGroup[key];
24 | }
25 | });
26 | });
27 | return mixing;
28 | }
29 |
30 | function formatBindings(bindings: inversify.interfaces.Binding[]) {
31 | return bindings.map((binding: any) => {
32 | if (typeof binding.scope === "number") {
33 | binding.scope = scopeFormatter(binding.scope);
34 | }
35 | if (typeof binding.type === "number") {
36 | binding.type = bindingTypeFormatter(binding.type);
37 | }
38 | return binding;
39 | });
40 | }
41 |
42 | export { makeActionCreator, combineActionsGroups, formatBindings };
43 |
--------------------------------------------------------------------------------
/style/scrollbar.css:
--------------------------------------------------------------------------------
1 | /* Turn on custom 8px wide scrollbar */
2 | ::-webkit-scrollbar {
3 | width: 10px; /* 1px wider than Lion. */
4 | /* This is more usable for users trying to click it. */
5 | background-color: rgba(0,0,0,0);
6 | -webkit-border-radius: 100px;
7 | }
8 | /* hover effect for both scrollbar area, and scrollbar 'thumb' */
9 | ::-webkit-scrollbar:hover {
10 | background-color: rgba(0, 0, 0, 0.09);
11 | }
12 |
13 | /* The scrollbar 'thumb' ...that marque oval shape in a scrollbar */
14 | ::-webkit-scrollbar-thumb:vertical {
15 | /* This is the EXACT color of Mac OS scrollbars.
16 | Yes, I pulled out digital color meter */
17 | background: rgba(0,0,0,0.5);
18 | -webkit-border-radius: 100px;
19 | background-clip: padding-box;
20 | border: 2px solid rgba(0, 0, 0, 0);
21 | min-height: 10px; /*Prevent it from getting too small */
22 | }
23 | ::-webkit-scrollbar-thumb:vertical:active {
24 | background: rgba(0,0,0,0.61); /* Some darker color when you click it */
25 | -webkit-border-radius: 100px;
26 | }
--------------------------------------------------------------------------------
/style/site.css:
--------------------------------------------------------------------------------
1 | @import url(https://fonts.googleapis.com/css?family=Raleway);
2 |
3 | body {
4 | min-height: 1000px
5 | }
6 | div#container {
7 | height: 200px;
8 | width: 300px;
9 | overflow: scroll;
10 | margin: 10px;
11 | border: 1px solid #000
12 | }
13 | div#content {
14 | height: 1000px;
15 | }
16 |
17 | body {
18 | font-family: 'Raleway', sans-serif;
19 | font-size: 14px;
20 | line-height: 1.5;
21 | color: #cfd2da;
22 | background-color: #1e1e1e;
23 | overflow: hidden;
24 | }
25 |
26 | ul {
27 | list-style: none;
28 | padding: 0px;
29 | }
30 |
31 | li {
32 | padding: 0px;
33 | }
34 |
35 | .main {
36 | float: left;
37 | overflow: hidden;
38 | }
39 |
40 | .menu {
41 | background-color: #333333;
42 | padding: 15px 0px;
43 | width: 53px;
44 | float: left;
45 | overflow: hidden;
46 | }
47 |
48 | .menu li {
49 | padding: 10px 0px;
50 | }
51 |
52 | .menu li a {
53 | color: #adadad;
54 | padding: 15px;
55 | font-size: 25px;
56 | cursor: pointer;
57 | }
58 |
59 | .menu li.active a {
60 | color: #ffffff;
61 | }
62 |
63 | .menu li a:hover {
64 | color: #ffffff;
65 | }
66 |
67 | .panel {
68 | background-color: #252526;
69 | width: 33%;
70 | float: left;
71 | padding: 10px 15px;
72 | border-right: 2px solid #333333;
73 | overflow-y: scroll;
74 | overflow-x: hidden;
75 | }
76 |
77 | .title {
78 | margin-top: 0;
79 | margin-bottom: 5px;
80 | font-weight: normal;
81 | font-size: 85%;
82 | letter-spacing: 1px;
83 | text-transform: uppercase;
84 | }
85 |
86 | .title h2, .title h6 {
87 | font-family: inherit;
88 | font-weight: 300;
89 | line-height: 1.1;
90 | }
91 |
92 | .title h2 {
93 | color: #ffffff;
94 | margin-top: 0px;
95 | padding-bottom: 10px;
96 | border-bottom: 1px solid #3e3e3e;
97 | }
98 |
99 | .title h6 {
100 | color: #adadad;
101 | text-transform: uppercase;
102 | margin-bottom: 0px;
103 | }
104 |
105 | .checkbox-custom, .radio-custom {
106 | opacity: 0;
107 | position: absolute;
108 | }
109 |
110 | .checkbox-custom, .checkbox-custom-label, .radio-custom, .radio-custom-label {
111 | display: inline-block;
112 | vertical-align: middle;
113 | margin: 5px;
114 | cursor: pointer;
115 | }
116 |
117 | .checkbox-custom-label, .radio-custom-label {
118 | position: relative;
119 | }
120 |
121 | .checkbox-custom + .checkbox-custom-label:before, .radio-custom + .radio-custom-label:before {
122 | content: '';
123 | background: #fff;
124 | border: 2px solid #ddd;
125 | display: inline-block;
126 | vertical-align: middle;
127 | width: 20px;
128 | height: 20px;
129 | padding: 2px;
130 | margin-right: 10px;
131 | text-align: center;
132 | }
133 |
134 | .checkbox-custom:checked + .checkbox-custom-label:before {
135 | content: "\f00c";
136 | font-family: 'FontAwesome';
137 | background: rebeccapurple;
138 | color: #fff;
139 | }
140 |
141 | .radio-custom + .radio-custom-label:before {
142 | border-radius: 50%;
143 | }
144 |
145 | .radio-custom:checked + .radio-custom-label:before {
146 | content: "\f00c";
147 | font-family: 'FontAwesome';
148 | color: #bbb;
149 | }
150 |
151 | .checkbox-custom:focus + .checkbox-custom-label, .radio-custom:focus + .radio-custom-label {
152 | outline: 1px solid #ddd; /* focus style */
153 | }
154 |
155 | .request {
156 | background-color: rgba(255, 255, 255, 0.0980392);
157 | padding: 10px 20px 10px 20px;
158 | margin-bottom: 5px;
159 | border-radius: 5px;
160 | cursor: pointer;
161 | }
162 |
163 | .request h6 {
164 | text-transform: uppercase;
165 | font-size: 11px;
166 | margin-top: 0px;
167 | margin-bottom: 5px;
168 | }
169 |
170 | .request h2 {
171 | font-size: 18px;
172 | margin-top: 0px;
173 | margin-bottom: 0px;
174 | }
175 |
176 | .requestBox {
177 | color: #ffffff;
178 | }
179 |
180 | .successBox {
181 | background-color: #1bc98e;
182 | }
183 |
184 | .errorBox {
185 | background-color: #e64759;
186 | }
187 |
188 | .defaultBox {
189 | background-color: #1ca8dd;
190 | }
191 |
192 | .warningBox {
193 | background-color: #e4d836;
194 | }
195 |
196 | .customAlert {
197 | color: #1997c6;
198 | background-color: transparent;
199 | border-color: #1997c6;
200 | border: 1px solid;
201 | padding: 10px 16px;
202 | font-size: 14px;
203 | line-height: 1.3333333;
204 | border-radius: 6px;
205 | margin-top: 5px;
206 | margin-bottom: 5px;
207 | }
208 |
209 | .customAlert i, .customErrorAlert i {
210 | margin-right: 5px;
211 | }
212 |
213 | .entryDetails ul {
214 | background-color: #252526 !important;
215 | }
216 |
217 | .customErrorAlert {
218 | color: #e33145;
219 | background-color: transparent;
220 | border-color: #e33145;
221 | border: 1px solid;
222 | padding: 10px 16px;
223 | font-size: 14px;
224 | line-height: 1.3333333;
225 | border-radius: 6px;
226 | margin-top: 5px;
227 | margin-bottom: 5px;
228 | }
229 |
230 | .panelTopMenu ul {
231 | list-style: none;
232 | padding: 0px;
233 | margin: 0px;
234 | height: 35px;
235 | }
236 |
237 | .panelTopMenu li {
238 | float: left;
239 | width: 25%;
240 | }
241 |
242 | .panelTopMenu a {
243 | background-color: rgb(79, 90, 101);
244 | color: #ffffff;
245 | text-decoration: none;
246 | padding: 5px;
247 | border-radius: 3px;
248 | font-size: 10px;
249 | width: 97%;
250 | text-align: center;
251 | display: table;
252 | cursor: pointer;
253 | }
254 |
255 | .panelTopMenu a.active {
256 | background-color: #1ca8dd;
257 | }
258 |
--------------------------------------------------------------------------------
/style/tree.css:
--------------------------------------------------------------------------------
1 | * {margin: 0; padding: 0;}
2 |
3 | .tree ul {
4 | padding-top: 20px; position: relative;
5 |
6 | transition: all 0.5s;
7 | -webkit-transition: all 0.5s;
8 | -moz-transition: all 0.5s;
9 | }
10 |
11 | .tree li {
12 | float: left; text-align: center;
13 | list-style-type: none;
14 | position: relative;
15 | padding: 20px 5px 0 5px;
16 |
17 | transition: all 0.5s;
18 | -webkit-transition: all 0.5s;
19 | -moz-transition: all 0.5s;
20 | }
21 |
22 | /*We will use ::before and ::after to draw the connectors*/
23 |
24 | .tree li::before, .tree li::after{
25 | content: '';
26 | position: absolute; top: 0; right: 50%;
27 | border-top: 1px solid rgb(166, 226, 46);
28 | width: 50%; height: 20px;
29 | }
30 | .tree li::after{
31 | right: auto; left: 50%;
32 | border-left: 1px solid rgb(166, 226, 46);
33 | }
34 |
35 | /*We need to remove left-right connectors from elements without
36 | any siblings*/
37 | .tree li:only-child::after, .tree li:only-child::before {
38 | display: none;
39 | }
40 |
41 | /*Remove space from the top of single children*/
42 | .tree li:only-child{ padding-top: 0;}
43 |
44 | /*Remove left connector from first child and
45 | right connector from last child*/
46 | .tree li:first-child::before, .tree li:last-child::after{
47 | border: 0 none;
48 | }
49 | /*Adding back the vertical connector to the last nodes*/
50 | .tree li:last-child::before{
51 | border-right: 1px solid rgb(166, 226, 46);
52 | border-radius: 0 5px 0 0;
53 | -webkit-border-radius: 0 5px 0 0;
54 | -moz-border-radius: 0 5px 0 0;
55 | }
56 | .tree li:first-child::after{
57 | border-radius: 5px 0 0 0;
58 | -webkit-border-radius: 5px 0 0 0;
59 | -moz-border-radius: 5px 0 0 0;
60 | }
61 |
62 | /*Time to add downward connectors from parents*/
63 | .tree ul ul::before{
64 | content: '';
65 | position: absolute; top: 0; left: 50%;
66 | border-left: 1px solid rgb(166, 226, 46);
67 | width: 0; height: 20px;
68 | }
69 |
70 | .tree li a{
71 | border: 1px solid rgb(166, 226, 46);
72 | padding: 5px 10px;
73 | text-decoration: none;
74 | color: #ffffff;
75 | font-family: arial, verdana, tahoma;
76 | font-size: 11px;
77 | display: inline-block;
78 |
79 | border-radius: 5px;
80 | -webkit-border-radius: 5px;
81 | -moz-border-radius: 5px;
82 |
83 | transition: all 0.5s;
84 | -webkit-transition: all 0.5s;
85 | -moz-transition: all 0.5s;
86 | }
87 |
88 | .tree a {
89 | cursor: default;
90 | }
91 |
--------------------------------------------------------------------------------
/test/stubs.ts:
--------------------------------------------------------------------------------
1 | import { Kernel, injectable, named, inject } from "inversify";
2 | import "reflect-metadata";
3 |
4 | let TYPES = {
5 | Warrior: Symbol("Warrior"),
6 | Weapon: Symbol("Weapon")
7 | };
8 |
9 | let TAGS = {
10 | katana: "katana",
11 | shuriken: "shuriken",
12 | };
13 |
14 | interface Weapon {}
15 |
16 | interface Warrior {
17 | katana: Weapon;
18 | shuriken: Weapon;
19 | }
20 |
21 | @injectable()
22 | class Katana implements Weapon {}
23 |
24 | @injectable()
25 | class Shuriken implements Weapon {}
26 |
27 | @injectable()
28 | class Ninja implements Warrior {
29 |
30 | public katana: Weapon;
31 | public shuriken: Weapon;
32 |
33 | public constructor(
34 | @inject(TYPES.Weapon) @named(TAGS.katana) katana: Weapon,
35 | @inject(TYPES.Weapon) @named(TAGS.shuriken) shuriken: Weapon
36 | ) {
37 | this.katana = katana;
38 | this.shuriken = shuriken;
39 | }
40 | }
41 |
42 | let kernel = new Kernel();
43 |
44 | kernel.bind(TYPES.Warrior).to(Ninja);
45 | kernel.bind(TYPES.Weapon).to(Katana).whenTargetNamed(TAGS.katana);
46 | kernel.bind(TYPES.Weapon).to(Shuriken).whenTargetNamed(TAGS.shuriken);
47 |
48 | function useDevtools(addKernel: (kernel: inversify.interfaces.Kernel) => void) {
49 | let win: any = window;
50 | win.kernel = addKernel(kernel);
51 | kernel.get("ninja");
52 | kernel.get(TYPES.Warrior);
53 | kernel.get(TYPES.Weapon);
54 | kernel.getNamed(TYPES.Weapon, TAGS.shuriken);
55 | kernel.getNamed(TYPES.Weapon, TAGS.katana);
56 | }
57 |
58 | export default useDevtools;
59 |
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "target": "es5",
4 | "module": "commonjs",
5 | "moduleResolution": "node",
6 | "isolatedModules": false,
7 | "jsx": "react",
8 | "experimentalDecorators": true,
9 | "emitDecoratorMetadata": true,
10 | "declaration": false,
11 | "noImplicitAny": true,
12 | "removeComments": true,
13 | "noLib": false,
14 | "preserveConstEnums": true,
15 | "suppressImplicitAnyIndexErrors": false
16 | },
17 | "files": [
18 | "./typings/index.d.ts",
19 | "./node_modules/immutable/dist/immutable.d.ts",
20 | "./node_modules/redux-bootstrap/type_definitions/redux-bootstrap/redux-bootstrap.d.ts",
21 | "./node_modules/inversify-dts/inversify/inversify.d.ts",
22 | "./node_modules/inversify-dts/inversify-logger-middleware/inversify-logger-middleware.d.ts",
23 | "./src/interfaces/globals.d.ts",
24 | "./src/main.tsx"
25 | ]
26 | }
--------------------------------------------------------------------------------
/tslint.json:
--------------------------------------------------------------------------------
1 | {
2 | "rules": {
3 | "class-name": true,
4 | "comment-format": [true, "check-space"],
5 | "curly": true,
6 | "eofline": true,
7 | "forin": true,
8 | "indent": [true, "spaces"],
9 | "label-position": true,
10 | "label-undefined": true,
11 | "max-line-length": [true, 140],
12 | "member-access": true,
13 | "member-ordering": [true,
14 | "public-before-private",
15 | "static-before-instance",
16 | "variables-before-functions"
17 | ],
18 | "no-arg": true,
19 | "no-bitwise": true,
20 | "no-console": [true,
21 | "debug",
22 | "info",
23 | "time",
24 | "timeEnd",
25 | "trace"
26 | ],
27 | "no-construct": true,
28 | "no-debugger": true,
29 | "no-duplicate-key": true,
30 | "no-duplicate-variable": true,
31 | "no-empty": true,
32 | "no-eval": true,
33 | "no-inferrable-types": true,
34 | "no-shadowed-variable": true,
35 | "no-string-literal": true,
36 | "no-switch-case-fall-through": false,
37 | "no-trailing-whitespace": true,
38 | "no-unused-expression": true,
39 | "no-unused-variable": false,
40 | "no-unreachable": true,
41 | "no-use-before-declare": true,
42 | "no-var-keyword": true,
43 | "object-literal-sort-keys": true,
44 | "one-line": [true,
45 | "check-open-brace",
46 | "check-catch",
47 | "check-else",
48 | "check-whitespace"
49 | ],
50 | "quotemark": [true, "double", "avoid-escape"],
51 | "radix": true,
52 | "semicolon": true,
53 | "trailing-comma": false,
54 | "triple-equals": [true, "allow-null-check"],
55 | "typedef-whitespace": [true, {
56 | "call-signature": "nospace",
57 | "index-signature": "nospace",
58 | "parameter": "nospace",
59 | "property-declaration": "nospace",
60 | "variable-declaration": "nospace"
61 | }],
62 | "variable-name": false,
63 | "whitespace": [true,
64 | "check-branch",
65 | "check-decl",
66 | "check-operator",
67 | "check-separator",
68 | "check-type"
69 | ]
70 | }
71 | }
--------------------------------------------------------------------------------
/typings.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "redux-bootstrap-example",
3 | "dependencies": {},
4 | "devDependencies": {},
5 | "globalDependencies": {
6 | "bluebird": "registry:dt/bluebird#2.0.0+20160319051630",
7 | "react-redux": "registry:dt/react-redux#4.4.0+20160501125835",
8 | "react-router": "registry:dt/react-router#2.0.0+20160621215300",
9 | "react-router-redux": "registry:dt/react-router-redux#4.0.0+20160316155526",
10 | "react-router/history": "registry:dt/react-router/history#2.0.0+20160608102730",
11 | "redux-thunk": "registry:dt/redux-thunk#2.0.1+20160317120654"
12 | }
13 | }
14 |
--------------------------------------------------------------------------------