@shapediver/viewer.shared.services 1.15.6 → 2.0.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.
Files changed (77) hide show
  1. package/dist/converter/Converter.js +1 -1
  2. package/dist/converter/Converter.js.map +1 -1
  3. package/dist/dom-event-engine/DomEventEngine.d.ts +1 -2
  4. package/dist/dom-event-engine/DomEventEngine.d.ts.map +1 -1
  5. package/dist/dom-event-engine/DomEventEngine.js +1 -2
  6. package/dist/dom-event-engine/DomEventEngine.js.map +1 -1
  7. package/dist/event-engine/EventEngine.d.ts +3 -3
  8. package/dist/event-engine/EventEngine.d.ts.map +1 -1
  9. package/dist/event-engine/EventEngine.js +2 -2
  10. package/dist/event-engine/EventEngine.js.map +1 -1
  11. package/dist/event-engine/EventTypes.d.ts +20 -24
  12. package/dist/event-engine/EventTypes.d.ts.map +1 -1
  13. package/dist/event-engine/EventTypes.js +55 -85
  14. package/dist/event-engine/EventTypes.js.map +1 -1
  15. package/dist/http-client/HttpClient.d.ts.map +1 -1
  16. package/dist/http-client/HttpClient.js +5 -5
  17. package/dist/http-client/HttpClient.js.map +1 -1
  18. package/dist/index.d.ts +4 -4
  19. package/dist/index.d.ts.map +1 -1
  20. package/dist/index.js +10 -3
  21. package/dist/index.js.map +1 -1
  22. package/dist/input-validator/InputValidator.d.ts +3 -3
  23. package/dist/input-validator/InputValidator.d.ts.map +1 -1
  24. package/dist/input-validator/InputValidator.js +6 -2
  25. package/dist/input-validator/InputValidator.js.map +1 -1
  26. package/dist/logger/Logger.d.ts +16 -16
  27. package/dist/logger/Logger.d.ts.map +1 -1
  28. package/dist/logger/Logger.js +77 -76
  29. package/dist/logger/Logger.js.map +1 -1
  30. package/dist/logger/ShapeDiverError.d.ts +1 -1
  31. package/dist/logger/ShapeDiverError.d.ts.map +1 -1
  32. package/dist/logger/ShapeDiverError.js +1 -1
  33. package/dist/logger/ShapeDiverError.js.map +1 -1
  34. package/dist/logger/ShapeDiverViewerErrors.d.ts +24 -24
  35. package/dist/logger/ShapeDiverViewerErrors.d.ts.map +1 -1
  36. package/dist/logger/ShapeDiverViewerErrors.js +1 -1
  37. package/dist/logger/ShapeDiverViewerErrors.js.map +1 -1
  38. package/dist/performance-evaluator/PerformanceEvaluator.js +1 -1
  39. package/dist/performance-evaluator/PerformanceEvaluator.js.map +1 -1
  40. package/dist/settings-engine/SettingsEngine.d.ts +1 -1
  41. package/dist/settings-engine/SettingsEngine.d.ts.map +1 -1
  42. package/dist/settings-engine/SettingsEngine.js +16 -25
  43. package/dist/settings-engine/SettingsEngine.js.map +1 -1
  44. package/dist/state-engine/StateEngine.d.ts +7 -16
  45. package/dist/state-engine/StateEngine.d.ts.map +1 -1
  46. package/dist/state-engine/StateEngine.js +8 -21
  47. package/dist/state-engine/StateEngine.js.map +1 -1
  48. package/dist/system-info/SystemInfo.js +1 -1
  49. package/dist/system-info/SystemInfo.js.map +1 -1
  50. package/dist/type-check/TypeChecker.js +1 -1
  51. package/dist/type-check/TypeChecker.js.map +1 -1
  52. package/dist/uuid-generator/UuidGenerator.js +5 -5
  53. package/dist/uuid-generator/UuidGenerator.js.map +1 -1
  54. package/package.json +11 -8
  55. package/src/converter/Converter.ts +299 -0
  56. package/src/dom-event-engine/DomEventEngine.ts +334 -0
  57. package/src/dom-event-engine/IDomEventListener.ts +14 -0
  58. package/src/event-engine/EventEngine.ts +116 -0
  59. package/src/event-engine/EventTypes.ts +66 -0
  60. package/src/event-engine/interfaces/ICallback.ts +5 -0
  61. package/src/event-engine/interfaces/IEvent.ts +1 -0
  62. package/src/event-engine/interfaces/IListener.ts +8 -0
  63. package/src/http-client/HttpClient.ts +177 -0
  64. package/src/http-client/HttpResponse.ts +4 -0
  65. package/src/index.ts +82 -0
  66. package/src/input-validator/InputValidator.ts +100 -0
  67. package/src/logger/Logger.ts +297 -0
  68. package/src/logger/ShapeDiverError.ts +48 -0
  69. package/src/logger/ShapeDiverViewerErrors.ts +115 -0
  70. package/src/performance-evaluator/PerformanceEvaluator.ts +102 -0
  71. package/src/settings-engine/SettingsEngine.ts +176 -0
  72. package/src/state-engine/StateEngine.ts +73 -0
  73. package/src/state-engine/StatePromise.ts +54 -0
  74. package/src/system-info/SystemInfo.ts +117 -0
  75. package/src/type-check/TypeChecker.ts +13 -0
  76. package/src/uuid-generator/UuidGenerator.ts +41 -0
  77. package/tsconfig.json +17 -0
