@onecx/accelerator 8.0.0-rc.6 → 8.0.0-rc.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs ADDED
@@ -0,0 +1,668 @@
1
+ "use strict";
2
+ var __create = Object.create;
3
+ var __defProp = Object.defineProperty;
4
+ var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
5
+ var __getOwnPropNames = Object.getOwnPropertyNames;
6
+ var __getProtoOf = Object.getPrototypeOf;
7
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
8
+ var __export = (target, all) => {
9
+ for (var name in all)
10
+ __defProp(target, name, { get: all[name], enumerable: true });
11
+ };
12
+ var __copyProps = (to, from, except, desc) => {
13
+ if (from && typeof from === "object" || typeof from === "function") {
14
+ for (let key of __getOwnPropNames(from))
15
+ if (!__hasOwnProp.call(to, key) && key !== except)
16
+ __defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
17
+ }
18
+ return to;
19
+ };
20
+ var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
21
+ // If the importer is in node compatibility mode or this is not an ESM
22
+ // file that has been converted to a CommonJS file using a Babel-
23
+ // compatible transform (i.e. "__esModule" has not been set), then set
24
+ // "default" to the CommonJS "module.exports" for node compatibility.
25
+ isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
26
+ mod
27
+ ));
28
+ var __toCommonJS = (mod) => __copyProps(__defProp({}, "__esModule", { value: true }), mod);
29
+
30
+ // libs/accelerator/src/index.ts
31
+ var index_exports = {};
32
+ __export(index_exports, {
33
+ BroadcastChannelMock: () => BroadcastChannelMock,
34
+ FakeTopic: () => FakeTopic,
35
+ Gatherer: () => Gatherer,
36
+ SyncableTopic: () => SyncableTopic,
37
+ Topic: () => Topic,
38
+ TopicPublisher: () => TopicPublisher,
39
+ createLoggerFactory: () => createLoggerFactory,
40
+ ensureProperty: () => ensureProperty,
41
+ getLocation: () => getLocation,
42
+ getNormalizedBrowserLocales: () => getNormalizedBrowserLocales,
43
+ getUTCDateWithoutTimezoneIssues: () => getUTCDateWithoutTimezoneIssues,
44
+ isTest: () => isTest,
45
+ isValidDate: () => isValidDate,
46
+ normalizeLocales: () => normalizeLocales
47
+ });
48
+ module.exports = __toCommonJS(index_exports);
49
+
50
+ // libs/accelerator/src/lib/topic/topic.ts
51
+ var import_operators = require("rxjs/operators");
52
+ var import_rxjs = require("rxjs");
53
+
54
+ // libs/accelerator/src/lib/declarations.ts
55
+ window["@onecx/accelerator"] ??= {};
56
+ window["@onecx/accelerator"].gatherer ??= {};
57
+ window["@onecx/accelerator"].gatherer.promises ??= {};
58
+ window["@onecx/accelerator"].topic ??= {};
59
+ window["@onecx/accelerator"].topic.useBroadcastChannel ??= "V2";
60
+ window["@onecx/accelerator"].topic.initDate ??= Date.now();
61
+ window["@onecx/accelerator"].topic.tabId ??= Math.ceil(globalThis.performance.now());
62
+
63
+ // libs/accelerator/src/lib/utils/logs.utils.ts
64
+ function isStatsEnabled() {
65
+ return window["@onecx/accelerator"]?.topic?.statsEnabled === true;
66
+ }
67
+ function increaseMessageCount(topicName, messageType) {
68
+ window["@onecx/accelerator"].topic ??= {};
69
+ window["@onecx/accelerator"].topic.stats ??= {};
70
+ window["@onecx/accelerator"].topic.stats.messagesPublished ??= {};
71
+ if (isStatsEnabled()) {
72
+ const messageStats = window["@onecx/accelerator"].topic.stats.messagesPublished;
73
+ if (!messageStats[topicName]) {
74
+ messageStats[topicName] = {
75
+ TopicNext: 0,
76
+ TopicGet: 0,
77
+ TopicResolve: 0
78
+ };
79
+ }
80
+ messageStats[topicName][messageType]++;
81
+ }
82
+ }
83
+ function increaseInstanceCount(topicName) {
84
+ window["@onecx/accelerator"].topic ??= {};
85
+ window["@onecx/accelerator"].topic.stats ??= {};
86
+ window["@onecx/accelerator"].topic.stats.instancesCreated ??= {};
87
+ if (isStatsEnabled()) {
88
+ const instanceStats = window["@onecx/accelerator"].topic.stats.instancesCreated;
89
+ if (!instanceStats[topicName]) {
90
+ instanceStats[topicName] = 0;
91
+ }
92
+ instanceStats[topicName]++;
93
+ }
94
+ }
95
+
96
+ // libs/accelerator/src/lib/topic/message.ts
97
+ window["onecxMessageId"] ??= 1;
98
+ var Message = class {
99
+ // id can be undefined while used via old implementation
100
+ constructor(type) {
101
+ this.type = type;
102
+ this.timestamp = window.performance.now();
103
+ this.id = window["onecxMessageId"]++;
104
+ }
105
+ timestamp;
106
+ id;
107
+ };
108
+
109
+ // libs/accelerator/src/lib/topic/topic-message.ts
110
+ var TopicMessage = class extends Message {
111
+ constructor(type, name, version) {
112
+ super(type);
113
+ this.name = name;
114
+ this.version = version;
115
+ if (isStatsEnabled()) {
116
+ increaseMessageCount(this.name, type);
117
+ }
118
+ }
119
+ };
120
+
121
+ // libs/accelerator/src/lib/topic/topic-data-message.ts
122
+ var TopicDataMessage = class extends TopicMessage {
123
+ constructor(type, name, version, data) {
124
+ super(type, name, version);
125
+ this.data = data;
126
+ }
127
+ };
128
+
129
+ // libs/accelerator/src/lib/topic/topic-resolve-message.ts
130
+ var TopicResolveMessage = class extends TopicMessage {
131
+ constructor(type, name, version, resolveId) {
132
+ super(type, name, version);
133
+ this.resolveId = resolveId;
134
+ }
135
+ };
136
+
137
+ // libs/accelerator/src/lib/utils/create-logger.utils.ts
138
+ var import_debug = __toESM(require("debug"), 1);
139
+ import_debug.default.log = console.log.bind(console);
140
+ function createLoggerFactory(libOrAppName) {
141
+ const prefix = libOrAppName.trim();
142
+ if (!prefix) throw new Error("createLoggerFactory(libOrAppName): libOrAppName must be a non-empty string.");
143
+ const createLogger2 = (location) => {
144
+ const trimmedLocation = location.trim();
145
+ if (!trimmedLocation) throw new Error("createLogger(location): location must be a non-empty string.");
146
+ const ns = (level) => `${prefix}:${trimmedLocation}:${level}`;
147
+ return {
148
+ debug: (0, import_debug.default)(ns("debug")),
149
+ info: (0, import_debug.default)(ns("info")),
150
+ warn: (0, import_debug.default)(ns("warn")),
151
+ error: (0, import_debug.default)(ns("error"))
152
+ };
153
+ };
154
+ return createLogger2;
155
+ }
156
+
157
+ // libs/accelerator/src/lib/utils/logger.utils.ts
158
+ var createLogger = createLoggerFactory("@onecx/accelerator");
159
+
160
+ // libs/accelerator/src/lib/topic/topic-publisher.ts
161
+ var TopicPublisher = class {
162
+ constructor(name, version) {
163
+ this.name = name;
164
+ this.version = version;
165
+ this.baseLogger = createLogger(`TopicPublisher:${this.name}`);
166
+ }
167
+ publishPromiseResolver = {};
168
+ publishBroadcastChannel;
169
+ publishBroadcastChannelV2;
170
+ baseLogger;
171
+ publish(value) {
172
+ const message = new TopicDataMessage("TopicNext" /* TopicNext */, this.name, this.version, value);
173
+ this.sendMessage(message);
174
+ const resolveMessage = new TopicResolveMessage("TopicResolve" /* TopicResolve */, this.name, this.version, message.id);
175
+ const promise = new Promise((resolve) => {
176
+ this.publishPromiseResolver[message.id] = resolve;
177
+ });
178
+ this.sendMessage(resolveMessage);
179
+ return promise;
180
+ }
181
+ createBroadcastChannel() {
182
+ if (this.publishBroadcastChannel && this.publishBroadcastChannelV2) {
183
+ return;
184
+ }
185
+ if (window["@onecx/accelerator"]?.topic?.useBroadcastChannel) {
186
+ if (typeof BroadcastChannel === "undefined") {
187
+ this.baseLogger.info("BroadcastChannel not supported. Disabling BroadcastChannel for topic publisher");
188
+ window["@onecx/accelerator"] ??= {};
189
+ window["@onecx/accelerator"].topic ??= {};
190
+ window["@onecx/accelerator"].topic.useBroadcastChannel = false;
191
+ } else {
192
+ this.publishBroadcastChannel = new BroadcastChannel(`Topic-${this.name}|${this.version}`);
193
+ this.publishBroadcastChannelV2 = new BroadcastChannel(`TopicV2-${this.name}|${this.version}-${window["@onecx/accelerator"].topic.tabId}`);
194
+ }
195
+ }
196
+ }
197
+ sendMessage(message) {
198
+ this.createBroadcastChannel();
199
+ if (window["@onecx/accelerator"]?.topic?.useBroadcastChannel === "V2") {
200
+ this.publishBroadcastChannelV2?.postMessage(message);
201
+ } else if (window["@onecx/accelerator"]?.topic?.useBroadcastChannel) {
202
+ this.publishBroadcastChannel?.postMessage(message);
203
+ } else {
204
+ window.postMessage(message, "*");
205
+ }
206
+ }
207
+ };
208
+
209
+ // libs/accelerator/src/lib/topic/topic.ts
210
+ var Topic = class extends TopicPublisher {
211
+ logger = createLogger(`Topic:${this.name}`);
212
+ isInitializedPromise;
213
+ data = new import_rxjs.BehaviorSubject(void 0);
214
+ isInit = false;
215
+ resolveInitPromise;
216
+ windowEventListener = (m) => this.onWindowMessage(m);
217
+ readBroadcastChannel;
218
+ readBroadcastChannelV2;
219
+ constructor(name, version, sendGetMessage = true) {
220
+ super(name, version);
221
+ window["@onecx/accelerator"] ??= {};
222
+ window["@onecx/accelerator"].topic ??= {};
223
+ window["@onecx/accelerator"].topic.initDate ??= Date.now();
224
+ if (window["@onecx/accelerator"]?.topic?.useBroadcastChannel) {
225
+ if (typeof BroadcastChannel === "undefined") {
226
+ this.logger.info("BroadcastChannel not supported. Disabling BroadcastChannel for topic");
227
+ window["@onecx/accelerator"] ??= {};
228
+ window["@onecx/accelerator"].topic ??= {};
229
+ window["@onecx/accelerator"].topic.useBroadcastChannel = false;
230
+ } else {
231
+ this.readBroadcastChannel = new BroadcastChannel(`Topic-${this.name}|${this.version}`);
232
+ this.readBroadcastChannelV2 = new BroadcastChannel(`TopicV2-${this.name}|${this.version}-${window["@onecx/accelerator"].topic.tabId}`);
233
+ }
234
+ }
235
+ if (isStatsEnabled()) {
236
+ increaseInstanceCount(this.name);
237
+ }
238
+ this.isInitializedPromise = new Promise((resolve) => {
239
+ this.resolveInitPromise = resolve;
240
+ });
241
+ window.addEventListener("message", this.windowEventListener);
242
+ this.readBroadcastChannel?.addEventListener("message", (m) => this.onBroadcastChannelMessage(m));
243
+ this.readBroadcastChannelV2?.addEventListener("message", (m) => this.onBroadcastChannelMessageV2(m));
244
+ if (sendGetMessage) {
245
+ if (window["@onecx/accelerator"].topic.initDate && Date.now() - window["@onecx/accelerator"].topic.initDate < 2e3) {
246
+ setTimeout(() => {
247
+ if (!this.isInit) {
248
+ const message = new TopicMessage("TopicGet" /* TopicGet */, this.name, this.version);
249
+ this.sendMessage(message);
250
+ }
251
+ }, 100);
252
+ } else {
253
+ const message = new TopicMessage("TopicGet" /* TopicGet */, this.name, this.version);
254
+ this.sendMessage(message);
255
+ }
256
+ }
257
+ }
258
+ get isInitialized() {
259
+ return this.isInitializedPromise;
260
+ }
261
+ asObservable() {
262
+ return this.data.asObservable().pipe(
263
+ (0, import_operators.filter)(() => this.isInit),
264
+ (0, import_operators.map)((d) => d.data)
265
+ );
266
+ }
267
+ subscribe(observerOrNext, error, complete) {
268
+ return this.asObservable().subscribe(observerOrNext, error, complete);
269
+ }
270
+ pipe(...operations) {
271
+ return this.asObservable().pipe(...operations);
272
+ }
273
+ /**
274
+ * @deprecated source is deprecated in rxjs. This is only here to be compatible with the interface.
275
+ */
276
+ get source() {
277
+ return this.asObservable().source;
278
+ }
279
+ /**
280
+ * @deprecated operator is deprecated in rxjs. This is only here to be compatible with the interface.
281
+ */
282
+ get operator() {
283
+ return this.asObservable().operator;
284
+ }
285
+ /**
286
+ * @deprecated lift is deprecated in rxjs. This is only here to be compatible with the interface.
287
+ */
288
+ lift(operator) {
289
+ return this.asObservable().lift(operator);
290
+ }
291
+ /**
292
+ * @deprecated foreach is deprecated in rxjs. This is only here to be compatible with the interface.
293
+ */
294
+ forEach(next, thisArg) {
295
+ return this.asObservable().forEach(next, thisArg);
296
+ }
297
+ /**
298
+ * @deprecated toPromise is deprecated in rxjs. This is only here to be compatible with the interface.
299
+ */
300
+ toPromise() {
301
+ return this.asObservable().toPromise();
302
+ }
303
+ destroy() {
304
+ window.removeEventListener("message", this.windowEventListener, true);
305
+ this.readBroadcastChannel?.close();
306
+ this.publishBroadcastChannel?.close();
307
+ this.readBroadcastChannelV2?.close();
308
+ this.publishBroadcastChannelV2?.close();
309
+ }
310
+ onWindowMessage(m) {
311
+ if (m.data?.name === this.name && m.data?.version === this.version) {
312
+ this.logger.debug("received message via window", m.data);
313
+ }
314
+ switch (m.data.type) {
315
+ case "TopicNext" /* TopicNext */: {
316
+ this.disableBroadcastChannel();
317
+ if (m.data.name === this.name && m.data.version === this.version) {
318
+ this.handleTopicNextMessage(m);
319
+ }
320
+ break;
321
+ }
322
+ case "TopicGet" /* TopicGet */: {
323
+ this.disableBroadcastChannel();
324
+ if (m.data.name === this.name && m.data.version === this.version && this.isInit && this.data.value) {
325
+ this.handleTopicGetMessage(m);
326
+ }
327
+ break;
328
+ }
329
+ case "TopicResolve" /* TopicResolve */: {
330
+ this.disableBroadcastChannel();
331
+ this.handleTopicResolveMessage(m);
332
+ break;
333
+ }
334
+ }
335
+ }
336
+ onBroadcastChannelMessage(m) {
337
+ this.disableBroadcastChannelV2();
338
+ this.onBroadcastChannelMessageV2(m);
339
+ }
340
+ onBroadcastChannelMessageV2(m) {
341
+ this.logger.debug("received message", m.data);
342
+ switch (m.data.type) {
343
+ case "TopicNext" /* TopicNext */: {
344
+ this.handleTopicNextMessage(m);
345
+ break;
346
+ }
347
+ case "TopicGet" /* TopicGet */: {
348
+ if (this.isInit && this.data.value) {
349
+ this.handleTopicGetMessage(m);
350
+ }
351
+ break;
352
+ }
353
+ case "TopicResolve" /* TopicResolve */: {
354
+ this.handleTopicResolveMessage(m);
355
+ break;
356
+ }
357
+ }
358
+ }
359
+ disableBroadcastChannel() {
360
+ window["@onecx/accelerator"] ??= {};
361
+ window["@onecx/accelerator"].topic ??= {};
362
+ if (window["@onecx/accelerator"].topic.useBroadcastChannel === true) {
363
+ this.logger.info("Disabling BroadcastChannel for topic");
364
+ }
365
+ window["@onecx/accelerator"].topic.useBroadcastChannel = false;
366
+ }
367
+ disableBroadcastChannelV2() {
368
+ window["@onecx/accelerator"] ??= {};
369
+ window["@onecx/accelerator"].topic ??= {};
370
+ if (window["@onecx/accelerator"].topic.useBroadcastChannel === "V2") {
371
+ this.logger.info("Disabling BroadcastChannel V2 for topic");
372
+ }
373
+ window["@onecx/accelerator"].topic.useBroadcastChannel = true;
374
+ }
375
+ handleTopicResolveMessage(m) {
376
+ const publishPromiseResolver = this.publishPromiseResolver[m.data.resolveId];
377
+ if (publishPromiseResolver) {
378
+ try {
379
+ publishPromiseResolver();
380
+ m.stopImmediatePropagation();
381
+ m.stopPropagation();
382
+ delete this.publishPromiseResolver[m.data.resolveId];
383
+ } catch (error) {
384
+ this.logger.error("Error handling TopicResolveMessage:", error);
385
+ }
386
+ }
387
+ }
388
+ handleTopicGetMessage(m) {
389
+ if (this.data.value) {
390
+ this.sendMessage(this.data.value);
391
+ m.stopImmediatePropagation();
392
+ m.stopPropagation();
393
+ }
394
+ }
395
+ handleTopicNextMessage(m) {
396
+ if (!this.data.value || this.isInit && m.data.id !== void 0 && this.data.value.id !== void 0 && m.data.id > this.data.value.id || this.isInit && m.data.timestamp > this.data.value.timestamp) {
397
+ this.isInit = true;
398
+ this.data.next(m.data);
399
+ this.resolveInitPromise();
400
+ } else if (this.data.value && this.isInit && m.data.timestamp === this.data.value.timestamp && (m.data.id && !this.data.value.id || !m.data.id && this.data.value.id)) {
401
+ this.logger.warn(
402
+ "Message was dropped because of equal timestamps, because there was an old style message in the system. Please upgrade all libraries to the latest version."
403
+ );
404
+ }
405
+ }
406
+ };
407
+
408
+ // libs/accelerator/src/lib/topic/mocks/fake-topic.ts
409
+ var import_rxjs2 = require("rxjs");
410
+ var FakeTopic = class _FakeTopic {
411
+ state;
412
+ constructor(initialValue = void 0) {
413
+ if (initialValue !== void 0) {
414
+ this.state = new import_rxjs2.BehaviorSubject(initialValue);
415
+ } else {
416
+ this.state = new import_rxjs2.ReplaySubject(1);
417
+ }
418
+ }
419
+ get isInitialized() {
420
+ return Promise.resolve();
421
+ }
422
+ subscribe(observerOrNext, error, complete) {
423
+ return this.asObservable().subscribe(observerOrNext, error, complete);
424
+ }
425
+ /**
426
+ * @deprecated source is deprecated in rxjs. This is only here to be compatible with the interface.
427
+ */
428
+ get source() {
429
+ return this.asObservable().source;
430
+ }
431
+ /**
432
+ * @deprecated operator is deprecated in rxjs. This is only here to be compatible with the interface.
433
+ */
434
+ get operator() {
435
+ return this.asObservable().operator;
436
+ }
437
+ /**
438
+ * @deprecated lift is deprecated in rxjs. This is only here to be compatible with the interface.
439
+ */
440
+ lift(operator) {
441
+ return this.asObservable().lift(operator);
442
+ }
443
+ /**
444
+ * @deprecated foreach is deprecated in rxjs. This is only here to be compatible with the interface.
445
+ */
446
+ forEach(next, thisArg) {
447
+ return this.asObservable().forEach(next, thisArg);
448
+ }
449
+ /**
450
+ * @deprecated toPromise is deprecated in rxjs. This is only here to be compatible with the interface.
451
+ */
452
+ toPromise() {
453
+ return this.asObservable().toPromise();
454
+ }
455
+ // The following are already present: publish, destroy, getValue
456
+ asObservable() {
457
+ return this.state.asObservable();
458
+ }
459
+ pipe(...operations) {
460
+ return this.asObservable().pipe(...operations);
461
+ }
462
+ publish(value) {
463
+ this.state.next(value);
464
+ return Promise.resolve();
465
+ }
466
+ destroy() {
467
+ this.state.complete();
468
+ }
469
+ getValue() {
470
+ if (this.state instanceof import_rxjs2.BehaviorSubject) {
471
+ return this.state.getValue();
472
+ }
473
+ throw new Error("Only possible for FakeTopic with initial value");
474
+ }
475
+ static create(initialValue = void 0) {
476
+ return new _FakeTopic(initialValue);
477
+ }
478
+ };
479
+
480
+ // libs/accelerator/src/lib/topic/mocks/broadcast-channel.mock.ts
481
+ var BroadcastChannelMock = class _BroadcastChannelMock {
482
+ constructor(name) {
483
+ this.name = name;
484
+ }
485
+ static listeners = {};
486
+ // NOSONAR
487
+ static asyncCalls = false;
488
+ // NOSONAR
489
+ listener;
490
+ postMessage(m) {
491
+ if (_BroadcastChannelMock.asyncCalls) {
492
+ setTimeout(() => {
493
+ _BroadcastChannelMock.listeners[this.name]?.forEach((l) => l({ data: m, stopImmediatePropagation: () => {
494
+ }, stopPropagation: () => {
495
+ } }));
496
+ }, 0);
497
+ } else {
498
+ _BroadcastChannelMock.listeners[this.name]?.forEach((l) => l({ data: m, stopImmediatePropagation: () => {
499
+ }, stopPropagation: () => {
500
+ } }));
501
+ }
502
+ }
503
+ addEventListener(event, listener) {
504
+ this.listener = listener;
505
+ _BroadcastChannelMock.listeners[this.name] ??= [];
506
+ _BroadcastChannelMock.listeners[this.name].push(listener);
507
+ }
508
+ close() {
509
+ _BroadcastChannelMock.listeners[this.name] = _BroadcastChannelMock.listeners[this.name].filter((l) => l !== this.listener);
510
+ }
511
+ };
512
+
513
+ // libs/accelerator/src/lib/topic/syncable-topic.ts
514
+ var SyncableTopic = class extends Topic {
515
+ constructor(name, version) {
516
+ super(name, version);
517
+ }
518
+ /**
519
+ * This function does not offer read after write consistency!
520
+ * This means you cannot call it directly after publish, because the new value will not be there yet!
521
+ * This function will return undefined until the isInitialized Promise is resolved.
522
+ * @returns the current value of the Topic in a synchronous way
523
+ */
524
+ getValue() {
525
+ return this.isInit ? this.data.value.data : void 0;
526
+ }
527
+ };
528
+
529
+ // libs/accelerator/src/lib/utils/path.utils.ts
530
+ function getLocation() {
531
+ const baseHref = document.getElementsByTagName("base")[0]?.href ?? window.location.origin + "/";
532
+ const location = window.location;
533
+ location.deploymentPath = baseHref.substring(window.location.origin.length);
534
+ location.applicationPath = window.location.href.substring(baseHref.length - 1);
535
+ return location;
536
+ }
537
+
538
+ // libs/accelerator/src/lib/utils/date.utils.ts
539
+ function isValidDate(value) {
540
+ return value instanceof Date && !isNaN(value);
541
+ }
542
+ function getUTCDateWithoutTimezoneIssues(date) {
543
+ return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0));
544
+ }
545
+
546
+ // libs/accelerator/src/lib/utils/is-test.utils.ts
547
+ function isTest() {
548
+ if (typeof globalThis.jasmine !== "undefined") {
549
+ return true;
550
+ }
551
+ if (typeof process !== "undefined" && process.env?.["JEST_WORKER_ID"] !== void 0) {
552
+ return true;
553
+ }
554
+ return false;
555
+ }
556
+
557
+ // libs/accelerator/src/lib/utils/normalize-locales.utils.ts
558
+ function normalizeLocales(locales) {
559
+ if (!locales || locales.length === 0) return [];
560
+ const expanded = [];
561
+ for (const locale of locales) {
562
+ if (!expanded.includes(locale)) expanded.push(locale);
563
+ const lang = locale.split(/[-_]/)[0];
564
+ if (!expanded.includes(lang) && !locales.includes(lang)) expanded.push(lang);
565
+ }
566
+ return expanded;
567
+ }
568
+
569
+ // libs/accelerator/src/lib/utils/get-normalized-browser-locales.utils.ts
570
+ function getNormalizedBrowserLocales() {
571
+ if (typeof window === "undefined" || typeof window.navigator === "undefined") {
572
+ return ["en"];
573
+ }
574
+ const langs = window.navigator.languages || [window.navigator.language];
575
+ return normalizeLocales(langs.filter(Boolean));
576
+ }
577
+
578
+ // libs/accelerator/src/lib/utils/gatherer.ts
579
+ var Gatherer = class _Gatherer {
580
+ logger;
581
+ static id = 0;
582
+ topic;
583
+ ownIds = /* @__PURE__ */ new Set();
584
+ topicSub = null;
585
+ topicName;
586
+ constructor(name, version, callback) {
587
+ this.topicName = name;
588
+ this.logger = createLogger(`Gatherer:${name}`);
589
+ this.logger.debug(`Gatherer ${name}: ${version} created`);
590
+ this.topic = new Topic(name, version, false);
591
+ this.topicSub = this.topic.subscribe((m) => {
592
+ if (!this.isOwnerOfRequest(m) && window["@onecx/accelerator"]?.gatherer?.promises) {
593
+ this.logReceivedIfDebug(name, version, m);
594
+ if (!window["@onecx/accelerator"].gatherer.promises[m.id]) {
595
+ this.logger.warn("Expected an array of promises to gather for id ", m.id, " but the id was not present");
596
+ return;
597
+ }
598
+ let resolve;
599
+ window["@onecx/accelerator"].gatherer.promises[m.id].push(
600
+ new Promise((r) => {
601
+ resolve = r;
602
+ })
603
+ );
604
+ callback(m.request).then((response) => {
605
+ resolve(response);
606
+ this.logAnsweredIfDebug(name, version, m, response);
607
+ });
608
+ }
609
+ });
610
+ }
611
+ destroy() {
612
+ this.logger.debug(`Gatherer ${this.topic.name}: ${this.topic.version} destroyed`);
613
+ this.topicSub?.unsubscribe();
614
+ this.topic.destroy();
615
+ for (const id of this.ownIds) {
616
+ if (window["@onecx/accelerator"]?.gatherer?.promises?.[id]) {
617
+ delete window["@onecx/accelerator"].gatherer.promises[id];
618
+ }
619
+ }
620
+ }
621
+ async gather(request) {
622
+ if (!window["@onecx/accelerator"]?.gatherer?.promises) {
623
+ throw new Error("Gatherer is not initialized");
624
+ }
625
+ const id = _Gatherer.id++;
626
+ this.ownIds.add(id);
627
+ window["@onecx/accelerator"].gatherer.promises[id] = [];
628
+ const message = { id, request };
629
+ await this.topic.publish(message);
630
+ const promises = window["@onecx/accelerator"].gatherer.promises[id];
631
+ delete window["@onecx/accelerator"].gatherer.promises[id];
632
+ this.ownIds.delete(id);
633
+ return Promise.all(promises).then((v) => {
634
+ this.logger.debug("Finished gathering responses", v);
635
+ return v;
636
+ });
637
+ }
638
+ logReceivedIfDebug(name, version, m) {
639
+ this.logger.debug("Gatherer " + name + ": " + version + " received request " + m.request);
640
+ }
641
+ logAnsweredIfDebug(name, version, m, response) {
642
+ this.logger.debug(
643
+ "Gatherer " + name + ": " + version + " answered request " + m.request + " with response",
644
+ response
645
+ );
646
+ }
647
+ isOwnerOfRequest(m) {
648
+ return this.ownIds.has(m.id);
649
+ }
650
+ };
651
+
652
+ // libs/accelerator/src/lib/utils/ensure-property.utils.ts
653
+ function ensureProperty(obj, path, initialValue) {
654
+ let current = obj;
655
+ for (let i = 0; i < path.length - 1; i++) {
656
+ const key = path[i];
657
+ if (current[key] == null || typeof current[key] !== "object") {
658
+ current[key] = {};
659
+ }
660
+ current = current[key];
661
+ }
662
+ const lastKey = path.at(-1);
663
+ if (lastKey === void 0) {
664
+ return obj;
665
+ }
666
+ current[lastKey] ??= initialValue;
667
+ return obj;
668
+ }
package/dist/index.mjs ADDED
@@ -0,0 +1,637 @@
1
+ // libs/accelerator/src/lib/topic/topic.ts
2
+ import { filter, map } from "rxjs/operators";
3
+ import {
4
+ BehaviorSubject
5
+ } from "rxjs";
6
+
7
+ // libs/accelerator/src/lib/declarations.ts
8
+ window["@onecx/accelerator"] ??= {};
9
+ window["@onecx/accelerator"].gatherer ??= {};
10
+ window["@onecx/accelerator"].gatherer.promises ??= {};
11
+ window["@onecx/accelerator"].topic ??= {};
12
+ window["@onecx/accelerator"].topic.useBroadcastChannel ??= "V2";
13
+ window["@onecx/accelerator"].topic.initDate ??= Date.now();
14
+ window["@onecx/accelerator"].topic.tabId ??= Math.ceil(globalThis.performance.now());
15
+
16
+ // libs/accelerator/src/lib/utils/logs.utils.ts
17
+ function isStatsEnabled() {
18
+ return window["@onecx/accelerator"]?.topic?.statsEnabled === true;
19
+ }
20
+ function increaseMessageCount(topicName, messageType) {
21
+ window["@onecx/accelerator"].topic ??= {};
22
+ window["@onecx/accelerator"].topic.stats ??= {};
23
+ window["@onecx/accelerator"].topic.stats.messagesPublished ??= {};
24
+ if (isStatsEnabled()) {
25
+ const messageStats = window["@onecx/accelerator"].topic.stats.messagesPublished;
26
+ if (!messageStats[topicName]) {
27
+ messageStats[topicName] = {
28
+ TopicNext: 0,
29
+ TopicGet: 0,
30
+ TopicResolve: 0
31
+ };
32
+ }
33
+ messageStats[topicName][messageType]++;
34
+ }
35
+ }
36
+ function increaseInstanceCount(topicName) {
37
+ window["@onecx/accelerator"].topic ??= {};
38
+ window["@onecx/accelerator"].topic.stats ??= {};
39
+ window["@onecx/accelerator"].topic.stats.instancesCreated ??= {};
40
+ if (isStatsEnabled()) {
41
+ const instanceStats = window["@onecx/accelerator"].topic.stats.instancesCreated;
42
+ if (!instanceStats[topicName]) {
43
+ instanceStats[topicName] = 0;
44
+ }
45
+ instanceStats[topicName]++;
46
+ }
47
+ }
48
+
49
+ // libs/accelerator/src/lib/topic/message.ts
50
+ window["onecxMessageId"] ??= 1;
51
+ var Message = class {
52
+ // id can be undefined while used via old implementation
53
+ constructor(type) {
54
+ this.type = type;
55
+ this.timestamp = window.performance.now();
56
+ this.id = window["onecxMessageId"]++;
57
+ }
58
+ timestamp;
59
+ id;
60
+ };
61
+
62
+ // libs/accelerator/src/lib/topic/topic-message.ts
63
+ var TopicMessage = class extends Message {
64
+ constructor(type, name, version) {
65
+ super(type);
66
+ this.name = name;
67
+ this.version = version;
68
+ if (isStatsEnabled()) {
69
+ increaseMessageCount(this.name, type);
70
+ }
71
+ }
72
+ };
73
+
74
+ // libs/accelerator/src/lib/topic/topic-data-message.ts
75
+ var TopicDataMessage = class extends TopicMessage {
76
+ constructor(type, name, version, data) {
77
+ super(type, name, version);
78
+ this.data = data;
79
+ }
80
+ };
81
+
82
+ // libs/accelerator/src/lib/topic/topic-resolve-message.ts
83
+ var TopicResolveMessage = class extends TopicMessage {
84
+ constructor(type, name, version, resolveId) {
85
+ super(type, name, version);
86
+ this.resolveId = resolveId;
87
+ }
88
+ };
89
+
90
+ // libs/accelerator/src/lib/utils/create-logger.utils.ts
91
+ import debug from "debug";
92
+ debug.log = console.log.bind(console);
93
+ function createLoggerFactory(libOrAppName) {
94
+ const prefix = libOrAppName.trim();
95
+ if (!prefix) throw new Error("createLoggerFactory(libOrAppName): libOrAppName must be a non-empty string.");
96
+ const createLogger2 = (location) => {
97
+ const trimmedLocation = location.trim();
98
+ if (!trimmedLocation) throw new Error("createLogger(location): location must be a non-empty string.");
99
+ const ns = (level) => `${prefix}:${trimmedLocation}:${level}`;
100
+ return {
101
+ debug: debug(ns("debug")),
102
+ info: debug(ns("info")),
103
+ warn: debug(ns("warn")),
104
+ error: debug(ns("error"))
105
+ };
106
+ };
107
+ return createLogger2;
108
+ }
109
+
110
+ // libs/accelerator/src/lib/utils/logger.utils.ts
111
+ var createLogger = createLoggerFactory("@onecx/accelerator");
112
+
113
+ // libs/accelerator/src/lib/topic/topic-publisher.ts
114
+ var TopicPublisher = class {
115
+ constructor(name, version) {
116
+ this.name = name;
117
+ this.version = version;
118
+ this.baseLogger = createLogger(`TopicPublisher:${this.name}`);
119
+ }
120
+ publishPromiseResolver = {};
121
+ publishBroadcastChannel;
122
+ publishBroadcastChannelV2;
123
+ baseLogger;
124
+ publish(value) {
125
+ const message = new TopicDataMessage("TopicNext" /* TopicNext */, this.name, this.version, value);
126
+ this.sendMessage(message);
127
+ const resolveMessage = new TopicResolveMessage("TopicResolve" /* TopicResolve */, this.name, this.version, message.id);
128
+ const promise = new Promise((resolve) => {
129
+ this.publishPromiseResolver[message.id] = resolve;
130
+ });
131
+ this.sendMessage(resolveMessage);
132
+ return promise;
133
+ }
134
+ createBroadcastChannel() {
135
+ if (this.publishBroadcastChannel && this.publishBroadcastChannelV2) {
136
+ return;
137
+ }
138
+ if (window["@onecx/accelerator"]?.topic?.useBroadcastChannel) {
139
+ if (typeof BroadcastChannel === "undefined") {
140
+ this.baseLogger.info("BroadcastChannel not supported. Disabling BroadcastChannel for topic publisher");
141
+ window["@onecx/accelerator"] ??= {};
142
+ window["@onecx/accelerator"].topic ??= {};
143
+ window["@onecx/accelerator"].topic.useBroadcastChannel = false;
144
+ } else {
145
+ this.publishBroadcastChannel = new BroadcastChannel(`Topic-${this.name}|${this.version}`);
146
+ this.publishBroadcastChannelV2 = new BroadcastChannel(`TopicV2-${this.name}|${this.version}-${window["@onecx/accelerator"].topic.tabId}`);
147
+ }
148
+ }
149
+ }
150
+ sendMessage(message) {
151
+ this.createBroadcastChannel();
152
+ if (window["@onecx/accelerator"]?.topic?.useBroadcastChannel === "V2") {
153
+ this.publishBroadcastChannelV2?.postMessage(message);
154
+ } else if (window["@onecx/accelerator"]?.topic?.useBroadcastChannel) {
155
+ this.publishBroadcastChannel?.postMessage(message);
156
+ } else {
157
+ window.postMessage(message, "*");
158
+ }
159
+ }
160
+ };
161
+
162
+ // libs/accelerator/src/lib/topic/topic.ts
163
+ var Topic = class extends TopicPublisher {
164
+ logger = createLogger(`Topic:${this.name}`);
165
+ isInitializedPromise;
166
+ data = new BehaviorSubject(void 0);
167
+ isInit = false;
168
+ resolveInitPromise;
169
+ windowEventListener = (m) => this.onWindowMessage(m);
170
+ readBroadcastChannel;
171
+ readBroadcastChannelV2;
172
+ constructor(name, version, sendGetMessage = true) {
173
+ super(name, version);
174
+ window["@onecx/accelerator"] ??= {};
175
+ window["@onecx/accelerator"].topic ??= {};
176
+ window["@onecx/accelerator"].topic.initDate ??= Date.now();
177
+ if (window["@onecx/accelerator"]?.topic?.useBroadcastChannel) {
178
+ if (typeof BroadcastChannel === "undefined") {
179
+ this.logger.info("BroadcastChannel not supported. Disabling BroadcastChannel for topic");
180
+ window["@onecx/accelerator"] ??= {};
181
+ window["@onecx/accelerator"].topic ??= {};
182
+ window["@onecx/accelerator"].topic.useBroadcastChannel = false;
183
+ } else {
184
+ this.readBroadcastChannel = new BroadcastChannel(`Topic-${this.name}|${this.version}`);
185
+ this.readBroadcastChannelV2 = new BroadcastChannel(`TopicV2-${this.name}|${this.version}-${window["@onecx/accelerator"].topic.tabId}`);
186
+ }
187
+ }
188
+ if (isStatsEnabled()) {
189
+ increaseInstanceCount(this.name);
190
+ }
191
+ this.isInitializedPromise = new Promise((resolve) => {
192
+ this.resolveInitPromise = resolve;
193
+ });
194
+ window.addEventListener("message", this.windowEventListener);
195
+ this.readBroadcastChannel?.addEventListener("message", (m) => this.onBroadcastChannelMessage(m));
196
+ this.readBroadcastChannelV2?.addEventListener("message", (m) => this.onBroadcastChannelMessageV2(m));
197
+ if (sendGetMessage) {
198
+ if (window["@onecx/accelerator"].topic.initDate && Date.now() - window["@onecx/accelerator"].topic.initDate < 2e3) {
199
+ setTimeout(() => {
200
+ if (!this.isInit) {
201
+ const message = new TopicMessage("TopicGet" /* TopicGet */, this.name, this.version);
202
+ this.sendMessage(message);
203
+ }
204
+ }, 100);
205
+ } else {
206
+ const message = new TopicMessage("TopicGet" /* TopicGet */, this.name, this.version);
207
+ this.sendMessage(message);
208
+ }
209
+ }
210
+ }
211
+ get isInitialized() {
212
+ return this.isInitializedPromise;
213
+ }
214
+ asObservable() {
215
+ return this.data.asObservable().pipe(
216
+ filter(() => this.isInit),
217
+ map((d) => d.data)
218
+ );
219
+ }
220
+ subscribe(observerOrNext, error, complete) {
221
+ return this.asObservable().subscribe(observerOrNext, error, complete);
222
+ }
223
+ pipe(...operations) {
224
+ return this.asObservable().pipe(...operations);
225
+ }
226
+ /**
227
+ * @deprecated source is deprecated in rxjs. This is only here to be compatible with the interface.
228
+ */
229
+ get source() {
230
+ return this.asObservable().source;
231
+ }
232
+ /**
233
+ * @deprecated operator is deprecated in rxjs. This is only here to be compatible with the interface.
234
+ */
235
+ get operator() {
236
+ return this.asObservable().operator;
237
+ }
238
+ /**
239
+ * @deprecated lift is deprecated in rxjs. This is only here to be compatible with the interface.
240
+ */
241
+ lift(operator) {
242
+ return this.asObservable().lift(operator);
243
+ }
244
+ /**
245
+ * @deprecated foreach is deprecated in rxjs. This is only here to be compatible with the interface.
246
+ */
247
+ forEach(next, thisArg) {
248
+ return this.asObservable().forEach(next, thisArg);
249
+ }
250
+ /**
251
+ * @deprecated toPromise is deprecated in rxjs. This is only here to be compatible with the interface.
252
+ */
253
+ toPromise() {
254
+ return this.asObservable().toPromise();
255
+ }
256
+ destroy() {
257
+ window.removeEventListener("message", this.windowEventListener, true);
258
+ this.readBroadcastChannel?.close();
259
+ this.publishBroadcastChannel?.close();
260
+ this.readBroadcastChannelV2?.close();
261
+ this.publishBroadcastChannelV2?.close();
262
+ }
263
+ onWindowMessage(m) {
264
+ if (m.data?.name === this.name && m.data?.version === this.version) {
265
+ this.logger.debug("received message via window", m.data);
266
+ }
267
+ switch (m.data.type) {
268
+ case "TopicNext" /* TopicNext */: {
269
+ this.disableBroadcastChannel();
270
+ if (m.data.name === this.name && m.data.version === this.version) {
271
+ this.handleTopicNextMessage(m);
272
+ }
273
+ break;
274
+ }
275
+ case "TopicGet" /* TopicGet */: {
276
+ this.disableBroadcastChannel();
277
+ if (m.data.name === this.name && m.data.version === this.version && this.isInit && this.data.value) {
278
+ this.handleTopicGetMessage(m);
279
+ }
280
+ break;
281
+ }
282
+ case "TopicResolve" /* TopicResolve */: {
283
+ this.disableBroadcastChannel();
284
+ this.handleTopicResolveMessage(m);
285
+ break;
286
+ }
287
+ }
288
+ }
289
+ onBroadcastChannelMessage(m) {
290
+ this.disableBroadcastChannelV2();
291
+ this.onBroadcastChannelMessageV2(m);
292
+ }
293
+ onBroadcastChannelMessageV2(m) {
294
+ this.logger.debug("received message", m.data);
295
+ switch (m.data.type) {
296
+ case "TopicNext" /* TopicNext */: {
297
+ this.handleTopicNextMessage(m);
298
+ break;
299
+ }
300
+ case "TopicGet" /* TopicGet */: {
301
+ if (this.isInit && this.data.value) {
302
+ this.handleTopicGetMessage(m);
303
+ }
304
+ break;
305
+ }
306
+ case "TopicResolve" /* TopicResolve */: {
307
+ this.handleTopicResolveMessage(m);
308
+ break;
309
+ }
310
+ }
311
+ }
312
+ disableBroadcastChannel() {
313
+ window["@onecx/accelerator"] ??= {};
314
+ window["@onecx/accelerator"].topic ??= {};
315
+ if (window["@onecx/accelerator"].topic.useBroadcastChannel === true) {
316
+ this.logger.info("Disabling BroadcastChannel for topic");
317
+ }
318
+ window["@onecx/accelerator"].topic.useBroadcastChannel = false;
319
+ }
320
+ disableBroadcastChannelV2() {
321
+ window["@onecx/accelerator"] ??= {};
322
+ window["@onecx/accelerator"].topic ??= {};
323
+ if (window["@onecx/accelerator"].topic.useBroadcastChannel === "V2") {
324
+ this.logger.info("Disabling BroadcastChannel V2 for topic");
325
+ }
326
+ window["@onecx/accelerator"].topic.useBroadcastChannel = true;
327
+ }
328
+ handleTopicResolveMessage(m) {
329
+ const publishPromiseResolver = this.publishPromiseResolver[m.data.resolveId];
330
+ if (publishPromiseResolver) {
331
+ try {
332
+ publishPromiseResolver();
333
+ m.stopImmediatePropagation();
334
+ m.stopPropagation();
335
+ delete this.publishPromiseResolver[m.data.resolveId];
336
+ } catch (error) {
337
+ this.logger.error("Error handling TopicResolveMessage:", error);
338
+ }
339
+ }
340
+ }
341
+ handleTopicGetMessage(m) {
342
+ if (this.data.value) {
343
+ this.sendMessage(this.data.value);
344
+ m.stopImmediatePropagation();
345
+ m.stopPropagation();
346
+ }
347
+ }
348
+ handleTopicNextMessage(m) {
349
+ if (!this.data.value || this.isInit && m.data.id !== void 0 && this.data.value.id !== void 0 && m.data.id > this.data.value.id || this.isInit && m.data.timestamp > this.data.value.timestamp) {
350
+ this.isInit = true;
351
+ this.data.next(m.data);
352
+ this.resolveInitPromise();
353
+ } else if (this.data.value && this.isInit && m.data.timestamp === this.data.value.timestamp && (m.data.id && !this.data.value.id || !m.data.id && this.data.value.id)) {
354
+ this.logger.warn(
355
+ "Message was dropped because of equal timestamps, because there was an old style message in the system. Please upgrade all libraries to the latest version."
356
+ );
357
+ }
358
+ }
359
+ };
360
+
361
+ // libs/accelerator/src/lib/topic/mocks/fake-topic.ts
362
+ import { BehaviorSubject as BehaviorSubject2, ReplaySubject } from "rxjs";
363
+ var FakeTopic = class _FakeTopic {
364
+ state;
365
+ constructor(initialValue = void 0) {
366
+ if (initialValue !== void 0) {
367
+ this.state = new BehaviorSubject2(initialValue);
368
+ } else {
369
+ this.state = new ReplaySubject(1);
370
+ }
371
+ }
372
+ get isInitialized() {
373
+ return Promise.resolve();
374
+ }
375
+ subscribe(observerOrNext, error, complete) {
376
+ return this.asObservable().subscribe(observerOrNext, error, complete);
377
+ }
378
+ /**
379
+ * @deprecated source is deprecated in rxjs. This is only here to be compatible with the interface.
380
+ */
381
+ get source() {
382
+ return this.asObservable().source;
383
+ }
384
+ /**
385
+ * @deprecated operator is deprecated in rxjs. This is only here to be compatible with the interface.
386
+ */
387
+ get operator() {
388
+ return this.asObservable().operator;
389
+ }
390
+ /**
391
+ * @deprecated lift is deprecated in rxjs. This is only here to be compatible with the interface.
392
+ */
393
+ lift(operator) {
394
+ return this.asObservable().lift(operator);
395
+ }
396
+ /**
397
+ * @deprecated foreach is deprecated in rxjs. This is only here to be compatible with the interface.
398
+ */
399
+ forEach(next, thisArg) {
400
+ return this.asObservable().forEach(next, thisArg);
401
+ }
402
+ /**
403
+ * @deprecated toPromise is deprecated in rxjs. This is only here to be compatible with the interface.
404
+ */
405
+ toPromise() {
406
+ return this.asObservable().toPromise();
407
+ }
408
+ // The following are already present: publish, destroy, getValue
409
+ asObservable() {
410
+ return this.state.asObservable();
411
+ }
412
+ pipe(...operations) {
413
+ return this.asObservable().pipe(...operations);
414
+ }
415
+ publish(value) {
416
+ this.state.next(value);
417
+ return Promise.resolve();
418
+ }
419
+ destroy() {
420
+ this.state.complete();
421
+ }
422
+ getValue() {
423
+ if (this.state instanceof BehaviorSubject2) {
424
+ return this.state.getValue();
425
+ }
426
+ throw new Error("Only possible for FakeTopic with initial value");
427
+ }
428
+ static create(initialValue = void 0) {
429
+ return new _FakeTopic(initialValue);
430
+ }
431
+ };
432
+
433
+ // libs/accelerator/src/lib/topic/mocks/broadcast-channel.mock.ts
434
+ var BroadcastChannelMock = class _BroadcastChannelMock {
435
+ constructor(name) {
436
+ this.name = name;
437
+ }
438
+ static listeners = {};
439
+ // NOSONAR
440
+ static asyncCalls = false;
441
+ // NOSONAR
442
+ listener;
443
+ postMessage(m) {
444
+ if (_BroadcastChannelMock.asyncCalls) {
445
+ setTimeout(() => {
446
+ _BroadcastChannelMock.listeners[this.name]?.forEach((l) => l({ data: m, stopImmediatePropagation: () => {
447
+ }, stopPropagation: () => {
448
+ } }));
449
+ }, 0);
450
+ } else {
451
+ _BroadcastChannelMock.listeners[this.name]?.forEach((l) => l({ data: m, stopImmediatePropagation: () => {
452
+ }, stopPropagation: () => {
453
+ } }));
454
+ }
455
+ }
456
+ addEventListener(event, listener) {
457
+ this.listener = listener;
458
+ _BroadcastChannelMock.listeners[this.name] ??= [];
459
+ _BroadcastChannelMock.listeners[this.name].push(listener);
460
+ }
461
+ close() {
462
+ _BroadcastChannelMock.listeners[this.name] = _BroadcastChannelMock.listeners[this.name].filter((l) => l !== this.listener);
463
+ }
464
+ };
465
+
466
+ // libs/accelerator/src/lib/topic/syncable-topic.ts
467
+ var SyncableTopic = class extends Topic {
468
+ constructor(name, version) {
469
+ super(name, version);
470
+ }
471
+ /**
472
+ * This function does not offer read after write consistency!
473
+ * This means you cannot call it directly after publish, because the new value will not be there yet!
474
+ * This function will return undefined until the isInitialized Promise is resolved.
475
+ * @returns the current value of the Topic in a synchronous way
476
+ */
477
+ getValue() {
478
+ return this.isInit ? this.data.value.data : void 0;
479
+ }
480
+ };
481
+
482
+ // libs/accelerator/src/lib/utils/path.utils.ts
483
+ function getLocation() {
484
+ const baseHref = document.getElementsByTagName("base")[0]?.href ?? window.location.origin + "/";
485
+ const location = window.location;
486
+ location.deploymentPath = baseHref.substring(window.location.origin.length);
487
+ location.applicationPath = window.location.href.substring(baseHref.length - 1);
488
+ return location;
489
+ }
490
+
491
+ // libs/accelerator/src/lib/utils/date.utils.ts
492
+ function isValidDate(value) {
493
+ return value instanceof Date && !isNaN(value);
494
+ }
495
+ function getUTCDateWithoutTimezoneIssues(date) {
496
+ return new Date(Date.UTC(date.getFullYear(), date.getMonth(), date.getDate(), 0, 0, 0));
497
+ }
498
+
499
+ // libs/accelerator/src/lib/utils/is-test.utils.ts
500
+ function isTest() {
501
+ if (typeof globalThis.jasmine !== "undefined") {
502
+ return true;
503
+ }
504
+ if (typeof process !== "undefined" && process.env?.["JEST_WORKER_ID"] !== void 0) {
505
+ return true;
506
+ }
507
+ return false;
508
+ }
509
+
510
+ // libs/accelerator/src/lib/utils/normalize-locales.utils.ts
511
+ function normalizeLocales(locales) {
512
+ if (!locales || locales.length === 0) return [];
513
+ const expanded = [];
514
+ for (const locale of locales) {
515
+ if (!expanded.includes(locale)) expanded.push(locale);
516
+ const lang = locale.split(/[-_]/)[0];
517
+ if (!expanded.includes(lang) && !locales.includes(lang)) expanded.push(lang);
518
+ }
519
+ return expanded;
520
+ }
521
+
522
+ // libs/accelerator/src/lib/utils/get-normalized-browser-locales.utils.ts
523
+ function getNormalizedBrowserLocales() {
524
+ if (typeof window === "undefined" || typeof window.navigator === "undefined") {
525
+ return ["en"];
526
+ }
527
+ const langs = window.navigator.languages || [window.navigator.language];
528
+ return normalizeLocales(langs.filter(Boolean));
529
+ }
530
+
531
+ // libs/accelerator/src/lib/utils/gatherer.ts
532
+ var Gatherer = class _Gatherer {
533
+ logger;
534
+ static id = 0;
535
+ topic;
536
+ ownIds = /* @__PURE__ */ new Set();
537
+ topicSub = null;
538
+ topicName;
539
+ constructor(name, version, callback) {
540
+ this.topicName = name;
541
+ this.logger = createLogger(`Gatherer:${name}`);
542
+ this.logger.debug(`Gatherer ${name}: ${version} created`);
543
+ this.topic = new Topic(name, version, false);
544
+ this.topicSub = this.topic.subscribe((m) => {
545
+ if (!this.isOwnerOfRequest(m) && window["@onecx/accelerator"]?.gatherer?.promises) {
546
+ this.logReceivedIfDebug(name, version, m);
547
+ if (!window["@onecx/accelerator"].gatherer.promises[m.id]) {
548
+ this.logger.warn("Expected an array of promises to gather for id ", m.id, " but the id was not present");
549
+ return;
550
+ }
551
+ let resolve;
552
+ window["@onecx/accelerator"].gatherer.promises[m.id].push(
553
+ new Promise((r) => {
554
+ resolve = r;
555
+ })
556
+ );
557
+ callback(m.request).then((response) => {
558
+ resolve(response);
559
+ this.logAnsweredIfDebug(name, version, m, response);
560
+ });
561
+ }
562
+ });
563
+ }
564
+ destroy() {
565
+ this.logger.debug(`Gatherer ${this.topic.name}: ${this.topic.version} destroyed`);
566
+ this.topicSub?.unsubscribe();
567
+ this.topic.destroy();
568
+ for (const id of this.ownIds) {
569
+ if (window["@onecx/accelerator"]?.gatherer?.promises?.[id]) {
570
+ delete window["@onecx/accelerator"].gatherer.promises[id];
571
+ }
572
+ }
573
+ }
574
+ async gather(request) {
575
+ if (!window["@onecx/accelerator"]?.gatherer?.promises) {
576
+ throw new Error("Gatherer is not initialized");
577
+ }
578
+ const id = _Gatherer.id++;
579
+ this.ownIds.add(id);
580
+ window["@onecx/accelerator"].gatherer.promises[id] = [];
581
+ const message = { id, request };
582
+ await this.topic.publish(message);
583
+ const promises = window["@onecx/accelerator"].gatherer.promises[id];
584
+ delete window["@onecx/accelerator"].gatherer.promises[id];
585
+ this.ownIds.delete(id);
586
+ return Promise.all(promises).then((v) => {
587
+ this.logger.debug("Finished gathering responses", v);
588
+ return v;
589
+ });
590
+ }
591
+ logReceivedIfDebug(name, version, m) {
592
+ this.logger.debug("Gatherer " + name + ": " + version + " received request " + m.request);
593
+ }
594
+ logAnsweredIfDebug(name, version, m, response) {
595
+ this.logger.debug(
596
+ "Gatherer " + name + ": " + version + " answered request " + m.request + " with response",
597
+ response
598
+ );
599
+ }
600
+ isOwnerOfRequest(m) {
601
+ return this.ownIds.has(m.id);
602
+ }
603
+ };
604
+
605
+ // libs/accelerator/src/lib/utils/ensure-property.utils.ts
606
+ function ensureProperty(obj, path, initialValue) {
607
+ let current = obj;
608
+ for (let i = 0; i < path.length - 1; i++) {
609
+ const key = path[i];
610
+ if (current[key] == null || typeof current[key] !== "object") {
611
+ current[key] = {};
612
+ }
613
+ current = current[key];
614
+ }
615
+ const lastKey = path.at(-1);
616
+ if (lastKey === void 0) {
617
+ return obj;
618
+ }
619
+ current[lastKey] ??= initialValue;
620
+ return obj;
621
+ }
622
+ export {
623
+ BroadcastChannelMock,
624
+ FakeTopic,
625
+ Gatherer,
626
+ SyncableTopic,
627
+ Topic,
628
+ TopicPublisher,
629
+ createLoggerFactory,
630
+ ensureProperty,
631
+ getLocation,
632
+ getNormalizedBrowserLocales,
633
+ getUTCDateWithoutTimezoneIssues,
634
+ isTest,
635
+ isValidDate,
636
+ normalizeLocales
637
+ };
package/package.json CHANGED
@@ -1,26 +1,35 @@
1
1
  {
2
2
  "name": "@onecx/accelerator",
3
- "version": "8.0.0-rc.6",
3
+ "version": "8.0.0-rc.8",
4
4
  "license": "Apache-2.0",
5
5
  "repository": {
6
6
  "type": "git",
7
7
  "url": "https://github.com/onecx/onecx-portal-ui-libs"
8
8
  },
9
9
  "peerDependencies": {
10
- "tslib": "^2.6.3",
11
10
  "rxjs": "^7.8.1",
12
11
  "@nx/devkit": "^22.0.2",
13
- "@onecx/nx-migration-utils": "^8.0.0-rc.6",
12
+ "@onecx/nx-migration-utils": "^8.0.0-rc.8",
14
13
  "debug": "^4.4.3"
15
14
  },
16
- "type": "commonjs",
17
- "main": "./src/index.js",
15
+ "type": "module",
16
+ "main": "./dist/index.cjs",
17
+ "module": "./dist/index.mjs",
18
+ "types": "./src/index.d.ts",
18
19
  "typings": "./src/index.d.ts",
20
+ "exports": {
21
+ ".": {
22
+ "types": "./src/index.d.ts",
23
+ "import": "./dist/index.mjs",
24
+ "require": "./dist/index.cjs",
25
+ "default": "./dist/index.mjs"
26
+ },
27
+ "./package.json": "./package.json"
28
+ },
19
29
  "publishConfig": {
20
30
  "access": "public"
21
31
  },
22
32
  "nx-migrations": {
23
33
  "migrations": "./migrations.json"
24
- },
25
- "types": "./src/index.d.ts"
26
- }
34
+ }
35
+ }
package/src/version.d.ts CHANGED
@@ -1,2 +1,2 @@
1
1
  export declare const LIB_NAME = "@onecx/accelerator";
2
- export declare const LIB_VERSION = "8.0.0-rc.6";
2
+ export declare const LIB_VERSION = "8.0.0-rc.8";
package/src/version.js CHANGED
@@ -1,3 +1,3 @@
1
1
  export const LIB_NAME = '@onecx/accelerator';
2
- export const LIB_VERSION = '8.0.0-rc.6';
2
+ export const LIB_VERSION = '8.0.0-rc.8';
3
3
  //# sourceMappingURL=version.js.map