ing
This commit is contained in:
commit
39851515f6
46
.gitignore
vendored
Normal file
46
.gitignore
vendored
Normal file
|
@ -0,0 +1,46 @@
|
||||||
|
# See http://help.github.com/ignore-files/ for more about ignoring files.
|
||||||
|
|
||||||
|
# compiled output
|
||||||
|
/dist
|
||||||
|
/dist-server
|
||||||
|
/tmp
|
||||||
|
/out-tsc
|
||||||
|
/docs
|
||||||
|
|
||||||
|
# dependencies
|
||||||
|
/node_modules
|
||||||
|
|
||||||
|
# IDEs and editors
|
||||||
|
/.idea
|
||||||
|
.project
|
||||||
|
.classpath
|
||||||
|
.c9/
|
||||||
|
*.launch
|
||||||
|
.settings/
|
||||||
|
*.sublime-workspace
|
||||||
|
|
||||||
|
# IDE - VSCode
|
||||||
|
.vscode/*
|
||||||
|
!.vscode/settings.json
|
||||||
|
!.vscode/tasks.json
|
||||||
|
!.vscode/launch.json
|
||||||
|
!.vscode/extensions.json
|
||||||
|
|
||||||
|
# misc
|
||||||
|
/.sass-cache
|
||||||
|
/connect.lock
|
||||||
|
/coverage
|
||||||
|
/libpeerconnection.log
|
||||||
|
npm-debug.log
|
||||||
|
testem.log
|
||||||
|
/typings
|
||||||
|
|
||||||
|
# e2e
|
||||||
|
/e2e/*.js
|
||||||
|
/e2e/*.map
|
||||||
|
|
||||||
|
# System Files
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
yarn.lock
|
9
.make-package.js
Normal file
9
.make-package.js
Normal file
|
@ -0,0 +1,9 @@
|
||||||
|
const fs = require('fs');
|
||||||
|
const packageJson = JSON.parse(fs.readFileSync('./package.json').toString());
|
||||||
|
|
||||||
|
delete packageJson.devDependencies;
|
||||||
|
delete packageJson.scripts;
|
||||||
|
|
||||||
|
packageJson.private = false;
|
||||||
|
|
||||||
|
fs.writeFileSync('./dist/package.json', JSON.stringify(packageJson, null, 2));
|
21
License
Normal file
21
License
Normal file
|
@ -0,0 +1,21 @@
|
||||||
|
MIT License
|
||||||
|
|
||||||
|
Copyright (c) 2017
|
||||||
|
|
||||||
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
|
in the Software without restriction, including without limitation the rights
|
||||||
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
|
The above copyright notice and this permission notice shall be included in all
|
||||||
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
|
SOFTWARE.
|
983
package-lock.json
generated
Normal file
983
package-lock.json
generated
Normal file
|
@ -0,0 +1,983 @@
|
||||||
|
{
|
||||||
|
"name": "@loafer/ng-rpc",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"lockfileVersion": 1,
|
||||||
|
"requires": true,
|
||||||
|
"dependencies": {
|
||||||
|
"@angular/common": {
|
||||||
|
"version": "5.2.10",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/@angular/common/-/common-5.2.10.tgz",
|
||||||
|
"integrity": "sha512-4zgI/Q6bo/KCvrDPf8gc2IpTJ3PFKgd9RF4jZuh1uc+uEYTAj396tDF8o412AJ/iwtYOHWUx+YgzAvT8dHXZ5Q==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "1.9.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@angular/core": {
|
||||||
|
"version": "5.2.10",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/@angular/core/-/core-5.2.10.tgz",
|
||||||
|
"integrity": "sha512-glDuTtHTcAVhfU3NVewxz/W+Iweq5IaeW2tnMa+RKLopYk9fRs8eR5iTixTGvegwKR770vfXg/gR7P6Ii5cYGQ==",
|
||||||
|
"requires": {
|
||||||
|
"tslib": "1.9.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@loafer/core": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/@loafer/core/-/core-0.0.1.tgz",
|
||||||
|
"integrity": "sha512-t0Nio5E4l/jqkstQYE4rYqrsnPIgTOWpoxuX6s4UwUvNfAsOnVWxeZ6cSg2ontSZYeEPaObFVfp7IjPiblhX0A==",
|
||||||
|
"requires": {
|
||||||
|
"reflect-metadata": "0.1.12"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@loafer/decorator": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/@loafer/decorator/-/decorator-0.0.1.tgz",
|
||||||
|
"integrity": "sha512-vN6NX2D3dS5wRevWtznqYSdCteaKpzR7X6YQ25LXXoGEljh5dbAqyBnMBLiULPGmshKV2zp762lZYlrGM5qW0Q==",
|
||||||
|
"requires": {
|
||||||
|
"@loafer/core": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@ngrx/store": {
|
||||||
|
"version": "5.2.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/@ngrx/store/-/store-5.2.0.tgz",
|
||||||
|
"integrity": "sha1-Yn7XTJzZVGKTBIXZEqVXEXsjkD4="
|
||||||
|
},
|
||||||
|
"@types/events": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/@types/events/-/events-1.2.0.tgz",
|
||||||
|
"integrity": "sha512-KEIlhXnIutzKwRbQkGWb/I4HFqBuUykAdHgDED6xqwXJfONCjF5VoE0cXEiurh3XauygxzeDzgtXUqvLkxFzzA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@types/fs-extra": {
|
||||||
|
"version": "5.0.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/@types/fs-extra/-/fs-extra-5.0.1.tgz",
|
||||||
|
"integrity": "sha512-h3wnflb+jMTipvbbZnClgA2BexrT4w0GcfoCz5qyxd0IRsbqhLSyesM6mqZTAnhbVmhyTm5tuxfRu9R+8l+lGw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/node": "9.6.16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@types/glob": {
|
||||||
|
"version": "5.0.35",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/@types/glob/-/glob-5.0.35.tgz",
|
||||||
|
"integrity": "sha512-wc+VveszMLyMWFvXLkloixT4n0harUIVZjnpzztaZ0nKLuul7Z32iMt2fUFGAaZ4y1XWjFRMtCI5ewvyh4aIeg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/events": "1.2.0",
|
||||||
|
"@types/minimatch": "3.0.3",
|
||||||
|
"@types/node": "9.6.16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"@types/handlebars": {
|
||||||
|
"version": "4.0.36",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/@types/handlebars/-/handlebars-4.0.36.tgz",
|
||||||
|
"integrity": "sha512-LjNiTX7TY7wtuC6y3QwC93hKMuqYhgV9A1uXBKNvZtVC8ZvyWAjZkJ5BvT0K7RKqORRYRLMrqCxpw5RgS+MdrQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@types/highlight.js": {
|
||||||
|
"version": "9.12.2",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/@types/highlight.js/-/highlight.js-9.12.2.tgz",
|
||||||
|
"integrity": "sha512-y5x0XD/WXDaGSyiTaTcKS4FurULJtSiYbGTeQd0m2LYZGBcZZ/7fM6t5H/DzeUF+kv8y6UfmF6yJABQsHcp9VQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@types/jasmine": {
|
||||||
|
"version": "2.8.7",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/@types/jasmine/-/jasmine-2.8.7.tgz",
|
||||||
|
"integrity": "sha512-RdbrPcW1aD78UmdLiDa9ZCKrbR5Go8PXh6GCpb4oIOkWVEusubSJJDrP4c5RYOu8m/CBz+ygZpicj6Pgms5a4Q==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@types/lodash": {
|
||||||
|
"version": "4.14.104",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/@types/lodash/-/lodash-4.14.104.tgz",
|
||||||
|
"integrity": "sha512-ufQcVg4daO8xQ5kopxRHanqFdL4AI7ondQkV+2f+7mz3gvp0LkBx2zBRC6hfs3T87mzQFmf5Fck7Fi145Ul6NQ==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@types/marked": {
|
||||||
|
"version": "0.3.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/@types/marked/-/marked-0.3.0.tgz",
|
||||||
|
"integrity": "sha512-CSf9YWJdX1DkTNu9zcNtdCcn6hkRtB5ILjbhRId4ZOQqx30fXmdecuaXhugQL6eyrhuXtaHJ7PHI+Vm7k9ZJjg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@types/minimatch": {
|
||||||
|
"version": "3.0.3",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/@types/minimatch/-/minimatch-3.0.3.tgz",
|
||||||
|
"integrity": "sha512-tHq6qdbT9U1IRSGf14CL0pUlULksvY9OZ+5eEgl1N7t+OA3tGvNpxJCzuKQlsNgCVwbAs670L1vcVQi8j9HjnA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@types/node": {
|
||||||
|
"version": "9.6.16",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/@types/node/-/node-9.6.16.tgz",
|
||||||
|
"integrity": "sha512-fwUW7S8gaSVNpPa1XUdzI0URY71xqXsc90S9vKr2uFIUpVCKV+8ysnN9vvAFK8np4H03A7QGRkHpQvgah0964Q==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"@types/shelljs": {
|
||||||
|
"version": "0.7.8",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/@types/shelljs/-/shelljs-0.7.8.tgz",
|
||||||
|
"integrity": "sha512-M2giRw93PxKS7YjU6GZjtdV9HASdB7TWqizBXe4Ju7AqbKlWvTr0gNO92XH56D/gMxqD/jNHLNfC5hA34yGqrQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/glob": "5.0.35",
|
||||||
|
"@types/node": "9.6.16"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"align-text": {
|
||||||
|
"version": "0.1.4",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/align-text/-/align-text-0.1.4.tgz",
|
||||||
|
"integrity": "sha1-DNkKVhCT810KmSVsIrcGlDP60Rc=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"kind-of": "3.2.2",
|
||||||
|
"longest": "1.0.1",
|
||||||
|
"repeat-string": "1.6.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"kind-of": {
|
||||||
|
"version": "3.2.2",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/kind-of/-/kind-of-3.2.2.tgz",
|
||||||
|
"integrity": "sha1-MeohpzS6ubuw8yRm2JOupR5KPGQ=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"is-buffer": "1.1.6"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"amdefine": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/amdefine/-/amdefine-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-SlKCrBZHKek2Gbz9OtFR+BfOkfU=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"ansi-regex": {
|
||||||
|
"version": "2.1.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/ansi-regex/-/ansi-regex-2.1.1.tgz",
|
||||||
|
"integrity": "sha1-w7M6te42DYbg5ijwRorn7yfWVN8=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "2.2.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/ansi-styles/-/ansi-styles-2.2.1.tgz",
|
||||||
|
"integrity": "sha1-tDLdM1i2NM914eRmQ2gkBTPB3b4=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"argparse": {
|
||||||
|
"version": "1.0.10",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/argparse/-/argparse-1.0.10.tgz",
|
||||||
|
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"sprintf-js": "1.0.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"arrify": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/arrify/-/arrify-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-iYUI2iIm84DfkEcoRWhJwVAaSw0=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"async": {
|
||||||
|
"version": "1.5.2",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/async/-/async-1.5.2.tgz",
|
||||||
|
"integrity": "sha1-7GphrlZIDAw8skHJVhjiCJL5Zyo=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"babel-code-frame": {
|
||||||
|
"version": "6.26.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/babel-code-frame/-/babel-code-frame-6.26.0.tgz",
|
||||||
|
"integrity": "sha1-Y/1D99weO7fONZR9uP42mj9Yx0s=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"chalk": "1.1.3",
|
||||||
|
"esutils": "2.0.2",
|
||||||
|
"js-tokens": "3.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"balanced-match": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"brace-expansion": {
|
||||||
|
"version": "1.1.11",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||||
|
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"balanced-match": "1.0.0",
|
||||||
|
"concat-map": "0.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"buffer-from": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/buffer-from/-/buffer-from-1.0.0.tgz",
|
||||||
|
"integrity": "sha512-83apNb8KK0Se60UE1+4Ukbe3HbfELJ6UlI4ldtOGs7So4KD26orJM8hIY9lxdzP+UpItH1Yh/Y8GUvNFWFFRxA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"builtin-modules": {
|
||||||
|
"version": "1.1.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/builtin-modules/-/builtin-modules-1.1.1.tgz",
|
||||||
|
"integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"center-align": {
|
||||||
|
"version": "0.1.3",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/center-align/-/center-align-0.1.3.tgz",
|
||||||
|
"integrity": "sha1-qg0yYptu6XIgBBHL1EYckHvCt60=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"align-text": "0.1.4",
|
||||||
|
"lazy-cache": "1.0.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"chalk": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/chalk/-/chalk-1.1.3.tgz",
|
||||||
|
"integrity": "sha1-qBFcVeSnAv5NFQq9OHKCKn4J/Jg=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ansi-styles": "2.2.1",
|
||||||
|
"escape-string-regexp": "1.0.5",
|
||||||
|
"has-ansi": "2.0.0",
|
||||||
|
"strip-ansi": "3.0.1",
|
||||||
|
"supports-color": "2.0.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-convert": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/color-convert/-/color-convert-1.9.1.tgz",
|
||||||
|
"integrity": "sha512-mjGanIiwQJskCC18rPR6OmrZ6fm2Lc7PeGFYwCmy5J34wC6F1PzdGL6xeMfmgicfYcNLGuVFA3WzXtIDCQSZxQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"color-name": "1.1.3"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"color-name": {
|
||||||
|
"version": "1.1.3",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/color-name/-/color-name-1.1.3.tgz",
|
||||||
|
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"commander": {
|
||||||
|
"version": "2.15.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/commander/-/commander-2.15.1.tgz",
|
||||||
|
"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"concat-map": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/concat-map/-/concat-map-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"decamelize": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/decamelize/-/decamelize-1.2.0.tgz",
|
||||||
|
"integrity": "sha1-9lNNFRSCabIDUue+4m9QH5oZEpA=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"diff": {
|
||||||
|
"version": "3.5.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/diff/-/diff-3.5.0.tgz",
|
||||||
|
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"doctrine": {
|
||||||
|
"version": "0.7.2",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/doctrine/-/doctrine-0.7.2.tgz",
|
||||||
|
"integrity": "sha1-fLhgNZujvpDgQLJrcpzkv6ZUxSM=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"esutils": "1.1.6",
|
||||||
|
"isarray": "0.0.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"esutils": {
|
||||||
|
"version": "1.1.6",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/esutils/-/esutils-1.1.6.tgz",
|
||||||
|
"integrity": "sha1-wBzKqa5LiXxtDD4hCuUvPHqEQ3U=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"isarray": {
|
||||||
|
"version": "0.0.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/isarray/-/isarray-0.0.1.tgz",
|
||||||
|
"integrity": "sha1-ihis/Kmo9Bd+Cav8YDiTmwXR7t8=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"escape-string-regexp": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||||
|
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"esutils": {
|
||||||
|
"version": "2.0.2",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/esutils/-/esutils-2.0.2.tgz",
|
||||||
|
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"fs.realpath": {
|
||||||
|
"version": "1.0.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||||
|
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"glob": {
|
||||||
|
"version": "7.1.2",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/glob/-/glob-7.1.2.tgz",
|
||||||
|
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"fs.realpath": "1.0.0",
|
||||||
|
"inflight": "1.0.6",
|
||||||
|
"inherits": "2.0.3",
|
||||||
|
"minimatch": "3.0.4",
|
||||||
|
"once": "1.4.0",
|
||||||
|
"path-is-absolute": "1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"graceful-fs": {
|
||||||
|
"version": "4.1.11",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/graceful-fs/-/graceful-fs-4.1.11.tgz",
|
||||||
|
"integrity": "sha1-Dovf5NHduIVNZOBOp8AOKgJuVlg=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"handlebars": {
|
||||||
|
"version": "4.0.11",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/handlebars/-/handlebars-4.0.11.tgz",
|
||||||
|
"integrity": "sha1-Ywo13+ApS8KB7a5v/F0yn8eYLcw=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"async": "1.5.2",
|
||||||
|
"optimist": "0.6.1",
|
||||||
|
"source-map": "0.4.4",
|
||||||
|
"uglify-js": "2.8.29"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"source-map": {
|
||||||
|
"version": "0.4.4",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/source-map/-/source-map-0.4.4.tgz",
|
||||||
|
"integrity": "sha1-66T12pwNyZneaAMti092FzZSA2s=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"amdefine": "1.0.1"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has-ansi": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/has-ansi/-/has-ansi-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-NPUEnOHs3ysGSa8+8k5F7TVBbZE=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ansi-regex": "2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"has-flag": {
|
||||||
|
"version": "3.0.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/has-flag/-/has-flag-3.0.0.tgz",
|
||||||
|
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"highlight.js": {
|
||||||
|
"version": "9.12.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/highlight.js/-/highlight.js-9.12.0.tgz",
|
||||||
|
"integrity": "sha1-5tnb5Xy+/mB1HwKvM2GVhwyQwB4=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"inflight": {
|
||||||
|
"version": "1.0.6",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/inflight/-/inflight-1.0.6.tgz",
|
||||||
|
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"once": "1.4.0",
|
||||||
|
"wrappy": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"inherits": {
|
||||||
|
"version": "2.0.3",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/inherits/-/inherits-2.0.3.tgz",
|
||||||
|
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"interpret": {
|
||||||
|
"version": "1.1.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/interpret/-/interpret-1.1.0.tgz",
|
||||||
|
"integrity": "sha1-ftGxQQxqDg94z5XTuEQMY/eLhhQ=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"is-buffer": {
|
||||||
|
"version": "1.1.6",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/is-buffer/-/is-buffer-1.1.6.tgz",
|
||||||
|
"integrity": "sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"jasmine-core": {
|
||||||
|
"version": "2.8.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/jasmine-core/-/jasmine-core-2.8.0.tgz",
|
||||||
|
"integrity": "sha1-vMl5rh+f0FcB5F5S5l06XWPxok4=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"js-tokens": {
|
||||||
|
"version": "3.0.2",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/js-tokens/-/js-tokens-3.0.2.tgz",
|
||||||
|
"integrity": "sha1-mGbfOVECEw449/mWvOtlRDIJwls=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"js-yaml": {
|
||||||
|
"version": "3.11.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/js-yaml/-/js-yaml-3.11.0.tgz",
|
||||||
|
"integrity": "sha512-saJstZWv7oNeOyBh3+Dx1qWzhW0+e6/8eDzo7p5rDFqxntSztloLtuKu+Ejhtq82jsilwOIZYsCz+lIjthg1Hw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"argparse": "1.0.10",
|
||||||
|
"esprima": "4.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"esprima": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/esprima/-/esprima-4.0.0.tgz",
|
||||||
|
"integrity": "sha512-oftTcaMu/EGrEIu904mWteKIv8vMuOgGYo7EhVJJN00R/EED9DCua/xxHRdYnKtcECzVg7xOWhflvJMnqcFZjw==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"jsonfile": {
|
||||||
|
"version": "4.0.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/jsonfile/-/jsonfile-4.0.0.tgz",
|
||||||
|
"integrity": "sha1-h3Gq4HmbZAdrdmQPygWPnBDjPss=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"graceful-fs": "4.1.11"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"lazy-cache": {
|
||||||
|
"version": "1.0.4",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/lazy-cache/-/lazy-cache-1.0.4.tgz",
|
||||||
|
"integrity": "sha1-odePw6UEdMuAhF07O24dpJpEbo4=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"lodash": {
|
||||||
|
"version": "4.17.10",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/lodash/-/lodash-4.17.10.tgz",
|
||||||
|
"integrity": "sha512-UejweD1pDoXu+AD825lWwp4ZGtSwgnpZxb3JDViD7StjQz+Nb/6l093lx4OQ0foGWNRoc19mWy7BzL+UAK2iVg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"longest": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/longest/-/longest-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-MKCy2jj3N3DoKUoNIuZiXtd9AJc=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"make-error": {
|
||||||
|
"version": "1.3.4",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/make-error/-/make-error-1.3.4.tgz",
|
||||||
|
"integrity": "sha512-0Dab5btKVPhibSalc9QGXb559ED7G7iLjFXBaj9Wq8O3vorueR5K5jaE3hkG6ZQINyhA/JgG6Qk4qdFQjsYV6g==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"marked": {
|
||||||
|
"version": "0.3.19",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/marked/-/marked-0.3.19.tgz",
|
||||||
|
"integrity": "sha512-ea2eGWOqNxPcXv8dyERdSr/6FmzvWwzjMxpfGB/sbMccXoct+xY+YukPD+QTUZwyvK7BZwcr4m21WBOW41pAkg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"minimatch": {
|
||||||
|
"version": "3.0.4",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/minimatch/-/minimatch-3.0.4.tgz",
|
||||||
|
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"brace-expansion": "1.1.11"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimist": {
|
||||||
|
"version": "0.0.8",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/minimist/-/minimist-0.0.8.tgz",
|
||||||
|
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"mkdirp": {
|
||||||
|
"version": "0.5.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||||
|
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "0.0.8"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"once": {
|
||||||
|
"version": "1.4.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/once/-/once-1.4.0.tgz",
|
||||||
|
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"wrappy": "1.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"optimist": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/optimist/-/optimist-0.6.1.tgz",
|
||||||
|
"integrity": "sha1-2j6nRob6IaGaERwybpDrFaAZZoY=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"minimist": "0.0.8",
|
||||||
|
"wordwrap": "0.0.3"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"wordwrap": {
|
||||||
|
"version": "0.0.3",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/wordwrap/-/wordwrap-0.0.3.tgz",
|
||||||
|
"integrity": "sha1-o9XabNXAvAAI03I0u68b7WMFkQc=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"path-is-absolute": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"path-parse": {
|
||||||
|
"version": "1.0.5",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/path-parse/-/path-parse-1.0.5.tgz",
|
||||||
|
"integrity": "sha1-PBrfhx6pzWyUMbbqK9dKD/BVxME=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"prettier": {
|
||||||
|
"version": "1.12.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/prettier/-/prettier-1.12.1.tgz",
|
||||||
|
"integrity": "sha1-wa0g6APndJ+vkFpAnSNn4Gu+cyU=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"progress": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/progress/-/progress-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-ihvjZr+Pwj2yvSPxDG/pILQ4nR8=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"rechoir": {
|
||||||
|
"version": "0.6.2",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/rechoir/-/rechoir-0.6.2.tgz",
|
||||||
|
"integrity": "sha1-hSBLVNuoLVdC4oyWdW70OvUOM4Q=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"resolve": "1.7.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"reflect-metadata": {
|
||||||
|
"version": "0.1.12",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/reflect-metadata/-/reflect-metadata-0.1.12.tgz",
|
||||||
|
"integrity": "sha512-n+IyV+nGz3+0q3/Yf1ra12KpCyi001bi4XFxSjbiWWjfqb52iTTtpGXmCCAOWWIAn9KEuFZKGqBERHmrtScZ3A=="
|
||||||
|
},
|
||||||
|
"repeat-string": {
|
||||||
|
"version": "1.6.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/repeat-string/-/repeat-string-1.6.1.tgz",
|
||||||
|
"integrity": "sha1-jcrkcOHIirwtYA//Sndihtp15jc=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"resolve": {
|
||||||
|
"version": "1.7.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/resolve/-/resolve-1.7.1.tgz",
|
||||||
|
"integrity": "sha512-c7rwLofp8g1U+h1KNyHL/jicrKg1Ek4q+Lr33AL65uZTinUZHe30D5HlyN5V9NW0JX1D5dXQ4jqW5l7Sy/kGfw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"path-parse": "1.0.5"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"right-align": {
|
||||||
|
"version": "0.1.3",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/right-align/-/right-align-0.1.3.tgz",
|
||||||
|
"integrity": "sha1-YTObci/mo1FWiSENJOFMlhSGE+8=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"align-text": "0.1.4"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rimraf": {
|
||||||
|
"version": "2.6.2",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/rimraf/-/rimraf-2.6.2.tgz",
|
||||||
|
"integrity": "sha512-lreewLK/BlghmxtfH36YYVg1i8IAce4TI7oao75I1g245+6BctqTVQiBP3YUJ9C6DQOXJmkYR9X9fCLtCOJc5w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"glob": "7.1.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"rxjs": {
|
||||||
|
"version": "5.5.10",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/rxjs/-/rxjs-5.5.10.tgz",
|
||||||
|
"integrity": "sha512-SRjimIDUHJkon+2hFo7xnvNC4ZEHGzCRwh9P7nzX3zPkCGFEg/tuElrNR7L/rZMagnK2JeH2jQwPRpmyXyLB6A==",
|
||||||
|
"requires": {
|
||||||
|
"symbol-observable": "1.0.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"semver": {
|
||||||
|
"version": "5.5.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/semver/-/semver-5.5.0.tgz",
|
||||||
|
"integrity": "sha512-4SJ3dm0WAwWy/NVeioZh5AntkdJoWKxHxcmyP622fOkgHa4z3R0TdBJICINyaSDE6uNwVc8gZr+ZinwZAH4xIA==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"shelljs": {
|
||||||
|
"version": "0.8.2",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/shelljs/-/shelljs-0.8.2.tgz",
|
||||||
|
"integrity": "sha512-pRXeNrCA2Wd9itwhvLp5LZQvPJ0wU6bcjaTMywHHGX5XWhVN2nzSu7WV0q+oUY7mGK3mgSkDDzP3MgjqdyIgbQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"glob": "7.1.2",
|
||||||
|
"interpret": "1.1.0",
|
||||||
|
"rechoir": "0.6.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"source-map": {
|
||||||
|
"version": "0.5.7",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/source-map/-/source-map-0.5.7.tgz",
|
||||||
|
"integrity": "sha1-igOdLRAh0i0eoUyA2OpGi6LvP8w=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"source-map-support": {
|
||||||
|
"version": "0.5.6",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/source-map-support/-/source-map-support-0.5.6.tgz",
|
||||||
|
"integrity": "sha512-N4KXEz7jcKqPf2b2vZF11lQIz9W5ZMuUcIOGj243lduidkf2fjkVKJS9vNxVWn3u/uxX38AcE8U9nnH9FPcq+g==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"buffer-from": "1.0.0",
|
||||||
|
"source-map": "0.6.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"source-map": {
|
||||||
|
"version": "0.6.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/source-map/-/source-map-0.6.1.tgz",
|
||||||
|
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"sprintf-js": {
|
||||||
|
"version": "1.0.3",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||||
|
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"strip-ansi": {
|
||||||
|
"version": "3.0.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/strip-ansi/-/strip-ansi-3.0.1.tgz",
|
||||||
|
"integrity": "sha1-ajhfuIU9lS1f8F0Oiq+UJ43GPc8=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ansi-regex": "2.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/supports-color/-/supports-color-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-U10EXOa2Nj+kARcIRimZXp3zJMc=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"symbol-observable": {
|
||||||
|
"version": "1.0.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/symbol-observable/-/symbol-observable-1.0.1.tgz",
|
||||||
|
"integrity": "sha1-g0D8RwLDEi310iKI+IKD9RPT/dQ="
|
||||||
|
},
|
||||||
|
"ts-node": {
|
||||||
|
"version": "6.0.3",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/ts-node/-/ts-node-6.0.3.tgz",
|
||||||
|
"integrity": "sha512-ARaOMNFEPKg2ZuC1qJddFvHxHNFVckR0g9xLxMIoMqSSIkDc8iS4/LoV53EdDWWNq2FGwqcEf0bVVGJIWpsznw==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"arrify": "1.0.1",
|
||||||
|
"chalk": "2.4.1",
|
||||||
|
"diff": "3.5.0",
|
||||||
|
"make-error": "1.3.4",
|
||||||
|
"minimist": "1.2.0",
|
||||||
|
"mkdirp": "0.5.1",
|
||||||
|
"source-map-support": "0.5.6",
|
||||||
|
"yn": "2.0.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"color-convert": "1.9.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"chalk": {
|
||||||
|
"version": "2.4.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/chalk/-/chalk-2.4.1.tgz",
|
||||||
|
"integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ansi-styles": "3.2.1",
|
||||||
|
"escape-string-regexp": "1.0.5",
|
||||||
|
"supports-color": "5.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"minimist": {
|
||||||
|
"version": "1.2.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/minimist/-/minimist-1.2.0.tgz",
|
||||||
|
"integrity": "sha1-o1AIsg9BOD7sH7kU9M1d95omQoQ=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "5.4.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/supports-color/-/supports-color-5.4.0.tgz",
|
||||||
|
"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"has-flag": "3.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tslib": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/tslib/-/tslib-1.9.1.tgz",
|
||||||
|
"integrity": "sha512-avfPS28HmGLLc2o4elcc2EIq2FcH++Yo5YxpBZi9Yw93BCTGFthI4HPE4Rpep6vSYQaK8e69PelM44tPj+RaQg=="
|
||||||
|
},
|
||||||
|
"tslint": {
|
||||||
|
"version": "5.10.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/tslint/-/tslint-5.10.0.tgz",
|
||||||
|
"integrity": "sha1-EeJrzLiK+gLdDZlWyuPUVAtfVMM=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"babel-code-frame": "6.26.0",
|
||||||
|
"builtin-modules": "1.1.1",
|
||||||
|
"chalk": "2.4.1",
|
||||||
|
"commander": "2.15.1",
|
||||||
|
"diff": "3.5.0",
|
||||||
|
"glob": "7.1.2",
|
||||||
|
"js-yaml": "3.11.0",
|
||||||
|
"minimatch": "3.0.4",
|
||||||
|
"resolve": "1.7.1",
|
||||||
|
"semver": "5.5.0",
|
||||||
|
"tslib": "1.9.1",
|
||||||
|
"tsutils": "2.27.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"ansi-styles": {
|
||||||
|
"version": "3.2.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||||
|
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"color-convert": "1.9.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"chalk": {
|
||||||
|
"version": "2.4.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/chalk/-/chalk-2.4.1.tgz",
|
||||||
|
"integrity": "sha512-ObN6h1v2fTJSmUXoS3nMQ92LbDK9be4TV+6G+omQlGJFdcUX5heKi1LZ1YnRMIgwTLEj3E24bT6tYni50rlCfQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"ansi-styles": "3.2.1",
|
||||||
|
"escape-string-regexp": "1.0.5",
|
||||||
|
"supports-color": "5.4.0"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"supports-color": {
|
||||||
|
"version": "5.4.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/supports-color/-/supports-color-5.4.0.tgz",
|
||||||
|
"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"has-flag": "3.0.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tslint-config-prettier": {
|
||||||
|
"version": "1.12.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/tslint-config-prettier/-/tslint-config-prettier-1.12.0.tgz",
|
||||||
|
"integrity": "sha512-7zugK8NWpoDPYT6UNGLDGpQOhk0CSodjkyrTNiHOCjwIAleYKlyQunxpsSXBIoGEs/kFVppd6YzZeQZtrJnyRg==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"tslint-config-standard": {
|
||||||
|
"version": "7.0.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/tslint-config-standard/-/tslint-config-standard-7.0.0.tgz",
|
||||||
|
"integrity": "sha512-QCrLt8WwiRgZpRSgRsk6cExy8/Vipa/5fHespm4Q1ly90EB6Lni04Ub8dkEW10bV3fPN3SkxEwj41ZOe/knCZA==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"tslint-eslint-rules": "4.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tslint-eslint-rules": {
|
||||||
|
"version": "4.1.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/tslint-eslint-rules/-/tslint-eslint-rules-4.1.1.tgz",
|
||||||
|
"integrity": "sha1-fDDniC8mvCdr/5HSOEl1xp2viLo=",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"doctrine": "0.7.2",
|
||||||
|
"tslib": "1.9.1",
|
||||||
|
"tsutils": "1.9.1"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"tsutils": {
|
||||||
|
"version": "1.9.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/tsutils/-/tsutils-1.9.1.tgz",
|
||||||
|
"integrity": "sha1-ufmrROVa+WgYMdXyjQrur1x1DLA=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"tsutils": {
|
||||||
|
"version": "2.27.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/tsutils/-/tsutils-2.27.0.tgz",
|
||||||
|
"integrity": "sha512-JcyX25oM9pFcb3zh60OqG1St8p/uSqC5Bgipdo3ieacB/Ao4dPhm7hAtKT9NrEu23CyYrrgJPV3CqYfo+/+T4w==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"tslib": "1.9.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"typedoc": {
|
||||||
|
"version": "0.11.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/typedoc/-/typedoc-0.11.1.tgz",
|
||||||
|
"integrity": "sha512-jdNIoHm5wkZqxQTe/g9AQ3LKnZyrzHXqu6A/c9GUOeJyBWLxNr7/Dm3rwFvLksuxRNwTvY/0HRDU9sJTa9WQSg==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"@types/fs-extra": "5.0.1",
|
||||||
|
"@types/handlebars": "4.0.36",
|
||||||
|
"@types/highlight.js": "9.12.2",
|
||||||
|
"@types/lodash": "4.14.104",
|
||||||
|
"@types/marked": "0.3.0",
|
||||||
|
"@types/minimatch": "3.0.3",
|
||||||
|
"@types/shelljs": "0.7.8",
|
||||||
|
"fs-extra": "5.0.0",
|
||||||
|
"handlebars": "4.0.11",
|
||||||
|
"highlight.js": "9.12.0",
|
||||||
|
"lodash": "4.17.10",
|
||||||
|
"marked": "0.3.19",
|
||||||
|
"minimatch": "3.0.4",
|
||||||
|
"progress": "2.0.0",
|
||||||
|
"shelljs": "0.8.2",
|
||||||
|
"typedoc-default-themes": "0.5.0",
|
||||||
|
"typescript": "2.7.2"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"fs-extra": {
|
||||||
|
"version": "5.0.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/fs-extra/-/fs-extra-5.0.0.tgz",
|
||||||
|
"integrity": "sha512-66Pm4RYbjzdyeuqudYqhFiNBbCIuI9kgRqLPSHIlXHidW8NIQtVdkM1yeZ4lXwuhbTETv3EUGMNHAAw6hiundQ==",
|
||||||
|
"dev": true,
|
||||||
|
"requires": {
|
||||||
|
"graceful-fs": "4.1.11",
|
||||||
|
"jsonfile": "4.0.0",
|
||||||
|
"universalify": "0.1.1"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"typescript": {
|
||||||
|
"version": "2.7.2",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/typescript/-/typescript-2.7.2.tgz",
|
||||||
|
"integrity": "sha512-p5TCYZDAO0m4G344hD+wx/LATebLWZNkkh2asWUFqSsD2OrDNhbAHuSjobrmsUmdzjJjEeZVU9g1h3O6vpstnw==",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"typedoc-default-themes": {
|
||||||
|
"version": "0.5.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/typedoc-default-themes/-/typedoc-default-themes-0.5.0.tgz",
|
||||||
|
"integrity": "sha1-bcJDPnjti+qOiHo6zeLzF4W9Yic=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"typescript": {
|
||||||
|
"version": "2.8.3",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/typescript/-/typescript-2.8.3.tgz",
|
||||||
|
"integrity": "sha512-K7g15Bb6Ra4lKf7Iq2l/I5/En+hLIHmxWZGq3D4DIRNFxMNV6j2SHSvDOqs2tGd4UvD/fJvrwopzQXjLrT7Itw==",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"uglify-js": {
|
||||||
|
"version": "2.8.29",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/uglify-js/-/uglify-js-2.8.29.tgz",
|
||||||
|
"integrity": "sha1-KcVzMUgFe7Th913zW3qcty5qWd0=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"source-map": "0.5.7",
|
||||||
|
"uglify-to-browserify": "1.0.2",
|
||||||
|
"yargs": "3.10.0"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"camelcase": {
|
||||||
|
"version": "1.2.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/camelcase/-/camelcase-1.2.1.tgz",
|
||||||
|
"integrity": "sha1-m7UwTS4LVmmLLHWLCKPqqdqlijk=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"cliui": {
|
||||||
|
"version": "2.1.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/cliui/-/cliui-2.1.0.tgz",
|
||||||
|
"integrity": "sha1-S0dXYP+AJkx2LDoXGQMukcf+oNE=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"center-align": "0.1.3",
|
||||||
|
"right-align": "0.1.3",
|
||||||
|
"wordwrap": "0.0.2"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"wordwrap": {
|
||||||
|
"version": "0.0.2",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/wordwrap/-/wordwrap-0.0.2.tgz",
|
||||||
|
"integrity": "sha1-t5Zpu0LstAn4PVg8rVLKF+qhZD8=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"yargs": {
|
||||||
|
"version": "3.10.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/yargs/-/yargs-3.10.0.tgz",
|
||||||
|
"integrity": "sha1-9+572FfdfB0tOMDnTvvWgdFDH9E=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true,
|
||||||
|
"requires": {
|
||||||
|
"camelcase": "1.2.1",
|
||||||
|
"cliui": "2.1.0",
|
||||||
|
"decamelize": "1.2.0",
|
||||||
|
"window-size": "0.1.0"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"uglify-to-browserify": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-bgkk1r2mta/jSeOabWMoUKD4grc=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"universalify": {
|
||||||
|
"version": "0.1.1",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/universalify/-/universalify-0.1.1.tgz",
|
||||||
|
"integrity": "sha1-+nG63UQ3r0wUiEHjs7Fl+enlkLc=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"window-size": {
|
||||||
|
"version": "0.1.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/window-size/-/window-size-0.1.0.tgz",
|
||||||
|
"integrity": "sha1-VDjNLqk7IC76Ohn+iIeu58lPnJ0=",
|
||||||
|
"dev": true,
|
||||||
|
"optional": true
|
||||||
|
},
|
||||||
|
"wrappy": {
|
||||||
|
"version": "1.0.2",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/wrappy/-/wrappy-1.0.2.tgz",
|
||||||
|
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||||
|
"dev": true
|
||||||
|
},
|
||||||
|
"yn": {
|
||||||
|
"version": "2.0.0",
|
||||||
|
"resolved": "https://nexus.loafle.net/repository/npm-all/yn/-/yn-2.0.0.tgz",
|
||||||
|
"integrity": "sha1-5a2ryKz0CPY4X8dklWhMiOavaJo=",
|
||||||
|
"dev": true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
45
package.json
Normal file
45
package.json
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
{
|
||||||
|
"name": "@loafer/ng-rpc",
|
||||||
|
"description": "Angular RPC",
|
||||||
|
"version": "0.0.1",
|
||||||
|
"license": "MIT",
|
||||||
|
"private": true,
|
||||||
|
"main": "./index.js",
|
||||||
|
"typings": "./index.d.ts",
|
||||||
|
"repository": {
|
||||||
|
"type": "git",
|
||||||
|
"url": "https://git.loafle.net/loafer/typescript/ng-rpc.git"
|
||||||
|
},
|
||||||
|
"publishConfig": {
|
||||||
|
"registry": "https://nexus.loafle.net/repository/npm-loafle/"
|
||||||
|
},
|
||||||
|
"keywords": [],
|
||||||
|
"author": "Loafle <loafer@loafle.com>",
|
||||||
|
"scripts": {
|
||||||
|
"generate:package": "node .make-package.js",
|
||||||
|
"generate:doc": "rimraf docs && typedoc --out docs --target es6 --theme minimal --mode file src",
|
||||||
|
"bundle": "rimraf dist && tsc",
|
||||||
|
"build": "npm run bundle && npm run generate:package && npm run generate:doc"
|
||||||
|
},
|
||||||
|
"dependencies": {
|
||||||
|
"@angular/common": "^5.2.9",
|
||||||
|
"@angular/core": "^5.2.9",
|
||||||
|
"@loafer/core": "^0.0.1",
|
||||||
|
"@loafer/decorator": "^0.0.1",
|
||||||
|
"@ngrx/store": "^5.2.0",
|
||||||
|
"rxjs": "^5.5.8"
|
||||||
|
},
|
||||||
|
"devDependencies": {
|
||||||
|
"@types/jasmine": "~2.8.5",
|
||||||
|
"@types/node": "^9.3.0",
|
||||||
|
"jasmine-core": "~2.8.0",
|
||||||
|
"prettier": "^1.12.1",
|
||||||
|
"rimraf": "^2.6.2",
|
||||||
|
"ts-node": "^6.0.3",
|
||||||
|
"tslint": "^5.10.0",
|
||||||
|
"tslint-config-prettier": "^1.12.0",
|
||||||
|
"tslint-config-standard": "^7.0.0",
|
||||||
|
"typedoc": "^0.11.1",
|
||||||
|
"typescript": "^2.8.3"
|
||||||
|
}
|
||||||
|
}
|
146
src/client/RPCClient.ts
Normal file
146
src/client/RPCClient.ts
Normal file
|
@ -0,0 +1,146 @@
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import { Subject } from 'rxjs/Subject';
|
||||||
|
|
||||||
|
import { RPCClientError } from '../protocol/RPCError';
|
||||||
|
import { RPCClientRWC } from './RPCClientRWC';
|
||||||
|
|
||||||
|
import {
|
||||||
|
RPCClientCodec,
|
||||||
|
RPCClientResponseCodec,
|
||||||
|
RPCClientNotificationCodec,
|
||||||
|
} from '../protocol/RPCClientCodec';
|
||||||
|
|
||||||
|
export interface RPCRequestState {
|
||||||
|
subject: Subject<any>;
|
||||||
|
request: {
|
||||||
|
method: string;
|
||||||
|
params: any[];
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
export abstract class RPCClient {
|
||||||
|
private _requestID: number;
|
||||||
|
|
||||||
|
private _pendingRequestsCount: number;
|
||||||
|
private _pendingRequests: Map<number, RPCRequestState>;
|
||||||
|
|
||||||
|
public constructor(
|
||||||
|
private _codec: RPCClientCodec,
|
||||||
|
private _rwc: RPCClientRWC,
|
||||||
|
) {
|
||||||
|
this._requestID = 0;
|
||||||
|
this._pendingRequestsCount = 0;
|
||||||
|
this._pendingRequests = new Map();
|
||||||
|
}
|
||||||
|
|
||||||
|
private getRequestID(): number {
|
||||||
|
return ++this._requestID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* connect
|
||||||
|
*/
|
||||||
|
public connect(queryString?: string): void {
|
||||||
|
this._rwc.connect(queryString);
|
||||||
|
this._rwc.readResponse().subscribe(
|
||||||
|
(value: Object) => {
|
||||||
|
this.onMessage(value);
|
||||||
|
},
|
||||||
|
(error: any) => {
|
||||||
|
console.error(error);
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* close
|
||||||
|
*/
|
||||||
|
public disconnect() {
|
||||||
|
this._rwc.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* notify
|
||||||
|
*/
|
||||||
|
public send(method: string, ...args: any[]): void {
|
||||||
|
this.sendInternal(false, method, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* call
|
||||||
|
*/
|
||||||
|
public call<T>(method: string, ...args: any[]): Observable<T> {
|
||||||
|
return this.sendInternal<T>(true, method, args);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* callTimeout
|
||||||
|
*/
|
||||||
|
public callTimeout<T>(ms: number, method: string, ...args: any[]): Observable<T> {
|
||||||
|
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private sendInternal<T>(hasResponse: boolean, method: string, args?: any[]): Observable<T> | undefined {
|
||||||
|
let id: number;
|
||||||
|
let resSubject: Subject<T>;
|
||||||
|
if (hasResponse) {
|
||||||
|
id = this.getRequestID();
|
||||||
|
resSubject = new Subject<T>();
|
||||||
|
const reqState: RPCRequestState = {
|
||||||
|
subject: resSubject,
|
||||||
|
request: {
|
||||||
|
method: method,
|
||||||
|
params: args,
|
||||||
|
}
|
||||||
|
};
|
||||||
|
this._pendingRequests.set(id, reqState);
|
||||||
|
this._pendingRequestsCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
const req = this._codec.request(method, args, id);
|
||||||
|
this._rwc.writeRequest(req);
|
||||||
|
|
||||||
|
if (undefined !== resSubject) {
|
||||||
|
return resSubject.asObservable();
|
||||||
|
}
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
private onMessage(message: Object): void {
|
||||||
|
const resCodec = this._codec.response(message);
|
||||||
|
|
||||||
|
if (resCodec.isNotification()) {
|
||||||
|
this.onNotification(resCodec.notification());
|
||||||
|
} else {
|
||||||
|
this.onResponse(resCodec);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected onResponse(resCodec: RPCClientResponseCodec): void {
|
||||||
|
const id = resCodec.id();
|
||||||
|
const result = resCodec.result();
|
||||||
|
const error = resCodec.error();
|
||||||
|
|
||||||
|
const reqState: RPCRequestState = this._pendingRequests.get(id);
|
||||||
|
|
||||||
|
this._pendingRequests.delete(id);
|
||||||
|
this._pendingRequestsCount--;
|
||||||
|
|
||||||
|
if (undefined !== result) {
|
||||||
|
reqState.subject.next(result);
|
||||||
|
} else if (undefined !== error) {
|
||||||
|
const rpcClientError: RPCClientError = {
|
||||||
|
request: reqState.request,
|
||||||
|
response: error,
|
||||||
|
};
|
||||||
|
console.error(rpcClientError);
|
||||||
|
reqState.subject.error(rpcClientError);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract onNotification(notiCodec: RPCClientNotificationCodec): void;
|
||||||
|
}
|
11
src/client/RPCClientRWC.ts
Normal file
11
src/client/RPCClientRWC.ts
Normal file
|
@ -0,0 +1,11 @@
|
||||||
|
import { InjectionToken } from '@angular/core';
|
||||||
|
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
|
||||||
|
export interface RPCClientRWC {
|
||||||
|
connect(queryString?: string): void;
|
||||||
|
readResponse(): Observable<Object>;
|
||||||
|
writeRequest(data: any): void;
|
||||||
|
disconnect(): void;
|
||||||
|
connectionStatus(): Observable<boolean>;
|
||||||
|
}
|
2
src/client/index.ts
Normal file
2
src/client/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export * from './RPCClient';
|
||||||
|
export * from './RPCClientRWC';
|
62
src/client/rwc/websocket/RPCClientWebsocketRWC.ts
Normal file
62
src/client/rwc/websocket/RPCClientWebsocketRWC.ts
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import { Subject } from 'rxjs/Subject';
|
||||||
|
import { map } from 'rxjs/operator/map';
|
||||||
|
|
||||||
|
import {
|
||||||
|
RxWebsocketSubject,
|
||||||
|
RxWebsocketSubjectConfig,
|
||||||
|
} from './RxWebsocketSubject';
|
||||||
|
|
||||||
|
import { RPCClientRWC } from '../../RPCClientRWC';
|
||||||
|
|
||||||
|
export class RPCClientWebsocketRWC implements RPCClientRWC {
|
||||||
|
private _wsSocketSubject: RxWebsocketSubject<Object>;
|
||||||
|
private _responseSubject: Subject<Object>;
|
||||||
|
|
||||||
|
public constructor(
|
||||||
|
private _config: RxWebsocketSubjectConfig,
|
||||||
|
) {
|
||||||
|
this._wsSocketSubject = new RxWebsocketSubject<Object>(this._config);
|
||||||
|
}
|
||||||
|
|
||||||
|
public connect(queryString?: string): void {
|
||||||
|
if (undefined !== queryString) {
|
||||||
|
this._wsSocketSubject.queryString = queryString;
|
||||||
|
}
|
||||||
|
this._wsSocketSubject.connect();
|
||||||
|
this._wsSocketSubject.subscribe(
|
||||||
|
(value: Object) => {
|
||||||
|
if (undefined !== this._responseSubject) {
|
||||||
|
this._responseSubject.next(value);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
(error: any) => {
|
||||||
|
if (undefined !== this._responseSubject) {
|
||||||
|
this._responseSubject.error(error);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
() => {
|
||||||
|
console.log('sss');
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnect(): void {
|
||||||
|
this._wsSocketSubject.disconnect();
|
||||||
|
}
|
||||||
|
|
||||||
|
public connectionStatus(): Observable<boolean> {
|
||||||
|
return this._wsSocketSubject.connectionStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public readResponse(): Observable<Object> {
|
||||||
|
if (undefined === this._responseSubject) {
|
||||||
|
this._responseSubject = new Subject<Object>();
|
||||||
|
}
|
||||||
|
return this._responseSubject.asObservable();
|
||||||
|
}
|
||||||
|
|
||||||
|
public writeRequest(data: any): void {
|
||||||
|
this._wsSocketSubject.write(data);
|
||||||
|
}
|
||||||
|
}
|
117
src/client/rwc/websocket/RxWebsocketSubject.ts
Normal file
117
src/client/rwc/websocket/RxWebsocketSubject.ts
Normal file
|
@ -0,0 +1,117 @@
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import { Observer } from 'rxjs/Observer';
|
||||||
|
import { Subject } from 'rxjs/Subject';
|
||||||
|
import {
|
||||||
|
WebSocketSubject,
|
||||||
|
WebSocketSubjectConfig
|
||||||
|
} from 'rxjs/observable/dom/WebSocketSubject';
|
||||||
|
|
||||||
|
import 'rxjs/add/operator/distinctUntilChanged';
|
||||||
|
import 'rxjs/add/operator/share';
|
||||||
|
import 'rxjs/add/operator/takeWhile';
|
||||||
|
import 'rxjs/add/observable/interval';
|
||||||
|
|
||||||
|
export interface RxWebsocketSubjectConfig {
|
||||||
|
url: string;
|
||||||
|
protocol?: string | Array<string>;
|
||||||
|
reconnectInterval?: 5000;
|
||||||
|
reconnectRetry?: 10;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class RxWebsocketSubject<T> extends Subject<T> {
|
||||||
|
private _reconnectionObservable: Observable<number>;
|
||||||
|
private _wsSubjectConfig: WebSocketSubjectConfig;
|
||||||
|
private _socket: WebSocketSubject<any>;
|
||||||
|
private _connectionObserver: Observer<boolean>;
|
||||||
|
private _connectionStatus: Observable<boolean>;
|
||||||
|
private _queryString: string;
|
||||||
|
|
||||||
|
public constructor(private _config: RxWebsocketSubjectConfig) {
|
||||||
|
super();
|
||||||
|
|
||||||
|
this._connectionStatus = new Observable<boolean>((observer) => {
|
||||||
|
this._connectionObserver = observer;
|
||||||
|
}).share().distinctUntilChanged();
|
||||||
|
|
||||||
|
this._wsSubjectConfig = {
|
||||||
|
url: _config.url,
|
||||||
|
protocol: _config.protocol,
|
||||||
|
closeObserver: {
|
||||||
|
next: (e: CloseEvent) => {
|
||||||
|
this._socket = null;
|
||||||
|
this._connectionObserver.next(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
openObserver: {
|
||||||
|
next: (e: Event) => {
|
||||||
|
this._connectionObserver.next(true);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
};
|
||||||
|
|
||||||
|
this._connectionStatus.subscribe((isConnected: boolean) => {
|
||||||
|
if (!this._reconnectionObservable && typeof(isConnected) === 'boolean' && !isConnected) {
|
||||||
|
this.reconnect();
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public set queryString(query: string) {
|
||||||
|
this._queryString = query;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get queryString(): string | undefined {
|
||||||
|
return this._queryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
public get connectionStatus(): Observable<boolean> {
|
||||||
|
return this._connectionStatus;
|
||||||
|
}
|
||||||
|
|
||||||
|
public connect(): void {
|
||||||
|
const wsSubjectConfig = Object.assign({}, this._wsSubjectConfig);
|
||||||
|
if (undefined !== this._queryString) {
|
||||||
|
wsSubjectConfig.url = wsSubjectConfig.url + '?' + this._queryString;
|
||||||
|
}
|
||||||
|
|
||||||
|
this._socket = new WebSocketSubject(wsSubjectConfig);
|
||||||
|
this._socket.subscribe(
|
||||||
|
(m) => {
|
||||||
|
this.next(m);
|
||||||
|
},
|
||||||
|
(error: Event) => {
|
||||||
|
if (!this._socket) {
|
||||||
|
this.reconnect();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public disconnect(): void {
|
||||||
|
this._socket.complete();
|
||||||
|
}
|
||||||
|
|
||||||
|
private reconnect(): void {
|
||||||
|
this._reconnectionObservable = Observable.interval(this._config.reconnectInterval)
|
||||||
|
.takeWhile((v, index) => {
|
||||||
|
return index < this._config.reconnectRetry && !this._socket;
|
||||||
|
});
|
||||||
|
this._reconnectionObservable.subscribe(
|
||||||
|
() => {
|
||||||
|
this.connect();
|
||||||
|
},
|
||||||
|
null,
|
||||||
|
() => {
|
||||||
|
this._reconnectionObservable = null;
|
||||||
|
if (!this._socket) {
|
||||||
|
this.complete();
|
||||||
|
this._connectionObserver.complete();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
public write(data: any): void {
|
||||||
|
this._socket.next(data);
|
||||||
|
}
|
||||||
|
}
|
2
src/client/rwc/websocket/index.ts
Normal file
2
src/client/rwc/websocket/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export * from './RPCClientWebsocketRWC';
|
||||||
|
export * from './RxWebsocketSubject';
|
6
src/core/error.ts
Normal file
6
src/core/error.ts
Normal file
|
@ -0,0 +1,6 @@
|
||||||
|
export class SubscriberParameterError extends Error {
|
||||||
|
public constructor(message?: string) {
|
||||||
|
super(message);
|
||||||
|
Object.setPrototypeOf(this, new.target.prototype);
|
||||||
|
}
|
||||||
|
}
|
2
src/core/index.ts
Normal file
2
src/core/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export * from './error';
|
||||||
|
export * from './token';
|
8
src/core/token.ts
Normal file
8
src/core/token.ts
Normal file
|
@ -0,0 +1,8 @@
|
||||||
|
import { InjectionToken } from '@angular/core';
|
||||||
|
|
||||||
|
export const RPC_CODEC = new InjectionToken('@loafer/ng-rpc RPC codec');
|
||||||
|
export const RPC_RWC = new InjectionToken('@loafer/ng-rpc RPC rwc');
|
||||||
|
|
||||||
|
export const _ROOT_SUBSCRIBERS = new InjectionToken('@loafer/ng-rpc RPC root subscribers');
|
||||||
|
export const _FEATURE_SUBSCRIBERS = new InjectionToken('@loafer/ng-rpc RPC feature subscribers');
|
||||||
|
|
1
src/decorator/index.ts
Normal file
1
src/decorator/index.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from './rpc-subscriber.decorator';
|
26
src/decorator/rpc-subscriber.decorator.ts
Normal file
26
src/decorator/rpc-subscriber.decorator.ts
Normal file
|
@ -0,0 +1,26 @@
|
||||||
|
import {
|
||||||
|
Type,
|
||||||
|
PropertyKeyType,
|
||||||
|
} from '@loafer/core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Decorator,
|
||||||
|
DecoratorFactory,
|
||||||
|
} from '@loafer/decorator';
|
||||||
|
|
||||||
|
export interface RPCSubscriberDecoratorAttribute {
|
||||||
|
method: string;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class RPCSubscriberDecorator extends Decorator<RPCSubscriberDecoratorAttribute> {
|
||||||
|
public constructor(config: RPCSubscriberDecoratorAttribute) {
|
||||||
|
super(config);
|
||||||
|
}
|
||||||
|
|
||||||
|
public methodDecorator = <T>(target: Object, propertyKey: PropertyKeyType,
|
||||||
|
descriptor: TypedPropertyDescriptor<T>): TypedPropertyDescriptor<T> | void => {
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
export const RPCSubscriber = DecoratorFactory.create<RPCSubscriberDecoratorAttribute>(RPCSubscriberDecorator);
|
1
src/index.ts
Normal file
1
src/index.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from './ng-rpc.module';
|
109
src/ng-rpc.module.ts
Normal file
109
src/ng-rpc.module.ts
Normal file
|
@ -0,0 +1,109 @@
|
||||||
|
import {
|
||||||
|
NgModule,
|
||||||
|
ModuleWithProviders,
|
||||||
|
Type,
|
||||||
|
Inject,
|
||||||
|
InjectionToken,
|
||||||
|
} from '@angular/core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
RPC_CODEC,
|
||||||
|
RPC_RWC,
|
||||||
|
|
||||||
|
_ROOT_SUBSCRIBERS,
|
||||||
|
_FEATURE_SUBSCRIBERS,
|
||||||
|
} from './core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
RPCClientRWC,
|
||||||
|
} from './client/RPCClientRWC';
|
||||||
|
|
||||||
|
import {
|
||||||
|
RPCClientCodec,
|
||||||
|
} from './protocol';
|
||||||
|
|
||||||
|
import {
|
||||||
|
SERVICES, RPCService,
|
||||||
|
} from './service';
|
||||||
|
|
||||||
|
import {
|
||||||
|
SUBSCRIBERS, RPCSubscribeService,
|
||||||
|
} from './subscribe';
|
||||||
|
|
||||||
|
export interface RPCFeatureModuleConfig {
|
||||||
|
subscribers?: Type<any>[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RPCRootModuleConfig {
|
||||||
|
subscribers?: Type<any>[];
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({})
|
||||||
|
export class RPCRootModule {
|
||||||
|
constructor(
|
||||||
|
private rpcService: RPCService,
|
||||||
|
private rpcSubscribeService: RPCSubscribeService,
|
||||||
|
@Inject(_ROOT_SUBSCRIBERS) rootSubscribers: any[],
|
||||||
|
) {
|
||||||
|
rootSubscribers.forEach((subscriber) => {
|
||||||
|
rpcSubscribeService.addSubscriber(subscriber);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({})
|
||||||
|
export class RPCFeatureModule {
|
||||||
|
constructor(
|
||||||
|
private rpcService: RPCService,
|
||||||
|
private rpcSubscribeService: RPCSubscribeService,
|
||||||
|
@Inject(_FEATURE_SUBSCRIBERS) featureSubscribersGroups: any[][],
|
||||||
|
private root: RPCRootModule,
|
||||||
|
) {
|
||||||
|
featureSubscribersGroups.forEach((featureSubscribers) => {
|
||||||
|
featureSubscribers.forEach((subscriber) => {
|
||||||
|
rpcSubscribeService.addSubscriber(subscriber);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@NgModule({})
|
||||||
|
export class RPCModule {
|
||||||
|
static forRoot(config: RPCRootModuleConfig): ModuleWithProviders {
|
||||||
|
const subscribers = undefined === config.subscribers ? [] : config.subscribers;
|
||||||
|
return {
|
||||||
|
ngModule: RPCRootModule,
|
||||||
|
providers: [
|
||||||
|
subscribers,
|
||||||
|
{
|
||||||
|
provide: _ROOT_SUBSCRIBERS,
|
||||||
|
deps: subscribers,
|
||||||
|
useFactory: createSourceInstances,
|
||||||
|
},
|
||||||
|
SERVICES,
|
||||||
|
SUBSCRIBERS,
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
static forFeature(config: RPCFeatureModuleConfig): ModuleWithProviders {
|
||||||
|
const subscribers = undefined === config.subscribers ? [] : config.subscribers;
|
||||||
|
|
||||||
|
return {
|
||||||
|
ngModule: RPCFeatureModule,
|
||||||
|
providers: [
|
||||||
|
subscribers,
|
||||||
|
{
|
||||||
|
provide: _FEATURE_SUBSCRIBERS,
|
||||||
|
multi: true,
|
||||||
|
deps: subscribers,
|
||||||
|
useFactory: createSourceInstances,
|
||||||
|
},
|
||||||
|
],
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export function createSourceInstances(...instances: any[]) {
|
||||||
|
return instances;
|
||||||
|
}
|
20
src/protocol/RPCClientCodec.ts
Normal file
20
src/protocol/RPCClientCodec.ts
Normal file
|
@ -0,0 +1,20 @@
|
||||||
|
import { RPCError } from './RPCError';
|
||||||
|
|
||||||
|
export interface RPCClientCodec {
|
||||||
|
request(method: string, args: any[], id: number): any;
|
||||||
|
response(res: any): RPCClientResponseCodec;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RPCClientResponseCodec {
|
||||||
|
id(): number | undefined;
|
||||||
|
error(): RPCError | undefined;
|
||||||
|
result(): any | undefined;
|
||||||
|
|
||||||
|
isNotification(): boolean;
|
||||||
|
notification(): RPCClientNotificationCodec | undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface RPCClientNotificationCodec {
|
||||||
|
method(): string;
|
||||||
|
params(): any | undefined;
|
||||||
|
}
|
41
src/protocol/RPCError.ts
Normal file
41
src/protocol/RPCError.ts
Normal file
|
@ -0,0 +1,41 @@
|
||||||
|
export interface RPCClientError {
|
||||||
|
request: {
|
||||||
|
method: string,
|
||||||
|
params: any[],
|
||||||
|
};
|
||||||
|
response: RPCError;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Error object representation when a method invocation fails.
|
||||||
|
*/
|
||||||
|
export interface RPCError {
|
||||||
|
/** Indicates the error type that occurred. */
|
||||||
|
code: RPCErrorCode;
|
||||||
|
|
||||||
|
/** A short description of the error. */
|
||||||
|
message: string;
|
||||||
|
|
||||||
|
/** Additional information about the error */
|
||||||
|
data?: any;
|
||||||
|
}/*
|
||||||
|
|
||||||
|
/** Error codes are same as xml-rpc codes. See http://xmlrpc-epi.sourceforge.net/specs/rfc.fault_codes.php */
|
||||||
|
export const enum RPCErrorCode {
|
||||||
|
/** Parse error Invalid JSON was received by the Server. */
|
||||||
|
ParseError = -32700,
|
||||||
|
|
||||||
|
/** Invalid Request The JSON sent is not a valid Request object. */
|
||||||
|
InvalidRequest = -32600,
|
||||||
|
|
||||||
|
/** The method does not exist / is not available. */
|
||||||
|
MethodNotFound = -32601,
|
||||||
|
|
||||||
|
/** Invalid method parameter(s). */
|
||||||
|
InvalidParams = - -32602,
|
||||||
|
|
||||||
|
/** Internal JSON-RPC error. */
|
||||||
|
InternalError = -32603
|
||||||
|
|
||||||
|
/** -32000 to -32099: Reserved for implementation-defined Server errors. */
|
||||||
|
}
|
2
src/protocol/index.ts
Normal file
2
src/protocol/index.ts
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
export * from './RPCClientCodec';
|
||||||
|
export * from './RPCError';
|
125
src/protocol/json/JSONRPCClientCodec.ts
Normal file
125
src/protocol/json/JSONRPCClientCodec.ts
Normal file
|
@ -0,0 +1,125 @@
|
||||||
|
import {
|
||||||
|
RPCClientCodec,
|
||||||
|
RPCClientResponseCodec,
|
||||||
|
RPCClientNotificationCodec,
|
||||||
|
} from '../RPCClientCodec';
|
||||||
|
|
||||||
|
import {
|
||||||
|
RPCError,
|
||||||
|
} from '../RPCError';
|
||||||
|
|
||||||
|
export interface ClientNotification {
|
||||||
|
method: string;
|
||||||
|
params?: string[];
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ClientRequest {
|
||||||
|
jsonrpc: string;
|
||||||
|
method: string;
|
||||||
|
params?: string[];
|
||||||
|
id?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export interface ClientResponse {
|
||||||
|
jsonrpc: string;
|
||||||
|
result?: any;
|
||||||
|
error?: RPCError;
|
||||||
|
id?: number;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class JSONRPCClientCodec implements RPCClientCodec {
|
||||||
|
public request(method: string, args: any[], id?: number): any {
|
||||||
|
const params = convertParamsToStringArray(args);
|
||||||
|
|
||||||
|
const req: ClientRequest = {
|
||||||
|
jsonrpc: '2.0',
|
||||||
|
method: method,
|
||||||
|
params: 0 === params.length ? null : params,
|
||||||
|
id: id,
|
||||||
|
};
|
||||||
|
return JSON.stringify(req);
|
||||||
|
}
|
||||||
|
public response(res: any): RPCClientResponseCodec {
|
||||||
|
const _res: ClientResponse = {
|
||||||
|
id: res.id,
|
||||||
|
jsonrpc: res.jsonrpc,
|
||||||
|
result: res.result,
|
||||||
|
error: res.error,
|
||||||
|
};
|
||||||
|
return new JSONRPCClientResponseCodec(_res);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function convertParamsToStringArray(args: any[]): string[] | undefined {
|
||||||
|
const values: string[] = [];
|
||||||
|
|
||||||
|
if (undefined === args || null === args || 0 === args.length) {
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (let indexI = 0; indexI < args.length; indexI++) {
|
||||||
|
const arg = args[indexI];
|
||||||
|
|
||||||
|
switch (typeof arg) {
|
||||||
|
case 'boolean':
|
||||||
|
case 'number': // enum
|
||||||
|
values.push(String(arg));
|
||||||
|
break;
|
||||||
|
case 'string':
|
||||||
|
values.push(arg);
|
||||||
|
break;
|
||||||
|
case 'object': // array, map
|
||||||
|
values.push(JSON.stringify(arg));
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
throw new Error(`Not supported type[${typeof arg}]`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return values;
|
||||||
|
}
|
||||||
|
|
||||||
|
export class JSONRPCClientResponseCodec implements RPCClientResponseCodec {
|
||||||
|
public constructor(private _res: ClientResponse) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public id(): number | undefined {
|
||||||
|
return this._res.id;
|
||||||
|
}
|
||||||
|
public error(): RPCError | undefined {
|
||||||
|
return this._res.error;
|
||||||
|
}
|
||||||
|
public result(): any | undefined {
|
||||||
|
return this._res.result;
|
||||||
|
}
|
||||||
|
|
||||||
|
public isNotification(): boolean {
|
||||||
|
if (undefined !== this.id() || undefined === this.result()) {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
public notification(): RPCClientNotificationCodec | undefined {
|
||||||
|
if (undefined !== this.id() || undefined === this.result()) {
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
const _noti: ClientNotification = {
|
||||||
|
method: this._res.result.method,
|
||||||
|
params: this._res.result.params,
|
||||||
|
};
|
||||||
|
return new JSONRPCClientNotificationCodec(_noti);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
export class JSONRPCClientNotificationCodec implements RPCClientNotificationCodec {
|
||||||
|
public constructor(private _noti: ClientNotification) {
|
||||||
|
}
|
||||||
|
|
||||||
|
public method(): string {
|
||||||
|
return this._noti.method;
|
||||||
|
}
|
||||||
|
public params(): any[] | undefined {
|
||||||
|
return this._noti.params;
|
||||||
|
}
|
||||||
|
}
|
1
src/protocol/json/index.ts
Normal file
1
src/protocol/json/index.ts
Normal file
|
@ -0,0 +1 @@
|
||||||
|
export * from './JSONRPCClientCodec';
|
7
src/service/index.ts
Normal file
7
src/service/index.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
export * from './rpc.service';
|
||||||
|
|
||||||
|
import { RPCService } from './rpc.service';
|
||||||
|
|
||||||
|
export const SERVICES = [
|
||||||
|
RPCService,
|
||||||
|
];
|
39
src/service/rpc.service.ts
Normal file
39
src/service/rpc.service.ts
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
import { Injectable, Inject } from '@angular/core';
|
||||||
|
import { Store, select } from '@ngrx/store';
|
||||||
|
|
||||||
|
import { Observable } from 'rxjs/Observable';
|
||||||
|
import { Subject } from 'rxjs/Subject';
|
||||||
|
|
||||||
|
import {
|
||||||
|
RPC_CODEC,
|
||||||
|
RPC_RWC,
|
||||||
|
} from '../core';
|
||||||
|
|
||||||
|
import {
|
||||||
|
RPCClient,
|
||||||
|
RPCClientRWC,
|
||||||
|
} from '../client';
|
||||||
|
|
||||||
|
import {
|
||||||
|
RPCClientCodec,
|
||||||
|
RPCClientNotificationCodec,
|
||||||
|
} from '../protocol';
|
||||||
|
|
||||||
|
import {
|
||||||
|
RPCSubscribeService,
|
||||||
|
} from '../subscribe';
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class RPCService extends RPCClient {
|
||||||
|
constructor(
|
||||||
|
@Inject(RPC_CODEC) rpcClientCodec: RPCClientCodec,
|
||||||
|
@Inject(RPC_RWC) rpcClientRWC: RPCClientRWC,
|
||||||
|
private rpcSubscribeService: RPCSubscribeService,
|
||||||
|
) {
|
||||||
|
super(rpcClientCodec, rpcClientRWC);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected onNotification(notiCodec: RPCClientNotificationCodec): void {
|
||||||
|
this.rpcSubscribeService.notify(notiCodec);
|
||||||
|
}
|
||||||
|
}
|
7
src/subscribe/index.ts
Normal file
7
src/subscribe/index.ts
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
export * from './subscribe.service';
|
||||||
|
|
||||||
|
import { RPCSubscribeService } from './subscribe.service';
|
||||||
|
|
||||||
|
export const SUBSCRIBERS = [
|
||||||
|
RPCSubscribeService,
|
||||||
|
];
|
161
src/subscribe/subscribe.service.ts
Normal file
161
src/subscribe/subscribe.service.ts
Normal file
|
@ -0,0 +1,161 @@
|
||||||
|
import { Injectable, Inject } from '@angular/core';
|
||||||
|
import { Store, select } from '@ngrx/store';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Type,
|
||||||
|
PropertyKeyType,
|
||||||
|
} from '@loafer/core';
|
||||||
|
|
||||||
|
import { TypeUtil } from '@loafer/core/util/TypeUtil';
|
||||||
|
|
||||||
|
import {
|
||||||
|
Class,
|
||||||
|
Method,
|
||||||
|
Metadata,
|
||||||
|
} from '@loafer/core/reflect';
|
||||||
|
|
||||||
|
import { RPCSubscriberDecorator } from '../decorator';
|
||||||
|
|
||||||
|
import {
|
||||||
|
RPCClientNotificationCodec,
|
||||||
|
} from '../protocol';
|
||||||
|
import { SubscriberParameterError } from '../core';
|
||||||
|
|
||||||
|
export interface SubscriberMethod {
|
||||||
|
className: PropertyKeyType;
|
||||||
|
methodName: PropertyKeyType;
|
||||||
|
parameterTypes: string[];
|
||||||
|
|
||||||
|
method: Method;
|
||||||
|
instance: any;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Injectable()
|
||||||
|
export class RPCSubscribeService {
|
||||||
|
private subscriberTypes: Set<Type<any>>;
|
||||||
|
private subscribers: Set<any>;
|
||||||
|
private subscriberMethodMap: Map<string, SubscriberMethod[]>;
|
||||||
|
|
||||||
|
constructor(
|
||||||
|
) {
|
||||||
|
this.subscriberTypes = new Set();
|
||||||
|
this.subscribers = new Set();
|
||||||
|
this.subscriberMethodMap = new Map();
|
||||||
|
}
|
||||||
|
|
||||||
|
public addSubscriber(subscriber: Type<any>): void {
|
||||||
|
const type = TypeUtil.getType(subscriber);
|
||||||
|
|
||||||
|
if (this.subscriberTypes.has(type)) {
|
||||||
|
// console.log(`Subscriber[${type.name}] has been added`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
this.subscriberTypes.add(type);
|
||||||
|
|
||||||
|
const clazz = Class.forType(type);
|
||||||
|
if (undefined === clazz) {
|
||||||
|
console.log(`Type[${subscriber.name}] is not decorated type`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const methods = clazz.getMethods();
|
||||||
|
methods.forEach((method, propertyKey) => {
|
||||||
|
const annon = method.getAnnotation(RPCSubscriberDecorator);
|
||||||
|
if (undefined === annon) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const subscriberMethodName = annon.attribute.method;
|
||||||
|
let subscriberMethods: SubscriberMethod[] = this.subscriberMethodMap.get(subscriberMethodName);
|
||||||
|
if (undefined === subscriberMethods) {
|
||||||
|
subscriberMethods = [];
|
||||||
|
this.subscriberMethodMap.set(subscriberMethodName, subscriberMethods);
|
||||||
|
}
|
||||||
|
|
||||||
|
const paramTypes = this.getParamTypes(method);
|
||||||
|
|
||||||
|
const subscriberMethod: SubscriberMethod = {
|
||||||
|
className: clazz.getName(),
|
||||||
|
methodName: method.getName(),
|
||||||
|
parameterTypes: paramTypes,
|
||||||
|
method: method,
|
||||||
|
instance: subscriber,
|
||||||
|
};
|
||||||
|
|
||||||
|
subscriberMethods.push(subscriberMethod);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public notify(codec: RPCClientNotificationCodec): void {
|
||||||
|
const method = codec.method();
|
||||||
|
const params = codec.params();
|
||||||
|
|
||||||
|
const subscriberMethods: SubscriberMethod[] = this.subscriberMethodMap.get(method);
|
||||||
|
if (undefined === subscriberMethods) {
|
||||||
|
console.warn(`Subscriber for method[${method}] is not exist`);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
subscriberMethods.forEach((subscriberMethod) => {
|
||||||
|
try {
|
||||||
|
const args = this.converParams(params, subscriberMethod.parameterTypes);
|
||||||
|
subscriberMethod.method.invoke(subscriberMethod.instance, ...args);
|
||||||
|
} catch (error) {
|
||||||
|
console.error(error);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private getParamTypes(method: Method): string[] {
|
||||||
|
if (undefined === method || null === method || 0 === method.getParameterCount()) {
|
||||||
|
return [];
|
||||||
|
}
|
||||||
|
|
||||||
|
const parameters = method.getParameters();
|
||||||
|
const results: string[] = [];
|
||||||
|
for (let indexI = 0; indexI < parameters.length; indexI++) {
|
||||||
|
const paramType = parameters[indexI].getType();
|
||||||
|
results.push(paramType.name);
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
|
||||||
|
private converParams(params: string[], paramTypes: string[]): any[] {
|
||||||
|
const results: any[] = [];
|
||||||
|
|
||||||
|
if (undefined === params || null === params || 0 === params.length) {
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
if (undefined === paramTypes || null === paramTypes || 0 === paramTypes.length) {
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
if (params.length !== paramTypes.length) {
|
||||||
|
throw new SubscriberParameterError(`Count is not same from server[${params.length}] and method[${paramTypes.length}]`);
|
||||||
|
}
|
||||||
|
for (let indexI = 0; indexI < params.length; indexI++) {
|
||||||
|
const param = params[indexI];
|
||||||
|
const type = paramTypes[indexI];
|
||||||
|
switch (type) {
|
||||||
|
case 'Object':
|
||||||
|
case 'Array':
|
||||||
|
case 'Map':
|
||||||
|
results.push(JSON.parse(param));
|
||||||
|
break;
|
||||||
|
case 'String':
|
||||||
|
results.push(param);
|
||||||
|
break;
|
||||||
|
case 'Number':
|
||||||
|
results.push(Number(param));
|
||||||
|
break;
|
||||||
|
case 'Boolean':
|
||||||
|
results.push(Boolean(param));
|
||||||
|
break;
|
||||||
|
case 'Function':
|
||||||
|
throw new SubscriberParameterError(`Function type [${indexI}] is not allowed`);
|
||||||
|
default:
|
||||||
|
throw new SubscriberParameterError(`${type} type parameter[${indexI}] is not allowed`);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return results;
|
||||||
|
}
|
||||||
|
}
|
45
tsconfig.json
Normal file
45
tsconfig.json
Normal file
|
@ -0,0 +1,45 @@
|
||||||
|
{
|
||||||
|
"compileOnSave": false,
|
||||||
|
"compilerOptions": {
|
||||||
|
"baseUrl": "./src",
|
||||||
|
"outDir": "./dist",
|
||||||
|
"sourceMap": true,
|
||||||
|
"declaration": true,
|
||||||
|
"newLine": "LF",
|
||||||
|
"moduleResolution": "node",
|
||||||
|
|
||||||
|
/* Strict Type-Checking Options */
|
||||||
|
// "noImplicitAny": true /* Raise error on expressions and declarations with an implied 'any' type. */,
|
||||||
|
// "strictNullChecks": true /* Enable strict null checks. */,
|
||||||
|
// "strictFunctionTypes": true /* Enable strict checking of function types. */,
|
||||||
|
// "strictPropertyInitialization": true /* Enable strict checking of property initialization in classes. */,
|
||||||
|
// "noImplicitThis": true /* Raise error on 'this' expressions with an implied 'any' type. */,
|
||||||
|
// "alwaysStrict": true /* Parse in strict mode and emit "use strict" for each source file. */,
|
||||||
|
|
||||||
|
/* Additional Checks */
|
||||||
|
// "noUnusedLocals": true /* Report errors on unused locals. */,
|
||||||
|
// "noUnusedParameters": true /* Report errors on unused parameters. */,
|
||||||
|
"noImplicitReturns": true /* Report error when not all code paths in function return a value. */,
|
||||||
|
"noFallthroughCasesInSwitch": true /* Report errors for fallthrough cases in switch statement. */,
|
||||||
|
|
||||||
|
/* Debugging Options */
|
||||||
|
"traceResolution": false /* Report module resolution log messages. */,
|
||||||
|
"listEmittedFiles": false /* Print names of generated files part of the compilation. */,
|
||||||
|
"listFiles": false /* Print names of files part of the compilation. */,
|
||||||
|
"pretty": true /* Stylize errors and messages using color and context. */,
|
||||||
|
|
||||||
|
/* Experimental Options */
|
||||||
|
"experimentalDecorators": true /* Enables experimental support for ES7 decorators. */,
|
||||||
|
"emitDecoratorMetadata": true /* Enables experimental support for emitting type metadata for decorators. */,
|
||||||
|
|
||||||
|
"target": "es5",
|
||||||
|
"typeRoots": [
|
||||||
|
"node_modules/@types"
|
||||||
|
],
|
||||||
|
"types": [
|
||||||
|
],
|
||||||
|
"lib": [
|
||||||
|
"es2015", "es2016", "es2017", "dom"
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
34
tslint.json
Normal file
34
tslint.json
Normal file
|
@ -0,0 +1,34 @@
|
||||||
|
{
|
||||||
|
"extends": ["tslint:latest", "tslint-config-prettier", "tslint-immutable"],
|
||||||
|
"rules": {
|
||||||
|
"interface-name": [true, "never-prefix"],
|
||||||
|
// TODO: allow devDependencies only in **/*.spec.ts files:
|
||||||
|
// waiting on https://github.com/palantir/tslint/pull/3708
|
||||||
|
"no-implicit-dependencies": [true, "dev"],
|
||||||
|
|
||||||
|
/* tslint-immutable rules */
|
||||||
|
// Recommended built-in rules
|
||||||
|
"no-var-keyword": true,
|
||||||
|
"no-parameter-reassignment": true,
|
||||||
|
"typedef": [true, "call-signature"],
|
||||||
|
|
||||||
|
// Immutability rules
|
||||||
|
"readonly-keyword": true,
|
||||||
|
"readonly-array": true,
|
||||||
|
"no-let": true,
|
||||||
|
"no-object-mutation": true,
|
||||||
|
"no-delete": true,
|
||||||
|
"no-method-signature": true,
|
||||||
|
|
||||||
|
// Functional style rules
|
||||||
|
"no-this": true,
|
||||||
|
"no-class": true,
|
||||||
|
"no-mixed-interface": true,
|
||||||
|
"no-expression-statement": [
|
||||||
|
true,
|
||||||
|
{ "ignore-prefix": ["console.", "process.exit"] }
|
||||||
|
],
|
||||||
|
"no-if-statement": true
|
||||||
|
/* end tslint-immutable rules */
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user