@configura/web-api 2.0.0-alpha.14 → 2.0.0-alpha.17
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/CatalogueAPI.d.ts +16 -16
- package/dist/CfgProduct.d.ts +57 -6
- package/dist/CfgProduct.js +74 -16
- package/dist/ConfigurationConverter.d.ts +7 -7
- package/dist/ConfigurationConverter.js +25 -25
- package/dist/io/CfgHistoryManager.d.ts +33 -1
- package/dist/io/CfgHistoryManager.js +74 -6
- package/dist/io/CfgHistoryToProdConfConnector.d.ts +7 -8
- package/dist/io/CfgHistoryToProdConfConnector.js +25 -12
- package/dist/io/CfgIOManager.d.ts +5 -0
- package/dist/io/CfgIOManager.js +20 -1
- package/dist/io/CfgIOProdConfConnector.d.ts +13 -12
- package/dist/io/CfgIOProdConfConnector.js +32 -17
- package/dist/io/CfgIOWarningSupplier.d.ts +4 -0
- package/dist/io/CfgIOWarningSupplier.js +1 -0
- package/dist/io/CfgObservableStateToProdConfConnector.d.ts +3 -4
- package/dist/io/CfgObservableStateToProdConfConnector.js +2 -3
- package/dist/io/CfgWindowMessageManager.js +4 -0
- package/dist/io/CfgWindowMessageToProdConfConnector.d.ts +3 -4
- package/dist/io/CfgWindowMessageToProdConfConnector.js +2 -3
- package/dist/productConfiguration/CfgFeature.d.ts +2 -2
- package/dist/productConfiguration/CfgFeature.js +8 -2
- package/dist/productConfiguration/CfgOption.d.ts +2 -2
- package/dist/productConfiguration/CfgOption.js +8 -2
- package/dist/productConfiguration/CfgProductConfiguration.d.ts +11 -8
- package/dist/productConfiguration/CfgProductConfiguration.js +16 -10
- package/dist/tasks/TaskHandler.js +2 -1
- package/package.json +3 -3
|
@@ -1,6 +1,22 @@
|
|
|
1
|
-
import { mapQueryString, unmapQueryString } from "@configura/web-utilities";
|
|
1
|
+
import { mapQueryString, Observable, unmapQueryString } from "@configura/web-utilities";
|
|
2
2
|
import { CfgIOManager } from "./CfgIOManager.js";
|
|
3
3
|
import { CfgWindowEventManager } from "./CfgWindowEventManager.js";
|
|
4
|
+
/**
|
|
5
|
+
* How the history is updated.
|
|
6
|
+
* @param DoNotWrite Only listens to initial URL-values.
|
|
7
|
+
* @param Replace Replaces the current history frame at updates.
|
|
8
|
+
* @param Push Adds history frames at updates.
|
|
9
|
+
* @param ReplaceAndUpdateUrl Replaces the current history frame at updates and updates the browser URL
|
|
10
|
+
* @param PushAndUpdateUrl Adds history frames at updates and updates the browser URL
|
|
11
|
+
*/
|
|
12
|
+
export var HistoryMode;
|
|
13
|
+
(function (HistoryMode) {
|
|
14
|
+
HistoryMode[HistoryMode["DoNotWrite"] = 0] = "DoNotWrite";
|
|
15
|
+
HistoryMode[HistoryMode["Replace"] = 1] = "Replace";
|
|
16
|
+
HistoryMode[HistoryMode["Push"] = 2] = "Push";
|
|
17
|
+
HistoryMode[HistoryMode["ReplaceAndUpdateUrl"] = 3] = "ReplaceAndUpdateUrl";
|
|
18
|
+
HistoryMode[HistoryMode["PushAndUpdateUrl"] = 4] = "PushAndUpdateUrl";
|
|
19
|
+
})(HistoryMode || (HistoryMode = {}));
|
|
4
20
|
/**
|
|
5
21
|
* This class is used to coordinate writing and reading to the browser history.
|
|
6
22
|
* It handles messages sent from the connectors.
|
|
@@ -8,6 +24,8 @@ import { CfgWindowEventManager } from "./CfgWindowEventManager.js";
|
|
|
8
24
|
export class CfgHistoryManager extends CfgWindowEventManager {
|
|
9
25
|
constructor() {
|
|
10
26
|
super();
|
|
27
|
+
this._aggregatedQsKeyValues = new Map();
|
|
28
|
+
this._urlUpdateObservable = new Observable();
|
|
11
29
|
this.eventType = "popstate";
|
|
12
30
|
}
|
|
13
31
|
static get instance() {
|
|
@@ -16,22 +34,62 @@ export class CfgHistoryManager extends CfgWindowEventManager {
|
|
|
16
34
|
}
|
|
17
35
|
return this._instance;
|
|
18
36
|
}
|
|
37
|
+
/**
|
|
38
|
+
* @returns The current browser URL updated with the latest updates from
|
|
39
|
+
* the Connectors.
|
|
40
|
+
*/
|
|
41
|
+
getUrl() {
|
|
42
|
+
return CfgHistoryManager._makeUpdatedUrl(this._aggregatedQsKeyValues);
|
|
43
|
+
}
|
|
44
|
+
/**
|
|
45
|
+
* Listen for updated URL:s. This doesn't have to mean the URL in the
|
|
46
|
+
* browser has been updated.
|
|
47
|
+
*/
|
|
48
|
+
listenForUrl(listener) {
|
|
49
|
+
this._urlUpdateObservable.listen(listener);
|
|
50
|
+
}
|
|
51
|
+
/**
|
|
52
|
+
* Stop listen.
|
|
53
|
+
*/
|
|
54
|
+
stopListenForUrl(listener) {
|
|
55
|
+
this._urlUpdateObservable.stopListen(listener);
|
|
56
|
+
}
|
|
19
57
|
/**
|
|
20
58
|
* Write to the history
|
|
21
59
|
*/
|
|
22
60
|
send(messageKey, data) {
|
|
23
|
-
const { qsKeyValues, message,
|
|
61
|
+
const { qsKeyValues, message, mode } = data;
|
|
62
|
+
const warnings = this.getWarnings();
|
|
63
|
+
if (warnings.length !== 0) {
|
|
64
|
+
console.warn("History updating blocked by warnings");
|
|
65
|
+
warnings.forEach((w) => console.warn(w));
|
|
66
|
+
return;
|
|
67
|
+
}
|
|
68
|
+
for (const keyValue of qsKeyValues) {
|
|
69
|
+
this._aggregatedQsKeyValues.set(keyValue[0], keyValue[1]);
|
|
70
|
+
}
|
|
71
|
+
this._urlUpdateObservable.notifyAll(this.getUrl());
|
|
72
|
+
if (mode === HistoryMode.DoNotWrite) {
|
|
73
|
+
return;
|
|
74
|
+
}
|
|
24
75
|
// Initial data is before user interaction has happened
|
|
25
76
|
const initial = message.initial;
|
|
77
|
+
const url = CfgHistoryManager._makeUpdatedUrl(qsKeyValues);
|
|
26
78
|
// At initial we do not replace the URL as we presumable have the defaults
|
|
27
|
-
const
|
|
79
|
+
const writeUrl = initial ||
|
|
80
|
+
!(mode === HistoryMode.PushAndUpdateUrl || mode === HistoryMode.ReplaceAndUpdateUrl)
|
|
81
|
+
? null
|
|
82
|
+
: url;
|
|
28
83
|
// ...but we do replace the state so that we can in the future browse back to here
|
|
29
84
|
const newState = CfgHistoryManager._makeUpdatedState(window.history.state, message, messageKey);
|
|
30
|
-
if (initial ||
|
|
31
|
-
|
|
85
|
+
if (initial ||
|
|
86
|
+
mode === HistoryMode.Replace ||
|
|
87
|
+
mode === HistoryMode.ReplaceAndUpdateUrl ||
|
|
88
|
+
this.receiveInProgress) {
|
|
89
|
+
window.history.replaceState(newState, "", writeUrl);
|
|
32
90
|
}
|
|
33
91
|
else {
|
|
34
|
-
window.history.pushState(newState, "",
|
|
92
|
+
window.history.pushState(newState, "", writeUrl);
|
|
35
93
|
}
|
|
36
94
|
}
|
|
37
95
|
/**
|
|
@@ -79,4 +137,14 @@ export class CfgHistoryManager extends CfgWindowEventManager {
|
|
|
79
137
|
getDataFromEvent(event) {
|
|
80
138
|
return event.state;
|
|
81
139
|
}
|
|
140
|
+
static getMessageFromCurrentHistoryState(messageKey) {
|
|
141
|
+
const state = window.history.state;
|
|
142
|
+
if (!CfgIOManager.isIOContainer(state)) {
|
|
143
|
+
return undefined;
|
|
144
|
+
}
|
|
145
|
+
if (!CfgIOManager.hasIOContainerMessageKey(state, messageKey)) {
|
|
146
|
+
return undefined;
|
|
147
|
+
}
|
|
148
|
+
return CfgIOManager.getMessageFromIOContainer(state, messageKey);
|
|
149
|
+
}
|
|
82
150
|
}
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import { CfgHistoryManager, CfgHistoryManagerSendData } from "./CfgHistoryManager.js";
|
|
1
|
+
import { DtoProductConf } from "../CatalogueAPI.js";
|
|
2
|
+
import { CfgHistoryManager, CfgHistoryManagerSendData, HistoryMode } from "./CfgHistoryManager.js";
|
|
3
3
|
import { CfgIOProdConfConnector, CfgProdConfMessage } from "./CfgIOProdConfConnector.js";
|
|
4
4
|
/**
|
|
5
5
|
* Instantiating this will make the browser history (and URL) update with the product configuration.
|
|
6
6
|
*/
|
|
7
7
|
export declare class CfgHistoryToProdConfConnector extends CfgIOProdConfConnector<CfgHistoryManagerSendData<CfgProdConfMessage>> {
|
|
8
|
-
private readonly
|
|
8
|
+
private readonly _mode;
|
|
9
9
|
private readonly _qsKey;
|
|
10
10
|
/**
|
|
11
|
-
* @param
|
|
11
|
+
* @param _mode
|
|
12
12
|
* @param _qsKey The Query String key for product configuration.
|
|
13
|
-
* @param doValidate When popping from the history stack (navigating in the browser), should a navigate call be sent to the server to verify that the product configuration is still valid?
|
|
14
13
|
*/
|
|
15
|
-
constructor(manager: CfgHistoryManager,
|
|
16
|
-
protected getInitialProdConf():
|
|
17
|
-
protected makeSendData(conf:
|
|
14
|
+
constructor(manager: CfgHistoryManager, _mode: HistoryMode, _qsKey?: string);
|
|
15
|
+
protected getInitialProdConf(): DtoProductConf | undefined;
|
|
16
|
+
protected makeSendData(conf: DtoProductConf, initial: boolean): CfgHistoryManagerSendData<CfgProdConfMessage>;
|
|
18
17
|
}
|
|
19
18
|
//# sourceMappingURL=CfgHistoryToProdConfConnector.d.ts.map
|
|
@@ -1,26 +1,39 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { augmentErrorMessage } from "@configura/web-utilities";
|
|
2
|
+
import { compactStringToDtoProductConf, dtoProductConfigurationToCompactString, } from "../ConfigurationConverter.js";
|
|
2
3
|
import { CfgHistoryManager } from "./CfgHistoryManager.js";
|
|
3
|
-
import { CfgIOProdConfConnector, CfgProdConfMessageVersions, STAGE_PROD_CONF_MESSAGE_KEY, } from "./CfgIOProdConfConnector.js";
|
|
4
|
+
import { CfgIOProdConfConnector, CfgProdConfMessageVersions, getHighestVersionProdConfMessage, isCfgProdConfMessageV2, STAGE_PROD_CONF_MESSAGE_KEY, } from "./CfgIOProdConfConnector.js";
|
|
4
5
|
/**
|
|
5
6
|
* Instantiating this will make the browser history (and URL) update with the product configuration.
|
|
6
7
|
*/
|
|
7
8
|
export class CfgHistoryToProdConfConnector extends CfgIOProdConfConnector {
|
|
8
9
|
/**
|
|
9
|
-
* @param
|
|
10
|
+
* @param _mode
|
|
10
11
|
* @param _qsKey The Query String key for product configuration.
|
|
11
|
-
* @param doValidate When popping from the history stack (navigating in the browser), should a navigate call be sent to the server to verify that the product configuration is still valid?
|
|
12
12
|
*/
|
|
13
|
-
constructor(manager,
|
|
14
|
-
super(manager,
|
|
15
|
-
this.
|
|
13
|
+
constructor(manager, _mode, _qsKey = STAGE_PROD_CONF_MESSAGE_KEY) {
|
|
14
|
+
super(manager, false, false);
|
|
15
|
+
this._mode = _mode;
|
|
16
16
|
this._qsKey = _qsKey;
|
|
17
17
|
}
|
|
18
18
|
getInitialProdConf() {
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
19
|
+
// First try to use the state, if that doesn't work use the query string
|
|
20
|
+
const initialMessage = CfgHistoryManager.getMessageFromCurrentHistoryState(STAGE_PROD_CONF_MESSAGE_KEY);
|
|
21
|
+
if (initialMessage !== undefined) {
|
|
22
|
+
const highestVersionMessage = getHighestVersionProdConfMessage(initialMessage.subMessages);
|
|
23
|
+
if (isCfgProdConfMessageV2(highestVersionMessage)) {
|
|
24
|
+
return highestVersionMessage.conf;
|
|
25
|
+
}
|
|
26
|
+
}
|
|
27
|
+
try {
|
|
28
|
+
const s = CfgHistoryManager.currentQsKeyValues().get(this._qsKey);
|
|
29
|
+
if (s === undefined) {
|
|
30
|
+
return undefined;
|
|
31
|
+
}
|
|
32
|
+
return compactStringToDtoProductConf(s);
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
throw augmentErrorMessage(err, "Failed read configuration from query string");
|
|
22
36
|
}
|
|
23
|
-
return compactStringToDtoProductConfiguration(s);
|
|
24
37
|
}
|
|
25
38
|
makeSendData(conf, initial) {
|
|
26
39
|
return {
|
|
@@ -28,7 +41,7 @@ export class CfgHistoryToProdConfConnector extends CfgIOProdConfConnector {
|
|
|
28
41
|
qsKeyValues: new Map([
|
|
29
42
|
[STAGE_PROD_CONF_MESSAGE_KEY, dtoProductConfigurationToCompactString(conf)],
|
|
30
43
|
]),
|
|
31
|
-
|
|
44
|
+
mode: this._mode,
|
|
32
45
|
};
|
|
33
46
|
}
|
|
34
47
|
}
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { CfgIOWarningSupplier } from "./CfgIOWarningSupplier";
|
|
1
2
|
declare type ConfiguraAttribute = "C0nf1gura";
|
|
2
3
|
declare type ConfiguraShebang = "arug1fn0C";
|
|
3
4
|
declare const CONFIGURA_ATTRIBUTE: ConfiguraAttribute;
|
|
@@ -17,6 +18,10 @@ export declare type CfgIOContainer = {
|
|
|
17
18
|
* Base class for classes handling input and output in globally shared environments.
|
|
18
19
|
*/
|
|
19
20
|
export declare abstract class CfgIOManager<S> {
|
|
21
|
+
private _warningSuppliers;
|
|
22
|
+
addWarningSupplier(supplier: CfgIOWarningSupplier): void;
|
|
23
|
+
removeWarningSupplier(supplier: CfgIOWarningSupplier): void;
|
|
24
|
+
getWarnings(): string[];
|
|
20
25
|
/**
|
|
21
26
|
* Listen for the message messageKey being received.
|
|
22
27
|
*/
|
package/dist/io/CfgIOManager.js
CHANGED
|
@@ -18,12 +18,31 @@ const hasConfiguraAttribute = (data) => {
|
|
|
18
18
|
*/
|
|
19
19
|
export class CfgIOManager {
|
|
20
20
|
constructor() {
|
|
21
|
+
this._warningSuppliers = [];
|
|
21
22
|
// A lock to avoid circular write. Asynchronous conditions can make this not be enough.
|
|
22
23
|
// Avoid creating pre-conditions where this can happen.
|
|
23
24
|
this._receiveInProgress = false;
|
|
24
25
|
this._messageListeners = [];
|
|
25
26
|
this._getIndexOfMessageListener = (l) => this._messageListeners.findIndex((item) => l === item.l);
|
|
26
27
|
}
|
|
28
|
+
addWarningSupplier(supplier) {
|
|
29
|
+
this._warningSuppliers.push(supplier);
|
|
30
|
+
}
|
|
31
|
+
removeWarningSupplier(supplier) {
|
|
32
|
+
const i = this._warningSuppliers.indexOf(supplier);
|
|
33
|
+
if (i === -1) {
|
|
34
|
+
return;
|
|
35
|
+
}
|
|
36
|
+
this._warningSuppliers.splice(i, 1);
|
|
37
|
+
}
|
|
38
|
+
getWarnings() {
|
|
39
|
+
return this._warningSuppliers.reduce((aggregated, supplier) => {
|
|
40
|
+
for (const warning of supplier.getWarnings()) {
|
|
41
|
+
aggregated.push(warning);
|
|
42
|
+
}
|
|
43
|
+
return aggregated;
|
|
44
|
+
}, []);
|
|
45
|
+
}
|
|
27
46
|
/**
|
|
28
47
|
* Listen for the message messageKey being received.
|
|
29
48
|
*/
|
|
@@ -81,7 +100,7 @@ export class CfgIOManager {
|
|
|
81
100
|
if (item.messageKey !== messageKey) {
|
|
82
101
|
continue;
|
|
83
102
|
}
|
|
84
|
-
// async, not waiting. Might need to change.
|
|
103
|
+
// async, not waiting on each other. Might need to change.
|
|
85
104
|
promises.push(item.l(message));
|
|
86
105
|
}
|
|
87
106
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
|
-
import { DtoAdditionalProductConfiguration,
|
|
1
|
+
import { DtoAdditionalProductConfiguration, DtoProductConf } from "../CatalogueAPI.js";
|
|
2
2
|
import { CfgProduct, CfgProductChangeNotification } from "../CfgProduct.js";
|
|
3
3
|
import { CfgIOManager } from "./CfgIOManager.js";
|
|
4
|
+
import { CfgIOWarningSupplier } from "./CfgIOWarningSupplier.js";
|
|
4
5
|
export declare const isCfgProdConfMessage: (data: unknown) => data is CfgProdConfMessageV1 | CfgProdConfMessageV2;
|
|
5
6
|
export declare type CfgProdConfMessageV1 = {
|
|
6
7
|
version: "1.0";
|
|
@@ -9,7 +10,7 @@ export declare type CfgProdConfMessageV1 = {
|
|
|
9
10
|
export declare const isCfgProdConfMessageV1: (data: unknown) => data is CfgProdConfMessageV1;
|
|
10
11
|
export declare type CfgProdConfMessageV2 = {
|
|
11
12
|
version: "2.0";
|
|
12
|
-
conf:
|
|
13
|
+
conf: DtoProductConf;
|
|
13
14
|
};
|
|
14
15
|
export declare const isCfgProdConfMessageV2: (data: unknown) => data is CfgProdConfMessageV2;
|
|
15
16
|
export declare type CfgProdConfMessage = {
|
|
@@ -23,26 +24,26 @@ export declare enum CfgProdConfMessageVersions {
|
|
|
23
24
|
}
|
|
24
25
|
export declare const STAGE_PROD_CONF_MESSAGE_KEY = "stageprodconf";
|
|
25
26
|
declare type ProdConfMessageCallback = (message: CfgProdConfMessage) => Promise<void>;
|
|
26
|
-
declare type ProdConfCallback = (conf:
|
|
27
|
+
declare type ProdConfCallback = (conf: DtoProductConf) => Promise<void>;
|
|
27
28
|
/**
|
|
28
29
|
* Base class for connecting the product configuration to an IO channel
|
|
29
30
|
*/
|
|
30
|
-
export declare abstract class CfgIOProdConfConnector<S> {
|
|
31
|
-
|
|
32
|
-
private readonly _doValidate;
|
|
31
|
+
export declare abstract class CfgIOProdConfConnector<S> implements CfgIOWarningSupplier {
|
|
32
|
+
protected readonly _ioManager: CfgIOManager<S>;
|
|
33
33
|
private readonly _includeExtendedDataInSend;
|
|
34
34
|
private readonly _includeProdParamsInSend;
|
|
35
|
-
|
|
35
|
+
protected _product: CfgProduct | undefined;
|
|
36
36
|
private _stopListenToMessage;
|
|
37
37
|
private _stopListenToProdConf;
|
|
38
|
-
constructor(_ioManager: CfgIOManager<S>,
|
|
38
|
+
constructor(_ioManager: CfgIOManager<S>, _includeExtendedDataInSend: boolean, // Only for v2.0
|
|
39
39
|
_includeProdParamsInSend: boolean);
|
|
40
|
-
destroy
|
|
40
|
+
destroy(): void;
|
|
41
|
+
getWarnings(): string[];
|
|
41
42
|
setProduct: (product: CfgProduct | undefined) => Promise<void>;
|
|
42
43
|
private _send;
|
|
43
|
-
protected getInitialProdConf():
|
|
44
|
-
protected abstract makeSendData(conf:
|
|
45
|
-
static makeMessage(conf:
|
|
44
|
+
protected getInitialProdConf(): DtoProductConf | undefined;
|
|
45
|
+
protected abstract makeSendData(conf: DtoProductConf, initial: boolean): S;
|
|
46
|
+
static makeMessage(conf: DtoProductConf, initial: boolean, sendVersions: CfgProdConfMessageVersions): CfgProdConfMessage;
|
|
46
47
|
static makeMessageListener(callback: ProdConfMessageCallback): (message: unknown) => Promise<void>;
|
|
47
48
|
/**
|
|
48
49
|
* Register the callback to listen for Product Configuration messages
|
|
@@ -7,7 +7,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge
|
|
|
7
7
|
step((generator = generator.apply(thisArg, _arguments || [])).next());
|
|
8
8
|
});
|
|
9
9
|
};
|
|
10
|
-
import {
|
|
10
|
+
import { convertDtoProductConfToV1 } from "../ConfigurationConverter.js";
|
|
11
11
|
export const isCfgProdConfMessage = (data) => typeof data === "object" && data !== null && "version" in data && "conf" in data;
|
|
12
12
|
export const isCfgProdConfMessageV1 = (data) => isCfgProdConfMessage(data) && data.version === "1.0";
|
|
13
13
|
export const isCfgProdConfMessageV2 = (data) => isCfgProdConfMessage(data) && data.version === "2.0";
|
|
@@ -24,20 +24,14 @@ export const STAGE_PROD_CONF_MESSAGE_KEY = "stageprodconf";
|
|
|
24
24
|
* Base class for connecting the product configuration to an IO channel
|
|
25
25
|
*/
|
|
26
26
|
export class CfgIOProdConfConnector {
|
|
27
|
-
constructor(_ioManager,
|
|
28
|
-
_includeProdParamsInSend // Only v2.0
|
|
27
|
+
constructor(_ioManager, _includeExtendedDataInSend, // Only for v2.0
|
|
28
|
+
_includeProdParamsInSend // Only for v2.0
|
|
29
29
|
) {
|
|
30
30
|
this._ioManager = _ioManager;
|
|
31
|
-
this._doValidate = _doValidate;
|
|
32
31
|
this._includeExtendedDataInSend = _includeExtendedDataInSend;
|
|
33
32
|
this._includeProdParamsInSend = _includeProdParamsInSend;
|
|
34
33
|
this._stopListenToMessage = undefined;
|
|
35
34
|
this._stopListenToProdConf = undefined;
|
|
36
|
-
this.destroy = () => {
|
|
37
|
-
var _a, _b;
|
|
38
|
-
(_a = this._stopListenToMessage) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
39
|
-
(_b = this._stopListenToProdConf) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
40
|
-
};
|
|
41
35
|
this.setProduct = (product) => __awaiter(this, void 0, void 0, function* () {
|
|
42
36
|
var _a, _b;
|
|
43
37
|
const currentProduct = this._product;
|
|
@@ -58,12 +52,17 @@ export class CfgIOProdConfConnector {
|
|
|
58
52
|
}
|
|
59
53
|
// We only try to load initial configuration at first load
|
|
60
54
|
if (currentProduct === undefined) {
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
55
|
+
try {
|
|
56
|
+
const initialProdConf = this.getInitialProdConf();
|
|
57
|
+
if (initialProdConf !== undefined) {
|
|
58
|
+
yield newProduct.setDtoConf(initialProdConf);
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
catch (err) {
|
|
62
|
+
console.error(err);
|
|
64
63
|
}
|
|
65
64
|
}
|
|
66
|
-
this._send(this.makeSendData(newProduct.
|
|
65
|
+
this._send(this.makeSendData(newProduct.getDtoConf(this._includeExtendedDataInSend, this._includeProdParamsInSend), true));
|
|
67
66
|
this._stopListenToMessage = CfgIOProdConfConnector.listenForMessage((messages) => __awaiter(this, void 0, void 0, function* () {
|
|
68
67
|
const subMessages = messages.subMessages;
|
|
69
68
|
if (subMessages.length === 0) {
|
|
@@ -72,11 +71,11 @@ export class CfgIOProdConfConnector {
|
|
|
72
71
|
}
|
|
73
72
|
const highestVersionMessage = getHighestVersionProdConfMessage(subMessages);
|
|
74
73
|
if (isCfgProdConfMessageV1(highestVersionMessage)) {
|
|
75
|
-
yield newProduct.setApiSelection(highestVersionMessage.conf
|
|
74
|
+
yield newProduct.setApiSelection(highestVersionMessage.conf);
|
|
76
75
|
return;
|
|
77
76
|
}
|
|
78
77
|
if (isCfgProdConfMessageV2(highestVersionMessage)) {
|
|
79
|
-
yield newProduct.
|
|
78
|
+
yield newProduct.setDtoConf(highestVersionMessage.conf);
|
|
80
79
|
return;
|
|
81
80
|
}
|
|
82
81
|
throw new Error("Unknown message version");
|
|
@@ -84,6 +83,22 @@ export class CfgIOProdConfConnector {
|
|
|
84
83
|
this._stopListenToProdConf = CfgIOProdConfConnector.listenForProdConf(newProduct, (conf) => __awaiter(this, void 0, void 0, function* () { return this._send(this.makeSendData(conf, false)); }), this._includeExtendedDataInSend, this._includeProdParamsInSend);
|
|
85
84
|
});
|
|
86
85
|
this._send = (data) => this._ioManager.send(STAGE_PROD_CONF_MESSAGE_KEY, data);
|
|
86
|
+
_ioManager.addWarningSupplier(this);
|
|
87
|
+
}
|
|
88
|
+
destroy() {
|
|
89
|
+
var _a, _b;
|
|
90
|
+
(_a = this._stopListenToMessage) === null || _a === void 0 ? void 0 : _a.call(this);
|
|
91
|
+
(_b = this._stopListenToProdConf) === null || _b === void 0 ? void 0 : _b.call(this);
|
|
92
|
+
this._ioManager.removeWarningSupplier(this);
|
|
93
|
+
}
|
|
94
|
+
getWarnings() {
|
|
95
|
+
const product = this._product;
|
|
96
|
+
if (product !== undefined && product.hasRootFeaturesChanged) {
|
|
97
|
+
return [
|
|
98
|
+
"In at least one of the Products, Functional Selection has taken place, thereby changing what root Features are used. The SDK can not yet apply a serialized configuration in these cases. Extracting this data from the SDK for external applications can work, but reinserting the data into Stage will most likely fail.",
|
|
99
|
+
];
|
|
100
|
+
}
|
|
101
|
+
return [];
|
|
87
102
|
}
|
|
88
103
|
getInitialProdConf() {
|
|
89
104
|
return undefined;
|
|
@@ -94,7 +109,7 @@ export class CfgIOProdConfConnector {
|
|
|
94
109
|
CfgProdConfMessageVersions.V1dot0) {
|
|
95
110
|
const v1 = {
|
|
96
111
|
version: "1.0",
|
|
97
|
-
conf:
|
|
112
|
+
conf: convertDtoProductConfToV1(conf, true),
|
|
98
113
|
};
|
|
99
114
|
result.push(v1);
|
|
100
115
|
}
|
|
@@ -130,7 +145,7 @@ export class CfgIOProdConfConnector {
|
|
|
130
145
|
if (!n.committed) {
|
|
131
146
|
return;
|
|
132
147
|
}
|
|
133
|
-
callback(n.freshRef.
|
|
148
|
+
callback(n.freshRef.getDtoConf(includeExtendedDataInSend, includeProdParamsInSend));
|
|
134
149
|
};
|
|
135
150
|
}
|
|
136
151
|
static listenForProdConf(product, callback, includeExtendedDataInSend, includeProdParamsInSend) {
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export {};
|
|
@@ -1,16 +1,15 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DtoProductConf } from "../CatalogueAPI.js";
|
|
2
2
|
import { CfgIOProdConfConnector, CfgProdConfMessage, CfgProdConfMessageVersions } from "./CfgIOProdConfConnector.js";
|
|
3
3
|
import { CfgObservableStateManager } from "./CfgObservableStateManager.js";
|
|
4
4
|
/**
|
|
5
5
|
* Instantiating this will make the observable state update with the product configuration.
|
|
6
|
-
* @param doValidate Run server side product validation for incoming
|
|
7
6
|
* @param sendVersions What versions of the productConfiguration shall be sent? Multiple can be selected
|
|
8
7
|
* @param includeExtendedDataInSend Only for version 2.0. Includes unit and groupCode.
|
|
9
8
|
* @param includeProdParamsInSend Only for version 2.0. Includes product params, in both main and additional products.
|
|
10
9
|
*/
|
|
11
10
|
export declare class CfgObservableStateToProdConfConnector extends CfgIOProdConfConnector<CfgProdConfMessage> {
|
|
12
11
|
private _sendVersions;
|
|
13
|
-
constructor(manager: CfgObservableStateManager,
|
|
14
|
-
protected makeSendData(conf:
|
|
12
|
+
constructor(manager: CfgObservableStateManager, _sendVersions?: CfgProdConfMessageVersions, includeExtendedDataInSend?: boolean, includeProdParamsInSend?: boolean);
|
|
13
|
+
protected makeSendData(conf: DtoProductConf, initial: boolean): CfgProdConfMessage;
|
|
15
14
|
}
|
|
16
15
|
//# sourceMappingURL=CfgObservableStateToProdConfConnector.d.ts.map
|
|
@@ -1,14 +1,13 @@
|
|
|
1
1
|
import { CfgIOProdConfConnector, CfgProdConfMessageVersions, } from "./CfgIOProdConfConnector.js";
|
|
2
2
|
/**
|
|
3
3
|
* Instantiating this will make the observable state update with the product configuration.
|
|
4
|
-
* @param doValidate Run server side product validation for incoming
|
|
5
4
|
* @param sendVersions What versions of the productConfiguration shall be sent? Multiple can be selected
|
|
6
5
|
* @param includeExtendedDataInSend Only for version 2.0. Includes unit and groupCode.
|
|
7
6
|
* @param includeProdParamsInSend Only for version 2.0. Includes product params, in both main and additional products.
|
|
8
7
|
*/
|
|
9
8
|
export class CfgObservableStateToProdConfConnector extends CfgIOProdConfConnector {
|
|
10
|
-
constructor(manager,
|
|
11
|
-
super(manager,
|
|
9
|
+
constructor(manager, _sendVersions = CfgProdConfMessageVersions.V2dot0, includeExtendedDataInSend = false, includeProdParamsInSend = false) {
|
|
10
|
+
super(manager, includeExtendedDataInSend, includeProdParamsInSend);
|
|
12
11
|
this._sendVersions = _sendVersions;
|
|
13
12
|
}
|
|
14
13
|
makeSendData(conf, initial) {
|
|
@@ -70,6 +70,10 @@ export class CfgWindowMessageManager extends CfgWindowEventManager {
|
|
|
70
70
|
const container = CfgIOManager.makeContainer({
|
|
71
71
|
[messageKey]: data,
|
|
72
72
|
});
|
|
73
|
+
const warnings = this.getWarnings();
|
|
74
|
+
if (warnings.length !== 0) {
|
|
75
|
+
warnings.forEach((w) => console.warn(w));
|
|
76
|
+
}
|
|
73
77
|
for (const remoteEnd of this._remoteEnds) {
|
|
74
78
|
remoteEnd.postMessage(container, this._targetOrigin);
|
|
75
79
|
}
|
|
@@ -1,18 +1,17 @@
|
|
|
1
|
-
import {
|
|
1
|
+
import { DtoProductConf } from "../CatalogueAPI.js";
|
|
2
2
|
import { CfgIOProdConfConnector, CfgProdConfMessage, CfgProdConfMessageVersions } from "./CfgIOProdConfConnector.js";
|
|
3
3
|
import { CfgWindowMessageManager } from "./CfgWindowMessageManager.js";
|
|
4
4
|
/**
|
|
5
5
|
* Instantiating this will make Stage send product configuration changes using the post message-API.
|
|
6
6
|
* It will also make Stage listen for incoming product configuration update messages.
|
|
7
7
|
* This can be used to communicate in and out of an iframe for example.
|
|
8
|
-
* @param doValidate Run server side product validation for incoming
|
|
9
8
|
* @param sendVersions What versions of the productConfiguration shall be sent? Multiple can be selected
|
|
10
9
|
* @param includeExtendedDataInSend Only for version 2.0. Includes unit and groupCode.
|
|
11
10
|
* @param includeProdParamsInSend Only for version 2.0. Includes product params, in both main and additional products.
|
|
12
11
|
*/
|
|
13
12
|
export declare class CfgWindowMessageToProdConfConnector extends CfgIOProdConfConnector<CfgProdConfMessage> {
|
|
14
13
|
private _sendVersions;
|
|
15
|
-
constructor(manager: CfgWindowMessageManager,
|
|
16
|
-
protected makeSendData(conf:
|
|
14
|
+
constructor(manager: CfgWindowMessageManager, _sendVersions?: CfgProdConfMessageVersions, includeExtendedDataInSend?: boolean, includeProdParamsInSend?: boolean);
|
|
15
|
+
protected makeSendData(conf: DtoProductConf, initial: boolean): CfgProdConfMessage;
|
|
17
16
|
}
|
|
18
17
|
//# sourceMappingURL=CfgWindowMessageToProdConfConnector.d.ts.map
|
|
@@ -3,14 +3,13 @@ import { CfgIOProdConfConnector, CfgProdConfMessageVersions, } from "./CfgIOProd
|
|
|
3
3
|
* Instantiating this will make Stage send product configuration changes using the post message-API.
|
|
4
4
|
* It will also make Stage listen for incoming product configuration update messages.
|
|
5
5
|
* This can be used to communicate in and out of an iframe for example.
|
|
6
|
-
* @param doValidate Run server side product validation for incoming
|
|
7
6
|
* @param sendVersions What versions of the productConfiguration shall be sent? Multiple can be selected
|
|
8
7
|
* @param includeExtendedDataInSend Only for version 2.0. Includes unit and groupCode.
|
|
9
8
|
* @param includeProdParamsInSend Only for version 2.0. Includes product params, in both main and additional products.
|
|
10
9
|
*/
|
|
11
10
|
export class CfgWindowMessageToProdConfConnector extends CfgIOProdConfConnector {
|
|
12
|
-
constructor(manager,
|
|
13
|
-
super(manager,
|
|
11
|
+
constructor(manager, _sendVersions = CfgProdConfMessageVersions.V2dot0, includeExtendedDataInSend = false, includeProdParamsInSend = false) {
|
|
12
|
+
super(manager, includeExtendedDataInSend, includeProdParamsInSend);
|
|
14
13
|
this._sendVersions = _sendVersions;
|
|
15
14
|
}
|
|
16
15
|
makeSendData(conf, initial) {
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LengthUnit, Observable, SingleArgCallback } from "@configura/web-utilities";
|
|
2
|
-
import { DtoFeature,
|
|
2
|
+
import { DtoFeature, DtoFeatureConf, DtoSelectedOption, DtoSyncGroup, DtoSyncGroupMethods } from "../CatalogueAPI.js";
|
|
3
3
|
import { CfgProduct, _CfgProductInternal } from "../CfgProduct.js";
|
|
4
4
|
import { CfgMtrlApplication } from "../material/CfgMtrlApplication.js";
|
|
5
5
|
import { SyncCode } from "../syncGroups/SyncGroupsHandler.js";
|
|
@@ -99,7 +99,7 @@ export declare class _CfgFeatureInternal {
|
|
|
99
99
|
* as nonexisting children can not call their parent.
|
|
100
100
|
*/
|
|
101
101
|
_childHasChanged: (childOption: _CfgOptionInternal, bubbleMode: ProductConfigurationBubbleMode, committed: boolean) => Promise<void>;
|
|
102
|
-
|
|
102
|
+
getDtoConf: (includeExtendedData: boolean) => DtoFeatureConf;
|
|
103
103
|
setApiSelection: (apiOptionSelectionMap: {
|
|
104
104
|
[index: string]: DtoSelectedOption;
|
|
105
105
|
} | undefined) => Promise<boolean>;
|
|
@@ -114,7 +114,7 @@ export class _CfgFeatureInternal {
|
|
|
114
114
|
}
|
|
115
115
|
yield this._notifyAllOfChange(bubbleMode, committed);
|
|
116
116
|
});
|
|
117
|
-
this.
|
|
117
|
+
this.getDtoConf = (includeExtendedData) => {
|
|
118
118
|
const result = {
|
|
119
119
|
code: this.code,
|
|
120
120
|
};
|
|
@@ -124,10 +124,16 @@ export class _CfgFeatureInternal {
|
|
|
124
124
|
}
|
|
125
125
|
const selectedOptions = this._selectedOptions;
|
|
126
126
|
if (0 < selectedOptions.length) {
|
|
127
|
-
result.options = selectedOptions.map((o) => o._internal.
|
|
127
|
+
result.options = selectedOptions.map((o) => o._internal.getDtoConf(includeExtendedData));
|
|
128
128
|
}
|
|
129
129
|
return result;
|
|
130
130
|
};
|
|
131
|
+
// DtoFeatureConf is the newer more easily readable format for configuration. As
|
|
132
|
+
// the API:s are still using the older format (and will for the forseeable future) we need
|
|
133
|
+
// to support both formats. The new format can be converted to the old, but not the other
|
|
134
|
+
// way around. For that reason the get-method above uses the new format, and the set-method
|
|
135
|
+
// below the old format. As these functions are meant to only be used internally this should't
|
|
136
|
+
// cause too much confusion.
|
|
131
137
|
this.setApiSelection = (apiOptionSelectionMap) => __awaiter(this, void 0, void 0, function* () {
|
|
132
138
|
const selectionType = this.selectionType;
|
|
133
139
|
const isGroup = selectionType === SelectionType.Group;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { LengthUnit, Observable, SingleArgCallback } from "@configura/web-utilities";
|
|
2
|
-
import { DtoFeature, DtoOption,
|
|
2
|
+
import { DtoFeature, DtoOption, DtoOptionConf, DtoSelectedOption } from "../CatalogueAPI.js";
|
|
3
3
|
import { CfgProduct, _CfgProductInternal } from "../CfgProduct.js";
|
|
4
4
|
import { CfgMtrlApplication } from "../material/CfgMtrlApplication.js";
|
|
5
5
|
import { NumericValuesSelection } from "../utilitiesNumericValues.js";
|
|
@@ -89,7 +89,7 @@ export declare class _CfgOptionInternal {
|
|
|
89
89
|
get features(): CfgFeature[];
|
|
90
90
|
/** Called by child to tell its parent that it has changed. */
|
|
91
91
|
_childHasChanged: (freshRef: CfgFeature, bubbleMode: ProductConfigurationBubbleMode, committed: boolean) => Promise<void>;
|
|
92
|
-
|
|
92
|
+
getDtoConf: (includeExtendedData: boolean) => DtoOptionConf;
|
|
93
93
|
setApiSelection: (apiOptionSelection: DtoSelectedOption | undefined) => Promise<boolean>;
|
|
94
94
|
structureCompare: (other: _CfgOptionInternal, strictOrder?: boolean, descriptionMatch?: boolean) => boolean;
|
|
95
95
|
tryMatchSelection: (other: CfgOption, descriptionMatch?: boolean) => Promise<boolean>;
|
|
@@ -110,7 +110,7 @@ export class _CfgOptionInternal {
|
|
|
110
110
|
yield this.parent._childHasChanged(this, bubbleMode, committed);
|
|
111
111
|
}
|
|
112
112
|
});
|
|
113
|
-
this.
|
|
113
|
+
this.getDtoConf = (includeExtendedData) => {
|
|
114
114
|
const { features, isUseNumericValue, code, selected, numericValue } = this;
|
|
115
115
|
if (!selected) {
|
|
116
116
|
throw new Error("Currently only useable on selected options. Selected in the result is for future use.");
|
|
@@ -128,10 +128,16 @@ export class _CfgOptionInternal {
|
|
|
128
128
|
}
|
|
129
129
|
}
|
|
130
130
|
if (0 < features.length) {
|
|
131
|
-
result.features = features.map((f) => f._internal.
|
|
131
|
+
result.features = features.map((f) => f._internal.getDtoConf(includeExtendedData));
|
|
132
132
|
}
|
|
133
133
|
return result;
|
|
134
134
|
};
|
|
135
|
+
// DtoOptionConf is the newer more easily readable format for configuration. As
|
|
136
|
+
// the API:s are still using the older format (and will for the forseeable future) we need
|
|
137
|
+
// to support both formats. The new format can be converted to the old, but not the other
|
|
138
|
+
// way around. For that reason the get-method above uses the new format, and the set-method
|
|
139
|
+
// below the old format. As these functions are meant to only be used internally this should't
|
|
140
|
+
// cause too much confusion.
|
|
135
141
|
this.setApiSelection = (apiOptionSelection) => __awaiter(this, void 0, void 0, function* () {
|
|
136
142
|
let features;
|
|
137
143
|
if (apiOptionSelection === undefined) {
|