@shapediver/viewer.session-engine.session-engine 2.8.5 → 2.9.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.
@@ -1,12 +1,11 @@
1
- import { HttpClient, HttpResponse, PerformanceEvaluator, UuidGenerator, SystemInfo, Logger, ShapeDiverViewerSessionError, ShapeDiverViewerError, Converter, SettingsEngine, EVENTTYPE, EventEngine, StateEngine, ShapeDiverViewerSettingsError } from '@shapediver/viewer.shared.services'
1
+ import { HttpClient, HttpResponse, PerformanceEvaluator, UuidGenerator, SystemInfo, Logger, ShapeDiverViewerSessionError, ShapeDiverViewerError, Converter, SettingsEngine, EVENTTYPE, EventEngine, StateEngine, ShapeDiverViewerSettingsError, ShapeDiverGeometryBackendResponseError, ShapeDiverGeometryBackendRequestError } from '@shapediver/viewer.shared.services'
2
2
 
3
3
  import { OutputDelayException } from './OutputDelayException'
4
- import { OutputLoader } from './OutputLoader'
4
+ import { OutputLoader, OutputLoaderTaskEventInfo } from './OutputLoader'
5
5
  import { SessionTreeNode } from './SessionTreeNode'
6
6
  import { ISessionEngine, ISettingsSections, PARAMETER_TYPE } from '../interfaces/ISessionEngine'
7
7
  import { SessionData } from './SessionData'
8
- import { create, ShapeDiverError as ShapeDiverBackendError, ShapeDiverResponseErrorType, ShapeDiverRequestGltfUploadQueryConversion, ShapeDiverResponseDto, ShapeDiverResponseError, ShapeDiverResponseExport, ShapeDiverResponseExportDefinitionType, ShapeDiverResponseOutput, ShapeDiverResponseParameter, ShapeDiverSdk, ShapeDiverSdkConfigType, ShapeDiverResponseModelComputationStatus } from '@shapediver/sdk.geometry-api-sdk-v2'
9
- import { AxiosRequestConfig } from 'axios'
8
+ import { create, ShapeDiverError as ShapeDiverBackendError, ShapeDiverResponseErrorType, ShapeDiverRequestGltfUploadQueryConversion, ShapeDiverResponseDto, ShapeDiverResponseError, ShapeDiverResponseExport, ShapeDiverResponseExportDefinitionType, ShapeDiverResponseOutput, ShapeDiverResponseParameter, ShapeDiverSdk, ShapeDiverSdkConfigType, ShapeDiverResponseModelComputationStatus, ShapeDiverRequestError } from '@shapediver/sdk.geometry-api-sdk-v2'
10
9
  import { ISessionTreeNode } from '../interfaces/ISessionTreeNode'
11
10
  import { ITree, ITreeNode, Tree, TreeNode } from '@shapediver/viewer.shared.node-tree'
12
11
  import { ITaskEvent, TASK_TYPE } from '@shapediver/viewer.shared.types'
@@ -19,7 +18,7 @@ import { Parameter } from './dto/Parameter'
19
18
  import { vec3 } from 'gl-matrix'
20
19
  import { Export } from './dto/Export'
21
20
  import { Output } from './dto/Output'
22
- import { convert, ISettingsV3_3, latestVersion, validate, versions } from '@shapediver/viewer.settings'
21
+ import { convert, ISettingsV3_4, latestVersion, validate, versions } from '@shapediver/viewer.settings'
23
22
 
