@rws-framework/client 2.3.0 → 2.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/cfg/_default.cfg.js +2 -2
- package/package.json +4 -3
- package/rws.webpack.config.js +33 -14
- package/src/client.ts +17 -8
- package/src/components/_component.ts +14 -13
- package/src/components/_decorator.ts +25 -72
- package/src/components/_decorators/RWSFillBuild.ts +37 -24
- package/src/components/_decorators/RWSInject.ts +50 -0
- package/src/components/_decorators/RWSService.ts +12 -0
- package/src/components/_decorators/_di.ts +15 -0
- package/src/components/router/component.ts +23 -10
- package/src/components/router/template.html +1 -0
- package/src/index.ts +1 -1
- package/src/routing/_router.ts +3 -1
- package/src/services/ConfigService.ts +23 -16
- package/_rws_build_configurator.d.ts +0 -12
- package/_rws_build_configurator.js +0 -44
package/cfg/_default.cfg.js
CHANGED
|
@@ -6,7 +6,7 @@ const _DEFAULT_CONFIG_VARS = {
|
|
|
6
6
|
publicDir: './public',
|
|
7
7
|
publicIndex: 'index.html',
|
|
8
8
|
outputFileName: 'client.rws.js',
|
|
9
|
-
outputDir: '
|
|
9
|
+
outputDir: process.cwd() + '/build',
|
|
10
10
|
//Frontend RWS client configs
|
|
11
11
|
backendUrl: null,
|
|
12
12
|
wsUrl: null,
|
|
@@ -15,7 +15,7 @@ const _DEFAULT_CONFIG_VARS = {
|
|
|
15
15
|
pubUrlFilePrefix: '/',
|
|
16
16
|
//Universal configs
|
|
17
17
|
transports: ['websocket'],
|
|
18
|
-
parted:
|
|
18
|
+
parted: false,
|
|
19
19
|
}
|
|
20
20
|
|
|
21
21
|
const _DEFAULT_CONFIG = Object.freeze(_DEFAULT_CONFIG_VARS);
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@rws-framework/client",
|
|
3
3
|
"private": false,
|
|
4
|
-
"version": "2.
|
|
4
|
+
"version": "2.4.0",
|
|
5
5
|
"main": "src/index.ts",
|
|
6
6
|
"scripts": {
|
|
7
7
|
"docs": "typedoc --tsconfig ./tsconfig.json"
|
|
@@ -26,6 +26,7 @@
|
|
|
26
26
|
},
|
|
27
27
|
"homepage": "https://github.com/papablack/rws-client#readme",
|
|
28
28
|
"dependencies": {
|
|
29
|
+
"@rws-framework/console": "^0.2.0",
|
|
29
30
|
"@microsoft/fast-element": "^1.12.0",
|
|
30
31
|
"@microsoft/fast-foundation": "^2.46.2",
|
|
31
32
|
"@types/moment": "^2.13.0",
|
|
@@ -52,7 +53,7 @@
|
|
|
52
53
|
"@open-wc/dev-server-hmr": "^0.1.2-next.0",
|
|
53
54
|
"@types/dragula": "^3.7.4",
|
|
54
55
|
"@types/express-fileupload": "^1.4.4",
|
|
55
|
-
"@types/he": "^1.2.3",
|
|
56
|
+
"@types/he": "^1.2.3",
|
|
56
57
|
"@types/json5": "^2.2.0",
|
|
57
58
|
"@types/sanitize-html": "^2.11.0",
|
|
58
59
|
"@types/socket.io-client": "^3.0.0",
|
|
@@ -67,7 +68,7 @@
|
|
|
67
68
|
"eslint-plugin-unused-imports": "^3.1.0",
|
|
68
69
|
"file-loader": "^6.2.0",
|
|
69
70
|
"html-webpack-plugin": "^5.5.3",
|
|
70
|
-
"loader-utils": "^3.2.1",
|
|
71
|
+
"loader-utils": "^3.2.1",
|
|
71
72
|
"mini-css-extract-plugin": "^2.7.6",
|
|
72
73
|
"node-sass": "^9.0.0",
|
|
73
74
|
"sass-loader": "^13.3.2",
|
package/rws.webpack.config.js
CHANGED
|
@@ -7,7 +7,8 @@ const BundleAnalyzerPlugin = require('webpack-bundle-analyzer').BundleAnalyzerPl
|
|
|
7
7
|
|
|
8
8
|
const RWSAfterPlugin = require('./webpack/rws_after_plugin');
|
|
9
9
|
const tools = require('./_tools');
|
|
10
|
-
const
|
|
10
|
+
const { _DEFAULT_CONFIG } = require('./cfg/_default.cfg');
|
|
11
|
+
const RWSConfigBuilder = require('@rws-framework/console').RWSConfigBuilder;
|
|
11
12
|
|
|
12
13
|
const TerserPlugin = require('terser-webpack-plugin');
|
|
13
14
|
const HtmlMinifier = require('html-minifier').minify;
|
|
@@ -20,6 +21,8 @@ const json5 = require('json5');
|
|
|
20
21
|
const RWSWebpackWrapper = (config) => {
|
|
21
22
|
const executionDir = config.executionDir || process.cwd();
|
|
22
23
|
|
|
24
|
+
const BuildConfigurator = new RWSConfigBuilder(executionDir + '/.rws.json', _DEFAULT_CONFIG);
|
|
25
|
+
|
|
23
26
|
const isDev = BuildConfigurator.get('dev') || config.dev;
|
|
24
27
|
const isHotReload = BuildConfigurator.get('hot') || config.hot;
|
|
25
28
|
const isReport = BuildConfigurator.get('report') || config.report;
|
|
@@ -40,22 +43,27 @@ const publicIndex = BuildConfigurator.get('publicIndex') || config.publicIndex;
|
|
|
40
43
|
|
|
41
44
|
let WEBPACK_PLUGINS = [
|
|
42
45
|
new webpack.DefinePlugin({
|
|
43
|
-
'process.env._RWS_DEFAULTS': JSON.stringify(BuildConfigurator.
|
|
44
|
-
|
|
45
|
-
new webpack.BannerPlugin({
|
|
46
|
-
banner: `if(!window.RWS){
|
|
47
|
-
const script = document.createElement('script');
|
|
48
|
-
script.src = '${partedDirUrlPrefix}/${partedPrefix}.vendors.js';
|
|
49
|
-
script.type = 'text/javascript';
|
|
50
|
-
document.body.appendChild(script);
|
|
51
|
-
}`.replace('\n', ''),
|
|
52
|
-
raw: true,
|
|
53
|
-
entryOnly: true,
|
|
54
|
-
// include: 'client'
|
|
46
|
+
'process.env._RWS_DEFAULTS': JSON.stringify(BuildConfigurator.exportDefaultConfig()),
|
|
47
|
+
'process.env._RWS_BUILD_OVERRIDE': JSON.stringify(BuildConfigurator.exportBuildConfig())
|
|
55
48
|
}),
|
|
56
49
|
new webpack.ContextReplacementPlugin(/moment[\/\\]locale$/, /en-gb/)
|
|
57
50
|
];
|
|
58
51
|
|
|
52
|
+
// if(isParted){
|
|
53
|
+
// WEBPACK_PLUGINS.push(new webpack.BannerPlugin({
|
|
54
|
+
// banner: `if(!window.RWS_PARTS_LOADED){
|
|
55
|
+
// const script = document.createElement('script');
|
|
56
|
+
// script.src = '${partedDirUrlPrefix}/${partedPrefix}.vendors.js';
|
|
57
|
+
// script.type = 'text/javascript';
|
|
58
|
+
// document.body.appendChild(script);
|
|
59
|
+
// window.RWS_PARTS_LOADED = true;
|
|
60
|
+
// }`.replace('\n', ''),
|
|
61
|
+
// raw: true,
|
|
62
|
+
// entryOnly: true,
|
|
63
|
+
// // include: 'client'
|
|
64
|
+
// }));
|
|
65
|
+
// }
|
|
66
|
+
|
|
59
67
|
const WEBPACK_AFTER_ACTIONS = config.actions || [];
|
|
60
68
|
|
|
61
69
|
const aliases = config.aliases = {};
|
|
@@ -125,7 +133,18 @@ const publicIndex = BuildConfigurator.get('publicIndex') || config.publicIndex;
|
|
|
125
133
|
|
|
126
134
|
const optimConfig = {
|
|
127
135
|
minimize: true,
|
|
128
|
-
minimizer: isDev ? [
|
|
136
|
+
minimizer: isDev ? [
|
|
137
|
+
new TerserPlugin({
|
|
138
|
+
terserOptions: {
|
|
139
|
+
mangle: false, //@error breaks FAST view stuff if enabled for all assets
|
|
140
|
+
output: {
|
|
141
|
+
comments: false
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
extractComments: false,
|
|
145
|
+
parallel: true,
|
|
146
|
+
})
|
|
147
|
+
] : [
|
|
129
148
|
new TerserPlugin({
|
|
130
149
|
terserOptions: {
|
|
131
150
|
keep_classnames: true, // Prevent mangling of class names
|
package/src/client.ts
CHANGED
|
@@ -39,7 +39,7 @@ class RWSClient {
|
|
|
39
39
|
private _container: Container;
|
|
40
40
|
private user: IRWSUser = null;
|
|
41
41
|
|
|
42
|
-
private config: IRWSConfig = {
|
|
42
|
+
private config: IRWSConfig = {};
|
|
43
43
|
protected initCallback: () => Promise<void> = async () => { };
|
|
44
44
|
|
|
45
45
|
private isSetup = false;
|
|
@@ -112,11 +112,9 @@ class RWSClient {
|
|
|
112
112
|
this.pushUserToServiceWorker(this.user);
|
|
113
113
|
}
|
|
114
114
|
|
|
115
|
-
await startClient(this.appConfig, this.wsService, this.notifyService, this.routingService);
|
|
115
|
+
await startClient(this.appConfig, this.wsService, this.notifyService, this.routingService);
|
|
116
116
|
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
await this.initCallback();
|
|
117
|
+
await this.initCallback();
|
|
120
118
|
|
|
121
119
|
return this;
|
|
122
120
|
}
|
|
@@ -226,13 +224,15 @@ class RWSClient {
|
|
|
226
224
|
const componentParts: string[] = await this.apiService.get<string[]>(this.appConfig.get('partedDirUrlPrefix') + '/rws_chunks_info.json');
|
|
227
225
|
|
|
228
226
|
componentParts.forEach((componentName: string, key: number) => {
|
|
227
|
+
const partUrl = `${this.appConfig.get('partedDirUrlPrefix')}/${this.appConfig.get('partedPrefix')}.${componentName}.js`;
|
|
228
|
+
|
|
229
229
|
const script: HTMLScriptElement = document.createElement('script');
|
|
230
|
-
script.src =
|
|
230
|
+
script.src = partUrl;
|
|
231
231
|
script.async = true;
|
|
232
232
|
script.type = 'text/javascript';
|
|
233
233
|
document.body.appendChild(script);
|
|
234
234
|
|
|
235
|
-
console.log(`Appended ${componentParts[key]} component`);
|
|
235
|
+
console.log(`Appended ${componentParts[key]} component (${partUrl})`);
|
|
236
236
|
});
|
|
237
237
|
}
|
|
238
238
|
|
|
@@ -272,7 +272,16 @@ class RWSClient {
|
|
|
272
272
|
|
|
273
273
|
static defineAllComponents() {
|
|
274
274
|
const richWindowComponents: RWSWindowComponentRegister = (window as Window & RWSWindow).RWS.components;
|
|
275
|
-
|
|
275
|
+
|
|
276
|
+
Object.keys(richWindowComponents).map(key => richWindowComponents[key].component).forEach((el: IWithCompose<RWSViewComponent>) => {
|
|
277
|
+
el.define(el as any, el.definition);
|
|
278
|
+
});
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
defineComponents(){
|
|
283
|
+
const richWindowComponents: RWSWindowComponentRegister = (window as Window & RWSWindow).RWS.components;
|
|
284
|
+
|
|
276
285
|
Object.keys(richWindowComponents).map(key => richWindowComponents[key].component).forEach((el: IWithCompose<RWSViewComponent>) => {
|
|
277
286
|
el.define(el as any, el.definition);
|
|
278
287
|
});
|
|
@@ -5,11 +5,10 @@ import UtilsService, { UtilsServiceInstance } from '../services/UtilsService';
|
|
|
5
5
|
import DOMService, { DOMServiceInstance, DOMOutputType } from '../services/DOMService';
|
|
6
6
|
import ApiService, { ApiServiceInstance } from '../services/ApiService';
|
|
7
7
|
import NotifyService, { NotifyServiceInstance } from '../services/NotifyService';
|
|
8
|
-
import RoutingService, { RoutingServiceInstance } from '../services/RoutingService';
|
|
9
8
|
import WSService, { WSServiceInstance } from '../services/WSService';
|
|
10
9
|
import { IRWSViewComponent, IAssetShowOptions } from '../interfaces/IRWSViewComponent';
|
|
11
10
|
import RWSWindow, { RWSWindowComponentInterface, loadRWSRichWindow } from '../interfaces/RWSWindow';
|
|
12
|
-
import {
|
|
11
|
+
import { applyConstructor, RWSInject } from './_decorator';
|
|
13
12
|
|
|
14
13
|
import 'reflect-metadata';
|
|
15
14
|
|
|
@@ -34,6 +33,7 @@ export interface IWithCompose<T extends RWSViewComponent> {
|
|
|
34
33
|
define<TType extends (...params: any[]) => any>(type: TType, nameOrDef?: string | PartialFASTElementDefinition | undefined): TType;
|
|
35
34
|
_verbose: boolean;
|
|
36
35
|
_toInject: {[key: string]: any};
|
|
36
|
+
_depKeys: {[key: string]: string[]};
|
|
37
37
|
}
|
|
38
38
|
|
|
39
39
|
abstract class RWSViewComponent extends FoundationElement implements IRWSViewComponent {
|
|
@@ -46,32 +46,33 @@ abstract class RWSViewComponent extends FoundationElement implements IRWSViewCom
|
|
|
46
46
|
static autoLoadFastElement = true;
|
|
47
47
|
static _defined: { [key: string]: boolean } = {};
|
|
48
48
|
static _toInject: any[] = [];
|
|
49
|
+
static _depKeys: {[key: string]: string[]} = {_all: []};
|
|
49
50
|
static _verbose: boolean = false;
|
|
50
51
|
|
|
52
|
+
@RWSInject(ConfigService, true) protected config: ConfigServiceInstance;
|
|
53
|
+
@RWSInject(DOMService, true) protected domService: DOMServiceInstance;
|
|
54
|
+
@RWSInject(UtilsService, true) protected utilsService: UtilsServiceInstance;
|
|
55
|
+
@RWSInject(ApiService, true) protected apiService: ApiServiceInstance;
|
|
56
|
+
@RWSInject(WSService, true) protected wsService: WSServiceInstance;
|
|
57
|
+
@RWSInject(NotifyService, true) protected notifyService: NotifyServiceInstance;
|
|
58
|
+
|
|
51
59
|
@observable trashIterator: number = 0;
|
|
52
60
|
@observable fileAssets: {
|
|
53
61
|
[key: string]: ViewTemplate
|
|
54
62
|
} = {};
|
|
55
63
|
|
|
56
|
-
constructor(
|
|
57
|
-
@RWSInject(ConfigService) protected config: ConfigServiceInstance,
|
|
58
|
-
@RWSInject(RoutingService) protected routingService: RoutingServiceInstance,
|
|
59
|
-
@RWSInject(DOMService) protected domService: DOMServiceInstance,
|
|
60
|
-
@RWSInject(UtilsService) protected utilsService: UtilsServiceInstance,
|
|
61
|
-
@RWSInject(ApiService) protected apiService: ApiServiceInstance,
|
|
62
|
-
@RWSInject(WSService) protected wsService: WSServiceInstance,
|
|
63
|
-
@RWSInject(NotifyService) protected notifyService: NotifyServiceInstance
|
|
64
|
-
) {
|
|
64
|
+
constructor() {
|
|
65
65
|
super();
|
|
66
66
|
applyConstructor(this);
|
|
67
|
+
|
|
67
68
|
}
|
|
68
69
|
|
|
69
70
|
connectedCallback() {
|
|
70
|
-
super.connectedCallback();
|
|
71
|
+
super.connectedCallback();
|
|
71
72
|
applyConstructor(this);
|
|
72
73
|
|
|
73
74
|
// console.trace(this.config);
|
|
74
|
-
|
|
75
|
+
// console.log(this.routingService);
|
|
75
76
|
if (!(this.constructor as IWithCompose<this>).definition && (this.constructor as IWithCompose<this>).autoLoadFastElement) {
|
|
76
77
|
throw new Error('RWS component is not named. Add `static definition = {name, template};`');
|
|
77
78
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { Key } from '@microsoft/fast-foundation';
|
|
2
1
|
import RWSViewComponent, { IWithCompose } from './_component';
|
|
3
|
-
import
|
|
2
|
+
import { RWSInject } from './_decorators/RWSInject';
|
|
3
|
+
|
|
4
4
|
import 'reflect-metadata';
|
|
5
5
|
|
|
6
6
|
interface RWSDecoratorOptions {
|
|
@@ -10,18 +10,8 @@ interface RWSDecoratorOptions {
|
|
|
10
10
|
ignorePackaging?: boolean
|
|
11
11
|
}
|
|
12
12
|
|
|
13
|
-
type InjectDecoratorReturnType = (target: any, key?: string | number | undefined, parameterIndex?: number) => void;
|
|
14
|
-
|
|
15
13
|
//const _PARAMTYPES_METADATA_KEY = 'design:paramtypes';
|
|
16
14
|
|
|
17
|
-
function RWSInject<T extends RWSViewComponent>(dependencyClass: Key): InjectDecoratorReturnType {
|
|
18
|
-
return (target: IWithCompose<T>, key?: keyof IWithCompose<T>, parameterIndex?: number) => {
|
|
19
|
-
const loadedDependency = RWSContainer().get(dependencyClass);
|
|
20
|
-
const paramNames = getFunctionParamNames(target.prototype.constructor);
|
|
21
|
-
target.prototype.constructor._toInject[paramNames[parameterIndex]] = loadedDependency;
|
|
22
|
-
};
|
|
23
|
-
}
|
|
24
|
-
|
|
25
15
|
function RWSView<T extends RWSViewComponent>(name: string, data?: RWSDecoratorOptions): (type: any) => void {
|
|
26
16
|
return (constructor: T) => {
|
|
27
17
|
};
|
|
@@ -31,15 +21,7 @@ function RWSIgnore(params: { mergeToApp?: boolean } = null): () => void {
|
|
|
31
21
|
return () => { };
|
|
32
22
|
}
|
|
33
23
|
|
|
34
|
-
function
|
|
35
|
-
// Convert the function to its string form and extract the parameter names
|
|
36
|
-
const funcStr = func.toString().replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s))/mg, '');
|
|
37
|
-
return funcStr.slice(funcStr.indexOf('(')+1, funcStr.indexOf(')')).split(',');
|
|
38
|
-
}
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
function getParentConstructor(instance: any): any
|
|
42
|
-
{
|
|
24
|
+
function getParentConstructor(instance: any): any {
|
|
43
25
|
const proto = Object.getPrototypeOf(instance.constructor.prototype);
|
|
44
26
|
if (proto && proto.constructor) {
|
|
45
27
|
return proto.constructor;
|
|
@@ -48,63 +30,34 @@ function getParentConstructor(instance: any): any
|
|
|
48
30
|
return null;
|
|
49
31
|
}
|
|
50
32
|
|
|
51
|
-
const applyConstructor = (component: RWSViewComponent): void => {
|
|
52
|
-
|
|
53
|
-
const parent = getParentConstructor(component);
|
|
54
|
-
|
|
55
|
-
if(!mainConstructor.length){
|
|
56
|
-
mainConstructor = parent;
|
|
57
|
-
}
|
|
58
|
-
|
|
59
|
-
let topConstructor = mainConstructor;
|
|
60
|
-
|
|
61
|
-
if( parent && parent.name === RWSViewComponent.name){
|
|
62
|
-
topConstructor = parent;
|
|
63
|
-
}
|
|
64
|
-
|
|
65
|
-
const existingInjectedDependencies = (topConstructor as IWithCompose<RWSViewComponent>)._toInject;
|
|
66
|
-
|
|
67
|
-
Object.keys(existingInjectedDependencies).forEach((depKey: string) => {
|
|
68
|
-
const loadedDependency = existingInjectedDependencies[depKey];
|
|
69
|
-
if(!(component as any)[depKey]){
|
|
70
|
-
(component as any)[depKey] = loadedDependency;
|
|
71
|
-
}
|
|
72
|
-
});
|
|
73
|
-
};
|
|
74
|
-
|
|
75
|
-
const applyProp = (component: RWSViewComponent, propName: string | symbol): any => {
|
|
76
|
-
let mainConstructor = component.constructor;
|
|
33
|
+
const applyConstructor = (component: RWSViewComponent, x: boolean = false): void => {
|
|
34
|
+
const mainConstructor: any = component.constructor;
|
|
77
35
|
const parent = getParentConstructor(component);
|
|
78
36
|
|
|
79
|
-
if(
|
|
80
|
-
|
|
81
|
-
}
|
|
82
|
-
|
|
83
|
-
let topConstructor = mainConstructor;
|
|
37
|
+
if (parent.name !== 'RWSViewComponent' ) {
|
|
38
|
+
return;
|
|
39
|
+
}
|
|
84
40
|
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
41
|
+
const existingInjectedDependencies = (mainConstructor as IWithCompose<RWSViewComponent>)._toInject;
|
|
42
|
+
const defaultDeps = (mainConstructor as IWithCompose<RWSViewComponent>)._depKeys['_all'] || [];
|
|
43
|
+
const depsToInject = (mainConstructor as IWithCompose<RWSViewComponent>)._depKeys[mainConstructor.name] || [];
|
|
88
44
|
|
|
89
|
-
if(
|
|
90
|
-
|
|
45
|
+
if (x) {
|
|
46
|
+
console.log({
|
|
47
|
+
mainConstructor: mainConstructor.name,
|
|
48
|
+
deps: existingInjectedDependencies
|
|
49
|
+
});
|
|
91
50
|
}
|
|
92
|
-
|
|
93
|
-
const existingInjectedDependencies = (topConstructor as IWithCompose<RWSViewComponent>)._toInject;
|
|
94
51
|
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
return null;
|
|
98
|
-
}
|
|
99
|
-
|
|
100
|
-
const loadedDependency = existingInjectedDependencies[propName];
|
|
52
|
+
Object.keys(existingInjectedDependencies).forEach((depKey: string) => {
|
|
53
|
+
// console.log(`Checking "${mainConstructor.name}" for "${depKey}"`, [...defaultDeps, ...depsToInject]);
|
|
101
54
|
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
55
|
+
if ([...defaultDeps, ...depsToInject].includes(depKey)) {
|
|
56
|
+
const loadedDependency = existingInjectedDependencies[depKey];
|
|
57
|
+
(component as any)[depKey] = loadedDependency;
|
|
58
|
+
console.log(`Assigned service to "${mainConstructor.name}(${depKey})":`, loadedDependency);
|
|
59
|
+
}
|
|
60
|
+
});
|
|
108
61
|
};
|
|
109
62
|
|
|
110
|
-
export { RWSView, RWSDecoratorOptions, RWSIgnore, RWSInject, applyConstructor
|
|
63
|
+
export { RWSView, RWSDecoratorOptions, RWSIgnore, RWSInject, applyConstructor };
|
|
@@ -1,43 +1,56 @@
|
|
|
1
1
|
import 'reflect-metadata';
|
|
2
2
|
import IRWSConfig from '../../interfaces/IRWSConfig.js';
|
|
3
3
|
|
|
4
|
+
function extractEnvVar(envVar: string){
|
|
5
|
+
const extractedVars = JSON.parse(JSON.stringify(envVar));
|
|
4
6
|
|
|
5
|
-
|
|
7
|
+
const {
|
|
8
|
+
backendUrl,
|
|
9
|
+
wsUrl,
|
|
10
|
+
partedDirUrlPrefix,
|
|
11
|
+
partedPrefix,
|
|
12
|
+
pubUrlFilePrefix,
|
|
13
|
+
transports,
|
|
14
|
+
parted
|
|
15
|
+
} = extractedVars;
|
|
16
|
+
|
|
17
|
+
const extractedFrontendVars = {
|
|
18
|
+
backendUrl,
|
|
19
|
+
wsUrl,
|
|
20
|
+
partedDirUrlPrefix,
|
|
21
|
+
partedPrefix,
|
|
22
|
+
pubUrlFilePrefix,
|
|
23
|
+
transports,
|
|
24
|
+
parted
|
|
25
|
+
};
|
|
26
|
+
|
|
27
|
+
return {
|
|
28
|
+
extractedVars,
|
|
29
|
+
extractedFrontendVars
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
|
|
33
|
+
function RWSFillBuild(config: Partial<IRWSConfig> = {}) {
|
|
6
34
|
return function <T extends { new(...args: any[]): {} }>(constructor: T) {
|
|
7
35
|
return class extends constructor {
|
|
8
36
|
_DEFAULTS: IRWSConfig;
|
|
37
|
+
_BUILD_OVERRIDE: IRWSConfig;
|
|
9
38
|
constructor(...args: any[]) {
|
|
10
39
|
super(...args);
|
|
11
40
|
|
|
12
|
-
const
|
|
13
|
-
|
|
14
|
-
const {
|
|
15
|
-
backendUrl,
|
|
16
|
-
wsUrl,
|
|
17
|
-
partedDirUrlPrefix,
|
|
18
|
-
partedPrefix,
|
|
19
|
-
pubUrlFilePrefix,
|
|
20
|
-
transports,
|
|
21
|
-
parted
|
|
22
|
-
} = extractedDefaults;
|
|
23
|
-
|
|
24
|
-
const extractedFrontendDefaults = {
|
|
25
|
-
backendUrl,
|
|
26
|
-
wsUrl,
|
|
27
|
-
partedDirUrlPrefix,
|
|
28
|
-
partedPrefix,
|
|
29
|
-
pubUrlFilePrefix,
|
|
30
|
-
transports,
|
|
31
|
-
parted
|
|
32
|
-
};
|
|
41
|
+
const extractedFrontendDefaults = extractEnvVar(process.env._RWS_DEFAULTS).extractedFrontendVars;
|
|
33
42
|
|
|
34
43
|
this._DEFAULTS = {
|
|
35
44
|
...config,
|
|
36
45
|
...extractedFrontendDefaults
|
|
37
|
-
};
|
|
46
|
+
} as IRWSConfig;
|
|
47
|
+
|
|
48
|
+
const extractedFrontendBuildVars = extractEnvVar(process.env._RWS_BUILD_OVERRIDE).extractedFrontendVars;
|
|
49
|
+
|
|
50
|
+
this._BUILD_OVERRIDE = extractedFrontendBuildVars as IRWSConfig;
|
|
38
51
|
}
|
|
39
52
|
};
|
|
40
53
|
};
|
|
41
54
|
}
|
|
42
55
|
|
|
43
|
-
export { RWSFillBuild }
|
|
56
|
+
export { RWSFillBuild };
|
|
@@ -0,0 +1,50 @@
|
|
|
1
|
+
import { Key } from '@microsoft/fast-foundation';
|
|
2
|
+
import RWSViewComponent, { IWithCompose } from '../_component';
|
|
3
|
+
import { loadDep, getFunctionParamNames } from './_di';
|
|
4
|
+
import TheRWSService from '../../services/_service';
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
type InjectDecoratorReturnType = (target: any, key?: string | number | undefined, parameterIndex?: number) => void;
|
|
8
|
+
type TargetType = any;
|
|
9
|
+
|
|
10
|
+
function addToComponentInjection(targetComponentName: string, constructor: any, depKey: string, dependencyClass: Key, isDefaultService: boolean = false){
|
|
11
|
+
|
|
12
|
+
if(isDefaultService){
|
|
13
|
+
targetComponentName = '_all';
|
|
14
|
+
}
|
|
15
|
+
|
|
16
|
+
if(!Object.keys(constructor._depKeys).includes(targetComponentName)){
|
|
17
|
+
constructor._depKeys = { [targetComponentName]: [] };
|
|
18
|
+
}
|
|
19
|
+
|
|
20
|
+
if(!constructor._depKeys[targetComponentName].includes(depKey)){
|
|
21
|
+
constructor._depKeys[targetComponentName].push(depKey);
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
if(!Object.keys(constructor._toInject).includes(depKey)){
|
|
25
|
+
const loadedDependency = loadDep<TheRWSService>(dependencyClass);
|
|
26
|
+
constructor._toInject[depKey] = loadedDependency;
|
|
27
|
+
}
|
|
28
|
+
|
|
29
|
+
console.log(targetComponentName);
|
|
30
|
+
}
|
|
31
|
+
|
|
32
|
+
function RWSInject<T extends RWSViewComponent>(dependencyClass: Key, defaultService: boolean = false): InjectDecoratorReturnType {
|
|
33
|
+
return (target: IWithCompose<T>, key?: keyof IWithCompose<T>, parameterIndex?: number) => {
|
|
34
|
+
if(key){
|
|
35
|
+
const targetConstructor = typeof target === 'function' ? target : (target as any).constructor;
|
|
36
|
+
console.log('propt', target.name);
|
|
37
|
+
addToComponentInjection(target.name, targetConstructor, key as string, dependencyClass, defaultService);
|
|
38
|
+
} else{
|
|
39
|
+
const targetConstructor = (target as any).prototype.constructor;
|
|
40
|
+
const paramNames = getFunctionParamNames(targetConstructor);
|
|
41
|
+
const depKey = paramNames[parameterIndex];
|
|
42
|
+
|
|
43
|
+
addToComponentInjection(target.name, targetConstructor, depKey, dependencyClass, defaultService);
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
}
|
|
47
|
+
|
|
48
|
+
export {
|
|
49
|
+
RWSInject
|
|
50
|
+
};
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import RWSViewComponent from '../_component';
|
|
2
|
+
|
|
3
|
+
interface RWSServiceDecoratorOptions {
|
|
4
|
+
_vars?: any
|
|
5
|
+
}
|
|
6
|
+
|
|
7
|
+
function RWSService<T extends RWSViewComponent>(options?: RWSServiceDecoratorOptions): (type: any) => void {
|
|
8
|
+
return (constructor: T) => {
|
|
9
|
+
};
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
export { RWSService };
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { Key } from '@microsoft/fast-foundation';
|
|
2
|
+
import RWSContainer from '../_container';
|
|
3
|
+
|
|
4
|
+
function getFunctionParamNames(func: () => any): string[] {
|
|
5
|
+
// Convert the function to its string form and extract the parameter names
|
|
6
|
+
const funcStr = func.toString().replace(/((\/\/.*$)|(\/\*[\s\S]*?\*\/)|(\s))/mg, '');
|
|
7
|
+
return funcStr.slice(funcStr.indexOf('(')+1, funcStr.indexOf(')')).split(',');
|
|
8
|
+
}
|
|
9
|
+
|
|
10
|
+
function loadDep<T>(dependencyKeyClass: Key): T
|
|
11
|
+
{
|
|
12
|
+
return RWSContainer().get(dependencyKeyClass) as T;
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
export { loadDep, getFunctionParamNames };
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { observable } from '@microsoft/fast-element';
|
|
2
|
-
import { RWSRouter, _ROUTING_EVENT_NAME, RouteReturn } from '../../services/RoutingService';
|
|
2
|
+
import RoutingService, { RWSRouter, _ROUTING_EVENT_NAME, RouteReturn, RoutingServiceInstance } from '../../services/RoutingService';
|
|
3
3
|
import RWSViewComponent, { IRWSViewComponent } from '../_component';
|
|
4
|
-
import {RWSView} from '../_decorator';
|
|
4
|
+
import {RWSInject, RWSView} from '../_decorator';
|
|
5
5
|
|
|
6
|
-
@RWSView('rws-router'
|
|
6
|
+
@RWSView('rws-router')
|
|
7
7
|
export class RouterComponent extends RWSViewComponent {
|
|
8
8
|
static autoLoadFastElement = false;
|
|
9
9
|
private routing: RWSRouter;
|
|
@@ -13,21 +13,34 @@ export class RouterComponent extends RWSViewComponent {
|
|
|
13
13
|
@observable childComponents: HTMLElement[] = [];
|
|
14
14
|
slotEl: HTMLElement = null;
|
|
15
15
|
|
|
16
|
+
constructor(@RWSInject(RoutingService) protected routingService: RoutingServiceInstance){
|
|
17
|
+
super();
|
|
18
|
+
}
|
|
19
|
+
|
|
16
20
|
connectedCallback() {
|
|
17
21
|
super.connectedCallback();
|
|
22
|
+
|
|
23
|
+
|
|
18
24
|
this.routing = this.routingService.apply(this);
|
|
19
|
-
|
|
20
|
-
if(this.currentUrl){
|
|
25
|
+
|
|
26
|
+
if(this.currentUrl){
|
|
21
27
|
this.handleRoute(this.routing.handleRoute(this.currentUrl));
|
|
22
28
|
}
|
|
23
29
|
}
|
|
24
30
|
|
|
25
|
-
currentUrlChanged(oldValue: string, newValue: string){
|
|
26
|
-
if(
|
|
27
|
-
this.
|
|
31
|
+
currentUrlChanged(oldValue: string, newValue: string){
|
|
32
|
+
if(newValue){
|
|
33
|
+
if(!this.routingService){
|
|
34
|
+
console.log(oldValue, newValue);
|
|
35
|
+
return;
|
|
36
|
+
}
|
|
37
|
+
|
|
38
|
+
if(!this.routing){
|
|
39
|
+
this.routing = this.routingService.apply(this);
|
|
28
40
|
|
|
29
|
-
|
|
30
|
-
|
|
41
|
+
}
|
|
42
|
+
this.handleRoute(this.routing.handleRoute(newValue));
|
|
43
|
+
}
|
|
31
44
|
}
|
|
32
45
|
|
|
33
46
|
private handleRoute(route: RouteReturn){
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
<div class="router"></div>
|
package/src/index.ts
CHANGED
|
@@ -27,7 +27,7 @@ import {
|
|
|
27
27
|
} from './services/RoutingService';
|
|
28
28
|
|
|
29
29
|
|
|
30
|
-
import { RWSDecoratorOptions, RWSIgnore,
|
|
30
|
+
import { RWSDecoratorOptions, RWSIgnore, RWSInject, RWSView } from './components/_decorator';
|
|
31
31
|
|
|
32
32
|
import { declareRWSComponents } from './components';
|
|
33
33
|
|
package/src/routing/_router.ts
CHANGED
|
@@ -28,13 +28,15 @@ class RWSRouter {
|
|
|
28
28
|
}
|
|
29
29
|
|
|
30
30
|
public fireHandler(route: IRWSRouteResult): RouteReturn
|
|
31
|
-
{
|
|
31
|
+
{
|
|
32
|
+
const handler = route.handler();
|
|
32
33
|
return [handler[0], handler[1], this.utilsService.mergeDeep(route.params, handler[2])];
|
|
33
34
|
}
|
|
34
35
|
|
|
35
36
|
public handleRoute(url: string): RouteReturn
|
|
36
37
|
{
|
|
37
38
|
const currentRoute = this.find(url);
|
|
39
|
+
console.log('CR', currentRoute);
|
|
38
40
|
|
|
39
41
|
if (history.pushState) {
|
|
40
42
|
window.history.pushState({ path: url }, '', url);
|
|
@@ -7,15 +7,13 @@ import { RWSFillBuild } from '../components/_decorators/RWSFillBuild';
|
|
|
7
7
|
|
|
8
8
|
const __SENT_TO_COMPONENTS: string[] = [];
|
|
9
9
|
|
|
10
|
-
@RWSFillBuild(
|
|
11
|
-
pubUrlFilePrefix: '/',
|
|
12
|
-
pubUrl: window.origin,
|
|
13
|
-
partedFileDir: '/',
|
|
14
|
-
partedPrefix: 'rws',
|
|
15
|
-
})
|
|
10
|
+
@RWSFillBuild()
|
|
16
11
|
class ConfigService extends TheService {
|
|
17
12
|
static isLoaded: boolean = false;
|
|
18
|
-
|
|
13
|
+
|
|
14
|
+
_DEFAULTS: Partial<IRWSConfig> = {};
|
|
15
|
+
_BUILD_OVERRIDE: IRWSConfig = {};
|
|
16
|
+
|
|
19
17
|
private data: IRWSConfig = {};
|
|
20
18
|
|
|
21
19
|
constructor() {
|
|
@@ -23,24 +21,33 @@ class ConfigService extends TheService {
|
|
|
23
21
|
}
|
|
24
22
|
|
|
25
23
|
public get(key: keyof IRWSConfig): any
|
|
26
|
-
{
|
|
24
|
+
{
|
|
25
|
+
|
|
27
26
|
if(!this._DEFAULTS){
|
|
28
|
-
throw new Error('No _DEFAULTS loaded!')
|
|
27
|
+
throw new Error('No _DEFAULTS loaded!');
|
|
29
28
|
}
|
|
30
29
|
|
|
31
|
-
|
|
30
|
+
|
|
32
31
|
const isInDefaults: boolean = Object.keys(this._DEFAULTS).includes(key);
|
|
32
|
+
const isInData: boolean = Object.keys(this.data).includes(key);
|
|
33
|
+
const isInBuildVars: boolean = Object.keys(this._BUILD_OVERRIDE).includes(key);
|
|
34
|
+
|
|
35
|
+
if(!isInData){
|
|
36
|
+
let defaultVal = null;
|
|
33
37
|
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
38
|
+
if(isInDefaults){
|
|
39
|
+
defaultVal = this._DEFAULTS[key];
|
|
40
|
+
}
|
|
41
|
+
|
|
42
|
+
if(isInBuildVars && !!this._BUILD_OVERRIDE[key]){
|
|
43
|
+
defaultVal = this._BUILD_OVERRIDE[key];
|
|
44
|
+
}
|
|
45
|
+
|
|
37
46
|
if(defaultVal && defaultVal[0] === '@'){
|
|
38
47
|
defaultVal = this.data[((defaultVal as string).slice(1)) as keyof IRWSConfig];
|
|
39
48
|
}
|
|
40
|
-
|
|
49
|
+
|
|
41
50
|
return defaultVal;
|
|
42
|
-
} else if(!isInData && !isInDefaults) {
|
|
43
|
-
return null;
|
|
44
51
|
}
|
|
45
52
|
|
|
46
53
|
|
|
@@ -1,12 +0,0 @@
|
|
|
1
|
-
declare const _DEFAULT_CONFIG: any;
|
|
2
|
-
|
|
3
|
-
declare function readConfigFile(filePath: string): any;
|
|
4
|
-
declare function get(key: string): any;
|
|
5
|
-
declare function exportConfig(): any;
|
|
6
|
-
|
|
7
|
-
export {
|
|
8
|
-
readConfigFile,
|
|
9
|
-
get,
|
|
10
|
-
exportConfig,
|
|
11
|
-
_DEFAULT_CONFIG
|
|
12
|
-
};
|
|
@@ -1,44 +0,0 @@
|
|
|
1
|
-
const fs = require('fs');
|
|
2
|
-
const json5 = require('json5');
|
|
3
|
-
|
|
4
|
-
const _DEFAULT_CONFIG = require('./cfg/_default.cfg')._DEFAULT_CONFIG;
|
|
5
|
-
const STORAGE = require('./cfg/_storage');
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
function readConfigFile(filePath){
|
|
9
|
-
if(!fs.existsSync(filePath)){
|
|
10
|
-
return _DEFAULT_CONFIG;
|
|
11
|
-
}
|
|
12
|
-
|
|
13
|
-
const fileConfig = json5.parse(fs.readFileSync(filePath, 'utf-8'));
|
|
14
|
-
|
|
15
|
-
return {
|
|
16
|
-
..._DEFAULT_CONFIG,
|
|
17
|
-
...fileConfig
|
|
18
|
-
}
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
function get(key){
|
|
22
|
-
_init();
|
|
23
|
-
|
|
24
|
-
return STORAGE.get(key);
|
|
25
|
-
}
|
|
26
|
-
|
|
27
|
-
function exportConfig(){
|
|
28
|
-
_init();
|
|
29
|
-
|
|
30
|
-
return STORAGE.getAll();
|
|
31
|
-
}
|
|
32
|
-
|
|
33
|
-
function _init(){
|
|
34
|
-
if(!STORAGE.isLoaded()){
|
|
35
|
-
STORAGE.init(readConfigFile(process.cwd() + '/.rws.json'))
|
|
36
|
-
}
|
|
37
|
-
}
|
|
38
|
-
|
|
39
|
-
module.exports = {
|
|
40
|
-
readConfigFile,
|
|
41
|
-
exportConfig,
|
|
42
|
-
get,
|
|
43
|
-
_DEFAULT_CONFIG
|
|
44
|
-
};
|