@shapediver/viewer.session-engine.session-engine 2.11.0 → 2.12.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.
@@ -19,7 +19,7 @@ var __classPrivateFieldSet = (this && this.__classPrivateFieldSet) || function (
19
19
  if (typeof state === "function" ? receiver !== state || !f : !state.has(receiver)) throw new TypeError("Cannot write private member to an object whose class did not declare it");
20
20
  return (kind === "a" ? f.call(receiver, value) : f ? f.value = value : state.set(receiver, value)), value;
21
21
  };
22
- var _SessionEngine_customizationProcess, _SessionEngine_parameterHistory, _SessionEngine_parameterHistoryCall, _SessionEngine_parameterHistoryForward;
22
+ var _SessionEngine_customizationBusyModes, _SessionEngine_customizationProcess, _SessionEngine_parameterHistory, _SessionEngine_parameterHistoryCall, _SessionEngine_parameterHistoryForward;
23
23
  Object.defineProperty(exports, "__esModule", { value: true });
24
24
  exports.SessionEngine = void 0;
25
25
  const viewer_settings_1 = require("@shapediver/viewer.settings");
@@ -38,14 +38,14 @@ const SessionData_1 = require("./SessionData");
38
38
  const SessionTreeNode_1 = require("./SessionTreeNode");
39
39
  /* eslint-disable @typescript-eslint/no-empty-function */
