@o3r/core 15.3.0-prerelease.9 → 15.4.0-prerelease.0
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/fesm2022/o3r-core.mjs +300 -470
- package/fesm2022/o3r-core.mjs.map +1 -1
- package/package.json +13 -13
- package/schematics/add-modules/schema.json +0 -3
- package/schematics/component/container/schema.json +0 -3
- package/schematics/component/presenter/schema.json +0 -3
- package/schematics/component/schema.json +0 -3
- package/schematics/ng-add/schema.json +0 -3
- package/schematics/ng-add-create/schema.json +0 -3
- package/schematics/page/schema.json +0 -3
- package/schematics/schematics-update/schema.json +0 -3
- package/schematics/service/schema.json +0 -3
- package/schematics/store/entity-async/schema.json +0 -3
- package/schematics/store/entity-sync/schema.json +0 -3
- package/schematics/store/schema.json +0 -3
- package/schematics/store/simple-async/schema.json +0 -3
- package/schematics/store/simple-sync/schema.json +0 -3
- package/schematics/store-action/schema.json +0 -3
- package/types/o3r-core.d.ts +553 -610
- package/types/o3r-core.d.ts.map +1 -1
package/fesm2022/o3r-core.mjs
CHANGED
|
@@ -1,521 +1,351 @@
|
|
|
1
|
-
import {
|
|
2
|
-
import {
|
|
3
|
-
import { v4 } from
|
|
4
|
-
|
|
5
|
-
/* eslint-disable @typescript-eslint/naming-convention -- exception for `BuildTimeProperties` */
|
|
6
|
-
/**
|
|
7
|
-
* Library build time default properties
|
|
8
|
-
*/
|
|
1
|
+
import { BehaviorSubject, EMPTY, animationFrameScheduler, filter, from, identity, isObservable, map, merge, observeOn, of } from "rxjs";
|
|
2
|
+
import { bufferCount, catchError, concatMap, delay, filter as filter$1, finalize, mergeMap, pairwise, scan, startWith, switchMap, tap } from "rxjs/operators";
|
|
3
|
+
import { v4 } from "uuid";
|
|
9
4
|
const DEFAULT_BUILD_PROPERTIES = {
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
5
|
+
DEBUG_MODE: true,
|
|
6
|
+
APP_BASE_HREF: ".",
|
|
7
|
+
APP_VERSION: "0.0.0",
|
|
8
|
+
DEFAULT_LOC_BUNDLE_NAME: "",
|
|
9
|
+
DEVTOOL_HISTORY_SIZE: 20,
|
|
10
|
+
ENABLE_GHOSTING: false,
|
|
11
|
+
ENABLE_WEBSTORAGE: true,
|
|
12
|
+
ENVIRONMENT: "dev",
|
|
13
|
+
LOCALIZATION_BUNDLES_OUTPUT: "localizations/",
|
|
14
|
+
USE_MOCKS: false
|
|
20
15
|
};
|
|
21
|
-
|
|
22
|
-
/**
|
|
23
|
-
* Private field where Otter component information are stored
|
|
24
|
-
*/
|
|
25
|
-
const otterComponentInfoPropertyName = '__otter-info__';
|
|
26
|
-
/**
|
|
27
|
-
* Decorates an Angular component to provide Otter information
|
|
28
|
-
* @param info Information to define the Otter component
|
|
29
|
-
* @returns the component with the information
|
|
30
|
-
*/
|
|
31
|
-
// eslint-disable-next-line @typescript-eslint/naming-convention -- decorator should be PascalCase
|
|
16
|
+
const otterComponentInfoPropertyName = "__otter-info__";
|
|
32
17
|
function O3rComponent(info) {
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
18
|
+
return (constructor) => {
|
|
19
|
+
const componentName = constructor.name;
|
|
20
|
+
constructor.prototype[otterComponentInfoPropertyName] = {
|
|
21
|
+
...info,
|
|
22
|
+
componentName
|
|
23
|
+
};
|
|
24
|
+
return constructor;
|
|
25
|
+
};
|
|
38
26
|
}
|
|
39
|
-
|
|
40
|
-
/**
|
|
41
|
-
* Compute the name of the component with the library's name to generate unique component identifier used in metadata and different modules
|
|
42
|
-
* @param componentName Name of the component to get the configuration
|
|
43
|
-
* @param libraryName Name of the library the component is coming from
|
|
44
|
-
*/
|
|
45
27
|
function computeItemIdentifier(componentName, libraryName) {
|
|
46
|
-
|
|
28
|
+
return (libraryName ? libraryName + "#" : "") + componentName;
|
|
47
29
|
}
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
const otterMessageType = 'otter';
|
|
51
|
-
/** Target of a message that should be handled by the application */
|
|
52
|
-
const applicationMessageTarget = 'app';
|
|
53
|
-
|
|
54
|
-
/**
|
|
55
|
-
* Determine if a message should be handle by the application
|
|
56
|
-
* @param message Message to analyze
|
|
57
|
-
*/
|
|
30
|
+
const otterMessageType = "otter";
|
|
31
|
+
const applicationMessageTarget = "app";
|
|
58
32
|
const isToAppOtterMessage = (message) => {
|
|
59
|
-
|
|
33
|
+
return message?.to === "app";
|
|
60
34
|
};
|
|
61
|
-
/**
|
|
62
|
-
* Determine if a message is emitted by an Otter tool
|
|
63
|
-
* @param message Message to analyze
|
|
64
|
-
*/
|
|
65
35
|
const isOtterMessage = (message) => {
|
|
66
|
-
|
|
36
|
+
return message?.type === otterMessageType;
|
|
67
37
|
};
|
|
68
|
-
/**
|
|
69
|
-
* Send an Otter Message
|
|
70
|
-
* @param dataType Type of the message
|
|
71
|
-
* @param content content of the message
|
|
72
|
-
* @param preStringify determine if the message should JSON.stringify before being send (will use the default mechanism otherwise)
|
|
73
|
-
*/
|
|
74
38
|
const sendOtterMessage = (dataType, content, preStringify = true) => {
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
39
|
+
const message = {
|
|
40
|
+
type: otterMessageType,
|
|
41
|
+
content: {
|
|
42
|
+
...content,
|
|
43
|
+
dataType
|
|
44
|
+
}
|
|
45
|
+
};
|
|
46
|
+
return window.postMessage(preStringify ? JSON.stringify(message) : message, "*");
|
|
83
47
|
};
|
|
84
|
-
/**
|
|
85
|
-
* Filter the Otter message that should be handle by the application and returns it content
|
|
86
|
-
* @param predicate condition to filter the message
|
|
87
|
-
* @returns content of the message
|
|
88
|
-
*/
|
|
89
|
-
/**
|
|
90
|
-
* Operator to get only Otter messages that match the predicate
|
|
91
|
-
* @param predicate
|
|
92
|
-
*/
|
|
93
48
|
function filterMessageContent(predicate) {
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
return obs;
|
|
103
|
-
};
|
|
49
|
+
return (source$) => {
|
|
50
|
+
const obs = source$.pipe(map((event) => {
|
|
51
|
+
const data = event.data;
|
|
52
|
+
return typeof data === "string" ? JSON.parse(data) : data;
|
|
53
|
+
}), filter(isOtterMessage), filter(isToAppOtterMessage), map((message) => message.content));
|
|
54
|
+
if (predicate) return obs.pipe(filter(predicate));
|
|
55
|
+
return obs;
|
|
56
|
+
};
|
|
104
57
|
}
|
|
105
|
-
|
|
106
58
|
const asyncStoreItemAdapter = {
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
59
|
+
addRequest: (item, requestId) => {
|
|
60
|
+
return {
|
|
61
|
+
...item,
|
|
62
|
+
requestIds: [...item.requestIds, requestId],
|
|
63
|
+
isFailure: item.requestIds.length === 0 ? false : item.isFailure,
|
|
64
|
+
isPending: true
|
|
65
|
+
};
|
|
66
|
+
},
|
|
67
|
+
failRequest: (item, requestId) => {
|
|
68
|
+
const requestIds = requestId ? item.requestIds.filter((id) => id !== requestId) : item.requestIds;
|
|
69
|
+
return {
|
|
70
|
+
...item,
|
|
71
|
+
isFailure: true,
|
|
72
|
+
isPending: requestIds.length > 0,
|
|
73
|
+
requestIds
|
|
74
|
+
};
|
|
75
|
+
},
|
|
76
|
+
resolveRequest: (item, requestId) => {
|
|
77
|
+
const requestIds = requestId ? item.requestIds.filter((id) => id !== requestId) : item.requestIds;
|
|
78
|
+
return {
|
|
79
|
+
...item,
|
|
80
|
+
requestIds,
|
|
81
|
+
isPending: requestIds.length > 0
|
|
82
|
+
};
|
|
83
|
+
},
|
|
84
|
+
initialize: (entityItem) => {
|
|
85
|
+
return {
|
|
86
|
+
...entityItem,
|
|
87
|
+
requestIds: []
|
|
88
|
+
};
|
|
89
|
+
},
|
|
90
|
+
extractAsyncStoreItem: (entityItem) => {
|
|
91
|
+
return {
|
|
92
|
+
requestIds: [...entityItem.requestIds],
|
|
93
|
+
isFailure: entityItem.isFailure,
|
|
94
|
+
isPending: entityItem.isPending
|
|
95
|
+
};
|
|
96
|
+
},
|
|
97
|
+
clearAsyncStoreItem: (entityItem) => {
|
|
98
|
+
const { isPending, isFailure, ...newResponse } = {
|
|
99
|
+
...entityItem,
|
|
100
|
+
requestIds: []
|
|
101
|
+
};
|
|
102
|
+
return newResponse;
|
|
103
|
+
},
|
|
104
|
+
merge: (...items) => {
|
|
105
|
+
return items.reduce((mergedItem, item) => item ? {
|
|
106
|
+
requestIds: [...mergedItem.requestIds, ...item.requestIds],
|
|
107
|
+
isFailure: mergedItem.isFailure || item.isFailure,
|
|
108
|
+
isPending: mergedItem.isPending || item.isPending
|
|
109
|
+
} : mergedItem, asyncStoreItemAdapter.initialize({}));
|
|
110
|
+
},
|
|
111
|
+
entityStatusAddRequest: (status, subResource, requestId) => {
|
|
112
|
+
const currentSubStatus = status[subResource] || asyncStoreItemAdapter.initialize({});
|
|
113
|
+
return {
|
|
114
|
+
...status,
|
|
115
|
+
[subResource]: asyncStoreItemAdapter.addRequest(currentSubStatus, requestId)
|
|
116
|
+
};
|
|
117
|
+
},
|
|
118
|
+
entityStatusResolveRequest: (status, subResource, requestId) => {
|
|
119
|
+
const currentSubStatus = status[subResource];
|
|
120
|
+
return {
|
|
121
|
+
...status,
|
|
122
|
+
[subResource]: currentSubStatus ? asyncStoreItemAdapter.resolveRequest(currentSubStatus, requestId) : { requestIds: [] }
|
|
123
|
+
};
|
|
124
|
+
},
|
|
125
|
+
entityStatusFailRequest: (status, subResource, requestId) => {
|
|
126
|
+
const currentSubStatus = status[subResource];
|
|
127
|
+
return {
|
|
128
|
+
...status,
|
|
129
|
+
[subResource]: currentSubStatus ? asyncStoreItemAdapter.failRequest(currentSubStatus, requestId) : {
|
|
130
|
+
requestIds: [],
|
|
131
|
+
isFailure: true
|
|
132
|
+
}
|
|
133
|
+
};
|
|
134
|
+
},
|
|
135
|
+
entityStatusResetFailure: (status, subResource) => {
|
|
136
|
+
const currentSubStatus = status[subResource];
|
|
137
|
+
return {
|
|
138
|
+
...status,
|
|
139
|
+
[subResource]: currentSubStatus ? asyncStoreItemAdapter.resetFailureStatus(currentSubStatus) : { requestIds: [] }
|
|
140
|
+
};
|
|
141
|
+
},
|
|
142
|
+
resetFailureStatus: (entityItem) => {
|
|
143
|
+
return {
|
|
144
|
+
...entityItem,
|
|
145
|
+
isFailure: false
|
|
146
|
+
};
|
|
147
|
+
},
|
|
148
|
+
setLoadingStatus: (entityItem) => {
|
|
149
|
+
return {
|
|
150
|
+
...entityItem,
|
|
151
|
+
isPending: true
|
|
152
|
+
};
|
|
153
|
+
}
|
|
198
154
|
};
|
|
199
|
-
|
|
200
|
-
/**
|
|
201
|
-
* Create an Asynchronous Request Entity Adapter
|
|
202
|
-
* @param adapter Entity Adapter
|
|
203
|
-
*/
|
|
204
155
|
function createEntityAsyncRequestAdapter(adapter) {
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
|
|
232
|
-
|
|
233
|
-
|
|
234
|
-
|
|
235
|
-
|
|
236
|
-
|
|
237
|
-
|
|
238
|
-
|
|
239
|
-
|
|
240
|
-
|
|
241
|
-
|
|
242
|
-
|
|
243
|
-
|
|
244
|
-
|
|
245
|
-
|
|
156
|
+
const addRequestOne = (state, id, requestId) => {
|
|
157
|
+
const currentEntity = typeof id !== "undefined" && id !== null && state.entities[id];
|
|
158
|
+
if (currentEntity) {
|
|
159
|
+
const changes = asyncStoreItemAdapter.addRequest(asyncStoreItemAdapter.extractAsyncStoreItem(currentEntity), requestId);
|
|
160
|
+
return adapter.updateOne({
|
|
161
|
+
id,
|
|
162
|
+
changes
|
|
163
|
+
}, state);
|
|
164
|
+
}
|
|
165
|
+
return asyncStoreItemAdapter.addRequest(state, requestId);
|
|
166
|
+
};
|
|
167
|
+
const addRequestMany = (state, ids, requestId) => adapter.updateMany(ids.filter((id) => !!state.entities[id]).map((id) => ({
|
|
168
|
+
id,
|
|
169
|
+
changes: asyncStoreItemAdapter.addRequest(asyncStoreItemAdapter.extractAsyncStoreItem(state.entities[id]), requestId)
|
|
170
|
+
})), state);
|
|
171
|
+
const resolveRequestOne = (state, entity, requestId, idProperty = "id") => {
|
|
172
|
+
const currentEntity = state.entities[entity[idProperty]];
|
|
173
|
+
const newEntity = currentEntity ? asyncStoreItemAdapter.resolveRequest({
|
|
174
|
+
...entity,
|
|
175
|
+
...asyncStoreItemAdapter.extractAsyncStoreItem(currentEntity)
|
|
176
|
+
}, requestId) : asyncStoreItemAdapter.initialize(entity);
|
|
177
|
+
state = asyncStoreItemAdapter.resolveRequest(state, requestId);
|
|
178
|
+
return adapter.upsertOne(newEntity, state);
|
|
179
|
+
};
|
|
180
|
+
const resolveRequestMany = (state, entities, requestId, idProperty = "id") => adapter.updateMany(entities.filter((entity) => !!state.entities[entity[idProperty]]).map((entity) => {
|
|
181
|
+
const model = {
|
|
182
|
+
...entity,
|
|
183
|
+
...asyncStoreItemAdapter.extractAsyncStoreItem(state.entities[entity[idProperty]])
|
|
184
|
+
};
|
|
185
|
+
return {
|
|
186
|
+
id: entity[idProperty],
|
|
187
|
+
changes: asyncStoreItemAdapter.resolveRequest(model, requestId)
|
|
188
|
+
};
|
|
189
|
+
}), state);
|
|
190
|
+
const failRequestMany = (state, ids = [], requestId) => {
|
|
191
|
+
if (ids.length > 0 && !ids.some((id) => state.entities[id] === void 0)) return adapter.updateMany(ids.map((id) => ({
|
|
192
|
+
id,
|
|
193
|
+
changes: asyncStoreItemAdapter.failRequest(asyncStoreItemAdapter.extractAsyncStoreItem(state.entities[id]), requestId)
|
|
194
|
+
})), state);
|
|
195
|
+
return asyncStoreItemAdapter.failRequest(state, requestId);
|
|
196
|
+
};
|
|
197
|
+
return {
|
|
198
|
+
...adapter,
|
|
199
|
+
failRequestMany,
|
|
200
|
+
addRequestOne,
|
|
201
|
+
addRequestMany,
|
|
202
|
+
resolveRequestOne,
|
|
203
|
+
resolveRequestMany
|
|
204
|
+
};
|
|
246
205
|
}
|
|
247
|
-
|
|
248
|
-
/**
|
|
249
|
-
* Determine if the action is an AsyncRequest action
|
|
250
|
-
* @param action Redux Action
|
|
251
|
-
*/
|
|
252
206
|
function isCallAction(action) {
|
|
253
|
-
|
|
254
|
-
|
|
255
|
-
}
|
|
256
|
-
return !!action.call && action.call instanceof Promise;
|
|
207
|
+
if (!action) return false;
|
|
208
|
+
return !!action.call && action.call instanceof Promise;
|
|
257
209
|
}
|
|
258
|
-
/**
|
|
259
|
-
* Determine if the action is an AsyncRequest action with a Request ID
|
|
260
|
-
* @param action Redux Action
|
|
261
|
-
*/
|
|
262
210
|
function isIdentifiedCallAction(action) {
|
|
263
|
-
|
|
211
|
+
return isCallAction(action) && typeof action.requestId !== "undefined";
|
|
264
212
|
}
|
|
265
|
-
/**
|
|
266
|
-
* Determine if the given item implements the AsyncRequest interface
|
|
267
|
-
* @param item
|
|
268
|
-
*/
|
|
269
213
|
function isAsyncRequest(item) {
|
|
270
|
-
|
|
214
|
+
return typeof item.requestId !== "undefined";
|
|
271
215
|
}
|
|
272
|
-
|
|
273
|
-
/**
|
|
274
|
-
* Determine if the given parameter is a Promise
|
|
275
|
-
* @param object
|
|
276
|
-
*/
|
|
277
|
-
const isPromise = (object) => object && typeof object === 'object' && typeof object.then !== 'undefined';
|
|
278
|
-
/**
|
|
279
|
-
* Custom operator to use instead of SwitchMap with effects based on FromApi actions.
|
|
280
|
-
* It makes sure to emit an action when the inner subscription is unsubscribed in order to keep the store up-to-date with pending information.
|
|
281
|
-
* @param successHandler function that returns the action to emit in case the FromApi call is a success
|
|
282
|
-
* @param errorHandler function that returns the action to emit in case the FromApi call fails
|
|
283
|
-
* @param cancelRequestActionFactory function that returns the action to emit in case the FromApi action is 'cancelled' because a new action was received by the switchMap
|
|
284
|
-
*/
|
|
216
|
+
const isPromise = (object) => object && typeof object === "object" && typeof object.then !== "undefined";
|
|
285
217
|
function fromApiEffectSwitchMap(successHandler, errorHandler, cancelRequestActionFactory) {
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
303
|
-
return isObservable(success) ? success : (isPromise(success) ? success : of(success));
|
|
304
|
-
}), catchError((error) => {
|
|
305
|
-
cleanStack();
|
|
306
|
-
return errorHandler?.(error, action) || EMPTY;
|
|
307
|
-
}), isPreviousActionStillRunning && cancelRequestActionFactory ? startWith(cancelRequestActionFactory({ requestId: previousAction.requestId }, action)) : identity);
|
|
308
|
-
}));
|
|
218
|
+
const pendingRequestIdsContext = {};
|
|
219
|
+
return (source$) => source$.pipe(tap((action) => {
|
|
220
|
+
if (isIdentifiedCallAction(action)) pendingRequestIdsContext[action.requestId] = true;
|
|
221
|
+
}), startWith(void 0), pairwise(), switchMap(([previousAction, action]) => {
|
|
222
|
+
if (!action) return EMPTY;
|
|
223
|
+
const isPreviousActionStillRunning = isIdentifiedCallAction(previousAction) && pendingRequestIdsContext[previousAction.requestId];
|
|
224
|
+
const cleanStack = () => {
|
|
225
|
+
if (isIdentifiedCallAction(action)) delete pendingRequestIdsContext[action.requestId];
|
|
226
|
+
};
|
|
227
|
+
return from(action.call).pipe(tap(cleanStack), switchMap((result) => {
|
|
228
|
+
const success = successHandler(result, action);
|
|
229
|
+
return isObservable(success) ? success : isPromise(success) ? success : of(success);
|
|
230
|
+
}), catchError((error) => {
|
|
231
|
+
cleanStack();
|
|
232
|
+
return errorHandler?.(error, action) || EMPTY;
|
|
233
|
+
}), isPreviousActionStillRunning && cancelRequestActionFactory ? startWith(cancelRequestActionFactory({ requestId: previousAction.requestId }, action)) : identity);
|
|
234
|
+
}));
|
|
309
235
|
}
|
|
310
|
-
/**
|
|
311
|
-
* Same as {@link fromApiEffectSwitchMap}, instead one inner subscription is kept by id.
|
|
312
|
-
* @param successHandler
|
|
313
|
-
* @param errorHandler
|
|
314
|
-
* @param cancelRequestActionFactory
|
|
315
|
-
* @param cleanUpTimer
|
|
316
|
-
*/
|
|
317
236
|
function fromApiEffectSwitchMapById(successHandler, errorHandler, cancelRequestActionFactory, cleanUpTimer) {
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
const streams = Object.values(innerSourcesById).map(([_, obs]) => obs);
|
|
340
|
-
return merge(...streams);
|
|
341
|
-
}));
|
|
342
|
-
};
|
|
237
|
+
const innerSourcesById = {};
|
|
238
|
+
return (source$) => {
|
|
239
|
+
return source$.pipe(filter$1((action) => {
|
|
240
|
+
if (!isIdentifiedCallAction(action) || !action.id) return false;
|
|
241
|
+
if (isIdentifiedCallAction(action) && innerSourcesById[action.id]) {
|
|
242
|
+
innerSourcesById[action.id][0].next(action);
|
|
243
|
+
return false;
|
|
244
|
+
}
|
|
245
|
+
return true;
|
|
246
|
+
}), switchMap((action) => {
|
|
247
|
+
const newIdSubject = new BehaviorSubject(action);
|
|
248
|
+
const newId$ = newIdSubject.pipe(fromApiEffectSwitchMap(successHandler, errorHandler, cancelRequestActionFactory));
|
|
249
|
+
innerSourcesById[action.id] = [newIdSubject, newId$];
|
|
250
|
+
if (cleanUpTimer !== void 0) newIdSubject.pipe(switchMap((myAction) => from(myAction.call).pipe(delay(cleanUpTimer), finalize(() => {
|
|
251
|
+
delete innerSourcesById[myAction.id];
|
|
252
|
+
newIdSubject.complete();
|
|
253
|
+
})))).subscribe();
|
|
254
|
+
const streams = Object.values(innerSourcesById).map(([_, obs]) => obs);
|
|
255
|
+
return merge(...streams);
|
|
256
|
+
}));
|
|
257
|
+
};
|
|
343
258
|
}
|
|
344
|
-
|
|
345
|
-
/**
|
|
346
|
-
* Returns a creator that makes sure that requestId is defined in the action's properties by generating one
|
|
347
|
-
* if needed.
|
|
348
|
-
*/
|
|
349
259
|
const asyncProps = () => {
|
|
350
|
-
|
|
260
|
+
return (props) => isAsyncRequest(props) ? props : {
|
|
261
|
+
...props,
|
|
262
|
+
requestId: v4()
|
|
263
|
+
};
|
|
351
264
|
};
|
|
352
|
-
|
|
353
|
-
/**
|
|
354
|
-
* Serializer for asynchronous store.
|
|
355
|
-
* @param state State of an asynchronous store to serialize
|
|
356
|
-
* @returns a plain json object to pass to json.stringify
|
|
357
|
-
*/
|
|
358
265
|
function asyncSerializer(state) {
|
|
359
|
-
|
|
266
|
+
return asyncStoreItemAdapter.clearAsyncStoreItem(state);
|
|
360
267
|
}
|
|
361
|
-
/**
|
|
362
|
-
* Serializer for asynchronous entity store.
|
|
363
|
-
* @param state State of an asynchronous entity store to serialize
|
|
364
|
-
* @returns a plain json object to pass to json.stringify
|
|
365
|
-
*/
|
|
366
268
|
function asyncEntitySerializer(state) {
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
269
|
+
const entities = state.ids.reduce((entitiesAcc, entityId) => {
|
|
270
|
+
entitiesAcc[entityId] = asyncStoreItemAdapter.clearAsyncStoreItem(state.entities[entityId]);
|
|
271
|
+
return entitiesAcc;
|
|
272
|
+
}, {});
|
|
273
|
+
return {
|
|
274
|
+
...asyncStoreItemAdapter.clearAsyncStoreItem(state),
|
|
275
|
+
entities
|
|
276
|
+
};
|
|
372
277
|
}
|
|
373
|
-
/**
|
|
374
|
-
* Serializer for asynchronous entity store with status.
|
|
375
|
-
* @param state State of an asynchronous entity store with status to serialize
|
|
376
|
-
* @returns a plain json object to pass to json.stringify
|
|
377
|
-
*/
|
|
378
278
|
function asyncEntityWithStatusSerializer(state) {
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
this.deserialize = serializer.deserialize || this.deserialize;
|
|
391
|
-
this.reviver = serializer.reviver || this.reviver;
|
|
392
|
-
this.replacer = serializer.replacer || this.replacer;
|
|
393
|
-
this.initialState = serializer.initialState || this.initialState;
|
|
394
|
-
}
|
|
279
|
+
const entities = state.ids.reduce((entitiesAcc, entityId) => {
|
|
280
|
+
entitiesAcc[entityId] = {
|
|
281
|
+
...asyncStoreItemAdapter.clearAsyncStoreItem(state.entities[entityId]),
|
|
282
|
+
status: {}
|
|
283
|
+
};
|
|
284
|
+
return entitiesAcc;
|
|
285
|
+
}, {});
|
|
286
|
+
return {
|
|
287
|
+
...asyncStoreItemAdapter.clearAsyncStoreItem(state),
|
|
288
|
+
entities
|
|
289
|
+
};
|
|
395
290
|
}
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
291
|
+
var StateSerializer = class {
|
|
292
|
+
constructor(serializer) {
|
|
293
|
+
this.reviver = (_, value) => value;
|
|
294
|
+
this.serialize = serializer.serialize || this.serialize;
|
|
295
|
+
this.deserialize = serializer.deserialize || this.deserialize;
|
|
296
|
+
this.reviver = serializer.reviver || this.reviver;
|
|
297
|
+
this.replacer = serializer.replacer || this.replacer;
|
|
298
|
+
this.initialState = serializer.initialState || this.initialState;
|
|
299
|
+
}
|
|
300
|
+
};
|
|
402
301
|
function padNumber(val, digits = 2) {
|
|
403
|
-
|
|
404
|
-
|
|
302
|
+
const str = `${val}`;
|
|
303
|
+
return "0".repeat(Math.max(0, digits - str.length)) + str;
|
|
405
304
|
}
|
|
406
|
-
/**
|
|
407
|
-
* Returns TRUE if bootstrap config environment is production FALSE otherwise
|
|
408
|
-
* @param dataset
|
|
409
|
-
* @returns TRUE if bootstrap config environment is production FALSE otherwise
|
|
410
|
-
*/
|
|
411
305
|
function isProductionEnvironment(dataset) {
|
|
412
|
-
|
|
413
|
-
return bootstrapConfig?.environment === 'prod';
|
|
306
|
+
return (dataset.bootstrapconfig && JSON.parse(dataset.bootstrapconfig))?.environment === "prod";
|
|
414
307
|
}
|
|
415
|
-
|
|
416
308
|
const defaultConstruct = (data) => data;
|
|
417
309
|
const isDate = (data) => data instanceof Date && !Number.isNaN(data);
|
|
418
|
-
/**
|
|
419
|
-
* Check if an object is not an array or a date
|
|
420
|
-
* @param obj
|
|
421
|
-
* @param additionalMappers
|
|
422
|
-
*/
|
|
423
310
|
function isObject(obj, additionalMappers) {
|
|
424
|
-
|
|
311
|
+
return obj instanceof Object && !Array.isArray(obj) && !additionalMappers?.some((mapper) => mapper.condition(obj)) && !isDate(obj);
|
|
425
312
|
}
|
|
426
|
-
/**
|
|
427
|
-
* Return a new reference of the given object
|
|
428
|
-
* @param obj
|
|
429
|
-
* @param additionalMappers
|
|
430
|
-
*/
|
|
431
313
|
function immutablePrimitive(obj, additionalMappers) {
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
}
|
|
440
|
-
if (isDate(obj)) {
|
|
441
|
-
return new Date(obj);
|
|
442
|
-
}
|
|
443
|
-
else if (obj instanceof Object) {
|
|
444
|
-
return deepFill(obj, obj, additionalMappers);
|
|
445
|
-
}
|
|
446
|
-
else {
|
|
447
|
-
return obj;
|
|
448
|
-
}
|
|
314
|
+
if (Array.isArray(obj)) return obj.slice();
|
|
315
|
+
const matchingPrimitive = additionalMappers?.find((mapper) => mapper.condition(obj));
|
|
316
|
+
const resolvedType = matchingPrimitive && (matchingPrimitive.construct || defaultConstruct)(obj);
|
|
317
|
+
if (resolvedType !== void 0) return resolvedType;
|
|
318
|
+
if (isDate(obj)) return new Date(obj);
|
|
319
|
+
else if (obj instanceof Object) return deepFill(obj, obj, additionalMappers);
|
|
320
|
+
else return obj;
|
|
449
321
|
}
|
|
450
|
-
/**
|
|
451
|
-
* Deep fill of base object using source
|
|
452
|
-
* It will do a deep merge of the objects, overriding arrays
|
|
453
|
-
* All properties not present in source, but present in base, will remain
|
|
454
|
-
* @param base
|
|
455
|
-
* @param source
|
|
456
|
-
* @param additionalMappers Map of conditions of type mapper
|
|
457
|
-
*/
|
|
458
322
|
function deepFill(base, source, additionalMappers) {
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
}
|
|
470
|
-
else if (key in source && typeof base[key] === typeof source[key]) {
|
|
471
|
-
const keyOfSource = source[key];
|
|
472
|
-
newObj[key] = typeof keyOfSource === 'undefined' ? immutablePrimitive(base[key], additionalMappers) : deepFill(base[key], keyOfSource, additionalMappers);
|
|
473
|
-
}
|
|
474
|
-
else {
|
|
475
|
-
newObj[key] = immutablePrimitive(base[key], additionalMappers);
|
|
476
|
-
}
|
|
477
|
-
}
|
|
478
|
-
// getting keys present in source and not present in base
|
|
479
|
-
for (const key in source) {
|
|
480
|
-
if (!(key in newObj)) {
|
|
481
|
-
newObj[key] = immutablePrimitive(source[key], additionalMappers);
|
|
482
|
-
}
|
|
483
|
-
}
|
|
484
|
-
return newObj;
|
|
323
|
+
if (typeof source === "undefined") return deepFill(base, base, additionalMappers);
|
|
324
|
+
if (!isObject(base, additionalMappers)) return immutablePrimitive(typeof source === "undefined" ? base : source, additionalMappers);
|
|
325
|
+
const newObj = { ...base };
|
|
326
|
+
for (const key in base) if (source[key] === null) newObj[key] = immutablePrimitive(null, additionalMappers);
|
|
327
|
+
else if (key in source && typeof base[key] === typeof source[key]) {
|
|
328
|
+
const keyOfSource = source[key];
|
|
329
|
+
newObj[key] = typeof keyOfSource === "undefined" ? immutablePrimitive(base[key], additionalMappers) : deepFill(base[key], keyOfSource, additionalMappers);
|
|
330
|
+
} else newObj[key] = immutablePrimitive(base[key], additionalMappers);
|
|
331
|
+
for (const key in source) if (!(key in newObj)) newObj[key] = immutablePrimitive(source[key], additionalMappers);
|
|
332
|
+
return newObj;
|
|
485
333
|
}
|
|
486
|
-
|
|
487
|
-
/**
|
|
488
|
-
* Buffers and emits data for lazy/progressive rendering of big lists
|
|
489
|
-
* That could solve issues with long-running tasks when trying to render an array
|
|
490
|
-
* of similar components.
|
|
491
|
-
* @param delayMs Delay between data emits
|
|
492
|
-
* @param concurrency Amount of elements that should be emitted at once
|
|
493
|
-
*/
|
|
494
334
|
function lazyArray(delayMs = 0, concurrency = 2) {
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
if (scanDidComplete) {
|
|
509
|
-
isFirstEmission = false;
|
|
510
|
-
}
|
|
511
|
-
}));
|
|
512
|
-
}));
|
|
513
|
-
};
|
|
335
|
+
let isFirstEmission = true;
|
|
336
|
+
return (source$) => {
|
|
337
|
+
return source$.pipe(mergeMap((items) => {
|
|
338
|
+
if (!isFirstEmission) return of(items);
|
|
339
|
+
return from(items).pipe(bufferCount(concurrency), concatMap((value, index) => {
|
|
340
|
+
return of(value).pipe(observeOn(animationFrameScheduler), delay(index * delayMs));
|
|
341
|
+
}), scan((acc, steps) => {
|
|
342
|
+
return [...acc, ...steps];
|
|
343
|
+
}, []), tap((scannedItems) => {
|
|
344
|
+
if (scannedItems.length === items.length) isFirstEmission = false;
|
|
345
|
+
}));
|
|
346
|
+
}));
|
|
347
|
+
};
|
|
514
348
|
}
|
|
515
|
-
|
|
516
|
-
/**
|
|
517
|
-
* Generated bundle index. Do not edit.
|
|
518
|
-
*/
|
|
519
|
-
|
|
520
349
|
export { DEFAULT_BUILD_PROPERTIES, O3rComponent, StateSerializer, applicationMessageTarget, asyncEntitySerializer, asyncEntityWithStatusSerializer, asyncProps, asyncSerializer, asyncStoreItemAdapter, computeItemIdentifier, createEntityAsyncRequestAdapter, deepFill, filterMessageContent, fromApiEffectSwitchMap, fromApiEffectSwitchMapById, immutablePrimitive, isAsyncRequest, isCallAction, isIdentifiedCallAction, isObject, isOtterMessage, isProductionEnvironment, isToAppOtterMessage, lazyArray, otterComponentInfoPropertyName, otterMessageType, padNumber, sendOtterMessage };
|
|
521
|
-
|
|
350
|
+
|
|
351
|
+
//# sourceMappingURL=o3r-core.mjs.map
|