@@ -0,0 +1,297 @@
1
+ import * as Sentry from '@sentry/browser'
2
+ import { container, singleton } from 'tsyringe'
3
+ import { build_data } from '@shapediver/viewer.shared.build-data'
4
+ import { ShapeDiverError as ShapeDiverBackendError } from '@shapediver/sdk.geometry-api-sdk-core'
5
+
6
+ import { UuidGenerator } from '../uuid-generator/UuidGenerator'
7
+ import { BrowserClient, Hub } from '@sentry/browser'
8
+ import { ShapeDiverViewerConnectionError, ShapeDiverViewerUnknownError } from './ShapeDiverViewerErrors'
9
+ import { ShapeDiverRequestError, ShapeDiverResponseError, ShapeDiverResponseErrorType } from '@shapediver/sdk.geometry-api-sdk-v2'
10
+ import { ShapeDiverViewerError } from './ShapeDiverError'
11
+
12
+ export enum LOGGING_LEVEL {
13
+ NONE = 'none',
14
+ ERROR = 'error',
15
+ FATAL = 'fatal',
16
+ WARN = 'warn',
17
+ INFO = 'info',
18
+ DEBUG = 'debug',
19
+ DEBUG_HIGH = 'debug_high',
20
+ DEBUG_MEDIUM = 'debug_medium',
21
+ DEBUG_LOW = 'debug_low',
22
+ }
23
+
24
+ export enum LOGGING_TOPIC {
25
+ AR = 'ar',
26
+ GENERAL = 'general',
27
+ EXPORT = 'export',
28
+ PARAMETER = 'parameter',
29
+ OUTPUT = 'output',
30
+ SESSION = 'session',
31
+ VIEWPORT = 'viewer',
32
+ CAMERA = 'camera',
33
+ LIGHT = 'light',
34
+ CAMERA_CONTROL = 'camera_control',
35
+ DATA_PROCESSING = 'data_processing',
36
+ SDTF = 'sdtf',
37
+ THREE = 'three',
38
+ SETTINGS = 'settings',
39
+ }
40
+
41
+ @singleton()
42
+ export class Logger {
43
+ // #region Properties (2)
44
+
45
+ private _loggingLevel: LOGGING_LEVEL = LOGGING_LEVEL.WARN;
46
+ private _showMessages: boolean = true;
47
+ private _breadCrumbs: Sentry.Breadcrumb[] = [];
48
+ private _breadCrumbCounter: number = 0;
49
+ private _sentryHub: Hub;
50
+ private _uuidGenerator: UuidGenerator = <UuidGenerator>container.resolve(UuidGenerator);
51
+ private _userId = this._uuidGenerator.create();
52
+
53
+ // #endregion Properties (2)
54
+
55
+ constructor() {
56
+ const client = new BrowserClient({
57
+ dsn: "https://0510990697b04b9da3ad07868e94e378@o363881.ingest.sentry.io/5828729",
58
+ environment: 'local',
59
+ release: build_data.build_version,
60
+ maxBreadcrumbs: 100,
61
+ beforeBreadcrumb: (breadcrumb: Sentry.Breadcrumb, hint?: Sentry.BreadcrumbHint | undefined): Sentry.Breadcrumb | null => {
62
+ this._breadCrumbCounter++;
63
+ return breadcrumb;
64
+ },
65
+ beforeSend: (event: Sentry.Event, hint?: Sentry.EventHint | undefined): Sentry.Event | PromiseLike<Sentry.Event | null> | null => {
66
+ if (event.level === Sentry.Severity.Debug) event.fingerprint ? event.fingerprint.push(this._userId + '') : event.fingerprint = [this._userId + ''];
67
+ return event;
68
+ },
69
+ // Set tracesSampleRate to 1.0 to capture 100%
70
+ // of transactions for performance monitoring.
71
+ // We recommend adjusting this value in production
72
+ tracesSampleRate: 1.0
73
+ });
74
+
75
+ this._sentryHub = new Hub(client);
76
+
77
+ this._sentryHub.setUser({
78
+ id: this._userId
79
+ })
80
+ }
81
+
82
+ // #region Public Accessors (4)
83
+
84
+ public get loggingLevel(): LOGGING_LEVEL {
85
+ return this._loggingLevel;
86
+ }
87
+
88
+ public set loggingLevel(value: LOGGING_LEVEL) {
89
+ this._loggingLevel = value;
90
+ }
91
+
92
+ public get showMessages(): boolean {
93
+ return this._showMessages;
94
+ }
95
+
96
+ public set showMessages(value: boolean) {
97
+ this._showMessages = value;
98
+ }
99
+
100
+ private canLog(loggingLevel: LOGGING_LEVEL): boolean {
101
+ switch (this.loggingLevel) {
102
+ case LOGGING_LEVEL.ERROR:
103
+ if (loggingLevel === LOGGING_LEVEL.FATAL) return false;
104
+ if (loggingLevel === LOGGING_LEVEL.WARN) return false;
105
+ if (loggingLevel === LOGGING_LEVEL.INFO) return false;
106
+ if (loggingLevel === LOGGING_LEVEL.DEBUG) return false;
107
+ if (loggingLevel === LOGGING_LEVEL.DEBUG_HIGH) return false;
108
+ if (loggingLevel === LOGGING_LEVEL.DEBUG_MEDIUM) return false;
109
+ if (loggingLevel === LOGGING_LEVEL.DEBUG_LOW) return false;
110
+ case LOGGING_LEVEL.FATAL:
111
+ if (loggingLevel === LOGGING_LEVEL.WARN) return false;
112
+ if (loggingLevel === LOGGING_LEVEL.INFO) return false;
113
+ if (loggingLevel === LOGGING_LEVEL.DEBUG) return false;
114
+ if (loggingLevel === LOGGING_LEVEL.DEBUG_HIGH) return false;
115
+ if (loggingLevel === LOGGING_LEVEL.DEBUG_MEDIUM) return false;
116
+ if (loggingLevel === LOGGING_LEVEL.DEBUG_LOW) return false;
117
+ case LOGGING_LEVEL.WARN:
118
+ if (loggingLevel === LOGGING_LEVEL.INFO) return false;
119
+ if (loggingLevel === LOGGING_LEVEL.DEBUG) return false;
120
+ if (loggingLevel === LOGGING_LEVEL.DEBUG_HIGH) return false;
121
+ if (loggingLevel === LOGGING_LEVEL.DEBUG_MEDIUM) return false;
122
+ if (loggingLevel === LOGGING_LEVEL.DEBUG_LOW) return false;
123
+ case LOGGING_LEVEL.INFO:
124
+ if (loggingLevel === LOGGING_LEVEL.DEBUG) return false;
125
+ if (loggingLevel === LOGGING_LEVEL.DEBUG_HIGH) return false;
126
+ if (loggingLevel === LOGGING_LEVEL.DEBUG_MEDIUM) return false;
127
+ if (loggingLevel === LOGGING_LEVEL.DEBUG_LOW) return false;
128
+ case LOGGING_LEVEL.DEBUG_HIGH:
129
+ if (loggingLevel === LOGGING_LEVEL.DEBUG_MEDIUM) return false;
130
+ if (loggingLevel === LOGGING_LEVEL.DEBUG_LOW) return false;
131
+ case LOGGING_LEVEL.DEBUG_MEDIUM:
132
+ if (loggingLevel === LOGGING_LEVEL.DEBUG_LOW) return false;
133
+ case LOGGING_LEVEL.DEBUG_LOW:
134
+ case LOGGING_LEVEL.DEBUG:
135
+ default:
136
+ return true;
137
+ }
138
+ }
139
+
140
+ // #endregion Public Accessors (4)
141
+
142
+ // #region Public Methods (8)
143
+
144
+ public handleError(topic: LOGGING_TOPIC, scope: string, e: ShapeDiverBackendError | ShapeDiverViewerError | Error | unknown, logToSentry = true) {
145
+ if (this.canLog(LOGGING_LEVEL.ERROR) && this.showMessages === true)
146
+ console.error('(ERROR) ', e);
147
+ if(e instanceof ShapeDiverRequestError) {
148
+ const messageProperty = e && e.message ? e.message : `An unknown issue occurred in ${scope}.`;
149
+ if(logToSentry) this.sentryError(topic, e, messageProperty);
150
+ throw e;
151
+ } else if(e instanceof ShapeDiverResponseError && e.error === ShapeDiverResponseErrorType.UNKNOWN) {
152
+ const messageProperty = e && e.message ? e.message : `An unknown issue occurred in ${scope}.`;
153
+ if(logToSentry) this.sentryError(topic, e, messageProperty);
154
+ throw e;
155
+ } else if(e instanceof ShapeDiverResponseError) {
156
+ throw e;
157
+ } else if (e instanceof ShapeDiverViewerError) {
158
+ const messageProperty = e && e.message ? e.message : `An unknown issue occurred in ${scope}.`;
159
+ if(logToSentry) {
160
+ if(!(e instanceof ShapeDiverViewerConnectionError) || (e.status && e.status >= 500)) {
161
+ this.sentryError(topic, e, messageProperty);
162
+ }
163
+ }
164
+ throw e;
165
+ } else if(e) {
166
+ const error = <any>e;
167
+ const messageProperty = error.message ? error.message : `An unknown issue occurred in ${scope}.`;
168
+ const viewerError = new ShapeDiverViewerUnknownError(messageProperty, error);
169
+ if(logToSentry) this.sentryError(topic, viewerError, messageProperty);
170
+ throw viewerError;
171
+ }
172
+ }
173
+
174
+ public sentryError(topic: LOGGING_TOPIC, error: ShapeDiverBackendError | ShapeDiverViewerError | Error, msg?: string) {
175
+ this.sentryBreadcrumb(topic, msg || error.message, Sentry.Severity.Error);
176
+
177
+ const breadcrumbCounter = this._breadCrumbCounter > 100 ? 100 : this._breadCrumbCounter;
178
+ for(let i = breadcrumbCounter; i < this._breadCrumbs.length + breadcrumbCounter; i++) {
179
+ if(i%100 === 0 && i !== 0) {
180
+ this._sentryHub.setTag('topic', topic);
181
+ this._sentryHub.setUser({ id: this._userId })
182
+ this._sentryHub.captureMessage('Breadcrumb Issue ' + (i/100 - 1) + ' (' + this._userId + ')', Sentry.Severity.Debug);
183
+ this._sentryHub.getScope()?.clear()
184
+ }
185
+ this._sentryHub.addBreadcrumb(this._breadCrumbs[i-breadcrumbCounter]);
186
+ }
187
+
188
+ this._sentryHub.setTag('topic', topic);
189
+ this._sentryHub.setUser({ id: this._userId })
190
+
191
+ if(error instanceof ShapeDiverBackendError || error instanceof ShapeDiverViewerError) {
192
+ this._sentryHub.captureMessage(error.message, Sentry.Severity.Error);
193
+ } else {
194
+ this._sentryHub.captureException(error);
195
+ }
196
+ }
197
+
198
+ public sentryBreadcrumb(topic: LOGGING_TOPIC, msg: string, level: Sentry.Severity) {
199
+ this._breadCrumbs.push({
200
+ category: topic,
201
+ message: msg,
202
+ level: Sentry.Severity.Debug,
203
+ timestamp: Math.floor(new Date().getTime() / 1000)
204
+ })
205
+ }
206
+
207
+ /**
208
+ * Logging a debug message.
209
+ * @param msg the message
210
+ */
211
+ public debug(topic: LOGGING_TOPIC, msg: string): void {
212
+ if (this.canLog(LOGGING_LEVEL.DEBUG) && this.showMessages === true)
213
+ console.debug('(DEBUG) ' + this.messageConstruction(msg));
214
+ }
215
+
216
+ /**
217
+ * Logging a debug message with high priority.
218
+ * @param msg the message
219
+ */
220
+ public debugHigh(topic: LOGGING_TOPIC, msg: string): void {
221
+ if (this.canLog(LOGGING_LEVEL.DEBUG_HIGH) && this.showMessages === true)
222
+ console.debug('(DEBUG_HIGH) ' + this.messageConstruction(msg));
223
+ }
224
+
225
+ /**
226
+ * Logging a debug message with low priority.
227
+ * @param msg the message
228
+ */
229
+ public debugLow(topic: LOGGING_TOPIC, msg: string): void {
230
+ if (this.canLog(LOGGING_LEVEL.DEBUG_LOW) && this.showMessages === true)
231
+ console.debug('(DEBUG_LOW) ' + this.messageConstruction(msg));
232
+ }
233
+
234
+ /**
235
+ * Logging a debug message with medium priority.
236
+ * @param msg the message
237
+ */
238
+ public debugMedium(topic: LOGGING_TOPIC, msg: string): void {
239
+ if (this.canLog(LOGGING_LEVEL.DEBUG_MEDIUM) && this.showMessages === true)
240
+ console.debug('(DEBUG_MEDIUM) ' + this.messageConstruction(msg));
241
+ }
242
+
243
+ /**
244
+ * Logging an error.
245
+ * @param msg the message
246
+ */
247
+ public error(topic: LOGGING_TOPIC, error: Error, msg?: string, throwError: boolean = false, notifySentry: boolean = true): void {
248
+ this.sentryBreadcrumb(topic, msg || error.message, Sentry.Severity.Error);
249
+ if(notifySentry)
250
+ this.sentryError(topic, error, msg);
251
+ if (this.canLog(LOGGING_LEVEL.ERROR) && this.showMessages === true)
252
+ console.error('(ERROR) ' + this.messageConstruction(msg || error.message));
253
+ if(throwError) throw error;
254
+ }
255
+
256
+ /**
257
+ * Logging a fatal error.
258
+ * @param msg the message
259
+ */
260
+ public fatal(topic: LOGGING_TOPIC, msg: string, error: Error, throwError: boolean = false): void {
261
+ this.sentryBreadcrumb(topic, msg, Sentry.Severity.Fatal);
262
+ this.sentryError(topic, error, msg);
263
+ if (this.canLog(LOGGING_LEVEL.FATAL) && this.showMessages === true)
264
+ console.error('(FATAL) ' + this.messageConstruction(msg));
265
+ if(throwError) throw error;
266
+ }
267
+
268
+ /**
269
+ * Logging an info.
270
+ * @param msg the message
271
+ */
272
+ public info(topic: LOGGING_TOPIC, msg: string): void {
273
+ this.sentryBreadcrumb(topic, msg, Sentry.Severity.Info);
274
+ if (this.canLog(LOGGING_LEVEL.INFO) && this.showMessages === true)
275
+ console.info('(INFO) ' + this.messageConstruction(msg));
276
+ }
277
+
278
+ /**
279
+ * Logging a warning.
280
+ * @param msg the message
281
+ */
282
+ public warn(topic: LOGGING_TOPIC, msg: string): void {
283
+ this.sentryBreadcrumb(topic, msg, Sentry.Severity.Warning);
284
+ if (this.canLog(LOGGING_LEVEL.WARN) && this.showMessages === true)
285
+ console.warn('(WARN) ' + this.messageConstruction(msg));
286
+ }
287
+
288
+ // #endregion Public Methods (8)
289
+
290
+ // #region Private Methods (2)
291
+
292
+ private messageConstruction(msg: string): string {
293
+ return new Date().toISOString() + ': ' + msg;
294
+ }
295
+
296
+ // #endregion Private Methods (2)
297
+ }
@@ -0,0 +1,48 @@
1
+
2
+ export enum ShapeDiverViewerErrorType {
3
+ AR_ERROR = 'SdARError',
4
+ CAMERA_ERROR = 'SdCameraError',
5
+ CONNECTION_ERROR = 'SdConnectionError',
6
+ DATA_PROCESSING_ERROR = 'SdDataProcessingError',
7
+ ENVIRONMENT_MAP_ERROR = 'SdEnvironmentMapError',
8
+ GENERAL_VIEWPORT_ERROR = 'SdGeneralViewerError',
9
+ LIGHT_ERROR = 'SdLightError',
10
+ SESSION_ERROR = 'SdSessionError',
11
+ SETTINGS_ERROR = 'SdSettingsError',
12
+ VALIDATION_ERROR = 'SdValidationError',
13
+ WEBGL_ERROR = 'SdWebGLError',
14
+ UNKNOWN = "",
15
+ }
16
+ export interface IShapeDiverViewerError {
17
+ error: ShapeDiverViewerErrorType;
18
+ desc: string;
19
+ message: string;
20
+ }
21
+
22
+ export class ShapeDiverError extends Error {
23
+ // #region Constructors (1)
24
+
25
+ constructor(message: string) {
26
+ super(message)
27
+ }
28
+
29
+ // #endregion Constructors (1)
30
+ }
31
+
32
+ export class ShapeDiverViewerError extends ShapeDiverError implements IShapeDiverViewerError {
33
+ // #region Constructors (1)
34
+
35
+ constructor(
36
+ public readonly error: ShapeDiverViewerErrorType,
37
+ public readonly desc: string,
38
+ message: string
39
+ ) {
40
+ super(message)
41
+
42
+ this.error = (Object.values(ShapeDiverViewerErrorType).includes(error as any))
43
+ ? error as ShapeDiverViewerErrorType
44
+ : ShapeDiverViewerErrorType.UNKNOWN
45
+ }
46
+
47
+ // #endregion Constructors (1)
48
+ }
@@ -0,0 +1,115 @@
1
+ import { ShapeDiverViewerError, ShapeDiverViewerErrorType } from "./ShapeDiverError";
2
+
3
+
4
+ export class ShapeDiverViewerUnknownError extends ShapeDiverViewerError {
5
+ constructor(
6
+ public readonly message: string,
7
+ public readonly errorObject: Error | unknown
8
+ ) {
9
+ super(ShapeDiverViewerErrorType.UNKNOWN, 'An unknown error occurred.', message);
10
+ Error.captureStackTrace(this, ShapeDiverViewerUnknownError)
11
+ }
12
+ }
13
+
14
+ export class ShapeDiverViewerDataProcessingError extends ShapeDiverViewerError {
15
+ constructor(
16
+ public readonly message: string,
17
+ public readonly errorObject?: Error | unknown
18
+ ) {
19
+ super(ShapeDiverViewerErrorType.DATA_PROCESSING_ERROR, 'An error occurred while processing data.', message);
20
+ }
21
+ }
22
+
23
+ export class ShapeDiverViewerEnvironmentMapError extends ShapeDiverViewerError {
24
+ constructor(
25
+ public readonly message: string,
26
+ public readonly url?: string | string[],
27
+ public readonly errorObject?: Error | unknown
28
+ ) {
29
+ super(ShapeDiverViewerErrorType.ENVIRONMENT_MAP_ERROR, 'An error occurred while loading the environment map.', message);
30
+ }
31
+ }
32
+
33
+ export class ShapeDiverViewerWebGLError extends ShapeDiverViewerError {
34
+ constructor(
35
+ public readonly message: string,
36
+ public readonly errorObject?: Error | unknown
37
+ ) {
38
+ super(ShapeDiverViewerErrorType.WEBGL_ERROR, 'An error occurred regarding to the WebGL context.', message);
39
+ }
40
+ }
41
+
42
+ export class ShapeDiverViewerSettingsError extends ShapeDiverViewerError {
43
+ constructor(
44
+ public readonly message: string,
45
+ public readonly errorObject?: Error | unknown
46
+ ) {
47
+ super(ShapeDiverViewerErrorType.SETTINGS_ERROR, 'An error occurred while loading the settings.', message);
48
+ }
49
+ }
50
+
51
+ export class ShapeDiverViewerSessionError extends ShapeDiverViewerError {
52
+ constructor(
53
+ public readonly message: string,
54
+ public readonly errorObject?: Error | unknown
55
+ ) {
56
+ super(ShapeDiverViewerErrorType.SESSION_ERROR, 'An error occurred while working with the session.', message);
57
+ }
58
+ }
59
+
60
+ export class ShapeDiverViewerLightError extends ShapeDiverViewerError {
61
+ constructor(
62
+ public readonly message: string,
63
+ public readonly errorObject?: Error | unknown
64
+ ) {
65
+ super(ShapeDiverViewerErrorType.LIGHT_ERROR, 'An error occurred while working with the lights.', message);
66
+ }
67
+ }
68
+
69
+ export class ShapeDiverViewerCameraError extends ShapeDiverViewerError {
70
+ constructor(
71
+ public readonly message: string,
72
+ public readonly errorObject?: Error | unknown
73
+ ) {
74
+ super(ShapeDiverViewerErrorType.CAMERA_ERROR, 'An error occurred while working with the cameras.', message);
75
+ }
76
+ }
77
+
78
+ export class ShapeDiverViewerGeneralError extends ShapeDiverViewerError {
79
+ constructor(
80
+ public readonly message: string,
81
+ public readonly errorObject?: Error | unknown
82
+ ) {
83
+ super(ShapeDiverViewerErrorType.GENERAL_VIEWPORT_ERROR, 'An error occurred while working with the viewer.', message);
84
+ }
85
+ }
86
+
87
+ export class ShapeDiverViewerArError extends ShapeDiverViewerError {
88
+ constructor(
89
+ public readonly message: string,
90
+ public readonly errorObject?: Error | unknown
91
+ ) {
92
+ super(ShapeDiverViewerErrorType.AR_ERROR, 'An error occurred while working with AR.', message);
93
+ }
94
+ }
95
+
96
+ export class ShapeDiverViewerValidationError extends ShapeDiverViewerError {
97
+ constructor(
98
+ public readonly message: string,
99
+ public readonly value: any,
100
+ public readonly requestedType: string,
101
+ public readonly errorObject?: Error | unknown
102
+ ) {
103
+ super(ShapeDiverViewerErrorType.VALIDATION_ERROR, 'An error occurred while validating the value.', message);
104
+ }
105
+ }
106
+
107
+ export class ShapeDiverViewerConnectionError extends ShapeDiverViewerError {
108
+ constructor(
109
+ public readonly message: string,
110
+ public readonly status?: number,
111
+ public readonly errorObject?: Error | unknown
112
+ ) {
113
+ super(ShapeDiverViewerErrorType.CONNECTION_ERROR, 'An error occurred while loading data.', message);
114
+ }
115
+ }
@@ -0,0 +1,102 @@
1
+ import { singleton } from 'tsyringe'
2
+
3
+ @singleton()
4
+ export class PerformanceEvaluator {
5
+
6
+ private _eval: {
7
+ start: number;
8
+ section: {
9
+ [key: string]: {
10
+ start: number;
11
+ end?: number;
12
+ duration?: number;
13
+ };
14
+ };
15
+ end?: number;
16
+ duration?: number;
17
+ } | undefined;
18
+
19
+ /**
20
+ * Start the evaluation with a specific id.
21
+ *
22
+ * @param id
23
+ */
24
+ public start(time?: number): void {
25
+ this._eval = {
26
+ start: time || performance.now(),
27
+ section: {}
28
+ }
29
+ }
30
+
31
+ /**
32
+ * Start the evaluation of a section with a specific id.
33
+ *
34
+ * @param id
35
+ */
36
+ public startSection(sectionId: string, time?: number): void {
37
+ if (!this._eval) return;
38
+ if (this._eval.end) return;
39
+ this._eval.section[sectionId] = {
40
+ start: time || performance.now(),
41
+ }
42
+ }
43
+
44
+ /**
45
+ * End the performance evaluation of a section and calculate the duration.
46
+ *
47
+ * @param id
48
+ */
49
+ public endSection(sectionId: string): void {
50
+ if (!this._eval) return;
51
+ if (this._eval.end) return;
52
+ if (!this._eval.section[sectionId]) return;
53
+ if (this._eval.section[sectionId].end) return;
54
+
55
+ this._eval.section[sectionId].end = performance.now();
56
+
57
+ this._eval.section[sectionId].duration = this._eval.section[sectionId].end! - this._eval.section[sectionId].start;
58
+ }
59
+
60
+ /**
61
+ * End the performance evaluation and calculate the duration.
62
+ *
63
+ * @param id
64
+ */
65
+ public end(): void {
66
+ if (!this._eval) return;
67
+ if (this._eval.end) return;
68
+
69
+ this._eval.end = performance.now();
70
+ this._eval.duration = this._eval.end! - this._eval.start;
71
+ }
72
+
73
+ /**
74
+ * Get the evaluation data for a specific id.
75
+ *
76
+ * @param id
77
+ */
78
+ public getEvaluation(): {
79
+ start: number,
80
+ section: {
81
+ [key: string]: {
82
+ start: number,
83
+ end?: number,
84
+ duration?: number
85
+ }
86
+ },
87
+ end?: number,
88
+ duration?: number,
89
+ } | undefined {
90
+ return this._eval;
91
+ }
92
+
93
+ /**
94
+ * Get the evaluation data for a specific id.
95
+ *
96
+ * @param id
97
+ */
98
+ public getEvaluationToString(): string {
99
+ const e = this._eval;
100
+ return `Performance Evaluation: ${e!.duration}ms\n`;
101
+ }
102
+ }