24
23
  export class SessionEngine implements ISessionEngine {
25
24
  // #region Properties (40)
@@ -66,7 +65,7 @@ export class SessionEngine implements ISessionEngine {
66
65
  private _refreshBearerToken?: () => Promise<string>;
67
66
  private _responseDto?: ShapeDiverResponseDto;
68
67
  private _retryCounter = 0;
69
- private _sdk: ShapeDiverSdk;
68
+ private _sdk!: ShapeDiverSdk;
70
69
  private _sessionId?: string;
71
70
  private _updateCallback: ((newNode: ITreeNode, oldNode: ITreeNode) => void) | null = null;
72
71
  private _viewerSettings?: object;
@@ -107,8 +106,12 @@ export class SessionEngine implements ISessionEngine {
107
106
  this._headers['X-ShapeDiver-BuildVersion'] = properties.buildVersion;
108
107
  this._outputLoader = new OutputLoader(this);
109
108
 
110
- this._sdk = create(this._modelViewUrl, this._bearerToken);
111
- this._sdk.setConfigurationValue(ShapeDiverSdkConfigType.REQUEST_HEADERS, this._headers);
109
+ try {
110
+ this._sdk = create(this._modelViewUrl, this._bearerToken);
111
+ this._sdk.setConfigurationValue(ShapeDiverSdkConfigType.REQUEST_HEADERS, this._headers);
112
+ } catch (e) {
113
+ throw this._httpClient.convertError(e);
114
+ }
112
115
  }
113
116
 
114
117
  // #endregion Constructors (1)
@@ -130,7 +133,11 @@ export class SessionEngine implements ISessionEngine {
130
133
 
131
134
  public set bearerToken(value: string | undefined) {
132
135
  this._bearerToken = value;
133
- this._sdk.setConfigurationValue(ShapeDiverSdkConfigType.JWT_TOKEN, value);
136
+ try {
137
+ this._sdk.setConfigurationValue(ShapeDiverSdkConfigType.JWT_TOKEN, value);
138
+ } catch (e) {
139
+ throw this._httpClient.convertError(e);
140
+ }
134
141
  }
135
142
 
136
143
  public get canUploadGLTF(): boolean {
@@ -255,7 +262,7 @@ export class SessionEngine implements ISessionEngine {
255
262
  throw new ShapeDiverViewerSettingsError('Session.applySettings: Was not able to validate config object.');
256
263
  }
257
264
 
258
- const settings = <ISettingsV3_3>convert(config, latestVersion);
265
+ const settings = <ISettingsV3_4>convert(config, latestVersion);
259
266
 
260
267
  const exportMappingUid: { [key: string]: string | undefined } = {};
261
268
  if (sections.session.export.displayname || sections.session.export.order || sections.session.export.hidden)
@@ -336,6 +343,7 @@ export class SessionEngine implements ISessionEngine {
336
343
  }
337
344
 
338
345
  if (sections.viewport.general) {
346
+ currentSettings.general.defaultMaterialColor = settings.general.defaultMaterialColor;
339
347
  currentSettings.general.commitParameters = settings.general.commitParameters;
340
348
  currentSettings.general.pointSize = settings.general.pointSize;
341
349
  }
@@ -346,6 +354,9 @@ export class SessionEngine implements ISessionEngine {
346
354
  currentSettings.environment.clearColor = settings.environment.clearColor;
347
355
  currentSettings.environment.map = settings.environment.map;
348
356
  currentSettings.environment.mapAsBackground = settings.environment.mapAsBackground;
357
+ currentSettings.environment.rotation = settings.environment.rotation;
358
+ currentSettings.environment.blurriness = settings.environment.blurriness;
359
+ currentSettings.environment.intensity = settings.environment.intensity;
349
360
  }
350
361
  }
351
362
 
@@ -465,12 +476,20 @@ export class SessionEngine implements ISessionEngine {
465
476
  this.parameterValues[parameterId] = parameterSet[parameterId].valueString;
466
477
  this._logger.info(`Session(${this.id}).customize: Customizing session with parameters ${JSON.stringify(this.parameterValues)}.`);
467
478
 
468
- const eventRequest: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 0.25, data: { sessionId: this.id }, status: 'Sending customization request' };
479
+ const eventRequest: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 0.1, data: { sessionId: this.id }, status: 'Sending customization request' };
469
480
  this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_PROCESS, eventRequest);
470
481
 
471
- const newNode = await this.customizeInternal(() => this.#customizationProcess !== customizationId);
472
-
473
- const eventSceneUpdate: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 0.75, data: { sessionId: this.id }, status: 'Updating scene' };
482
+ const newNode = await this.customizeInternal(() => this.#customizationProcess !== customizationId, {
483
+ eventId,
484
+ type: TASK_TYPE.SESSION_CUSTOMIZATION,
485
+ progressRange: {
486
+ min: 0.1,
487
+ max: 0.9
488
+ },
489
+ data: { sessionId: this.id }
490
+ });
491
+
492
+ const eventSceneUpdate: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 0.9, data: { sessionId: this.id }, status: 'Updating scene' };
474
493
  this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_PROCESS, eventSceneUpdate);