40
40
  class SessionEngine {
41
- // #endregion Properties (43)
41
+ // #endregion Properties (44)
42
42
  // #region Constructors (1)
43
43
  /**
44
44
  * Can be use to initialize a session with the ticket/guid and modelViewUrl and returns a scene graph node with the result.
45
45
  * Can be use to customize the session with updated parameters to get the updated scene graph node.
46
46
  */
47
47
  constructor(properties) {
48
- // #region Properties (43)
48
+ // #region Properties (44)
49
49
  this._eventEngine = viewer_shared_services_1.EventEngine.instance;
50
50
  this._exports = {};
51
51
  this._httpClient = viewer_shared_services_1.HttpClient.instance;
@@ -60,6 +60,7 @@ class SessionEngine {
60
60
  this._settingsEngine = new viewer_shared_services_1.SettingsEngine();
61
61
  this._stateEngine = viewer_shared_services_1.StateEngine.instance;
62
62
  this._uuidGenerator = viewer_shared_services_1.UuidGenerator.instance;
63
+ _SessionEngine_customizationBusyModes.set(this, []);
63
64
  _SessionEngine_customizationProcess.set(this, void 0);
64
65
  _SessionEngine_parameterHistory.set(this, []);
65
66
  _SessionEngine_parameterHistoryCall.set(this, false);
@@ -185,7 +186,7 @@ class SessionEngine {
185
186
  return this._viewerSettings;
186
187
  }
187
188
  // #endregion Public Accessors (25)
188
- // #region Public Methods (25)
189
+ // #region Public Methods (27)
189
190
  applySettings(response, sections) {
190
191
  sections = sections || {};
191
192
  if (sections.session === undefined) {
@@ -232,7 +233,7 @@ class SessionEngine {
232
233
  if (sections.session.parameter.hidden)
233
234
  this.parameters[p].hidden = settings.session[p].hidden || false;
234
235
  }
235
- if (response.parameters && response.parameters[p]) {
236
+ if (response.parameters && response.parameters[p] && !((this.parameters[p] instanceof FileParameter_1.FileParameter) || this.parameters[p].type.startsWith('s'))) {
236
237
  if (sections.session.parameter.value)
237
238
  this.parameters[p].value = response.parameters[p].defval !== undefined ? response.parameters[p].defval : this.parameters[p].value;
238
239
  }
@@ -318,6 +319,18 @@ class SessionEngine {
318
319
  canGoForward() {
319
320
  return __classPrivateFieldGet(this, _SessionEngine_parameterHistoryForward, "f").length > 0;
320
321
  }
322
+ cancelCustomization() {
323
+ if (__classPrivateFieldGet(this, _SessionEngine_customizationProcess, "f"))
324
+ this.removeBusyMode(__classPrivateFieldGet(this, _SessionEngine_customizationProcess, "f"));
325
+ for (const busyId of __classPrivateFieldGet(this, _SessionEngine_customizationBusyModes, "f")) {
326
+ for (const r in this._stateEngine.renderingEngines) {
327
+ if (this._stateEngine.renderingEngines[r].busy.includes(busyId))
328
+ this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(busyId), 1);
329
+ }
330
+ }
331
+ __classPrivateFieldSet(this, _SessionEngine_customizationBusyModes, [], "f");
332
+ __classPrivateFieldSet(this, _SessionEngine_customizationProcess, undefined, "f");
333
+ }
321
334
  close(retry = false) {
322
335
  return __awaiter(this, void 0, void 0, function* () {
323
336
  this.checkAvailability('close');
@@ -359,9 +372,7 @@ class SessionEngine {
359
372
  const oldNode = this.node.cloneInstance();
360
373
  __classPrivateFieldSet(this, _SessionEngine_customizationProcess, customizationId, "f");
361
374
  this._logger.debugLow(`Session(${this.id}).customize: Customizing session.`);
362
- for (const r in this._stateEngine.renderingEngines)
363
- if (!this.excludeViewports.includes(r))
364
- this._stateEngine.renderingEngines[r].busy.push(customizationId);
375
+ this.addBusyMode(customizationId);
365
376
  const eventFileUpload = { type: viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 0.1, data: { sessionId: this.id }, status: 'Uploading file parameters' };
366
377
  this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_PROCESS, eventFileUpload);
367
378
  const fileParameterIds = {};
@@ -370,45 +381,15 @@ class SessionEngine {
370
381
  if (this.parameters[parameterId] instanceof FileParameter_1.FileParameter) {
371
382
  fileParameterIds[parameterId] = yield this.parameters[parameterId].upload();
372
383
  // OPTION TO SKIP - PART 1a
373
- if (__classPrivateFieldGet(this, _SessionEngine_customizationProcess, "f") !== customizationId) {
374
- for (const r in this._stateEngine.renderingEngines)
375
- if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
376
- this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
377
- this._logger.debug(`Session(${this.id}).customize: Session customization was exceeded by other customization request.`);
378
- const eventCancel1a = { type: viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session customization was exceeded by other customization request' };
379
- this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_CANCEL, eventCancel1a);
380
- return new SessionTreeNode_1.SessionTreeNode();
381
- }
382
- else if (this._closed === true) {
383
- for (const r in this._stateEngine.renderingEngines)
384
- if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
385
- this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
386
- this._logger.debug(`Session(${this.id}).customize: Session was closed during customization request.`);
387
- const eventCancel1a = { type: viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session was closed during customization request' };
388
- this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_CANCEL, eventCancel1a);
389
- return new SessionTreeNode_1.SessionTreeNode();
390
- }
384
+ const cancelResult = this.cancelProcess(customizationId, eventId, viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, 1, { sessionId: this.id });
385
+ if (cancelResult)
386
+ return cancelResult;
391
387
  }
392
388
  }
393
389
  // OPTION TO SKIP - PART 1b
394
- if (__classPrivateFieldGet(this, _SessionEngine_customizationProcess, "f") !== customizationId) {
395
- for (const r in this._stateEngine.renderingEngines)
396
- if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
397
- this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
398
- const eventCancel1b = { type: viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session customization was exceeded by other customization request' };
399
- this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_CANCEL, eventCancel1b);
400
- this._logger.debug(`Session(${this.id}).customize: Session customization was exceeded by other customization request.`);
401
- return new SessionTreeNode_1.SessionTreeNode();
402
- }
403
- else if (this._closed === true) {
404
- for (const r in this._stateEngine.renderingEngines)
405
- if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
406
- this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
407
- this._logger.debug(`Session(${this.id}).customize: Session was closed during customization request.`);
408
- const eventCancel1b = { type: viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session was closed during customization request' };
409
- this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_CANCEL, eventCancel1b);
410
- return new SessionTreeNode_1.SessionTreeNode();
411
- }
390
+ const cancelResult = this.cancelProcess(customizationId, eventId, viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, 1, { sessionId: this.id });
391
+ if (cancelResult)
392
+ return cancelResult;
412
393
  // assign the uploaded parameters
413
394
  for (const parameterId in fileParameterIds)
414
395
  this.parameters[parameterId].value = fileParameterIds[parameterId];
@@ -426,6 +407,7 @@ class SessionEngine {
426
407
  this._logger.info(`Session(${this.id}).customize: Customizing session with parameters ${JSON.stringify(this.parameterValues)}.`);
427
408
  const eventRequest = { type: viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 0.1, data: { sessionId: this.id }, status: 'Sending customization request' };
428
409
  this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_PROCESS, eventRequest);
410
+ const oldOutputVersions = this._outputLoader.getCurrentOutputVersions();
429
411
  const newNode = yield this.customizeInternal(() => __classPrivateFieldGet(this, _SessionEngine_customizationProcess, "f") !== customizationId, {
430
412
  eventId,
431
413
  type: viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION,
@@ -435,26 +417,29 @@ class SessionEngine {
435
417
  },
436
418
  data: { sessionId: this.id }
437
419
  });
420
+ // OPTION TO SKIP - PART 2
421
+ const cancelResult2 = this.cancelProcess(customizationId, eventId, viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, 1, { sessionId: this.id });
422
+ if (cancelResult2)
423
+ return cancelResult2;
424
+ const newOutputVersions = this._outputLoader.getCurrentOutputVersions();
438
425
  const eventSceneUpdate = { type: viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 0.9, data: { sessionId: this.id }, status: 'Updating scene' };
439
426
  this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_PROCESS, eventSceneUpdate);
440
- // OPTION TO SKIP - PART 2
441
- if (__classPrivateFieldGet(this, _SessionEngine_customizationProcess, "f") !== customizationId) {
442
- for (const r in this._stateEngine.renderingEngines)
443
- if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
444
- this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
445
- const eventCancel2 = { type: viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session customization was exceeded by other customization request' };
446
- this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_CANCEL, eventCancel2);
447
- this._logger.debug(`Session(${this.id}).customize: Session customization was exceeded by other customization request.`);
448
- return newNode;
449
- }
450
- else if (this._closed === true) { // I get a TS warning here that the type of _closed is "false", I think TS doesn't get that there is a promise inbetween
451
- for (const r in this._stateEngine.renderingEngines)
452
- if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
453
- this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
454
- this._logger.debug(`Session(${this.id}).customize: Session was closed during customization request.`);
455
- const eventCancel2 = { type: viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session was closed during customization request' };
456
- this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_CANCEL, eventCancel2);
457
- return new SessionTreeNode_1.SessionTreeNode();
427
+ // call the update callbacks
428
+ if (waitForViewportUpdate === false) {
429
+ for (const outputId in this.outputs) {
430
+ if (oldOutputVersions[outputId] !== newOutputVersions[outputId]) {
431
+ this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.OUTPUT.OUTPUT_UPDATED, {
432
+ outputId: outputId,
433
+ outputVersion: newOutputVersions[outputId],
434
+ newNode: newNode.children.find(c => c.name === outputId),
435
+ oldNode: oldNode.children.find(c => c.name === outputId)
436
+ });
437
+ }
438
+ }
439
+ yield this.waitForUpdateCallbacks(newOutputVersions, oldOutputVersions, newNode, oldNode);
440
+ const cancelResult = this.cancelProcess(customizationId, eventId, viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, 1, { sessionId: this.id });
441
+ if (cancelResult)
442
+ return cancelResult;
458
443
  }
459
444
  // if this is not a call by the goBack or goForward functions, add the parameter values to the history and delete the forward history
460
445
  if (!__classPrivateFieldGet(this, _SessionEngine_parameterHistoryCall, "f")) {
@@ -478,37 +463,50 @@ class SessionEngine {
478
463
  this.exports[exportId].updateExport();
479
464
  this._warningCreator();
480
465
  this.node.excludeViewports = JSON.parse(JSON.stringify(this._excludeViewports));
481
- for (const r in this._stateEngine.renderingEngines)
482
- if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
483
- this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
466
+ this.removeBusyMode(customizationId);
484
467
  this._logger.debug(`Session(${this.id}).customize: Session customized.`);
485
468
  this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.SESSION.SESSION_CUSTOMIZED, { sessionId: this.id });
486
469
  const eventEnd = { type: viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session customized' };
487
470
  this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_END, eventEnd);
488
471
  // update the viewports
489
- if (waitForViewportUpdate)
472
+ if (waitForViewportUpdate) {
490
473
  for (const r in this._stateEngine.renderingEngines)
491
474
  if (!this.excludeViewports.includes(this._stateEngine.renderingEngines[r].id))
492
475
  this._stateEngine.renderingEngines[r].update(`SessionEngine(${this.id}).customize`);
493
- // call the update callback function on the session
494
- if (this._updateCallback)
495
- this._updateCallback(newNode, oldNode);
496
- // call the update callback functions on the outputs
497
- for (const outputId in this.outputs)
498
- this.outputs[outputId].triggerUpdateCallback(newNode.children.find(c => c.name === outputId), oldNode.children.find(c => c.name === outputId));
476
+ for (const outputId in this.outputs) {
477
+ if (oldOutputVersions[outputId] !== newOutputVersions[outputId]) {
478
+ this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.OUTPUT.OUTPUT_UPDATED, {
479
+ outputId: outputId,
480
+ outputVersion: newOutputVersions[outputId],
481
+ newNode: newNode.children.find(c => c.name === outputId),
482
+ oldNode: oldNode.children.find(c => c.name === outputId)
483
+ });
484
+ }
485
+ }
486
+ // call the update callbacks
487
+ yield this.waitForUpdateCallbacks(newOutputVersions, oldOutputVersions, newNode, oldNode);
488
+ const cancelResult = this.cancelProcess(customizationId, eventId, viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, 1, { sessionId: this.id });
489
+ if (cancelResult)
490
+ return cancelResult;
491
+ }
492
+ if (!waitForViewportUpdate) {
493
+ setTimeout(() => {
494
+ for (const r in this._stateEngine.renderingEngines)
495
+ if (!this.excludeViewports.includes(this._stateEngine.renderingEngines[r].id))
496
+ this._stateEngine.renderingEngines[r].update(`SessionEngine(${this.id}).customize`);
497
+ }, 0);
498
+ }
499
499
  return this.node;
500
500
  }
501
501
  catch (e) {
502
502
  const eventCancel = { type: viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session customization failed' };
503
503
  this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_CANCEL, eventCancel);
504
- for (const r in this._stateEngine.renderingEngines)
505
- if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
506
- this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
504
+ this.removeBusyMode(customizationId);
507
505
  throw this._httpClient.convertError(e);
508
506
  }
509
507
  });
510
508
  }
511
- customizeParallel(parameterValues) {
509
+ customizeParallel(parameterValues, loadOutputs = true) {
512
510
  return __awaiter(this, void 0, void 0, function* () {
513
511
  const eventId = this._uuidGenerator.create();
514
512
  const eventStart = { type: viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 0, data: { sessionId: this.id }, status: 'Customizing session' };
@@ -517,7 +515,7 @@ class SessionEngine {
517
515
  // create a set of the current validated parameter values
518
516
  for (const parameterId in this.parameters)
519
517
  parameterSet[parameterId] = parameterValues[parameterId] !== undefined ? (' ' + parameterValues[parameterId]).slice(1) : this.parameters[parameterId].stringify();
520
- const newNode = yield this.customizeSession(parameterSet, () => false, {
518
+ const result = yield this.customizeSession(parameterSet, () => false, {
521
519
  eventId,
522
520
  type: viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION,
523
521
  progressRange: {
@@ -525,11 +523,12 @@ class SessionEngine {
525
523
  max: 1
526
524
  },
527
525
  data: { sessionId: this.id }
528
- }, true);
529
- newNode.excludeViewports = JSON.parse(JSON.stringify(this._excludeViewports));
526
+ }, true, loadOutputs);
527
+ if (result instanceof SessionTreeNode_1.SessionTreeNode)
528
+ result.excludeViewports = JSON.parse(JSON.stringify(this._excludeViewports));
530
529
  const eventEnd = { type: viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session customized' };
531
530
  this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_END, eventEnd);
532
- return newNode;
531
+ return result;
533
532
  });
534
533
  }
535
534
  goBack() {
@@ -621,6 +620,55 @@ class SessionEngine {
621
620
  }
622
621
  });
623
622
  }
623
+ loadCachedOutputsParallel(outputMapping, taskEventInfo, retry = false) {
624
+ var _a;
625
+ return __awaiter(this, void 0, void 0, function* () {
626
+ this.checkAvailability();
627
+ // if there is already task event info, use it
628
+ // this happens after a retry
629
+ const eventId = taskEventInfo ? taskEventInfo.eventId : this._uuidGenerator.create();
630
+ const eventType = taskEventInfo ? taskEventInfo.type : viewer_shared_types_1.TASK_TYPE.SESSION_OUTPUTS_LOADING;
631
+ const eventData = taskEventInfo ? taskEventInfo.data : { sessionId: this.id };
632
+ taskEventInfo = taskEventInfo ? taskEventInfo : {
633
+ eventId,
634
+ type: eventType,
635
+ progressRange: {
636
+ min: 0,
637
+ max: 1
638
+ },
639
+ data: eventData
640
+ };
641
+ try {
642
+ // send start event if this function was called initially
643
+ if (!taskEventInfo) {
644
+ const eventStart = { type: eventType, id: eventId, progress: 0, data: eventData, status: 'Loading cached outputs' };
645
+ this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_START, eventStart);
646
+ }
647
+ // get the cached outputs
648
+ const responseDto = yield this._sdk.output.getCache(this._sessionId, outputMapping);
649
+ // create atomic output api objects for them
650
+ const outputs = {};
651
+ for (const outputId in responseDto.outputs) {
652
+ responseDto.outputs[outputId].id = outputId;
653
+ outputs[outputId] = new Output_1.Output(responseDto.outputs[outputId], this);
654
+ }
655
+ // process the output data
656
+ const node = yield this._outputLoader.loadOutputs(((_a = this._responseDto.model) === null || _a === void 0 ? void 0 : _a.name) || 'model', outputs, {}, taskEventInfo, false);
657
+ // send the end event once done
658
+ const eventEnd = { type: eventType, id: eventId, progress: 1, data: eventData, status: 'Loaded cached outputs' };
659
+ this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_END, eventEnd);
660
+ // create a mapping with a dictionary for the id of the outputs
661
+ const outputNodeMapping = {};
662
+ for (const outputId in outputMapping)
663
+ outputNodeMapping[outputId] = node.children.find(n => n.name === outputId);
664
+ return outputNodeMapping;
665
+ }
666
+ catch (e) {
667
+ yield this.handleError(e, retry);
668
+ return yield this.loadCachedOutputsParallel(outputMapping, taskEventInfo, true);
669
+ }
670
+ });
671
+ }
624
672
  /**
625
673
  * Load the outputs and return the scene graph node of the result.
626
674
  * In case the outputs have a delay property, another customization request with the parameter set is sent.
@@ -640,12 +688,7 @@ class SessionEngine {
640
688
  node.data.push(new SessionData_1.SessionData(this._responseDto));
641
689
  if (cancelRequest())
642
690
  return node;
643
- if (this._automaticSceneUpdate)
644
- this.removeFromSceneTree(this._node);
645
- this._node = node;
646
- if (this._automaticSceneUpdate && this._closed === false)
647
- this.addToSceneTree(this._node);
648
- this.node.excludeViewports = JSON.parse(JSON.stringify(this._excludeViewports));
691
+ node.excludeViewports = JSON.parse(JSON.stringify(this._excludeViewports));
649
692
  return node;
650
693
  }
651
694
  catch (e) {
@@ -963,11 +1006,10 @@ class SessionEngine {
963
1006
  const oldNode = this.node.cloneInstance();
964
1007
  __classPrivateFieldSet(this, _SessionEngine_customizationProcess, customizationId, "f");
965
1008
  this._logger.debugLow(`Session(${this.id}).updateOutputs: Updating Outputs.`);
966
- for (const r in this._stateEngine.renderingEngines)
967
- if (!this.excludeViewports.includes(r))
968
- this._stateEngine.renderingEngines[r].busy.push(customizationId);
1009
+ this.addBusyMode(customizationId);
969
1010
  const eventRequest = { type: eventType, id: eventId, progress: taskEventInfo ? (taskEventInfo.progressRange.max - taskEventInfo.progressRange.min) * 0.1 + taskEventInfo.progressRange.min : 0.1, data: eventData, status: 'Loading outputs' };
970
1011
  this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_PROCESS, eventRequest);
1012
+ const oldOutputVersions = this._outputLoader.getCurrentOutputVersions();
971
1013
  const newNode = yield this.loadOutputs(() => __classPrivateFieldGet(this, _SessionEngine_customizationProcess, "f") !== customizationId, {
972
1014
  eventId,
973
1015
  type: eventType,
@@ -977,26 +1019,30 @@ class SessionEngine {
977
1019
  },
978
1020
  data: eventData
979
1021
  });
1022
+ const newOutputVersions = this._outputLoader.getCurrentOutputVersions();
980
1023
  const eventSceneUpdate = { type: eventType, id: eventId, progress: taskEventInfo ? (taskEventInfo.progressRange.max - taskEventInfo.progressRange.min) * 0.9 + taskEventInfo.progressRange.min : 0.9, data: eventData, status: 'Updating scene' };
981
1024
  this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_PROCESS, eventSceneUpdate);
982
1025
  // OPTION TO SKIP - PART 1
983
- if (__classPrivateFieldGet(this, _SessionEngine_customizationProcess, "f") !== customizationId) {
984
- for (const r in this._stateEngine.renderingEngines)
985
- if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
986
- this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
987
- const eventCancel1 = { type: eventType, id: eventId, progress: taskEventInfo ? (taskEventInfo.progressRange.max - taskEventInfo.progressRange.min) * 1 + taskEventInfo.progressRange.min : 1, data: eventData, status: 'Output updating was exceeded by other customization request' };
988
- this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_CANCEL, eventCancel1);
989
- this._logger.debug(`Session(${this.id}).updateOutputs: Output updating was exceeded by other request.`);
990
- return newNode;
991
- }
992
- else if (this._closed === true) {
993
- for (const r in this._stateEngine.renderingEngines)
994
- if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
995
- this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
996
- this._logger.debug(`Session(${this.id}).customize: Session was closed during customization request.`);
997
- const eventCancel1a = { type: viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session was closed during customization request' };
998
- this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_CANCEL, eventCancel1a);
999
- return new SessionTreeNode_1.SessionTreeNode();
1026
+ const cancelResult = this.cancelProcess(customizationId, eventId, eventType, taskEventInfo ? (taskEventInfo.progressRange.max - taskEventInfo.progressRange.min) * 1 + taskEventInfo.progressRange.min : 1, eventData, newNode);
1027
+ if (cancelResult)
1028
+ return cancelResult;
1029
+ // call the update callbacks
1030
+ if (waitForViewportUpdate === false) {
1031
+ for (const outputId in this.outputs) {
1032
+ if (oldOutputVersions[outputId] !== newOutputVersions[outputId]) {
1033
+ this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.OUTPUT.OUTPUT_UPDATED, {
1034
+ outputId: outputId,
1035
+ outputVersion: newOutputVersions[outputId],
1036
+ newNode: newNode.children.find(c => c.name === outputId),
1037
+ oldNode: oldNode.children.find(c => c.name === outputId)
1038
+ });
1039
+ }
1040
+ }
1041
+ yield this.waitForUpdateCallbacks(newOutputVersions, oldOutputVersions, newNode, oldNode);
1042
+ // OPTION TO SKIP - PART 2
1043
+ const cancelResult = this.cancelProcess(customizationId, eventId, eventType, taskEventInfo ? (taskEventInfo.progressRange.max - taskEventInfo.progressRange.min) * 1 + taskEventInfo.progressRange.min : 1, eventData, newNode);
1044
+ if (cancelResult)
1045
+ return cancelResult;
1000
1046
  }
1001
1047
  if (this.automaticSceneUpdate)
1002
1048
  this.removeFromSceneTree(this.node);
@@ -1013,25 +1059,33 @@ class SessionEngine {
1013
1059
  this.exports[exportId].updateExport();
1014
1060
  this._warningCreator();
1015
1061
  this.node.excludeViewports = JSON.parse(JSON.stringify(this._excludeViewports));
1016
- for (const r in this._stateEngine.renderingEngines)
1017
- if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
1018
- this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
1062
+ this.removeBusyMode(customizationId);
1019
1063
  this._logger.debug(`Session(${this.id}).updateOutputs: Updated outputs.`);
1020
1064
  if (!taskEventInfo) {
1021
1065
  const eventEnd = { type: eventType, id: eventId, progress: 1, data: eventData, status: 'Outputs updated' };
1022
1066
  this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_END, eventEnd);
1023
1067
  }
1024
1068
  // update the viewports
1025
- if (waitForViewportUpdate)
1069
+ if (waitForViewportUpdate) {
1026
1070
  for (const r in this._stateEngine.renderingEngines)
1027
1071
  if (!this.excludeViewports.includes(this._stateEngine.renderingEngines[r].id))
1028
1072
  this._stateEngine.renderingEngines[r].update(`SessionEngine(${this.id}).updateOutputs`);
1029
- // call the update callback function on the session
1030
- if (this._updateCallback)
1031
- this._updateCallback(newNode, oldNode);
1032
- // call the update callback functions on the outputs
1033
- for (const outputId in this.outputs)
1034
- this.outputs[outputId].triggerUpdateCallback(newNode.children.find(c => c.name === outputId), oldNode.children.find(c => c.name === outputId));
1073
+ for (const outputId in this.outputs) {
1074
+ if (oldOutputVersions[outputId] !== newOutputVersions[outputId]) {
1075
+ this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.OUTPUT.OUTPUT_UPDATED, {
1076
+ outputId: outputId,
1077
+ outputVersion: newOutputVersions[outputId],
1078
+ newNode: newNode.children.find(c => c.name === outputId),
1079
+ oldNode: oldNode.children.find(c => c.name === outputId)
1080
+ });
1081
+ }
1082
+ }
1083
+ yield this.waitForUpdateCallbacks(newOutputVersions, oldOutputVersions, newNode, oldNode);
1084
+ // OPTION TO SKIP - PART 3
1085
+ const cancelResult = this.cancelProcess(customizationId, eventId, eventType, taskEventInfo ? (taskEventInfo.progressRange.max - taskEventInfo.progressRange.min) * 1 + taskEventInfo.progressRange.min : 1, eventData, newNode);
1086
+ if (cancelResult)
1087
+ return cancelResult;
1088
+ }
1035
1089
  return this.node;
1036
1090
  });
1037
1091
  }
@@ -1072,8 +1126,8 @@ class SessionEngine {
1072
1126
  }
1073
1127
  });
1074
1128
  }
1075
- // #endregion Public Methods (25)
1076
- // #region Private Methods (11)
1129
+ // #endregion Public Methods (27)
1130
+ // #region Private Methods (15)
1077
1131
  _saveSessionSettings() {
1078
1132
  const parameters = this.parameters;
1079
1133
  const exports = this.exports;
@@ -1133,10 +1187,40 @@ class SessionEngine {
1133
1187
  this._logger.warn(`\nExport(${exportId}):${warning}`);
1134
1188
  }
1135
1189
  }
1190
+ addBusyMode(busyId) {
1191
+ for (const r in this._stateEngine.renderingEngines) {
1192
+ if (!this.excludeViewports.includes(r)) {
1193
+ this._stateEngine.renderingEngines[r].busy.push(busyId);
1194
+ __classPrivateFieldGet(this, _SessionEngine_customizationBusyModes, "f").push(busyId);
1195
+ }
1196
+ }
1197
+ }
1136
1198
  addToSceneTree(node) {
1137
1199
  this._sceneTree.addNode(node);
1138
1200
  this._sceneTree.root.updateVersion();
1139
1201
  }
1202
+ cancelProcess(customizationId, eventId, eventType, eventProgress, eventData, newNode = new SessionTreeNode_1.SessionTreeNode()) {
1203
+ if (__classPrivateFieldGet(this, _SessionEngine_customizationProcess, "f") !== customizationId) {
1204
+ this.removeBusyMode(customizationId);
1205
+ const eventCancel = {
1206
+ type: eventType,
1207
+ id: eventId,
1208
+ progress: eventProgress,
1209
+ data: eventData,
1210
+ status: 'The request was exceeded by another customization request'
1211
+ };
1212
+ this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_CANCEL, eventCancel);
1213
+ this._logger.debug(`Session(${this.id}).cancelProcess: The request was was exceeded by another request.`);
1214
+ return newNode;
1215
+ }
1216
+ else if (this._closed === true) {
1217
+ this.removeBusyMode(customizationId);
1218
+ this._logger.debug(`Session(${this.id}).cancelProcess: The session was closed during the request.`);
1219
+ const eventCancel = { type: viewer_shared_types_1.TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'The session was closed during the request.' };
1220
+ this._eventEngine.emitEvent(viewer_shared_services_1.EVENTTYPE.TASK.TASK_CANCEL, eventCancel);
1221
+ return new SessionTreeNode_1.SessionTreeNode();
1222
+ }
1223
+ }
1140
1224
  checkAvailability(action, checkForModelId = false) {
1141
1225
  var _a;
1142
1226
  if (!this._responseDto)
@@ -1180,24 +1264,36 @@ class SessionEngine {
1180
1264
  return this.customizeSession(this._parameterValues, cancelRequest, taskEventInfo);
1181
1265
  });
1182
1266
  }
1183
- customizeSession(parameters, cancelRequest, taskEventInfo, parallel = false, retry = false) {
1267
+ customizeSession(parameters, cancelRequest, taskEventInfo, parallel = false, loadOutputs = true, retry = false) {
1184
1268
  return __awaiter(this, void 0, void 0, function* () {
1185
1269
  this.checkAvailability('customize');
1186
1270
  try {
1187
1271
  this._performanceEvaluator.startSection('sessionResponse');
1188
1272
  const responseDto = yield this._sdk.utils.submitAndWaitForCustomization(this._sdk, this._sessionId, parameters);
1189
1273
  this._performanceEvaluator.endSection('sessionResponse');
1190
- if (cancelRequest())
1191
- return new SessionTreeNode_1.SessionTreeNode();
1192
- if (parallel === false)
1193
- this.updateResponseDto(responseDto);
1194
- return parallel === false ? this.loadOutputs(cancelRequest, taskEventInfo) : this.loadOutputsParallel(responseDto, cancelRequest, taskEventInfo);
1274
+ if (loadOutputs === true) {
1275
+ if (cancelRequest())
1276
+ return new SessionTreeNode_1.SessionTreeNode();
1277
+ if (parallel === true) {
1278
+ // special case, we load the outputs put don't add them to the scene
1279
+ return this.loadOutputsParallel(responseDto, cancelRequest, taskEventInfo);
1280
+ }
1281
+ else {
1282
+ // default case, we load the outputs and return the nodes
1283
+ this.updateResponseDto(responseDto);
1284
+ return this.loadOutputs(cancelRequest, taskEventInfo);
1285
+ }
1286
+ }
1287
+ else {
1288
+ // special case, we don't load the outputs and only return the responseDto
1289
+ return responseDto;
1290
+ }
1195
1291
  }
1196
1292
  catch (e) {
1197
1293
  yield this.handleError(e, retry);
1198
1294
  if (cancelRequest())
1199
1295
  return new SessionTreeNode_1.SessionTreeNode();
1200
- return yield this.customizeSession(parameters, cancelRequest, taskEventInfo, parallel, true);
1296
+ return yield this.customizeSession(parameters, cancelRequest, taskEventInfo, parallel, loadOutputs, true);
1201
1297
  }
1202
1298
  });
1203
1299
  }
@@ -1267,6 +1363,14 @@ class SessionEngine {
1267
1363
  }
1268
1364
  });
1269
1365
  }
1366
+ removeBusyMode(busyId) {
1367
+ for (const r in this._stateEngine.renderingEngines) {
1368
+ if (this._stateEngine.renderingEngines[r].busy.includes(busyId))
1369
+ this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(busyId), 1);
1370
+ if (__classPrivateFieldGet(this, _SessionEngine_customizationBusyModes, "f").includes(busyId))
1371
+ __classPrivateFieldGet(this, _SessionEngine_customizationBusyModes, "f").splice(__classPrivateFieldGet(this, _SessionEngine_customizationBusyModes, "f").indexOf(busyId), 1);
1372
+ }
1373
+ }
1270
1374
  removeFromSceneTree(node) {
1271
1375
  this._sceneTree.removeNode(node);
1272
1376
  this._sceneTree.root.updateVersion();
@@ -1381,7 +1485,22 @@ class SessionEngine {
1381
1485
  }
1382
1486
  }
1383
1487
  }
1488
+ waitForUpdateCallbacks(newOutputVersions, oldOutputVersions, newNode, oldNode) {
1489
+ return __awaiter(this, void 0, void 0, function* () {
1490
+ // call the update callback function on the session
1491
+ if (this._updateCallback)
1492
+ yield Promise.resolve(this._updateCallback(newNode, oldNode));
1493
+ const promises = [];
1494
+ // call the update callback functions on the outputs
1495
+ for (const outputId in this.outputs) {
1496
+ if (oldOutputVersions[outputId] !== newOutputVersions[outputId]) {
1497
+ promises.push(this.outputs[outputId].triggerUpdateCallback(newNode.children.find(c => c.name === outputId), oldNode.children.find(c => c.name === outputId)));
1498
+ }
1499
+ }
1500
+ yield Promise.all(promises);
1501
+ });
1502
+ }
1384
1503
  }
1385
1504
  exports.SessionEngine = SessionEngine;
1386
- _SessionEngine_customizationProcess = new WeakMap(), _SessionEngine_parameterHistory = new WeakMap(), _SessionEngine_parameterHistoryCall = new WeakMap(), _SessionEngine_parameterHistoryForward = new WeakMap();
1505
+ _SessionEngine_customizationBusyModes = new WeakMap(), _SessionEngine_customizationProcess = new WeakMap(), _SessionEngine_parameterHistory = new WeakMap(), _SessionEngine_parameterHistoryCall = new WeakMap(), _SessionEngine_parameterHistoryForward = new WeakMap();
1387
1506
  //# sourceMappingURL=SessionEngine.js.map