goblin-laboratory 2.2.1 → 2.2.2

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.
Files changed (62) hide show
  1. package/.editorconfig +9 -9
  2. package/.eslintrc.js +28 -28
  3. package/.zou-flow +3 -3
  4. package/README.md +107 -107
  5. package/carnotzet.js +10 -10
  6. package/config.js +13 -13
  7. package/laboratory.js +13 -13
  8. package/lib/.webpack-config.js +53 -53
  9. package/lib/carnotzet.js +118 -118
  10. package/lib/helpers.js +16 -16
  11. package/lib/index.js +66 -66
  12. package/package.json +47 -47
  13. package/widgets/connect-helpers/arrayEquals.js +5 -5
  14. package/widgets/connect-helpers/arraysEquals.js +24 -24
  15. package/widgets/connect-helpers/c.js +99 -99
  16. package/widgets/connect-helpers/join-models.js +16 -16
  17. package/widgets/connect-helpers/with-c.js +276 -276
  18. package/widgets/devtools.js +5 -5
  19. package/widgets/disconnect-overlay/styles.js +50 -50
  20. package/widgets/disconnect-overlay/widget.js +40 -40
  21. package/widgets/fields-view/widget.js +34 -34
  22. package/widgets/form/index.js +79 -79
  23. package/widgets/frame/widget.js +47 -47
  24. package/widgets/frontend-form/reducer.js +18 -18
  25. package/widgets/frontend-form/widget.js +15 -15
  26. package/widgets/importer/default.js +14 -14
  27. package/widgets/importer/importer.js +54 -53
  28. package/widgets/importer/index.js +4 -4
  29. package/widgets/index-browsers.js +195 -195
  30. package/widgets/index-electron-ws.js +153 -153
  31. package/widgets/index-electron.js +69 -69
  32. package/widgets/index.js +1 -1
  33. package/widgets/laboratory/service.js +542 -542
  34. package/widgets/laboratory/widget.js +98 -98
  35. package/widgets/maintenance/styles.js +38 -38
  36. package/widgets/maintenance/widget.js +65 -65
  37. package/widgets/props-binder/widget.js +48 -48
  38. package/widgets/renderer.js +85 -85
  39. package/widgets/root/index.js +54 -54
  40. package/widgets/searchkit/index.js +68 -68
  41. package/widgets/store/backend-reducer.js +116 -116
  42. package/widgets/store/commands-reducer.js +14 -14
  43. package/widgets/store/middlewares.js +171 -171
  44. package/widgets/store/network-reducer.js +23 -23
  45. package/widgets/store/root-reducer.js +35 -35
  46. package/widgets/store/store.js +40 -40
  47. package/widgets/store/widgets-reducer.js +95 -95
  48. package/widgets/theme-context/js-to-css.js +20 -20
  49. package/widgets/theme-context/widget.js +130 -130
  50. package/widgets/view/index.js +31 -31
  51. package/widgets/widget/index.js +1205 -1205
  52. package/widgets/widget/utils/connect.js +47 -47
  53. package/widgets/widget/utils/connectBackend.js +48 -48
  54. package/widgets/widget/utils/connectWidget.js +31 -31
  55. package/widgets/widget/utils/manifest.txt +134 -134
  56. package/widgets/widget/utils/shallowEqualShredder.js +36 -36
  57. package/widgets/widget/utils/widgets-actions.js +21 -21
  58. package/widgets/widget/utils/wrapMapStateToProps.js +26 -26
  59. package/widgets/with-desktop-id/widget.js +20 -20
  60. package/widgets/with-model/context.js +5 -5
  61. package/widgets/with-model/widget.js +42 -42
  62. package/widgets/with-workitem/widget.js +30 -30