475
494
 
476
495
  // OPTION TO SKIP - PART 2
@@ -538,11 +557,16 @@ export class SessionEngine implements ISessionEngine {
538
557
  if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
539
558
  this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
540
559
 
541
- throw e;
560
+ throw this._httpClient.convertError(e);
542
561
  }
543
562
  }
544
563
 
545
564
  public async customizeParallel(parameterValues: { [key: string]: string }): Promise<ITreeNode> {
565
+ const eventId = this._uuidGenerator.create();
566
+
567
+ const eventStart: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 0, data: { sessionId: this.id }, status: 'Customizing session' };
568
+ this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_START, eventStart);
569
+
546
570
  const parameterSet: {
547
571
  [key: string]: string
548
572
  } = {};
@@ -551,8 +575,20 @@ export class SessionEngine implements ISessionEngine {
551
575
  for (const parameterId in this.parameters)
552
576
  parameterSet[parameterId] = parameterValues[parameterId] !== undefined ? (' ' + parameterValues[parameterId]).slice(1) : this.parameters[parameterId].stringify()
553
577
 
554
- const newNode = await this.customizeSession(parameterSet, () => false, true);
578
+ const newNode = await this.customizeSession(parameterSet, () => false, {
579
+ eventId,
580
+ type: TASK_TYPE.SESSION_CUSTOMIZATION,
581
+ progressRange: {
582
+ min: 0.0,
583
+ max: 1
584
+ },
585
+ data: { sessionId: this.id }
586
+ }, true);
555
587
  newNode.excludeViewports = JSON.parse(JSON.stringify(this._excludeViewports));
588
+
589
+
590
+ const eventEnd: ITaskEvent = { type: TASK_TYPE.SESSION_CUSTOMIZATION, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Session customized' };
591
+ this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_END, eventEnd);
556
592
  return newNode;
557
593
  }
558
594
 
@@ -622,7 +658,6 @@ export class SessionEngine implements ISessionEngine {
622
658
 
623
659
  this._viewerSettings = this._responseDto.viewer?.config;
624
660
  this._viewerSettingsVersionBackend = this._responseDto.viewerSettingsVersion || latestVersion;
625
- this._settingsEngine.loadSettings(this._viewerSettings);
626
661
  this._sessionId = this._responseDto.sessionId;
627
662
  this._modelId = this._responseDto.model?.id;
628
663
 
@@ -631,6 +666,8 @@ export class SessionEngine implements ISessionEngine {
631
666
  downloadTexture: this._sdk.asset.downloadImage.bind(this._sdk.asset),
632
667
  })
633
668
 
669
+ this._settingsEngine.loadSettings(this._viewerSettings);
670
+
634
671
  if (!this._sessionId)
635
672
  throw new ShapeDiverViewerSessionError(`Session.init: Initialization of session failed. ResponseDto did not have a sessionId.`)
636
673
  if (!this._modelId)
