@rws-framework/client 2.1.0 → 2.1.1
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/README.md +429 -201
- package/package.json +1 -1
- package/src/service_worker/src/_service_worker.ts +2 -3
- package/src/services/ConfigService.ts +5 -3
- package/typedoc.json +1 -1
package/README.md
CHANGED
|
@@ -8,13 +8,14 @@ Realtime Web Suit is a web-component powered, MS FAST powered fullstack-oriented
|
|
|
8
8
|
2. [Getting Started](#getting-started)
|
|
9
9
|
3. [Key Components: RWSClient & RoutingService](#key-components-rwsclient--routingservice)
|
|
10
10
|
4. [Component Initialization](#component-initialization)
|
|
11
|
-
5. [
|
|
12
|
-
6. [
|
|
13
|
-
7. [
|
|
14
|
-
8. [
|
|
15
|
-
9. [
|
|
16
|
-
10. [
|
|
17
|
-
11. [
|
|
11
|
+
5. [DI](#dependency-injection)
|
|
12
|
+
6. [Frontend routes](#frontend-routes)
|
|
13
|
+
7. [Backend Imports](#backend-imports)
|
|
14
|
+
8. [Utilizing APIService](#utilizing-apiservice)
|
|
15
|
+
9. [Notifier](#notifier)
|
|
16
|
+
10. [Service Worker](#service-worker)
|
|
17
|
+
11. [Example: WebChat Component](#example-webchat-component)
|
|
18
|
+
12. [Links](#links)
|
|
18
19
|
|
|
19
20
|
## Overview
|
|
20
21
|
|
|
@@ -30,12 +31,12 @@ from your project dir do:
|
|
|
30
31
|
yarn
|
|
31
32
|
```
|
|
32
33
|
|
|
33
|
-
Initiate cfg files:
|
|
34
|
+
Initiate cfg files and webpack build:
|
|
34
35
|
```bash
|
|
35
36
|
rws-client init
|
|
36
37
|
```
|
|
37
38
|
|
|
38
|
-
to install once and then to build after preparing
|
|
39
|
+
to install once and then to build after preparing components:
|
|
39
40
|
|
|
40
41
|
```bash
|
|
41
42
|
yarn build
|
|
@@ -48,7 +49,18 @@ yarn watch
|
|
|
48
49
|
then start engine in the site javascript (can be inline):
|
|
49
50
|
|
|
50
51
|
```javascript
|
|
51
|
-
window.RWSClient.start(CFG);
|
|
52
|
+
window.RWSClient.start(CFG).then();
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
*or for initial setup then start on certain event (example)*
|
|
56
|
+
|
|
57
|
+
```javascript
|
|
58
|
+
window.RWSClient.setup(CFG).then(() => {
|
|
59
|
+
$.on('loaded', function(data){
|
|
60
|
+
const optionalNewCfg = { backendRoutes: data.backendRoutes };
|
|
61
|
+
window.RWSClient.start(optionalNewCfg).then();
|
|
62
|
+
})
|
|
63
|
+
});
|
|
52
64
|
```
|
|
53
65
|
|
|
54
66
|
example config with interface:
|
|
@@ -56,23 +68,89 @@ example config with interface:
|
|
|
56
68
|
```javascript
|
|
57
69
|
const CFG = {
|
|
58
70
|
backendUrl: 'http://localhost:1337',
|
|
59
|
-
wsUrl: 'http://localhost:1338'
|
|
71
|
+
wsUrl: 'http://localhost:1338',
|
|
72
|
+
transports: ['websocket'],
|
|
73
|
+
user: rwsUser,
|
|
74
|
+
parted: true,
|
|
75
|
+
splitFileDir: '/lib/rws',
|
|
76
|
+
splitPrefix: 'myapp'
|
|
60
77
|
}
|
|
61
78
|
```
|
|
62
79
|
|
|
80
|
+
### The FRONT config interface:
|
|
81
|
+
|
|
63
82
|
```typescript
|
|
64
|
-
|
|
65
|
-
defaultLayout?: typeof RWSViewComponent
|
|
66
|
-
backendUrl?: string
|
|
67
|
-
wsUrl?: string
|
|
68
|
-
|
|
83
|
+
interface IRWSConfig {
|
|
84
|
+
defaultLayout?: typeof RWSViewComponent
|
|
85
|
+
backendUrl?: string // url to backend request/response gateway
|
|
86
|
+
wsUrl?: string // url to backend websockets gateway
|
|
87
|
+
backendRoutes?: any[] // routes from backend
|
|
69
88
|
apiPrefix?: string // f.e /api after host
|
|
70
89
|
routes?: IFrontRoutes, //override front routes
|
|
71
90
|
transports?: string[], //ws transports setup
|
|
72
91
|
user?: any, //user data if logged
|
|
73
92
|
ignoreRWSComponents?: boolean //do not register base RWS components
|
|
93
|
+
pubUrl?: string //the url for accessing public dir from browser URL (default: /)
|
|
94
|
+
pubPrefix?: string
|
|
95
|
+
parted?: boolean //sets async partitioning mode for components. Those wil be parted and loaded in BG.
|
|
96
|
+
splitFileDir?: string //the url for accessing split dir from browser URL (default: /)
|
|
97
|
+
splitPrefix?: string // prefix for parted file (`${pubPrefix}.${cmpName}.ts`)
|
|
98
|
+
routing_enabled?: boolean
|
|
99
|
+
_noLoad?: boolean
|
|
74
100
|
}
|
|
75
101
|
```
|
|
102
|
+
### The FRONT webpack config:
|
|
103
|
+
|
|
104
|
+
```javascript
|
|
105
|
+
const path = require('path');
|
|
106
|
+
const fs = require('fs');
|
|
107
|
+
const { spawn } = require('child_process');
|
|
108
|
+
const CopyWebpackPlugin = require('copy-webpack-plugin');
|
|
109
|
+
const RWSWebpackWrapper = require('rws-js-client/rws.webpack.config');
|
|
110
|
+
const { RuntimeGlobals } = require('webpack');
|
|
111
|
+
|
|
112
|
+
|
|
113
|
+
const executionDir = process.cwd();
|
|
114
|
+
|
|
115
|
+
const libdir = path.resolve(executionDir, '..', '..', 'target', 'app', 'lib', 'rws');
|
|
116
|
+
const pubdir = path.resolve(executionDir, '..', '..', 'target', 'app');
|
|
117
|
+
|
|
118
|
+
if(!fs.existsSync(libdir)){
|
|
119
|
+
fs.mkdirSync(libdir);
|
|
120
|
+
}
|
|
121
|
+
|
|
122
|
+
const copies = {
|
|
123
|
+
[libdir]: [
|
|
124
|
+
'./build',
|
|
125
|
+
'./src/styles/compiled/main.rws.css',
|
|
126
|
+
],
|
|
127
|
+
[pubdir]: [
|
|
128
|
+
'./public/service_worker.js',
|
|
129
|
+
'./public/service_worker.js.map'
|
|
130
|
+
]
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
const myappFrontPath = path.resolve(__dirname, '../myapp/frontend');
|
|
134
|
+
|
|
135
|
+
module.exports = RWSWebpackWrapper({
|
|
136
|
+
dev: true,
|
|
137
|
+
hot: false,
|
|
138
|
+
tsConfigPath: executionDir + '/tsconfig.json',
|
|
139
|
+
entry: `${executionDir}/src/index.ts`,
|
|
140
|
+
executionDir: executionDir,
|
|
141
|
+
publicDir: path.resolve(executionDir, 'public'),
|
|
142
|
+
outputDir: path.resolve(executionDir, 'build'),
|
|
143
|
+
outputFileName: 'junction.client.js',
|
|
144
|
+
copyToDir: copies,
|
|
145
|
+
serviceWorker: './src/service_worker/MyServiceWorker.ts',
|
|
146
|
+
parted: true,
|
|
147
|
+
partedPrefix: 'myapp',
|
|
148
|
+
partedComponentsLocations: ['../myapp', './src'],
|
|
149
|
+
customServiceLocations: ['${myappFrontPath}/src/services']
|
|
150
|
+
});
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
|
|
76
154
|
|
|
77
155
|
## Key Components
|
|
78
156
|
|
|
@@ -98,26 +176,34 @@ import RWSClient, { NotifyUiType, NotifyLogType } from '@rws-framework/client';
|
|
|
98
176
|
//@ts-ignore
|
|
99
177
|
import alertify from 'alertifyjs';
|
|
100
178
|
|
|
101
|
-
import './styles/main.scss';
|
|
102
|
-
|
|
103
|
-
import routes from './routing/routes';
|
|
104
|
-
|
|
179
|
+
import './styles/main.rws.scss';
|
|
105
180
|
import { backendRoutes } from './backendImport';
|
|
106
|
-
|
|
107
|
-
import initComponents from './application/_initComponents';
|
|
108
181
|
import { provideFASTDesignSystem, allComponents } from '@microsoft/fast-components';
|
|
109
182
|
|
|
110
|
-
|
|
111
|
-
|
|
183
|
+
// For single file output (will inject itself to DI on import):
|
|
184
|
+
//import initComponents from './application/_initComponents'
|
|
112
185
|
|
|
186
|
+
async function initializeApp() {
|
|
187
|
+
const theClient = RWSContainer().get(RWSClient);
|
|
188
|
+
|
|
113
189
|
theClient.setBackendRoutes(backendRoutes());
|
|
114
|
-
theClient.addRoutes(routes);
|
|
115
190
|
|
|
116
|
-
theClient.onInit(async () => {
|
|
117
|
-
|
|
191
|
+
theClient.onInit(async () => {
|
|
192
|
+
|
|
193
|
+
// For single file output:
|
|
194
|
+
//initComponents();
|
|
195
|
+
|
|
118
196
|
provideFASTDesignSystem().register(allComponents);
|
|
119
|
-
});
|
|
120
197
|
|
|
198
|
+
// const swFilePath: string = `${theClient.appConfig.get('pubUrl')}/service_worker.js`;
|
|
199
|
+
|
|
200
|
+
await theClient.swService.registerServiceWorker();
|
|
201
|
+
|
|
202
|
+
if(theClient.getUser()){
|
|
203
|
+
theClient.pushUserToServiceWorker({...theClient.getUser(), instructor: false});
|
|
204
|
+
}
|
|
205
|
+
|
|
206
|
+
});
|
|
121
207
|
|
|
122
208
|
theClient.setNotifier((message: string, logType: NotifyLogType, uiType: NotifyUiType = 'notification', onConfirm: (params: any) => void) => {
|
|
123
209
|
switch(uiType){
|
|
@@ -148,11 +234,11 @@ async function initializeApp() {
|
|
|
148
234
|
return;
|
|
149
235
|
}
|
|
150
236
|
});
|
|
151
|
-
|
|
237
|
+
|
|
238
|
+
theClient.assignClientToBrowser();
|
|
152
239
|
}
|
|
153
240
|
|
|
154
241
|
initializeApp().catch(console.error);
|
|
155
|
-
|
|
156
242
|
```
|
|
157
243
|
|
|
158
244
|
## Component Initialization
|
|
@@ -203,22 +289,27 @@ component-dir/
|
|
|
203
289
|
|
|
204
290
|
### application/_initComponents.ts
|
|
205
291
|
|
|
292
|
+
Only if parted mode is false.
|
|
293
|
+
|
|
206
294
|
```typescript
|
|
207
|
-
import
|
|
208
|
-
|
|
209
|
-
import {
|
|
210
|
-
import {
|
|
211
|
-
|
|
295
|
+
import jTrainerComponents from '../../../jtrainer/frontend/src/application/_initComponents';
|
|
296
|
+
|
|
297
|
+
import { WebChat } from '../../../jtrainer/frontend/src/components/webchat/component';
|
|
298
|
+
import { JunctionTrainer } from '../../../jtrainer/frontend/src/components/trainer/component';
|
|
299
|
+
|
|
300
|
+
import { BookLoader } from '../components/book-loader/component'
|
|
301
|
+
import { ChatLoader } from '../components/chat-loader/component'
|
|
212
302
|
|
|
213
303
|
import { registerRWSComponents } from '@rws-framework/client';
|
|
214
304
|
|
|
215
305
|
export default () => {
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
306
|
+
jTrainerComponents();
|
|
307
|
+
WebChat;
|
|
308
|
+
JunctionTrainer;
|
|
309
|
+
BookLoader;
|
|
310
|
+
ChatLoader;
|
|
311
|
+
|
|
312
|
+
RWSClientInstance.defineAllComponents();
|
|
222
313
|
}
|
|
223
314
|
|
|
224
315
|
```
|
|
@@ -232,7 +323,7 @@ export default () => {
|
|
|
232
323
|
theClient.addRoutes(routes); //routes are optional
|
|
233
324
|
|
|
234
325
|
theClient.onInit(async () => {
|
|
235
|
-
initComponents(); //user components from _initComponents.ts
|
|
326
|
+
initComponents(); //user components from _initComponents.ts (dont run and import when parted: true)
|
|
236
327
|
provideFASTDesignSystem().register(allComponents); // @microsoft/fast-components ready components init
|
|
237
328
|
});
|
|
238
329
|
|
|
@@ -246,7 +337,12 @@ import { RWSViewComponent, RWSView, observable, attr } from '@rws-framework/cli
|
|
|
246
337
|
const options?: RWSDecoratorOptions;
|
|
247
338
|
|
|
248
339
|
@RWSView('tag-name', options)
|
|
249
|
-
class WebChat extends RWSViewComponent {
|
|
340
|
+
class WebChat extends RWSViewComponent {
|
|
341
|
+
@attr tagAttr: string; //HTML tag attr
|
|
342
|
+
@ngAttr fromNgAttr: string; //HTML attr from angular template
|
|
343
|
+
@sanitizedAttr htmlAttr: string; //HTML attr that's sanitized with every val change
|
|
344
|
+
@observable someVar: any; //Var for templates/value change observation
|
|
345
|
+
}
|
|
250
346
|
```
|
|
251
347
|
|
|
252
348
|
The decorator options type:
|
|
@@ -257,6 +353,65 @@ interface RWSDecoratorOptions{
|
|
|
257
353
|
styles?: string //relative path to SCSS file (./styles/layout.scss)
|
|
258
354
|
fastElementOptions?: any //the stuff you would insert into static definition in FASTElement class.
|
|
259
355
|
}
|
|
356
|
+
|
|
357
|
+
```
|
|
358
|
+
|
|
359
|
+
# Dependency Injection
|
|
360
|
+
|
|
361
|
+
## Default service usage:
|
|
362
|
+
|
|
363
|
+
```typescript
|
|
364
|
+
import { RWSViewComponent, RWSView } from 'rws-js-client';
|
|
365
|
+
|
|
366
|
+
@RWSView('your-tag');
|
|
367
|
+
class YourComponent extends RWSViewComponent {
|
|
368
|
+
someMethod(url: string): void
|
|
369
|
+
{
|
|
370
|
+
this.apiService.get(url);
|
|
371
|
+
}
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
```
|
|
375
|
+
|
|
376
|
+
Default services: https://github.com/papablack/rws-client/blob/7d16d9c6d83c81c9fe470eb0f507756bc6c71b35/src/components/_component.ts#L58
|
|
377
|
+
|
|
378
|
+
## Custom service usage:
|
|
379
|
+
|
|
380
|
+
```typescript
|
|
381
|
+
import {
|
|
382
|
+
NotifyService, RWSView, RWSViewComponent,
|
|
383
|
+
WSService, ApiService, ConfigService,
|
|
384
|
+
ConfigServiceInstance, UtilsServiceInstance, ApiServiceInstance,
|
|
385
|
+
UtilsService, DOMServiceInstance, DOMService,
|
|
386
|
+
NotifyServiceInstance, WSServiceInstance, RoutingService,
|
|
387
|
+
RoutingServiceInstance, RWSInject
|
|
388
|
+
} from 'rws-js-client';
|
|
389
|
+
|
|
390
|
+
import DateService, {DateServiceInstance} from '../../my-custom-services/DateService';
|
|
391
|
+
|
|
392
|
+
|
|
393
|
+
@RWSView('your-tag')
|
|
394
|
+
class YourComponent extends RWSViewComponent {
|
|
395
|
+
constructor(
|
|
396
|
+
@RWSInject(DateService) protected dateService: DateServiceInstance, //custom service - default services from RWSViewComponent below
|
|
397
|
+
@RWSInject(ConfigService) protected config: ConfigServiceInstance,
|
|
398
|
+
@RWSInject(RoutingService) protected routingService: RoutingServiceInstance,
|
|
399
|
+
@RWSInject(DOMService) protected domService: DOMServiceInstance,
|
|
400
|
+
@RWSInject(UtilsService) protected utilsService: UtilsServiceInstance,
|
|
401
|
+
@RWSInject(ApiService) protected apiService: ApiServiceInstance,
|
|
402
|
+
@RWSInject(WSService) protected wsService: WSServiceInstance,
|
|
403
|
+
@RWSInject(NotifyService) protected notifyService: NotifyServiceInstance
|
|
404
|
+
) {
|
|
405
|
+
super(config, routingService, domService, utilsService, apiService, wsService, notifyService);
|
|
406
|
+
applyConstructor(this); //fix-incoming: DI constructor data inheritance problem - applyConstructor in super is bugged. Need tmp workaround.
|
|
407
|
+
}
|
|
408
|
+
|
|
409
|
+
someMethod(url: string): void
|
|
410
|
+
{
|
|
411
|
+
this.dateService.get(url);
|
|
412
|
+
}
|
|
413
|
+
}
|
|
414
|
+
|
|
260
415
|
```
|
|
261
416
|
|
|
262
417
|
## Frontend routes
|
|
@@ -321,7 +476,7 @@ after control method we have dynamic types those are: <**ResponseType**, **Paylo
|
|
|
321
476
|
Example Usage by controller route
|
|
322
477
|
|
|
323
478
|
```typescript
|
|
324
|
-
const apiPromise: Promise<ITalkApiResponse> =
|
|
479
|
+
const apiPromise: Promise<ITalkApiResponse> = this.apiService.back.post<ITalkApiResponse, IApiTalkPayload>('talk:models:prompt', {
|
|
325
480
|
message: msg,
|
|
326
481
|
model: this.chosenModel,
|
|
327
482
|
});
|
|
@@ -330,7 +485,7 @@ Example Usage by controller route
|
|
|
330
485
|
Example Usage by url
|
|
331
486
|
|
|
332
487
|
```typescript
|
|
333
|
-
const apiPromise: Promise<ITalkApiResponse> =
|
|
488
|
+
const apiPromise: Promise<ITalkApiResponse> = this.apiService.post<ITalkApiResponse, IApiTalkPayload>('/api/path/to/action', {
|
|
334
489
|
message: msg,
|
|
335
490
|
model: this.chosenModel,
|
|
336
491
|
});
|
|
@@ -388,95 +543,123 @@ import { RWSWSService as WSService } from '@rws-framework/client/src/services/WS
|
|
|
388
543
|
|
|
389
544
|
declare const self: ServiceWorkerGlobalScope;
|
|
390
545
|
|
|
391
|
-
class
|
|
546
|
+
class MyServiceWorker extends RWSServiceWorker {
|
|
547
|
+
public tracker: { currentTracker: TimeTracker | null };
|
|
548
|
+
public trackersToSync: TimeTracker[];
|
|
549
|
+
|
|
550
|
+
protected regExTypes: { [key: string]: RegExp } = {
|
|
551
|
+
SOME_VIEW: new RegExp('.*:\\/\\/.*\\/#\\/([a-z0-9].*)\\/route\\/action$')
|
|
552
|
+
};
|
|
392
553
|
ignoredUrls = [
|
|
393
554
|
new RegExp('(.*(?=.[^.]*$).*)/#/login'),
|
|
394
555
|
new RegExp('(.*(?=.[^.]*$).*)/#/logout'),
|
|
395
|
-
];
|
|
396
|
-
|
|
397
|
-
protected regExTypes = {
|
|
398
|
-
FLASHCARDS_VIEW: new RegExp('.*:\\/\\/.*\\/#\\/([a-z0-9].*)\\/reports\\/flashcards$')
|
|
399
|
-
};
|
|
556
|
+
];
|
|
400
557
|
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
558
|
+
constructor(){
|
|
559
|
+
super(self, RWSContainer());
|
|
560
|
+
}
|
|
561
|
+
|
|
562
|
+
checkForbidden(url: string): boolean {
|
|
563
|
+
if (!url) {
|
|
564
|
+
return true;
|
|
565
|
+
}
|
|
566
|
+
|
|
567
|
+
console.log('[SW] Check forbidden', url);
|
|
404
568
|
|
|
405
|
-
|
|
406
|
-
|
|
569
|
+
return this.ignoredUrls.some((item) => url.match(item));
|
|
570
|
+
}
|
|
407
571
|
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
572
|
+
isExtraType(id: string){
|
|
573
|
+
let result: string | null = null;
|
|
574
|
+
const _self = this;
|
|
575
|
+
|
|
576
|
+
Object.keys(this.regExTypes).forEach(function(key){
|
|
577
|
+
if(result === null && _self.regExTypes[key].exec(id) !== null){
|
|
578
|
+
result = key;
|
|
579
|
+
}
|
|
411
580
|
});
|
|
581
|
+
|
|
582
|
+
return result;
|
|
583
|
+
}
|
|
412
584
|
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
585
|
+
startServiceWorker(regExTypes: { [key: string]: RegExp }, forbiddenUrls: RegExp[]): JunctionServiceWorker
|
|
586
|
+
{
|
|
587
|
+
this.tracker = { currentTracker: null };
|
|
588
|
+
this.ignoredUrls = forbiddenUrls;
|
|
589
|
+
this.trackersToSync = [];
|
|
590
|
+
this.regExTypes = regExTypes;
|
|
418
591
|
|
|
592
|
+
return this;
|
|
593
|
+
}
|
|
419
594
|
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
client.postMessage(payload);
|
|
426
|
-
}
|
|
427
|
-
});
|
|
428
|
-
};
|
|
429
|
-
|
|
430
|
-
interface MSGEvent{
|
|
431
|
-
data?: {
|
|
432
|
-
command: string,
|
|
433
|
-
asset_type?: string,
|
|
434
|
-
params: any
|
|
435
|
-
}
|
|
436
|
-
}
|
|
595
|
+
async onInit(): Promise<void>
|
|
596
|
+
{
|
|
597
|
+
const _self: JunctionServiceWorker = this;
|
|
598
|
+
let THE_USER: IJunctionUser | null = null;
|
|
599
|
+
const toSync: TimeTracker[] = [];
|
|
437
600
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
}
|
|
442
|
-
};
|
|
601
|
+
let WS_URL: string | null;
|
|
602
|
+
|
|
603
|
+
console.log('Initiating ServiceWorker');
|
|
443
604
|
|
|
444
|
-
|
|
445
|
-
|
|
605
|
+
this.workerScope.addEventListener('message', (event: MSGEvent) => {
|
|
606
|
+
// console.log(event);
|
|
446
607
|
if(!event.data){
|
|
608
|
+
console.warn('[SW] Got empty message');
|
|
447
609
|
return;
|
|
448
610
|
}
|
|
449
611
|
|
|
450
612
|
if (event.data.command){
|
|
451
|
-
console.log('[SW] OP Message:', event.data);
|
|
613
|
+
console.log('[SW] OP Message:', event.data.command);
|
|
452
614
|
|
|
453
615
|
switch (event.data.command) {
|
|
454
616
|
case 'SET_WS_URL':
|
|
455
617
|
WS_URL = event.data.params.url;
|
|
456
618
|
break;
|
|
457
619
|
case 'SET_USER':
|
|
458
|
-
|
|
459
|
-
|
|
620
|
+
if(!this.getUser()){
|
|
621
|
+
THE_USER = event.data.params;
|
|
622
|
+
this.setUser(THE_USER);
|
|
623
|
+
}
|
|
624
|
+
_self.checkWs(WS_URL, this.getUser());
|
|
460
625
|
break;
|
|
461
626
|
case 'START_TRACKING':
|
|
462
|
-
checkWs();
|
|
463
|
-
if(!
|
|
627
|
+
_self.checkWs(WS_URL, this.getUser());
|
|
628
|
+
if(!this.wsService.socket() && this.getUser()){
|
|
464
629
|
break;
|
|
465
630
|
}
|
|
466
|
-
|
|
631
|
+
_self.trackActivity(event.data.asset_type, event.data.params.page_location, event.data.params, toSync);
|
|
467
632
|
break;
|
|
468
633
|
case 'TRACKER_SAVED':
|
|
469
634
|
const { clientId, tracker } = event.data.params;
|
|
470
635
|
|
|
471
|
-
sendMessageToClient(clientId, { message: 'TRACKER_SAVED_RESPONSE', data: tracker });
|
|
636
|
+
_self.sendMessageToClient(clientId, { message: 'TRACKER_SAVED_RESPONSE', data: tracker });
|
|
472
637
|
break;
|
|
473
638
|
}
|
|
474
639
|
}
|
|
475
|
-
});
|
|
640
|
+
});
|
|
476
641
|
}
|
|
642
|
+
|
|
643
|
+
async onActivate(): Promise<void>
|
|
644
|
+
{
|
|
645
|
+
console.log('Activated ServiceWorker');
|
|
646
|
+
|
|
647
|
+
this.startServiceWorker(this.regExTypes, this.ignoredUrls);
|
|
648
|
+
}
|
|
649
|
+
|
|
650
|
+
private checkWs(WS_URL: string, THE_USER: IJunctionUser): boolean
|
|
651
|
+
{
|
|
652
|
+
if(!this.wsService.socket() && WS_URL){
|
|
653
|
+
this.wsService.init(WS_URL, THE_USER);
|
|
654
|
+
|
|
655
|
+
return true;
|
|
656
|
+
}
|
|
657
|
+
|
|
658
|
+
return false;
|
|
659
|
+
};
|
|
477
660
|
}
|
|
478
661
|
|
|
479
|
-
|
|
662
|
+
MyServiceWorker.create();
|
|
480
663
|
```
|
|
481
664
|
|
|
482
665
|
## Example: WebChat Component
|
|
@@ -497,136 +680,181 @@ import { IMessage } from '../chat-message/component';
|
|
|
497
680
|
import { ITalkApiResponse, BedrockBaseModel, IHyperParameter,
|
|
498
681
|
|
|
499
682
|
@RWSView('web-chat')
|
|
500
|
-
class WebChat extends RWSViewComponent {
|
|
683
|
+
class WebChat extends RWSViewComponent {
|
|
501
684
|
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
@observable hyperParameters: { key: string, value: any }[] = [];
|
|
685
|
+
static fileList: string[] = [
|
|
686
|
+
'svg/icon_talk_1.svg'
|
|
687
|
+
];
|
|
506
688
|
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
this.chatContext = event.detail.item;
|
|
512
|
-
});
|
|
689
|
+
@observable messages: IMessage[] = [];
|
|
690
|
+
@observable hyperParameters: { key: string, value: any } | any = {};
|
|
691
|
+
@observable bookId: string = null;
|
|
692
|
+
@observable chapterNr: string = null;
|
|
513
693
|
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
this.chosenModel = null;
|
|
517
|
-
return;
|
|
518
|
-
}
|
|
694
|
+
@observable chosenModel: BedrockBaseModel = null;
|
|
695
|
+
@observable chatContext: IContext = { label: 'Book chat' };
|
|
519
696
|
|
|
520
|
-
|
|
697
|
+
@observable bookModel: IBook = null;
|
|
521
698
|
|
|
522
|
-
|
|
523
|
-
});
|
|
699
|
+
@observable minified: boolean = true;
|
|
524
700
|
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
this.setupModel();
|
|
528
|
-
}
|
|
701
|
+
@ngAttr custombookid: string = null;
|
|
702
|
+
@ngAttr customchapternr: string = null;
|
|
529
703
|
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
});
|
|
535
|
-
|
|
536
|
-
}
|
|
537
|
-
setupModel() {
|
|
538
|
-
// other code
|
|
539
|
-
}
|
|
704
|
+
@observable customTemperature: number = 0.7;
|
|
705
|
+
@observable customTopK: number = 250;
|
|
706
|
+
@observable customMaxTokensToSample: number = 1024;
|
|
707
|
+
@observable customTopP: number = 0.7;
|
|
540
708
|
|
|
541
|
-
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
709
|
+
@ngAttr hTemperature?: string = '0.7';
|
|
710
|
+
@ngAttr hTopK?: string = '250';
|
|
711
|
+
@ngAttr hMaxTokensToSample?: string = '1024';
|
|
712
|
+
@ngAttr hTopP?: string = '0.7';
|
|
545
713
|
|
|
546
|
-
|
|
547
|
-
|
|
548
|
-
this.hyperParameters = [
|
|
549
|
-
...this.hyperParameters,
|
|
550
|
-
{
|
|
551
|
-
key,
|
|
552
|
-
value
|
|
553
|
-
}
|
|
554
|
-
];
|
|
555
|
-
}
|
|
714
|
+
@observable convoId: string;
|
|
715
|
+
@observable wsId: string;
|
|
556
716
|
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
// other code
|
|
560
|
-
}
|
|
717
|
+
@ngAttr dev: PseudoBool = 'false';
|
|
718
|
+
@ngAttr opened: PseudoBool = 'false';
|
|
561
719
|
|
|
720
|
+
@ngAttr userImage: string | null = null;
|
|
721
|
+
@ngAttr initials: string | null = 'U';
|
|
562
722
|
|
|
563
|
-
|
|
564
|
-
|
|
723
|
+
handlers: (this: WebChat) => IWebChatHandlers = assignHandlers;
|
|
724
|
+
streamCall: (msg: IMessage) => Promise<void> = callStreamApi;
|
|
565
725
|
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
model: any;
|
|
569
|
-
}
|
|
726
|
+
getDefaultHyperParams = getDefaultParams;
|
|
727
|
+
setHyperParam = setHyperParam;
|
|
570
728
|
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
|
|
575
|
-
});
|
|
576
|
-
|
|
577
|
-
this.injectMessages = [msg, {
|
|
578
|
-
_promise: apiPromise,
|
|
579
|
-
me: false,
|
|
580
|
-
author: this.chosenModel.modelName,
|
|
581
|
-
content: null,
|
|
582
|
-
model: this.chosenModel,
|
|
583
|
-
created_at: new Date()
|
|
584
|
-
}];
|
|
729
|
+
public msgOptions: IConvoMsgOptions = {
|
|
730
|
+
headerEnabled: false,
|
|
731
|
+
dateEnabled: false
|
|
732
|
+
};
|
|
585
733
|
|
|
586
|
-
|
|
587
|
-
|
|
588
|
-
}
|
|
589
|
-
}
|
|
734
|
+
connectedCallback() {
|
|
735
|
+
super.connectedCallback();
|
|
590
736
|
|
|
591
|
-
|
|
592
|
-
|
|
737
|
+
if (this.routeParams?.dev || this.dev === 'true') {
|
|
738
|
+
this.dev = 'true';
|
|
739
|
+
} else {
|
|
740
|
+
this.dev = 'false';
|
|
741
|
+
}
|
|
593
742
|
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
model: any;
|
|
597
|
-
}
|
|
743
|
+
this.checkForBookId();
|
|
744
|
+
this.checkForBookChapter();
|
|
598
745
|
|
|
599
|
-
|
|
746
|
+
this.chosenModel = ClaudeModel;
|
|
600
747
|
|
|
601
|
-
|
|
602
|
-
|
|
603
|
-
author: this.chosenModel.modelName,
|
|
604
|
-
content: null,
|
|
605
|
-
model: this.chosenModel,
|
|
606
|
-
created_at: new Date()
|
|
607
|
-
};
|
|
748
|
+
const provider = this.chosenModel?.providerName?.toLowerCase() || null;
|
|
749
|
+
const defParams = this.getDefaultHyperParams(provider);
|
|
608
750
|
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
751
|
+
const defaultParams: { [key: string]: any } = {};
|
|
752
|
+
|
|
753
|
+
Object.keys(defParams).forEach(paramKey => {
|
|
754
|
+
if (defParams[paramKey]) {
|
|
755
|
+
defaultParams[paramKey] = this.setHyperParam(paramKey, defParams[paramKey]);
|
|
756
|
+
}
|
|
757
|
+
});
|
|
613
758
|
|
|
614
|
-
|
|
615
|
-
this.injectMessages = [msg, {
|
|
616
|
-
...sendMsg,
|
|
617
|
-
_stream: llmStream,
|
|
618
|
-
}];
|
|
759
|
+
this.hyperParameters = { ...defaultParams, ...this.hyperParameters };
|
|
619
760
|
|
|
620
|
-
|
|
621
|
-
|
|
622
|
-
|
|
623
|
-
|
|
761
|
+
this.wsId = uuid();
|
|
762
|
+
|
|
763
|
+
this.on<{ item: IMessage }>(WebChatEvents.message.send, (event: CustomEvent<{ item: IMessage }>) => {
|
|
764
|
+
|
|
765
|
+
|
|
766
|
+
this.streamCall(event.detail.item);
|
|
767
|
+
});
|
|
768
|
+
|
|
769
|
+
if (this.routeParams?.opened || this.opened === 'true') {
|
|
770
|
+
this.minified = false;
|
|
771
|
+
}
|
|
772
|
+
|
|
773
|
+
if (this.hTemperature) {
|
|
774
|
+
this.hHandlers.hTemperature(null, this.hTemperature);
|
|
775
|
+
}
|
|
776
|
+
|
|
777
|
+
if (this.hMaxTokensToSample) {
|
|
778
|
+
this.hHandlers.hMaxTokensToSample(null, this.hMaxTokensToSample);
|
|
779
|
+
}
|
|
780
|
+
|
|
781
|
+
if (this.hTopK) {
|
|
782
|
+
this.hHandlers.hTopK(null, this.hTopK);
|
|
783
|
+
}
|
|
784
|
+
|
|
785
|
+
if (this.hTopP) {
|
|
786
|
+
this.hHandlers.hTopP(null, this.hTopP);
|
|
787
|
+
}
|
|
788
|
+
}
|
|
789
|
+
checkForBookId() {
|
|
790
|
+
this.bookId = this.routeParams.bookId || this.custombookid || null;
|
|
791
|
+
|
|
792
|
+
if (this.bookId) {
|
|
793
|
+
this.apiService.back.get<IBook>('train:get:book', { routeParams: { bookId: this.bookId } }).then((data: IBook) => {
|
|
794
|
+
this.bookModel = data;
|
|
795
|
+
});
|
|
796
|
+
}
|
|
797
|
+
}
|
|
798
|
+
|
|
799
|
+
checkForBookChapter() {
|
|
800
|
+
this.chapterNr = this.routeParams.chapterNr || this.customchapternr || null;
|
|
801
|
+
}
|
|
802
|
+
|
|
803
|
+
custombookidChanged(oldVal: string, newVal: string) {
|
|
804
|
+
if (newVal) {
|
|
805
|
+
this.custombookid = newVal;
|
|
806
|
+
this.checkForBookId();
|
|
807
|
+
} else {
|
|
808
|
+
this.custombookid = null;
|
|
809
|
+
}
|
|
810
|
+
}
|
|
811
|
+
|
|
812
|
+
customchapternrChanged(oldVal: string, newVal: string) {
|
|
813
|
+
if (newVal) {
|
|
814
|
+
this.customchapternr = newVal;
|
|
815
|
+
this.checkForBookChapter();
|
|
816
|
+
} else {
|
|
817
|
+
this.customchapternr = null;
|
|
818
|
+
}
|
|
819
|
+
}
|
|
820
|
+
|
|
821
|
+
devChanged(oldVal: string, newVal: string) {
|
|
822
|
+
if (oldVal !== newVal) {
|
|
823
|
+
this.dev = newVal === 'true' ? 'true' : 'false';
|
|
824
|
+
}
|
|
825
|
+
}
|
|
826
|
+
|
|
827
|
+
hHandlers: IHyperHandler = getParamChangeHandlers.bind(this)();
|
|
828
|
+
|
|
829
|
+
hTemperatureChanged: ChangeHandlerType<string> = this.hHandlers.hTemperature;
|
|
830
|
+
hMaxTokensToSampleChanged: ChangeHandlerType<string> = this.hHandlers.hMaxTokensToSample;
|
|
831
|
+
hTopKChanged: ChangeHandlerType<string> = this.hHandlers.hTopK;
|
|
832
|
+
hTopPChanged: ChangeHandlerType<string> = this.hHandlers.hTopP;
|
|
833
|
+
|
|
834
|
+
userImageChanged(oldVal: string, newVal: string) {
|
|
835
|
+
if (newVal && oldVal !== newVal) {
|
|
836
|
+
this.userImage = newVal;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
|
|
840
|
+
initialsChanged(oldVal: string, newVal: string) {
|
|
841
|
+
if (newVal && oldVal !== newVal) {
|
|
842
|
+
this.initials = newVal;
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
|
|
846
|
+
convoIdChanged(oldVal: string, newVal: string) {
|
|
847
|
+
if (newVal && oldVal !== newVal) {
|
|
848
|
+
console.log(this.convoId);
|
|
849
|
+
this.convoId = newVal;
|
|
850
|
+
}
|
|
851
|
+
}
|
|
624
852
|
}
|
|
625
853
|
|
|
626
854
|
WebChat.defineComponent();
|
|
627
855
|
|
|
628
856
|
|
|
629
|
-
export { WebChat }
|
|
857
|
+
export { WebChat, IContext };
|
|
630
858
|
|
|
631
859
|
```
|
|
632
860
|
|
|
@@ -672,7 +900,7 @@ and src/config/config
|
|
|
672
900
|
Socket route from
|
|
673
901
|
|
|
674
902
|
```typescript
|
|
675
|
-
WSService.sendMessage('send_msg', {
|
|
903
|
+
WSService.sendMessage<PayloadType>('send_msg', {
|
|
676
904
|
modelId: this.chosenModel.modelId,
|
|
677
905
|
prompt: msg.content
|
|
678
906
|
});
|
package/package.json
CHANGED
|
@@ -74,9 +74,8 @@ abstract class RWSServiceWorker<UserType extends IRWSUser> {
|
|
|
74
74
|
{
|
|
75
75
|
const className = this.name;
|
|
76
76
|
|
|
77
|
-
if (!RWSServiceWorker._instances[className]) {
|
|
78
|
-
|
|
79
|
-
RWSServiceWorker._instances[className] = new this(workerScope, WSService);
|
|
77
|
+
if (!RWSServiceWorker._instances[className]) {
|
|
78
|
+
RWSServiceWorker._instances[className] = new this(workerScope, RWSContainer());
|
|
80
79
|
}
|
|
81
80
|
|
|
82
81
|
return RWSServiceWorker._instances[className] as InstanceType<T>;
|
|
@@ -3,9 +3,11 @@ import IRWSConfig from '../interfaces/IRWSConfig';
|
|
|
3
3
|
|
|
4
4
|
|
|
5
5
|
const _DEFAULTS: {[property: string]: any} = {
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
|
|
6
|
+
pubPrefix: '/',
|
|
7
|
+
pubUrl : window.origin,
|
|
8
|
+
splitFileDir: '/',
|
|
9
|
+
splitPrefix: 'rws'
|
|
10
|
+
}
|
|
9
11
|
|
|
10
12
|
const __SENT_TO_COMPONENTS: string[] = [];
|
|
11
13
|
|
package/typedoc.json
CHANGED