@@ -1,542 +1,542 @@
1
- 'use strict';
2
-
3
- const path = require('path');
4
- const Goblin = require('xcraft-core-goblin');
5
- const goblinName = path.basename(module.parent.filename, '.js');
6
-
7
- // Define initial logic values
8
- const logicState = {};
9
-
10
- // Define logic handlers according rc.json
11
- const logicHandlers = {
12
- 'create': (state, action) => {
13
- const conf = action.get('config');
14
- const id = action.get('id');
15
- return state.set('', {
16
- id: id,
17
- root: null,
18
- rootId: null,
19
- titlebar: null,
20
- titlebarId: null,
21
- url: action.get('url'),
22
- feed: action.get('feed'),
23
- wid: action.get('wid'),
24
- clientSessionId: action.get('clientSessionId'),
25
- feeds: conf.feeds,
26
- theme: 'default',
27
- themesGen: {default: 1},
28
- zoom: null,
29
- themeContext: conf.themeContexts ? conf.themeContexts[0] : 'theme',
30
- });
31
- },
32
- 'set-feed': (state, action) => {
33
- return state.set('feed', action.get('desktopId'));
34
- },
35
- 'set-titlebar': (state, action) => {
36
- return state
37
- .set('titlebar', action.get('titlebar'))
38
- .set('titlebarId', action.get('titlebarId'));
39
- },
40
- 'set-root': (state, action) => {
41
- const widgetId = action.get('widgetId');
42
- let themeContext = action.get('themeContext');
43
- if (themeContext) {
44
- state = state.set('themeContext', themeContext);
45
- }
46
- let widget = action.get('widget');
47
- if (!widget) {
48
- widget = widgetId;
49
- }
50
- return state.set('rootId', widgetId).set('root', widget);
51
- },
52
- 'change-theme': (state, action) => {
53
- return state.set('theme', action.get('name'));
54
- },
55
- 'reload-theme': (state, action) => {
56
- const path = `themesGen.${action.get('name')}`;
57
- const gen = state.get(path, 1) + 1;
58
- return state.set(path, gen);
59
- },
60
- 'update-feeds': (state, action) => {
61
- return state.set('feeds', action.get('feeds'));
62
- },
63
- 'set-zoom': (state, action) => {
64
- return state.set('zoom', action.get('zoom'));
65
- },
66
- 'zoom': (state) => {
67
- const zoom = Math.round((state.get('zoom') + 0.1) * 10) / 10;
68
- return state.set('zoom', zoom);
69
- },
70
- 'un-zoom': (state) => {
71
- let zoom = Math.round((state.get('zoom') - 0.1) * 10) / 10;
72
- if (zoom <= 0) {
73
- zoom = 0.1;
74
- }
75
- return state.set('zoom', zoom);
76
- },
77
- 'default-zoom': (state) => {
78
- return state.set('zoom', 1.0);
79
- },
80
- 'change-zoom': (state, action) => {
81
- const zoom = action.get('zoom');
82
- return state.set('zoom', zoom);
83
- },
84
- };
85
-
86
- // Register quest's according rc.json
87
- Goblin.registerQuest(goblinName, 'create', function* (
88
- quest,
89
- desktopId,
90
- clientSessionId,
91
- userId,
92
- url,
93
- config,
94
- next
95
- ) {
96
- quest.goblin.setX('url', url);
97
- quest.goblin.setX('desktopId', desktopId);
98
- quest.goblin.setX('clientSessionId', clientSessionId);
99
- const labId = quest.goblin.id;
100
- const feed = desktopId;
101
- const winId = `wm@${labId}`;
102
-
103
- const themeContexts = config.themeContexts || ['theme'];
104
-
105
- for (const ctx of themeContexts) {
106
- const composerId = `theme-composer@${ctx}`;
107
- quest.create(
108
- 'theme-composer',
109
- {
110
- id: composerId,
111
- desktopId: desktopId,
112
- },
113
- next.parallel()
114
- );
115
- config.feeds.push(composerId);
116
- }
117
-
118
- const id = quest.goblin.id;
119
-
120
- quest.goblin.defer(
121
- quest.sub('goblin.released', function* (err, {msg, resp}) {
122
- yield resp.cmd('laboratory.del', {
123
- id,
124
- widgetId: msg.data.id,
125
- });
126
- })
127
- );
128
-
129
- quest.goblin.defer(
130
- quest.sub(
131
- `*::theme-composer@*.${clientSessionId}.reload-theme.requested`,
132
- function* (err, {msg, resp}) {
133
- yield resp.cmd('laboratory.reload-theme', {...msg.data, id});
134
- }
135
- )
136
- );
137
-
138
- quest.goblin.setX('forceDispose', false);
139
-
140
- /* Case where the socket is still connected but it lags */
141
- quest.goblin.defer(
142
- quest.sub.local('greathall::<perf>', (err, {msg}) => {
143
- quest.goblin.setX('forceDispose', !!msg.data.lag);
144
- })
145
- );
146
-
147
- /* Case where the socket */
148
- quest.goblin.defer(
149
- quest.resp.onReconnect((status) => {
150
- switch (status) {
151
- case 'attempt':
152
- quest.goblin.setX('forceDispose', true);
153
- break;
154
- case 'done':
155
- quest.goblin.setX('forceDispose', false);
156
- break;
157
- }
158
- })
159
- );
160
-
161
- quest.doSync(
162
- {id: quest.goblin.id, feed, wid: winId, url, config},
163
- next.parallel()
164
- );
165
-
166
- quest.me.initZoom(
167
- {
168
- clientSessionId,
169
- },
170
- next.parallel()
171
- );
172
-
173
- quest.me.initTheme(
174
- {
175
- clientSessionId,
176
- },
177
- next.parallel()
178
- );
179
-
180
- yield next.sync();
181
-
182
- quest.goblin.defer(
183
- quest.sub.local(
184
- `*::${winId}.${clientSessionId}.<window-closed>`,
185
- function* (err, {msg, resp}) {
186
- yield resp.cmd('laboratory.close', {id});
187
- }
188
- )
189
- );
190
-
191
- quest.goblin.defer(
192
- quest.sub.local(
193
- `*::${winId}.${clientSessionId}.<window-state-changed>`,
194
- function* (err, {msg, resp}) {
195
- yield resp.cmd('laboratory.save-window-state', {
196
- id,
197
- winId,
198
- state: msg.data.state,
199
- });
200
- }
201
- )
202
- );
203
- yield quest.create('wm', {
204
- id: winId,
205
- desktopId,
206
- url,
207
- labId: quest.goblin.id,
208
- clientSessionId,
209
- userId,
210
- feeds: config.feeds,
211
- options: {
212
- openDevTools: process.env.GOBLINS_DEVTOOLS === '1',
213
- useWS: config.useWS,
214
- target: config.target,
215
- title: config.title,
216
- fullscreenable: !!config.fullscreenable,
217
- //enableTestAutomationLogguer: true,
218
- },
219
- });
220
-
221
- /*const titlebarInfos = yield win.getTitlebar();
222
- if (titlebarInfos) {
223
- const {titlebar, titlebarId} = titlebarInfos;
224
- yield quest.me.setTitlebar({titlebar, titlebarId});
225
- }*/
226
- quest.log.info(`Laboratory ${quest.goblin.id} created!`);
227
- return quest.goblin.id;
228
- });
229
-
230
- Goblin.registerQuest(goblinName, 'close', function* (quest) {
231
- const clientSessionId = quest.goblin.getX('clientSessionId');
232
- const labId = quest.goblin.id;
233
-
234
- yield quest.cmd('client-session.close-window', {
235
- id: clientSessionId,
236
- winId: `wm@${labId}`,
237
- });
238
- yield quest.cmd('client.close-window', {labId});
239
- quest.release(labId);
240
- });
241
-
242
- Goblin.registerQuest(goblinName, 'get-client-session-id', function (quest) {
243
- return quest.goblin.getX('clientSessionId');
244
- });
245
-
246
- Goblin.registerQuest(goblinName, 'get-win-feed', function (quest) {
247
- const state = quest.goblin.getState();
248
- return {
249
- feed: state.get('feed'),
250
- wid: state.get('wid'),
251
- };
252
- });
253
-
254
- Goblin.registerQuest(goblinName, 'set-feed', function* (quest, desktopId) {
255
- quest.goblin.setX('desktopId', desktopId);
256
- const feeds = quest.goblin.getState().get('feeds');
257
- const wm = quest.getAPI(`wm@${quest.goblin.id}`);
258
- yield wm.feedSub({desktopId, feeds: feeds.valueSeq().toArray()});
259
-
260
- const labId = quest.goblin.id;
261
- const clientSessionId = quest.goblin.getState().get('clientSessionId');
262
- const fromFeed = quest.goblin.getState().get('feed');
263
- for (const branch of [labId, clientSessionId].filter((id) => !!id)) {
264
- yield quest.warehouse.graft({
265
- branch,
266
- fromFeed,
267
- toFeed: desktopId,
268
- });
269
- }
270
-
271
- quest.do();
272
- yield quest.warehouse.resend({feed: desktopId});
273
- });
274
-
275
- Goblin.registerQuest(goblinName, 'set-titlebar', function (
276
- quest,
277
- titlebar,
278
- titlebarId
279
- ) {
280
- quest.do({titlebar, titlebarId});
281
- });
282
-
283
- Goblin.registerQuest(goblinName, 'get-feed', function (quest) {
284
- return quest.goblin.getX('desktopId');
285
- });
286
-
287
- Goblin.registerQuest(goblinName, 'get-url', function (quest) {
288
- return quest.goblin.getX('url');
289
- });
290
-
291
- Goblin.registerQuest(goblinName, 'duplicate', function* (quest, forId) {
292
- const state = quest.goblin.getState();
293
- const url = state.get('url');
294
- const newLabId = `laboratory@${quest.uuidV4()}`;
295
- const lab = yield quest.createFor(forId, forId, newLabId, {
296
- id: newLabId,
297
- url,
298
- });
299
- return lab.id;
300
- });
301
-
302
- Goblin.registerQuest(goblinName, 'when-ui-crash', function (
303
- quest,
304
- desktopId,
305
- error,
306
- info
307
- ) {
308
- quest.log.err(
309
- `UI generate errors ! ${
310
- (error && error.stack) || ''
311
- }\nStack :${info.componentStack.replace(/\\n/g, '\n')}`
312
- );
313
- /*quest.fail(
314
- 'Erreur UI',
315
- 'Un composant graphique à crashé :(',
316
- 'ctrl+shift+i pour contrôler',
317
- info.componentStack
318
- );*/
319
- // RESET APP?
320
- //const state = quest.goblin.getState ();
321
- //const existingRoot = state.get ('root', null);
322
- //quest.me.setRoot ({widgetId: existingRoot});
323
- });
324
-
325
- Goblin.registerQuest(goblinName, 'set-root', function (
326
- quest,
327
- widget,
328
- widgetId,
329
- themeContext
330
- ) {
331
- quest.do();
332
- });
333
-
334
- Goblin.registerQuest(goblinName, 'listen', function* (
335
- quest,
336
- desktopId,
337
- userId,
338
- useConfigurator
339
- ) {
340
- unlisten(quest);
341
-
342
- if (useConfigurator === true || useConfigurator === false) {
343
- quest.goblin.setX('useConfigurator', useConfigurator);
344
- }
345
-
346
- if (userId) {
347
- const wmAPI = quest.getAPI(`wm@${quest.goblin.id}`);
348
- yield wmAPI.setUserId({userId});
349
- }
350
-
351
- const labId = quest.goblin.id;
352
- quest.goblin.setX(
353
- `nav-unsub`,
354
- quest.sub(`*::<${desktopId}>.nav.requested`, function* (err, {msg, resp}) {
355
- yield resp.cmd('laboratory.nav', {
356
- id: labId,
357
- desktopId,
358
- ...msg.data,
359
- });
360
- })
361
- );
362
-
363
- quest.goblin.setX(
364
- `change-theme-unsub`,
365
- quest.sub(`*::<${desktopId}>.change-theme.requested`, function* (
366
- err,
367
- {msg, resp}
368
- ) {
369
- yield resp.cmd('laboratory.change-theme', {
370
- id: labId,
371
- ...msg.data,
372
- });
373
- })
374
- );
375
-
376
- quest.goblin.setX(
377
- `dispatch-unsub`,
378
- quest.sub(`*::<${desktopId}>.dispatch.requested`, function* (
379
- err,
380
- {msg, resp}
381
- ) {
382
- yield resp.cmd('laboratory.dispatch', {
383
- id: labId,
384
- ...msg.data,
385
- });
386
- })
387
- );
388
- });
389
-
390
- function unlisten(quest) {
391
- if (quest.goblin.getX(`nav-unsub`)) {
392
- quest.goblin.getX(`nav-unsub`)();
393
- quest.goblin.getX(`change-theme-unsub`)();
394
- quest.goblin.getX(`dispatch-unsub`)();
395
- quest.goblin.delX(`nav-unsub`);
396
- quest.goblin.delX(`reload-theme-unsub`);
397
- quest.goblin.delX(`dispatch-unsub`);
398
- }
399
- }
400
-
401
- Goblin.registerQuest(goblinName, 'nav', function* (quest, route) {
402
- const win = quest.getAPI(`wm@${quest.goblin.id}`);
403
- yield win.nav({route});
404
- });
405
-
406
- /************************ SETTINGS *********************************/
407
-
408
- Goblin.registerQuest(goblinName, 'save-settings', function* (quest, propertie) {
409
- const value = quest.goblin.getState().get(propertie);
410
- const clientSessionId = quest.goblin.getX('clientSessionId');
411
- yield quest.cmd(`client-session.set-${propertie}`, {
412
- id: clientSessionId,
413
- [propertie]: value,
414
- });
415
- });
416
-
417
- Goblin.registerQuest(goblinName, 'save-window-state', function* (
418
- quest,
419
- winId,
420
- state
421
- ) {
422
- const clientSessionId = quest.goblin.getX('clientSessionId');
423
- yield quest.cmd(`client-session.set-window-state`, {
424
- id: clientSessionId,
425
- winId,
426
- state,
427
- });
428
- });
429
-
430
- /******************************************************************************/
431
-
432
- Goblin.registerQuest(goblinName, 'init-theme', function* (
433
- quest,
434
- clientSessionId
435
- ) {
436
- const name = yield quest.cmd('client-session.get-theme', {
437
- id: clientSessionId,
438
- });
439
-
440
- if (name) {
441
- yield quest.me.changeTheme({name});
442
- }
443
- });
444
-
445
- Goblin.registerQuest(goblinName, 'change-theme', function* (quest, name) {
446
- quest.do({name});
447
- yield quest.me.saveSettings({propertie: 'theme'});
448
- });
449
-
450
- Goblin.registerQuest(goblinName, 'reload-theme', function (quest, name) {
451
- quest.do({name});
452
- });
453
-
454
- /******************************************************************************/
455
-
456
- Goblin.registerQuest(goblinName, 'init-zoom', function* (
457
- quest,
458
- clientSessionId
459
- ) {
460
- let zoom = yield quest.cmd('client-session.get-zoom', {
461
- id: clientSessionId,
462
- });
463
-
464
- yield quest.me.setZoom({
465
- zoom,
466
- });
467
- });
468
-
469
- Goblin.registerQuest(goblinName, 'set-zoom', function* (quest) {
470
- quest.do();
471
- yield quest.me.saveSettings({propertie: 'zoom'});
472
- });
473
-
474
- Goblin.registerQuest(goblinName, 'zoom', function* (quest) {
475
- quest.do();
476
- yield quest.me.saveSettings({propertie: 'zoom'});
477
- });
478
-
479
- Goblin.registerQuest(goblinName, 'un-zoom', function* (quest) {
480
- quest.do();
481
- yield quest.me.saveSettings({propertie: 'zoom'});
482
- });
483
-
484
- Goblin.registerQuest(goblinName, 'default-zoom', function* (quest) {
485
- quest.do();
486
- yield quest.me.saveSettings({propertie: 'zoom'});
487
- });
488
-
489
- Goblin.registerQuest(goblinName, 'change-zoom', function* (quest) {
490
- quest.do();
491
- yield quest.me.saveSettings({propertie: 'zoom'});
492
- });
493
-
494
- /******************************************************************************/
495
-
496
- Goblin.registerQuest(goblinName, 'dispatch', function* (quest, action) {
497
- const win = quest.getAPI(`wm@${quest.goblin.id}`);
498
- yield win.dispatch({action});
499
- });
500
-
501
- Goblin.registerQuest(goblinName, 'open', function (quest, route) {
502
- quest.log.info('Laboratory opening:');
503
- quest.log.info(route);
504
- });
505
-
506
- Goblin.registerQuest(goblinName, 'del', function* (quest, widgetId) {
507
- const state = quest.goblin.getState();
508
- const feed = state.get('feed');
509
- const branch = widgetId;
510
- const labId = quest.goblin.id;
511
- const useConfigurator = quest.goblin.getX('useConfigurator');
512
-
513
- if (quest.goblin.getX('forceDispose')) {
514
- const WM = require('xcraft-core-host/lib/wm.js').instance;
515
- WM.disposeAll();
516
- quest.cmd('shutdown'); /* no yield here because it's terminated */
517
- return;
518
- }
519
-
520
- if (branch === feed || (branch === labId && useConfigurator === false)) {
521
- yield quest.warehouse.unsubscribe({feed: branch});
522
- } else {
523
- quest.log.info(
524
- `Laboratory deleting widget ${widgetId} from window ${feed}`
525
- );
526
- const parents = [labId];
527
- /* This special case ensures that the laboratory is removed like the case
528
- * where a client (orc socket) is destroyed.
529
- */
530
- if (branch === labId) {
531
- parents.push(`goblin-orc@*`);
532
- }
533
- yield quest.warehouse.feedSubscriptionDel({feed, branch, parents});
534
- }
535
- });
536
-
537
- Goblin.registerQuest(goblinName, 'delete', function (quest) {
538
- unlisten(quest);
539
- });
540
-
541
- // Create a Goblin with initial state and handlers
542
- module.exports = Goblin.configure(goblinName, logicState, logicHandlers);
1
+ 'use strict';
2
+
3
+ const path = require('path');
4
+ const Goblin = require('xcraft-core-goblin');
5
+ const goblinName = path.basename(module.parent.filename, '.js');
6
+
7
+ // Define initial logic values
8
+ const logicState = {};
9
+
10
+ // Define logic handlers according rc.json
11
+ const logicHandlers = {
12
+ 'create': (state, action) => {
13
+ const conf = action.get('config');
14
+ const id = action.get('id');
15
+ return state.set('', {
16
+ id: id,
17
+ root: null,
18
+ rootId: null,
19
+ titlebar: null,
20
+ titlebarId: null,
21
+ url: action.get('url'),
22
+ feed: action.get('feed'),
23
+ wid: action.get('wid'),
24
+ clientSessionId: action.get('clientSessionId'),
25
+ feeds: conf.feeds,
26
+ theme: 'default',
27
+ themesGen: {default: 1},
28
+ zoom: null,
29
+ themeContext: conf.themeContexts ? conf.themeContexts[0] : 'theme',
30
+ });
31
+ },
32
+ 'set-feed': (state, action) => {
33
+ return state.set('feed', action.get('desktopId'));
34
+ },
35
+ 'set-titlebar': (state, action) => {
36
+ return state
37
+ .set('titlebar', action.get('titlebar'))
38
+ .set('titlebarId', action.get('titlebarId'));
39
+ },
40
+ 'set-root': (state, action) => {
41
+ const widgetId = action.get('widgetId');
42
+ let themeContext = action.get('themeContext');
43
+ if (themeContext) {
44
+ state = state.set('themeContext', themeContext);
45
+ }
46
+ let widget = action.get('widget');
47
+ if (!widget) {
48
+ widget = widgetId;
49
+ }
50
+ return state.set('rootId', widgetId).set('root', widget);
51
+ },
52
+ 'change-theme': (state, action) => {
53
+ return state.set('theme', action.get('name'));
54
+ },
55
+ 'reload-theme': (state, action) => {
56
+ const path = `themesGen.${action.get('name')}`;
57
+ const gen = state.get(path, 1) + 1;
58
+ return state.set(path, gen);
59
+ },
60
+ 'update-feeds': (state, action) => {
61
+ return state.set('feeds', action.get('feeds'));
62
+ },
63
+ 'set-zoom': (state, action) => {
64
+ return state.set('zoom', action.get('zoom'));
65
+ },
66
+ 'zoom': (state) => {
67
+ const zoom = Math.round((state.get('zoom') + 0.1) * 10) / 10;
68
+ return state.set('zoom', zoom);
69
+ },
70
+ 'un-zoom': (state) => {
71
+ let zoom = Math.round((state.get('zoom') - 0.1) * 10) / 10;
72
+ if (zoom <= 0) {
73
+ zoom = 0.1;
74
+ }
75
+ return state.set('zoom', zoom);
76
+ },
77
+ 'default-zoom': (state) => {
78
+ return state.set('zoom', 1.0);
79
+ },
80
+ 'change-zoom': (state, action) => {
81
+ const zoom = action.get('zoom');
82
+ return state.set('zoom', zoom);
83
+ },
84
+ };
85
+
86
+ // Register quest's according rc.json
87
+ Goblin.registerQuest(goblinName, 'create', function* (
88
+ quest,
89
+ desktopId,
90
+ clientSessionId,
91
+ userId,
92
+ url,
93
+ config,
94
+ next
95
+ ) {
96
+ quest.goblin.setX('url', url);
97
+ quest.goblin.setX('desktopId', desktopId);
98
+ quest.goblin.setX('clientSessionId', clientSessionId);
99
+ const labId = quest.goblin.id;
100
+ const feed = desktopId;
101
+ const winId = `wm@${labId}`;
102
+
103
+ const themeContexts = config.themeContexts || ['theme'];
104
+
105
+ for (const ctx of themeContexts) {
106
+ const composerId = `theme-composer@${ctx}`;
107
+ quest.create(
108
+ 'theme-composer',
109
+ {
110
+ id: composerId,
111
+ desktopId: desktopId,
112
+ },
113
+ next.parallel()
114
+ );
115
+ config.feeds.push(composerId);
116
+ }
117
+
118
+ const id = quest.goblin.id;
119
+
120
+ quest.goblin.defer(
121
+ quest.sub('goblin.released', function* (err, {msg, resp}) {
122
+ yield resp.cmd('laboratory.del', {
123
+ id,
124
+ widgetId: msg.data.id,
125
+ });
126
+ })
127
+ );
128
+
129
+ quest.goblin.defer(
130
+ quest.sub(
131
+ `*::theme-composer@*.${clientSessionId}.reload-theme.requested`,
132
+ function* (err, {msg, resp}) {
133
+ yield resp.cmd('laboratory.reload-theme', {...msg.data, id});
134
+ }
135
+ )
136
+ );
137
+
138
+ quest.goblin.setX('forceDispose', false);
139
+
140
+ /* Case where the socket is still connected but it lags */
141
+ quest.goblin.defer(
142
+ quest.sub.local('greathall::<perf>', (err, {msg}) => {
143
+ quest.goblin.setX('forceDispose', !!msg.data.lag);
144
+ })
145
+ );
146
+
147
+ /* Case where the socket */
148
+ quest.goblin.defer(
149
+ quest.resp.onReconnect((status) => {
150
+ switch (status) {
151
+ case 'attempt':
152
+ quest.goblin.setX('forceDispose', true);
153
+ break;
154
+ case 'done':
155
+ quest.goblin.setX('forceDispose', false);
156
+ break;
157
+ }
158
+ })
159
+ );
160
+
161
+ quest.doSync(
162
+ {id: quest.goblin.id, feed, wid: winId, url, config},
163
+ next.parallel()
164
+ );
165
+
166
+ quest.me.initZoom(
167
+ {
168
+ clientSessionId,
169
+ },
170
+ next.parallel()
171
+ );
172
+
173
+ quest.me.initTheme(
174
+ {
175
+ clientSessionId,
176
+ },
177
+ next.parallel()
178
+ );
179
+
180
+ yield next.sync();
181
+
182
+ quest.goblin.defer(
183
+ quest.sub.local(
184
+ `*::${winId}.${clientSessionId}.<window-closed>`,
185
+ function* (err, {msg, resp}) {
186
+ yield resp.cmd('laboratory.close', {id});
187
+ }
188
+ )
189
+ );
190
+
191
+ quest.goblin.defer(
192
+ quest.sub.local(
193
+ `*::${winId}.${clientSessionId}.<window-state-changed>`,
194
+ function* (err, {msg, resp}) {
195
+ yield resp.cmd('laboratory.save-window-state', {
196
+ id,
197
+ winId,
198
+ state: msg.data.state,
199
+ });
200
+ }
201
+ )
202
+ );
203
+ yield quest.create('wm', {
204
+ id: winId,
205
+ desktopId,
206
+ url,
207
+ labId: quest.goblin.id,
208
+ clientSessionId,
209
+ userId,
210
+ feeds: config.feeds,
211
+ options: {
212
+ openDevTools: process.env.GOBLINS_DEVTOOLS === '1',
213
+ useWS: config.useWS,
214
+ target: config.target,
215
+ title: config.title,
216
+ fullscreenable: !!config.fullscreenable,
217
+ //enableTestAutomationLogguer: true,
218
+ },
219
+ });
220
+
221
+ /*const titlebarInfos = yield win.getTitlebar();
222
+ if (titlebarInfos) {
223
+ const {titlebar, titlebarId} = titlebarInfos;
224
+ yield quest.me.setTitlebar({titlebar, titlebarId});
225
+ }*/
226
+ quest.log.info(`Laboratory ${quest.goblin.id} created!`);
227
+ return quest.goblin.id;
228
+ });
229
+
230
+ Goblin.registerQuest(goblinName, 'close', function* (quest) {
231
+ const clientSessionId = quest.goblin.getX('clientSessionId');
232
+ const labId = quest.goblin.id;
233
+
234
+ yield quest.cmd('client-session.close-window', {
235
+ id: clientSessionId,
236
+ winId: `wm@${labId}`,
237
+ });
238
+ yield quest.cmd('client.close-window', {labId});
239
+ quest.release(labId);
240
+ });
241
+
242
+ Goblin.registerQuest(goblinName, 'get-client-session-id', function (quest) {
243
+ return quest.goblin.getX('clientSessionId');
244
+ });
245
+
246
+ Goblin.registerQuest(goblinName, 'get-win-feed', function (quest) {
247
+ const state = quest.goblin.getState();
248
+ return {
249
+ feed: state.get('feed'),
250
+ wid: state.get('wid'),
251
+ };
252
+ });
253
+
254
+ Goblin.registerQuest(goblinName, 'set-feed', function* (quest, desktopId) {
255
+ quest.goblin.setX('desktopId', desktopId);
256
+ const feeds = quest.goblin.getState().get('feeds');
257
+ const wm = quest.getAPI(`wm@${quest.goblin.id}`);
258
+ yield wm.feedSub({desktopId, feeds: feeds.valueSeq().toArray()});
259
+
260
+ const labId = quest.goblin.id;
261
+ const clientSessionId = quest.goblin.getState().get('clientSessionId');
262
+ const fromFeed = quest.goblin.getState().get('feed');
263
+ for (const branch of [labId, clientSessionId].filter((id) => !!id)) {
264
+ yield quest.warehouse.graft({
265
+ branch,
266
+ fromFeed,
267
+ toFeed: desktopId,
268
+ });
269
+ }
270
+
271
+ quest.do();
272
+ yield quest.warehouse.resend({feed: desktopId});
273
+ });
274
+
275
+ Goblin.registerQuest(goblinName, 'set-titlebar', function (
276
+ quest,
277
+ titlebar,
278
+ titlebarId
279
+ ) {
280
+ quest.do({titlebar, titlebarId});
281
+ });
282
+
283
+ Goblin.registerQuest(goblinName, 'get-feed', function (quest) {
284
+ return quest.goblin.getX('desktopId');
285
+ });
286
+
287
+ Goblin.registerQuest(goblinName, 'get-url', function (quest) {
288
+ return quest.goblin.getX('url');
289
+ });
290
+
291
+ Goblin.registerQuest(goblinName, 'duplicate', function* (quest, forId) {
292
+ const state = quest.goblin.getState();
293
+ const url = state.get('url');
294
+ const newLabId = `laboratory@${quest.uuidV4()}`;
295
+ const lab = yield quest.createFor(forId, forId, newLabId, {
296
+ id: newLabId,
297
+ url,
298
+ });
299
+ return lab.id;
300
+ });
301
+
302
+ Goblin.registerQuest(goblinName, 'when-ui-crash', function (
303
+ quest,
304
+ desktopId,
305
+ error,
306
+ info
307
+ ) {
308
+ quest.log.err(
309
+ `UI generate errors ! ${
310
+ (error && error.stack) || ''
311
+ }\nStack :${info.componentStack.replace(/\\n/g, '\n')}`
312
+ );
313
+ /*quest.fail(
314
+ 'Erreur UI',
315
+ 'Un composant graphique à crashé :(',
316
+ 'ctrl+shift+i pour contrôler',
317
+ info.componentStack
318
+ );*/
319
+ // RESET APP?
320
+ //const state = quest.goblin.getState ();
321
+ //const existingRoot = state.get ('root', null);
322
+ //quest.me.setRoot ({widgetId: existingRoot});
323
+ });
324
+
325
+ Goblin.registerQuest(goblinName, 'set-root', function (
326
+ quest,
327
+ widget,
328
+ widgetId,
329
+ themeContext
330
+ ) {
331
+ quest.do();
332
+ });
333
+
334
+ Goblin.registerQuest(goblinName, 'listen', function* (
335
+ quest,
336
+ desktopId,
337
+ userId,
338
+ useConfigurator
339
+ ) {
340
+ unlisten(quest);
341
+
342
+ if (useConfigurator === true || useConfigurator === false) {
343
+ quest.goblin.setX('useConfigurator', useConfigurator);
344
+ }
345
+
346
+ if (userId) {
347
+ const wmAPI = quest.getAPI(`wm@${quest.goblin.id}`);
348
+ yield wmAPI.setUserId({userId});
349
+ }
350
+
351
+ const labId = quest.goblin.id;
352
+ quest.goblin.setX(
353
+ `nav-unsub`,
354
+ quest.sub(`*::<${desktopId}>.nav.requested`, function* (err, {msg, resp}) {
355
+ yield resp.cmd('laboratory.nav', {
356
+ id: labId,
357
+ desktopId,
358
+ ...msg.data,
359
+ });
360
+ })
361
+ );
362
+
363
+ quest.goblin.setX(
364
+ `change-theme-unsub`,
365
+ quest.sub(`*::<${desktopId}>.change-theme.requested`, function* (
366
+ err,
367
+ {msg, resp}
368
+ ) {
369
+ yield resp.cmd('laboratory.change-theme', {
370
+ id: labId,
371
+ ...msg.data,
372
+ });
373
+ })
374
+ );
375
+
376
+ quest.goblin.setX(
377
+ `dispatch-unsub`,
378
+ quest.sub(`*::<${desktopId}>.dispatch.requested`, function* (
379
+ err,
380
+ {msg, resp}
381
+ ) {
382
+ yield resp.cmd('laboratory.dispatch', {
383
+ id: labId,
384
+ ...msg.data,
385
+ });
386
+ })
387
+ );
388
+ });
389
+
390
+ function unlisten(quest) {
391
+ if (quest.goblin.getX(`nav-unsub`)) {
392
+ quest.goblin.getX(`nav-unsub`)();
393
+ quest.goblin.getX(`change-theme-unsub`)();
394
+ quest.goblin.getX(`dispatch-unsub`)();
395
+ quest.goblin.delX(`nav-unsub`);
396
+ quest.goblin.delX(`reload-theme-unsub`);
397
+ quest.goblin.delX(`dispatch-unsub`);
398
+ }
399
+ }
400
+
401
+ Goblin.registerQuest(goblinName, 'nav', function* (quest, route) {
402
+ const win = quest.getAPI(`wm@${quest.goblin.id}`);
403
+ yield win.nav({route});
404
+ });
405
+
406
+ /************************ SETTINGS *********************************/
407
+
408
+ Goblin.registerQuest(goblinName, 'save-settings', function* (quest, propertie) {
409
+ const value = quest.goblin.getState().get(propertie);
410
+ const clientSessionId = quest.goblin.getX('clientSessionId');
411
+ yield quest.cmd(`client-session.set-${propertie}`, {
412
+ id: clientSessionId,
413
+ [propertie]: value,
414
+ });
415
+ });
416
+
417
+ Goblin.registerQuest(goblinName, 'save-window-state', function* (
418
+ quest,
419
+ winId,
420
+ state
421
+ ) {
422
+ const clientSessionId = quest.goblin.getX('clientSessionId');
423
+ yield quest.cmd(`client-session.set-window-state`, {
424
+ id: clientSessionId,
425
+ winId,
426
+ state,
427
+ });
428
+ });
429
+
430
+ /******************************************************************************/
431
+
432
+ Goblin.registerQuest(goblinName, 'init-theme', function* (
433
+ quest,
434
+ clientSessionId
435
+ ) {
436
+ const name = yield quest.cmd('client-session.get-theme', {
437
+ id: clientSessionId,
438
+ });
439
+
440
+ if (name) {
441
+ yield quest.me.changeTheme({name});
442
+ }
443
+ });
444
+
445
+ Goblin.registerQuest(goblinName, 'change-theme', function* (quest, name) {
446
+ quest.do({name});
447
+ yield quest.me.saveSettings({propertie: 'theme'});
448
+ });
449
+
450
+ Goblin.registerQuest(goblinName, 'reload-theme', function (quest, name) {
451
+ quest.do({name});
452
+ });
453
+
454
+ /******************************************************************************/
455
+
456
+ Goblin.registerQuest(goblinName, 'init-zoom', function* (
457
+ quest,
458
+ clientSessionId
459
+ ) {
460
+ let zoom = yield quest.cmd('client-session.get-zoom', {
461
+ id: clientSessionId,
462
+ });
463
+
464
+ yield quest.me.setZoom({
465
+ zoom,
466
+ });
467
+ });
468
+
469
+ Goblin.registerQuest(goblinName, 'set-zoom', function* (quest) {
470
+ quest.do();
471
+ yield quest.me.saveSettings({propertie: 'zoom'});
472
+ });
473
+
474
+ Goblin.registerQuest(goblinName, 'zoom', function* (quest) {
475
+ quest.do();
476
+ yield quest.me.saveSettings({propertie: 'zoom'});
477
+ });
478
+
479
+ Goblin.registerQuest(goblinName, 'un-zoom', function* (quest) {
480
+ quest.do();
481
+ yield quest.me.saveSettings({propertie: 'zoom'});
482
+ });
483
+
484
+ Goblin.registerQuest(goblinName, 'default-zoom', function* (quest) {
485
+ quest.do();
486
+ yield quest.me.saveSettings({propertie: 'zoom'});
487
+ });
488
+
489
+ Goblin.registerQuest(goblinName, 'change-zoom', function* (quest) {
490
+ quest.do();
491
+ yield quest.me.saveSettings({propertie: 'zoom'});
492
+ });
493
+
494
+ /******************************************************************************/
495
+
496
+ Goblin.registerQuest(goblinName, 'dispatch', function* (quest, action) {
497
+ const win = quest.getAPI(`wm@${quest.goblin.id}`);
498
+ yield win.dispatch({action});
499
+ });
500
+
501
+ Goblin.registerQuest(goblinName, 'open', function (quest, route) {
502
+ quest.log.info('Laboratory opening:');
503
+ quest.log.info(route);
504
+ });
505
+
506
+ Goblin.registerQuest(goblinName, 'del', function* (quest, widgetId) {
507
+ const state = quest.goblin.getState();
508
+ const feed = state.get('feed');
509
+ const branch = widgetId;
510
+ const labId = quest.goblin.id;
511
+ const useConfigurator = quest.goblin.getX('useConfigurator');
512
+
513
+ if (quest.goblin.getX('forceDispose')) {
514
+ const WM = require('xcraft-core-host/lib/wm.js').instance;
515
+ WM.disposeAll();
516
+ quest.cmd('shutdown'); /* no yield here because it's terminated */
517
+ return;
518
+ }
519
+
520
+ if (branch === feed || (branch === labId && useConfigurator === false)) {
521
+ yield quest.warehouse.unsubscribe({feed: branch});
522
+ } else {
523
+ quest.log.info(
524
+ `Laboratory deleting widget ${widgetId} from window ${feed}`
525
+ );
526
+ const parents = [labId];
527
+ /* This special case ensures that the laboratory is removed like the case
528
+ * where a client (orc socket) is destroyed.
529
+ */
530
+ if (branch === labId) {
531
+ parents.push(`goblin-orc@*`);
532
+ }
533
+ yield quest.warehouse.feedSubscriptionDel({feed, branch, parents});
534
+ }
535
+ });
536
+
537
+ Goblin.registerQuest(goblinName, 'delete', function (quest) {
538
+ unlisten(quest);
539
+ });
540
+
541
+ // Create a Goblin with initial state and handlers
542
+ module.exports = Goblin.configure(goblinName, logicState, logicHandlers);