@@ -653,7 +690,7 @@ export class SessionEngine implements ISessionEngine {
653
690
  * @param outputs the outputs to load
654
691
  * @returns promise with a scene graph node
655
692
  */
656
- public async loadOutputsParallel(responseDto: ShapeDiverResponseDto, cancelRequest: () => boolean = () => false, retry = false): Promise<ISessionTreeNode> {
693
+ public async loadOutputsParallel(responseDto: ShapeDiverResponseDto, cancelRequest: () => boolean = () => false, taskEventInfo: OutputLoaderTaskEventInfo, retry = false): Promise<ISessionTreeNode> {
657
694
  this.checkAvailability();
658
695
 
659
696
  let outputs: {
@@ -670,7 +707,7 @@ export class SessionEngine implements ISessionEngine {
670
707
  }
671
708
 
672
709
  try {
673
- const node = await this._outputLoader.loadOutputs(this._responseDto!.model?.name || 'model', outputs, outputsFreeze);
710
+ const node = await this._outputLoader.loadOutputs(this._responseDto!.model?.name || 'model', outputs, outputsFreeze, taskEventInfo);
674
711
  node.data.push(new SessionData(responseDto));
675
712
  return node;
676
713
  }
@@ -680,7 +717,7 @@ export class SessionEngine implements ISessionEngine {
680
717
  } else {
681
718
  await this.handleError(e, retry);
682
719
  if (cancelRequest()) return new SessionTreeNode();
683
- return await this.loadOutputsParallel(responseDto, cancelRequest, true);
720
+ return await this.loadOutputsParallel(responseDto, cancelRequest, taskEventInfo, true);
684
721
  }
685
722
 
686
723
  if (cancelRequest()) return new SessionTreeNode();
@@ -692,11 +729,11 @@ export class SessionEngine implements ISessionEngine {
692
729
  const responseDto = await this._sdk.output.getCache(this._sessionId!, outputMapping);
693
730
  if (cancelRequest()) return new SessionTreeNode();
694
731
  this.updateResponseDto(responseDto);
695
- return await this.loadOutputsParallel(responseDto, cancelRequest);
732
+ return await this.loadOutputsParallel(responseDto, cancelRequest, taskEventInfo);
696
733
  } catch (e) {
697
734
  await this.handleError(e, retry);
698
735
  if (cancelRequest()) return new SessionTreeNode();
699
- return await this.loadOutputsParallel(responseDto, cancelRequest, true);
736
+ return await this.loadOutputsParallel(responseDto, cancelRequest, taskEventInfo, true);
700
737
  }
701
738
  }
702
739
  }
@@ -709,13 +746,13 @@ export class SessionEngine implements ISessionEngine {
709
746
  * @param outputs the outputs to load
710
747
  * @returns promise with a scene graph node
711
748
  */
712
- public async loadOutputs(cancelRequest: () => boolean = () => false, retry = false): Promise<ISessionTreeNode> {
749
+ public async loadOutputs(cancelRequest: () => boolean = () => false, taskEventInfo: OutputLoaderTaskEventInfo, retry = false): Promise<ISessionTreeNode> {
713
750
  this.checkAvailability();
714
751
 
715
752
  const o = Object.assign({}, this._outputs);
716
753
  const of = Object.assign({}, this._outputsFreeze);
717
754
  try {
718
- const node = await this._outputLoader.loadOutputs(this._responseDto!.model?.name || 'model', o, of);
755
+ const node = await this._outputLoader.loadOutputs(this._responseDto!.model?.name || 'model', o, of, taskEventInfo);
719
756
  node.data.push(new SessionData(this._responseDto!));
720
757
 
721
758
  if (cancelRequest()) return node;
@@ -734,7 +771,7 @@ export class SessionEngine implements ISessionEngine {
734
771
  } else {
735
772
  await this.handleError(e, retry);
736
773
  if (cancelRequest()) return new SessionTreeNode();
737
- return await this.loadOutputs(cancelRequest, true);
774
+ return await this.loadOutputs(cancelRequest, taskEventInfo, true);
738
775
  }
739
776
 
740
777
  if (cancelRequest()) return new SessionTreeNode();
@@ -746,11 +783,11 @@ export class SessionEngine implements ISessionEngine {
746
783
  const responseDto = await this._sdk.output.getCache(this._sessionId!, outputMapping);
747
784
  if (cancelRequest()) return new SessionTreeNode();
748
785
  this.updateResponseDto(responseDto);
749
- return await this.loadOutputs(cancelRequest);
786
+ return await this.loadOutputs(cancelRequest, taskEventInfo);
750
787
  } catch (e) {
751
788
  await this.handleError(e, retry);
752
789
  if (cancelRequest()) return new SessionTreeNode();
753
- return await this.loadOutputs(cancelRequest, true);
790
+ return await this.loadOutputs(cancelRequest, taskEventInfo, true);
754
791
  }
755
792
  }
756
793
  }
@@ -965,12 +1002,17 @@ export class SessionEngine implements ISessionEngine {
965
1002
  return response && responseP && responseO && responseE;
966
1003
  }
967
1004
 
968
- public async updateOutputs(): Promise<ITreeNode> {
969
- const eventId = this._uuidGenerator.create();
970
- const customizationId = this._uuidGenerator.create();
971
- const eventStart: ITaskEvent = { type: TASK_TYPE.SESSION_OUTPUTS_UPDATE, id: eventId, progress: 0, data: { sessionId: this.id }, status: 'Updating outputs' };
972
- this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_START, eventStart);
1005
+ public async updateOutputs(taskEventInfo?: OutputLoaderTaskEventInfo): Promise<ITreeNode> {
1006
+ const eventId = taskEventInfo ? taskEventInfo.eventId : this._uuidGenerator.create();
1007
+ const eventType = taskEventInfo ? taskEventInfo.type : TASK_TYPE.SESSION_OUTPUTS_UPDATE;
1008
+ const eventData = taskEventInfo ? taskEventInfo.data : { sessionId: this.id };
1009
+
1010
+ if(!taskEventInfo) {
1011
+ const eventStart: ITaskEvent = { type: eventType, id: eventId, progress: 0, data: eventData, status: 'Updating outputs' };
1012
+ this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_START, eventStart);
1013
+ }
973
1014
 
1015
+ const customizationId = this._uuidGenerator.create();
974
1016
  const oldNode = this.node.cloneInstance();
975
1017
  this.#customizationProcess = customizationId;
976
1018
 
@@ -979,12 +1021,20 @@ export class SessionEngine implements ISessionEngine {
979
1021
  for (let r in this._stateEngine.renderingEngines)
980
1022
  this._stateEngine.renderingEngines[r].busy.push(customizationId);
981
1023
 
982
- const eventRequest: ITaskEvent = { type: TASK_TYPE.SESSION_OUTPUTS_UPDATE, id: eventId, progress: 0.25, data: { sessionId: this.id }, status: 'Loading outputs' };
1024
+ const eventRequest: ITaskEvent = { type: eventType, id: eventId, progress: taskEventInfo ? (taskEventInfo.progressRange.max - taskEventInfo.progressRange.min) * 0.1 + taskEventInfo.progressRange.min : 0.1, data: eventData, status: 'Loading outputs' };
983
1025
  this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_PROCESS, eventRequest);
984
1026
 
985
- const newNode = await this.loadOutputs(() => this.#customizationProcess !== customizationId);
986
-
987
- const eventSceneUpdate: ITaskEvent = { type: TASK_TYPE.SESSION_OUTPUTS_UPDATE, id: eventId, progress: 0.75, data: { sessionId: this.id }, status: 'Updating scene' };
1027
+ const newNode = await this.loadOutputs(() => this.#customizationProcess !== customizationId, {
1028
+ eventId,
1029
+ type: eventType,
1030
+ progressRange: {
1031
+ min: taskEventInfo ? (taskEventInfo.progressRange.max - taskEventInfo.progressRange.min) * 0.1 + taskEventInfo.progressRange.min : 0.1,
1032
+ max: taskEventInfo ? (taskEventInfo.progressRange.max - taskEventInfo.progressRange.min) * 0.9 + taskEventInfo.progressRange.min : 0.9
1033
+ },
1034
+ data: eventData
1035
+ });
1036
+
1037
+ const eventSceneUpdate: ITaskEvent = { type: eventType, id: eventId, progress: taskEventInfo ? (taskEventInfo.progressRange.max - taskEventInfo.progressRange.min) * 0.9 + taskEventInfo.progressRange.min : 0.9, data: eventData, status: 'Updating scene' };
988
1038
  this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_PROCESS, eventSceneUpdate);
989
1039
 
990
1040
  // OPTION TO SKIP - PART 1
@@ -993,7 +1043,7 @@ export class SessionEngine implements ISessionEngine {
993
1043
  if (this._stateEngine.renderingEngines[r].busy.includes(customizationId))
994
1044
  this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
995
1045
 
996
- const eventCancel1: ITaskEvent = { type: TASK_TYPE.SESSION_OUTPUTS_UPDATE, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Output updating was exceeded by other customization request' };
1046
+ const eventCancel1: ITaskEvent = { 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' };
997
1047
  this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_CANCEL, eventCancel1);
998
1048
  this._logger.debug(`Session(${this.id}).updateOutputs: Output updating was exceeded by other request.`);
999
1049
  return newNode;
@@ -1027,9 +1077,11 @@ export class SessionEngine implements ISessionEngine {
1027
1077
  this._stateEngine.renderingEngines[r].busy.splice(this._stateEngine.renderingEngines[r].busy.indexOf(customizationId), 1);
1028
1078
 
1029
1079
  this._logger.debug(`Session(${this.id}).updateOutputs: Updated outputs.`);
1030
-
1031
- const eventEnd: ITaskEvent = { type: TASK_TYPE.SESSION_OUTPUTS_UPDATE, id: eventId, progress: 1, data: { sessionId: this.id }, status: 'Outputs updated' };
1032
- this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_END, eventEnd);
1080
+
1081
+ if(!taskEventInfo) {
1082
+ const eventEnd: ITaskEvent = { type: eventType, id: eventId, progress: 1, data: eventData, status: 'Outputs updated' };
1083
+ this._eventEngine.emitEvent(EVENTTYPE.TASK.TASK_END, eventEnd);
1084
+ }
1033
1085
 
1034
1086
  return this.node;
1035
1087
  }
@@ -1159,11 +1211,11 @@ export class SessionEngine implements ISessionEngine {
1159
1211
  throw new ShapeDiverViewerSessionError(`Session.checkAvailability: action ${action} not available.`);
1160
1212
  }
1161
1213
 
1162
- private async customizeInternal(cancelRequest: () => boolean): Promise<ISessionTreeNode> {
1163
- return this.customizeSession(this._parameterValues, cancelRequest);
1214
+ private async customizeInternal(cancelRequest: () => boolean, taskEventInfo: OutputLoaderTaskEventInfo): Promise<ISessionTreeNode> {
1215
+ return this.customizeSession(this._parameterValues, cancelRequest, taskEventInfo);
1164
1216
  }
1165
1217
 
1166
- private async customizeSession(parameters: { [key: string]: string }, cancelRequest: () => boolean, parallel = false, retry = false): Promise<ISessionTreeNode> {
1218
+ private async customizeSession(parameters: { [key: string]: string }, cancelRequest: () => boolean, taskEventInfo: OutputLoaderTaskEventInfo, parallel = false, retry = false): Promise<ISessionTreeNode> {
1167
1219
  this.checkAvailability('customize');
1168
1220
  try {
1169
1221
  this._performanceEvaluator.startSection('sessionResponse');
@@ -1171,11 +1223,11 @@ export class SessionEngine implements ISessionEngine {
1171
1223
  this._performanceEvaluator.endSection('sessionResponse');
1172
1224
  if (cancelRequest()) return new SessionTreeNode();
1173
1225
  if (parallel === false) this.updateResponseDto(responseDto);
1174
- return parallel === false ? this.loadOutputs(cancelRequest) : this.loadOutputsParallel(responseDto, cancelRequest);
1226
+ return parallel === false ? this.loadOutputs(cancelRequest, taskEventInfo) : this.loadOutputsParallel(responseDto, cancelRequest, taskEventInfo);
1175
1227
  } catch (e) {
1176
1228
  await this.handleError(e, retry);
1177
1229
  if (cancelRequest()) return new SessionTreeNode();
1178
- return await this.customizeSession(parameters, cancelRequest, parallel, true);
1230
+ return await this.customizeSession(parameters, cancelRequest, taskEventInfo, parallel, true);
1179
1231
  }
1180
1232
  }
1181
1233
 
@@ -1186,6 +1238,7 @@ export class SessionEngine implements ISessionEngine {
1186
1238
  // we try to re-initialize the session 3 times, if that does not work, we close it
1187
1239
 
1188
1240
  this._logger.warn(`The session has been closed, trying to re-initialize.`);
1241
+ if(this._sessionId) this._httpClient.removeDataLoading(this._sessionId)
1189
1242
 
1190
1243
  if (this._retryCounter < 3) {
1191
1244
  // we retry this 3 times, the `retry` option in the init function is set to true and passed on
@@ -1196,7 +1249,7 @@ export class SessionEngine implements ISessionEngine {
1196
1249
  // the retries were exceeded, we close the session
1197
1250
  this._logger.warn('Tried to retry the connect multiple times, bearer token still not valid. Closing Session.');
1198
1251
  try { await this._closeOnFailure(); } catch (e) { }
1199
- throw e;
1252
+ throw this._httpClient.convertError(e);
1200
1253
  }
1201
1254
  } else if (e.error === ShapeDiverResponseErrorType.JWT_VALIDATION_ERROR) {
1202
1255
  // if any of the above errors occur, we try to get a new bearer token
@@ -1210,19 +1263,19 @@ export class SessionEngine implements ISessionEngine {
1210
1263
  // no bearer tokens are supplied, we close the session
1211
1264
  this._logger.warn('No retry possible, no new bearer token was supplied. Closing Session.');
1212
1265
  try { await this._closeOnFailure(); } catch (e) { }
1213
- throw e;
1266
+ throw this._httpClient.convertError(e);
1214
1267
  }
1215
1268
  } else {
1216
1269
  // the retries were exceeded, we close the session
1217
1270
  this._logger.warn('Tried to retry the connect multiple times, bearer token still not valid. Closing Session.');
1218
1271
  try { await this._closeOnFailure(); } catch (e) { }
1219
- throw e;
1272
+ throw this._httpClient.convertError(e);
1220
1273
  }
1221
1274
  } else {
1222
- throw e;
1275
+ throw this._httpClient.convertError(e);
1223
1276
  }
1224
1277
  } else {
1225
- throw e;
1278
+ throw this._httpClient.convertError(e);
1226
1279
  }
1227
1280
  }
1228
1281
 
@@ -1299,8 +1352,22 @@ export class SessionEngine implements ISessionEngine {
1299
1352
  break;
1300
1353
  }
1301
1354
 
1302
- if(initialParameters && initialParameters[parameterId] !== undefined)
1303
- this.parameters[parameterId].value = initialParameters[parameterId]
1355
+ // we don't have to do larger restrictions for this as the backend would have already thrown an error if the values were not correct
1356
+ if(initialParameters) {
1357
+ // check if the id is within the initial parameters
1358
+ if(initialParameters[parameterId] !== undefined) {
1359
+ this.parameters[parameterId].value = initialParameters[parameterId]
1360
+ }
1361
+ // check if the name is within the initial parameters
1362
+ else if(initialParameters[this.parameters[parameterId].name] !== undefined) {
1363
+ this.parameters[parameterId].value = initialParameters[this.parameters[parameterId].name];
1364
+ }
1365
+ // NOTE: At some point the checking may also be done with the displayname, this is the code for it
1366
+ // // check if the displayname is within the initial parameters
1367
+ // else if(this.parameters[parameterId].displayname && initialParameters[this.parameters[parameterId].displayname!] !== undefined) {
1368
+ // this.parameters[parameterId].value = initialParameters[this.parameters[parameterId].displayname!];
1369
+ // }
1370
+ }
1304
1371
 
1305
1372
  parameterSet[parameterId] = {
1306
1373
  value: this.parameters[parameterId].value,
@@ -1,5 +1,5 @@
1
1
  import { ShapeDiverResponseExport, ShapeDiverResponseExportContent, ShapeDiverResponseExportDefinitionType, ShapeDiverResponseExportResult, ShapeDiverResponseModelComputationStatus, ShapeDiverResponseParameterGroup } from "@shapediver/sdk.geometry-api-sdk-v2";
2
- import { EventEngine, EVENTTYPE, InputValidator, Logger, ShapeDiverBackendError, ShapeDiverViewerError, UuidGenerator } from "@shapediver/viewer.shared.services";
2
+ import { EventEngine, EVENTTYPE, InputValidator, Logger, UuidGenerator } from "@shapediver/viewer.shared.services";
3
3
  import { ITaskEvent, TASK_TYPE } from "@shapediver/viewer.shared.types";
4
4
  import { IExport } from "../../interfaces/dto/IExport";
5
5
  import { SessionEngine } from "../SessionEngine";
@@ -1,6 +1,6 @@
1
1
  import { ShapeDiverResponseModelComputationStatus, ShapeDiverResponseOutput } from "@shapediver/sdk.geometry-api-sdk-v2";
2
2
  import { ITreeNode, TreeNode } from "@shapediver/viewer.shared.node-tree";
3
- import { InputValidator, UuidGenerator, ShapeDiverViewerError, ShapeDiverBackendError, Logger } from "@shapediver/viewer.shared.services";
3
+ import { InputValidator, UuidGenerator, Logger } from "@shapediver/viewer.shared.services";
4
4
  import { IOutput, ShapeDiverResponseOutputContent, ShapeDiverResponseOutputChunk } from "../../interfaces/dto/IOutput";
5
5
  import { SessionEngine } from "../SessionEngine";
6
6
 
@@ -1,6 +1,7 @@
1
1
  import { ShapeDiverRequestGltfUploadQueryConversion, ShapeDiverResponseDto, ShapeDiverResponseExport, ShapeDiverResponseOutput, ShapeDiverResponseParameter } from '@shapediver/sdk.geometry-api-sdk-v2';
2
2
  import { ITreeNode, TreeNode } from '@shapediver/viewer.shared.node-tree'
3
3
  import { SettingsEngine } from '@shapediver/viewer.shared.services';
4
+ import { OutputLoaderTaskEventInfo } from '../implementation/OutputLoader';
4
5
  import { IExport } from './dto/IExport';
5
6
  import { IOutput } from './dto/IOutput';
6
7
  import { IParameter } from './dto/IParameter';
@@ -126,14 +127,14 @@ export interface ISessionEngine {
126
127
  goBack(): Promise<ITreeNode>;
127
128
  goForward(): Promise<ITreeNode>;
128
129
  init(parameterValues?: { [key: string]: string; }): Promise<void>;
129
- loadOutputs(cancelRequest: () => boolean): Promise<ITreeNode>;
130
- loadOutputsParallel(responseDto: ShapeDiverResponseDto, cancelRequest: () => boolean): Promise<ITreeNode>;
130
+ loadOutputs(cancelRequest: () => boolean, taskEventInfo: OutputLoaderTaskEventInfo): Promise<ITreeNode>;
131
+ loadOutputsParallel(responseDto: ShapeDiverResponseDto, cancelRequest: () => boolean, taskEventInfo: OutputLoaderTaskEventInfo): Promise<ITreeNode>;
131
132
  requestExport(exportId: string, parameters: { [key: string]: string }, maxWaitTime: number): Promise<ShapeDiverResponseExport>;
132
133
  resetSettings(sections?: ISettingsSections): void;
133
134
  saveDefaultParameterValues(): Promise<boolean>;
134
135
  saveSettings(viewportId?: string): Promise<boolean>;
135
136
  saveUiProperties(): Promise<boolean>;
136
- updateOutputs(): Promise<ITreeNode>;
137
+ updateOutputs(taskEventInfo?: OutputLoaderTaskEventInfo): Promise<ITreeNode>;
137
138
  uploadFile(parameterId: string, data: File, type: string): Promise<string>;
138
139
  uploadGLTF(blob: Blob, conversion?: ShapeDiverRequestGltfUploadQueryConversion): Promise<ShapeDiverResponseDto>;
139
140