@kosdev-code/kos-dispense-sdk 3.0.26 → 3.0.27
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/dispense-registration-manager-Da9CW_cN.js.map +1 -1
- package/dispense-registration-manager-Dtb31fcI.cjs.map +1 -1
- package/{extension-utils-CwctwFhK.cjs → extension-utils-Cfhe358W.cjs} +39 -166
- package/extension-utils-Cfhe358W.cjs.map +1 -0
- package/{extension-utils-C_pwmFbZ.js → extension-utils-D_dnBLH6.js} +39 -166
- package/extension-utils-D_dnBLH6.js.map +1 -0
- package/index.cjs +2 -2
- package/index.js +2 -2
- package/models/constants/constants.d.ts +14 -178
- package/models/constants/constants.d.ts.map +1 -1
- package/models/models/assembly/assembly-registration.d.ts +9 -69
- package/models/models/assembly/assembly-registration.d.ts.map +1 -1
- package/models/models/availability/availability-model.d.ts +10 -76
- package/models/models/availability/availability-model.d.ts.map +1 -1
- package/models/models/availability/types/index.d.ts +3 -12
- package/models/models/board/board-container-registration.d.ts +9 -74
- package/models/models/board/board-container-registration.d.ts.map +1 -1
- package/models/models/board/board-registration.d.ts +9 -72
- package/models/models/board/board-registration.d.ts.map +1 -1
- package/models/models/device-assembly/device-assembly-registration.d.ts +10 -76
- package/models/models/device-assembly/device-assembly-registration.d.ts.map +1 -1
- package/models/models/generic-pour/generic-pour-registration.d.ts +9 -72
- package/models/models/generic-pour/generic-pour-registration.d.ts.map +1 -1
- package/models/models/holder/holder-model.d.ts +9 -73
- package/models/models/holder/holder-model.d.ts.map +1 -1
- package/models/models/holder-container/holder-container-model.d.ts +9 -68
- package/models/models/holder-container/holder-container-model.d.ts.map +1 -1
- package/models/models/ingredient/ingredient-model.d.ts +9 -74
- package/models/models/ingredient/ingredient-model.d.ts.map +1 -1
- package/models/models/ingredient/types/index.d.ts +3 -10
- package/models/models/ingredient-container/ingredient-container-model.d.ts +9 -68
- package/models/models/ingredient-container/ingredient-container-model.d.ts.map +1 -1
- package/models/models/nozzle/nozzle-model.d.ts +10 -72
- package/models/models/nozzle/nozzle-model.d.ts.map +1 -1
- package/models/models/nozzle/services/nozzle-services.d.ts +11 -65
- package/models/models/nozzle/services/nozzle-services.d.ts.map +1 -1
- package/models/models/pump/pump-model.d.ts +9 -79
- package/models/models/pump/pump-model.d.ts.map +1 -1
- package/models/models/pump-container/pump-container-model.d.ts +9 -68
- package/models/models/pump-container/pump-container-model.d.ts.map +1 -1
- package/models/models/types/intent.d.ts +11 -78
- package/models/models/types/intent.d.ts.map +1 -1
- package/models/utils/extension-utils.d.ts +38 -165
- package/models/utils/extension-utils.d.ts.map +1 -1
- package/models.cjs +1 -1
- package/models.js +1 -1
- package/package.json +2 -2
- package/{pump-provider-CAKW652V.js → pump-provider-BQmCKz7S.js} +3 -5
- package/pump-provider-BQmCKz7S.js.map +1 -0
- package/{pump-provider-SXrqGmxO.cjs → pump-provider-uNNMh9uh.cjs} +3 -5
- package/pump-provider-uNNMh9uh.cjs.map +1 -0
- package/ui/hooks/cui-kit/use-default-cui-kit-lifecycle.d.ts +16 -43
- package/ui/hooks/cui-kit/use-default-cui-kit-lifecycle.d.ts.map +1 -1
- package/ui/hooks/ingredient/use-ingredient-pour.d.ts +7 -18
- package/ui/hooks/ingredient/use-ingredient-pour.d.ts.map +1 -1
- package/ui/hooks/nozzle-pour/use-nozzle-pour.d.ts +6 -17
- package/ui/hooks/nozzle-pour/use-nozzle-pour.d.ts.map +1 -1
- package/ui/hooks/pour/use-pour.d.ts +7 -18
- package/ui/hooks/pour/use-pour.d.ts.map +1 -1
- package/ui.cjs +1 -1
- package/ui.js +1 -1
- package/extension-utils-C_pwmFbZ.js.map +0 -1
- package/extension-utils-CwctwFhK.cjs.map +0 -1
- package/pump-provider-CAKW652V.js.map +0 -1
- package/pump-provider-SXrqGmxO.cjs.map +0 -1
|
@@ -80,55 +80,18 @@ const getFuelGaugeValue = (holder) => {
|
|
|
80
80
|
class DispenseExtensionManager {
|
|
81
81
|
core = new kosUiSdk.CoreExtensionManager();
|
|
82
82
|
/**
|
|
83
|
-
*
|
|
83
|
+
* Registers a data mapper for the {@link IngredientModel}.
|
|
84
84
|
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
87
|
-
*
|
|
85
|
+
* Ingredient service data often needs properties the base model does not carry. The mapper receives each
|
|
86
|
+
* {@link IngredientResponse} and the data returned by the ingredient loader as context, and its result
|
|
87
|
+
* becomes the model's `data` property.
|
|
88
88
|
*
|
|
89
89
|
* @param ingredientDataMapper - Mapping function that maps an {@link IngredientResponse} into additional model data
|
|
90
90
|
* @param options - Optional {@link ExtensionOptions} to control failure behavior.
|
|
91
91
|
* Defaults to `failurePolicy: "throw"`, which throws an {@link ExtensionException} on mapper failure.
|
|
92
92
|
* Set to `"continue"` to log the error and continue processing remaining mappers.
|
|
93
93
|
* @returns this instance for chaining
|
|
94
|
-
|
|
95
|
-
* @example
|
|
96
|
-
* The following example shows how to map the data from the service response into the {@link IngredientModel}.
|
|
97
|
-
* The context is provided by the {@link IngredientLoader} extension point with its data being used to optionally augment the
|
|
98
|
-
* ingredient data.
|
|
99
|
-
*
|
|
100
|
-
* The result of the mapping will be available in the `data` property of the {@link IngredientModel}.
|
|
101
|
-
*
|
|
102
|
-
* In this case the `IngedientReponseData` interface represents the data being returned by the ingredient service and the
|
|
103
|
-
* `IngredientData` interface represents the data that will be available in the {@link IngredientModel.data} property. The `ingredientDataMapper`
|
|
104
|
-
* is responsible for mapping from one format to the other.
|
|
105
|
-
*
|
|
106
|
-
* ```typescript
|
|
107
|
-
*
|
|
108
|
-
* interface IngredientResponseData extends NozzleServices.IngredientResponse {
|
|
109
|
-
* chilled: boolean;
|
|
110
|
-
* carbonated: boolean;
|
|
111
|
-
* highYield: boolean;
|
|
112
|
-
* }
|
|
113
|
-
*
|
|
114
|
-
* interface IngredientData {
|
|
115
|
-
* chilled: boolean;
|
|
116
|
-
* carbonated: boolean;
|
|
117
|
-
* highYield: boolean;
|
|
118
|
-
* }
|
|
119
|
-
*
|
|
120
|
-
* export const ingredientDataMapper = async (
|
|
121
|
-
* data: IngredientResponseData,
|
|
122
|
-
* context: IngredientContext
|
|
123
|
-
* ): Promise<IngredientData> => {
|
|
124
|
-
* return {
|
|
125
|
-
* chilled: data.chilled,
|
|
126
|
-
* carbonated: data.carbonated,
|
|
127
|
-
* highYield: data.highYield,
|
|
128
|
-
* }
|
|
129
|
-
* }
|
|
130
|
-
* ```
|
|
131
|
-
* */
|
|
94
|
+
*/
|
|
132
95
|
registerIngredientDataMapper(ingredientDataMapper, options) {
|
|
133
96
|
kosUiSdk.ExtensionManager.dataMapper.registerDataMapper(
|
|
134
97
|
dispenseRegistrationManager.ExtensionType.IngredientMapper,
|
|
@@ -138,34 +101,14 @@ class DispenseExtensionManager {
|
|
|
138
101
|
return this;
|
|
139
102
|
}
|
|
140
103
|
/**
|
|
141
|
-
*
|
|
104
|
+
* Registers a loader whose result is passed as context to the ingredient data and type mappers.
|
|
142
105
|
*
|
|
143
106
|
* @param ingredientLoader - Async function that loads and returns ingredient context data
|
|
144
107
|
* @param options - Optional {@link ExtensionOptions} to control failure behavior.
|
|
145
108
|
* Defaults to `failurePolicy: "throw"`, which throws an {@link ExtensionException} on loader failure.
|
|
146
109
|
* Set to `"continue"` to log the error and return `undefined` instead.
|
|
147
110
|
* @returns this instance for chaining
|
|
148
|
-
|
|
149
|
-
* @example
|
|
150
|
-
* The following example shows how to load the brandset data, normalize it into a map and then provide it back to the framework
|
|
151
|
-
* where it can be used by the other extension points.
|
|
152
|
-
*
|
|
153
|
-
* In the ingredient container model, the data is provided to the {@link IngredientMapper} extension point in order to augment ingredient data
|
|
154
|
-
* and also loaded into the ingredient container model context in order to make the data available throughout the code.
|
|
155
|
-
*
|
|
156
|
-
* ```typescript
|
|
157
|
-
* export const ingredientContextLoader = async (): Promise<BeverageContext> => {
|
|
158
|
-
* const response = await kosFetch('kos:/system/some/ingredient/endpoint.json');
|
|
159
|
-
*
|
|
160
|
-
* if (response.status !== 200) {
|
|
161
|
-
* KosLog.error('Failed to load ingredient data');
|
|
162
|
-
* return {};
|
|
163
|
-
* }
|
|
164
|
-
* const json = await response.json();
|
|
165
|
-
* return json;
|
|
166
|
-
* };
|
|
167
|
-
* ```
|
|
168
|
-
* */
|
|
111
|
+
*/
|
|
169
112
|
registerIngredientLoader(ingredientLoader, options) {
|
|
170
113
|
kosUiSdk.ExtensionManager.loader.registerLoader(
|
|
171
114
|
dispenseRegistrationManager.ExtensionType.IngredientLoader,
|
|
@@ -261,7 +204,10 @@ class DispenseExtensionManager {
|
|
|
261
204
|
return this;
|
|
262
205
|
}
|
|
263
206
|
/**
|
|
264
|
-
*
|
|
207
|
+
* Registers a data mapper for the {@link AvailabilityModel}.
|
|
208
|
+
*
|
|
209
|
+
* The mapper receives each availability node, with its `groupId`, and the data returned by the
|
|
210
|
+
* availability loader as context. Its result becomes the model's `data` property.
|
|
265
211
|
*
|
|
266
212
|
* @param availabilityMapper - Mapping function that maps a {@link GroupBeverageResponse} into additional availability data
|
|
267
213
|
* @param options - Optional {@link ExtensionOptions} to control failure behavior.
|
|
@@ -270,28 +216,15 @@ class DispenseExtensionManager {
|
|
|
270
216
|
* @returns this instance for chaining
|
|
271
217
|
*
|
|
272
218
|
* @example
|
|
273
|
-
* The following example shows how to map the data from the service response into the {@link AvailabilityModel}.
|
|
274
|
-
* The context is provided by the {@link AvailabilityLoader} extension point with its data being used to augment the
|
|
275
|
-
* availability data.
|
|
276
|
-
*
|
|
277
|
-
* The result of the mapping will be available in the `data` property of the {@link AvailabilityModel}.
|
|
278
|
-
*
|
|
279
219
|
* ```typescript
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
*
|
|
283
|
-
* )
|
|
284
|
-
*
|
|
285
|
-
*
|
|
286
|
-
* `http://localhost:8081/system/brandset/${context?.[id]?.icon}`
|
|
287
|
-
* );
|
|
288
|
-
* const cuiColorCode = context?.[id]?.cuiColorCode
|
|
289
|
-
* ? context?.[id]?.cuiColorCode
|
|
290
|
-
* : '';
|
|
291
|
-
* return { iconUrl, cuiColorCode };
|
|
292
|
-
* };
|
|
220
|
+
* const beverageDataMapper: AvailabilityDataMapper<BeverageData> = async (
|
|
221
|
+
* data,
|
|
222
|
+
* context?: Record<string, BrandsetIngredient>
|
|
223
|
+
* ) => ({
|
|
224
|
+
* iconUrl: context?.[data.altId]?.icon ?? "",
|
|
225
|
+
* });
|
|
293
226
|
* ```
|
|
294
|
-
|
|
227
|
+
*/
|
|
295
228
|
registerAvailabilityDataMapper(availabilityMapper, options) {
|
|
296
229
|
kosUiSdk.ExtensionManager.dataMapper.registerDataMapper(
|
|
297
230
|
dispenseRegistrationManager.ExtensionType.AvailabilityMapper,
|
|
@@ -301,7 +234,8 @@ class DispenseExtensionManager {
|
|
|
301
234
|
return this;
|
|
302
235
|
}
|
|
303
236
|
/**
|
|
304
|
-
*
|
|
237
|
+
* Registers a loader whose result is passed as context to the availability data mapper. A common use is
|
|
238
|
+
* loading UI-specific brandset data that the backend service does not provide.
|
|
305
239
|
*
|
|
306
240
|
* @param availabilityLoader - Async function that loads and returns availability context data
|
|
307
241
|
* @param options - Optional {@link ExtensionOptions} to control failure behavior.
|
|
@@ -310,32 +244,14 @@ class DispenseExtensionManager {
|
|
|
310
244
|
* @returns this instance for chaining
|
|
311
245
|
*
|
|
312
246
|
* @example
|
|
313
|
-
* A common use case is to load brandset data that is UI specific and not provided directly by the Java service.
|
|
314
|
-
*
|
|
315
|
-
* The following example shows how to load the brandset data, normalize it into a map and then provide it back to the framework
|
|
316
|
-
* where it can be used by the other extension points.
|
|
317
|
-
*
|
|
318
|
-
* In the nozzle model, the data is provided to the {@link AvailabilityMapper} extension point in order to augment availability data
|
|
319
|
-
* and also loaded into the nozzle model context in order to make the data available throughout the code.
|
|
320
|
-
*
|
|
321
247
|
* ```typescript
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
*
|
|
327
|
-
* return {};
|
|
328
|
-
* }
|
|
329
|
-
* const json: BrandsetResponse | null = await response.json();
|
|
330
|
-
* const initialBeverages: Record<string, BrandsetIngredient> = {};
|
|
331
|
-
* const beverages = json?.ingredients?.reduce((acc, beverage) => {
|
|
332
|
-
* acc[beverage.ingredientId] = beverage;
|
|
333
|
-
* return acc;
|
|
334
|
-
* }, initialBeverages);
|
|
335
|
-
* return beverages;
|
|
336
|
-
* };
|
|
248
|
+
* const beverageContextLoader = async () => {
|
|
249
|
+
* const response = await kosFetch("kos:/system/brandset/brandset.json");
|
|
250
|
+
* const json: BrandsetResponse = await response.json();
|
|
251
|
+
* return Object.fromEntries(json.ingredients.map((i) => [i.ingredientId, i]));
|
|
252
|
+
* };
|
|
337
253
|
* ```
|
|
338
|
-
|
|
254
|
+
*/
|
|
339
255
|
registerAvailabilityLoader(availabilityLoader, options) {
|
|
340
256
|
kosUiSdk.ExtensionManager.loader.registerLoader(
|
|
341
257
|
dispenseRegistrationManager.ExtensionType.AvailabilityLoader,
|
|
@@ -362,9 +278,8 @@ class DispenseExtensionManager {
|
|
|
362
278
|
return this;
|
|
363
279
|
}
|
|
364
280
|
/**
|
|
365
|
-
*
|
|
366
|
-
*
|
|
367
|
-
* point allows for the data to be mapped into the {@link AssemblyModel} and augmented with additional properties.
|
|
281
|
+
* Registers a data mapper for the {@link AssemblyModel}, for backends that extend the assembly response
|
|
282
|
+
* with additional properties. The mapper's result is merged into the assembly model.
|
|
368
283
|
*
|
|
369
284
|
* @param assemblyDataMapper - Mapping function that maps an {@link AssemblyTypes.AssemblyResponse} into additional assembly data
|
|
370
285
|
* @param options - Optional {@link ExtensionOptions} to control failure behavior.
|
|
@@ -373,60 +288,18 @@ class DispenseExtensionManager {
|
|
|
373
288
|
* @returns this instance for chaining
|
|
374
289
|
*
|
|
375
290
|
* @example
|
|
376
|
-
*
|
|
377
|
-
* In this example of an implementation of a {@link AssemblyMapper}, the {@link AssemblyResponse} data is mapped into
|
|
378
|
-
* a {@link FreestyleAssembly} object.
|
|
379
|
-
*
|
|
380
|
-
* The {@link FreestyleAssemblyResponse} interface represents the additional data being returned by the assembly service and is
|
|
381
|
-
* merged into the {@link AssemblyResponse} interface.
|
|
382
|
-
*
|
|
383
|
-
* The {@link FreestyleAssembly} interface represents the additional data, beyond the base data set, that will be merged into the {@link AssemblyModel}.
|
|
384
|
-
*
|
|
385
|
-
* The mapper is responsible for mapping from the {@link FreestyleAssemblyResponse} format to the {@link FreestyleAssembly} format.
|
|
386
291
|
* ```typescript
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
*
|
|
390
|
-
* // define the additional data being returned by the assembly service
|
|
391
|
-
* export interface FreestyleAssemblyResponse {
|
|
392
|
-
* iceAgitator?: {
|
|
393
|
-
* name: "iceAgitator";
|
|
394
|
-
* path: string;
|
|
395
|
-
* };
|
|
396
|
-
* }
|
|
397
|
-
*
|
|
398
|
-
* // define the additional data structure that will be merged into the assembly model
|
|
399
|
-
* export interface FreestyleAssembly {
|
|
400
|
-
* iceAgitator: {
|
|
401
|
-
* path: string;
|
|
402
|
-
* };
|
|
403
|
-
* carbAgitator: {
|
|
404
|
-
* path: string;
|
|
405
|
-
* };
|
|
406
|
-
* }
|
|
407
|
-
*
|
|
408
|
-
*
|
|
409
|
-
* // define the mapper that will map the data from the service response into the additional data structure
|
|
410
|
-
* // that will be merged into the assembly model.
|
|
411
|
-
* // In this case the mapper is responsible for mapping from the {@link FreestyleAssemblyResponse} format to the {@link FreestyleAssembly} format.
|
|
412
|
-
* export const assemblyDataMapper: DataMapper<
|
|
413
|
-
* AssemblyTypes.AssemblyResponse<FreestyleAssemblyResponse>,
|
|
414
|
-
* FreestyleAssembly
|
|
415
|
-
* > = async (data) => {
|
|
416
|
-
* const response = data.assemblies.reduce((acc, assembly) => {
|
|
417
|
-
* const agitatorKeys = ["iceAgitator", "carbAgitator"];
|
|
418
|
-
* agitatorKeys.forEach((key) => {
|
|
419
|
-
* const agitator = assembly[key];
|
|
420
|
-
* if (agitator) {
|
|
421
|
-
* acc[key] = agitator;
|
|
422
|
-
* }
|
|
423
|
-
* });
|
|
292
|
+
* interface IceAgitatorExt {
|
|
293
|
+
* iceAgitator?: { name: string; path: string };
|
|
294
|
+
* }
|
|
424
295
|
*
|
|
425
|
-
*
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
*
|
|
429
|
-
|
|
296
|
+
* const assemblyDataMapper: AssemblyMapper<
|
|
297
|
+
* { iceAgitatorPath?: string },
|
|
298
|
+
* AssemblyTypes.AssemblyResponse<{ AssemblyExt: IceAgitatorExt }>
|
|
299
|
+
* > = async (data) => ({
|
|
300
|
+
* iceAgitatorPath: data.assemblies.find((a) => a.iceAgitator)?.iceAgitator?.path,
|
|
301
|
+
* });
|
|
302
|
+
* ```
|
|
430
303
|
*/
|
|
431
304
|
registerAssemblyDataMapper(assemblyDataMapper, options) {
|
|
432
305
|
kosUiSdk.ExtensionManager.dataMapper.registerDataMapper(
|
|
@@ -486,4 +359,4 @@ exports.index$2 = index$4;
|
|
|
486
359
|
exports.index$3 = index$5;
|
|
487
360
|
exports.index$4 = index$1;
|
|
488
361
|
exports.index$5 = index$2;
|
|
489
|
-
//# sourceMappingURL=extension-utils-
|
|
362
|
+
//# sourceMappingURL=extension-utils-Cfhe358W.cjs.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"extension-utils-Cfhe358W.cjs","sources":["../../../packages/kos-dispense-sdk/src/models/models/holder/utils/holder-utils.ts","../../../packages/kos-dispense-sdk/src/models/utils/extension-utils.ts"],"sourcesContent":["import { kosAutoEffect } from \"@kosdev-code/kos-ui-sdk\";\nimport { useEffect, useState } from \"react\";\nimport type { HolderModel } from \"../types\";\n\nexport const getFuelGaugeValue = (holder: HolderModel) => {\n const [maxVolume, setMaxVolume] = useState<number>(\n holder?.slice?.maxVolMl ?? 0\n );\n const [remainingVolume, setRemainingVolume] = useState<number>(\n holder?.slice?.currentVolMl ?? 0\n );\n\n const [hasMaxVolume, setHasMaxVolume] = useState<boolean>(\n holder?.slice?.maxVolMl !== undefined\n );\n\n const [hasRemainingVolume, setHasRemainingVolume] = useState<boolean>(\n holder?.slice?.currentVolMl !== undefined\n );\n\n const [fillPercent, setFillPercent] = useState<number>(\n remainingVolume <= 0\n ? 0\n : Math.floor(((remainingVolume || 1) / (maxVolume || 1)) * 100)\n );\n\n const [hasFuelGuage, setHasFuelGuage] = useState<boolean>(\n hasMaxVolume && hasRemainingVolume\n );\n\n useEffect(() => {\n const disposer = kosAutoEffect(() => {\n setMaxVolume(holder?.slice?.maxVolMl ?? 0);\n setRemainingVolume(holder?.slice?.currentVolMl ?? 0);\n setHasMaxVolume(holder?.slice?.maxVolMl !== undefined);\n setHasRemainingVolume(holder?.slice?.currentVolMl !== undefined);\n setFillPercent(\n remainingVolume <= 0\n ? 0\n : Math.floor(((remainingVolume || 1) / (maxVolume || 1)) * 100)\n );\n setHasFuelGuage(hasMaxVolume && hasRemainingVolume);\n });\n\n return () => {\n disposer();\n };\n }, [holder]);\n\n return { maxVolume, remainingVolume, fillPercent, hasFuelGuage };\n};\n","/* eslint-disable @typescript-eslint/no-explicit-any */\nimport {\n CoreExtensionManager,\n DataLoader,\n DataMapper,\n EXTENSION_FEATURE_FLAG_RESOLVER,\n ExtensionManager,\n ExtensionOptions,\n IndexExtension,\n PropertyMapper,\n type FlagResolver,\n} from \"@kosdev-code/kos-ui-sdk\";\nimport { ExtensionType } from \"../constants\";\nimport { AssemblyTypes, type AssemblyModel } from \"../models\";\nimport type { HolderResponse } from \"../models/holder/services\";\nimport type { HolderModel } from \"../models/holder/types\";\nimport type { IngredientResponse } from \"../models/ingredient/services\";\nimport type { BeverageResponse } from \"../models/nozzle/services\";\nimport type { SelectedPourable } from \"../models/nozzle/types\";\n\nexport type IngredientDataMapper<\n AdditionalData extends object = Record<string, any>\n> = DataMapper<IngredientResponse, AdditionalData, any>;\n\n/**\n * Mapping function that maps an ingredient response into the type property of\n * the {@link IngredientModel}.\n */\nexport type IngredientTypeMapper<\n T extends IngredientResponse = IngredientResponse\n> = PropertyMapper<T, string>;\n\n/**\n * Mapping function that maps additional data from holder service response\n * into the {@link HolderModel} data.\n */\nexport type HolderTypeMapper<T extends HolderResponse = HolderResponse> =\n PropertyMapper<T, string>;\n\n/**\n * Mapping function that maps additional data from holder service response\n * into the {@link HolderModel} data.\n */\nexport type HolderDataMapper<\n AdditionalData extends object = Record<string, any>,\n HolderData extends HolderResponse = HolderResponse\n> = DataMapper<HolderData, AdditionalData, any>;\n\nexport type GroupBeverageResponse = BeverageResponse & { groupId: string };\nexport type AvailabilityDataMapper<\n AdditionalData extends object = Record<string, any>,\n AvailabilityData extends GroupBeverageResponse = GroupBeverageResponse\n> = DataMapper<AvailabilityData, AdditionalData, any>;\n\nexport type SelectedPourableMapper = DataMapper<SelectedPourable, any>;\n\nexport type BoardDataMapper<\n AdditionalData extends object = Record<string, any>,\n BoardData extends AssemblyTypes.AssemblyBoard<any> = AssemblyTypes.AssemblyBoard<any>\n> = DataMapper<BoardData, AdditionalData, any>;\n\nexport type AssemblyMapper<\n AdditionalData extends object = Record<string, any>,\n AssemblyResponseData extends AssemblyTypes.AssemblyResponse<any> = AssemblyTypes.AssemblyResponse<any>\n> = DataMapper<AssemblyResponseData, AdditionalData, any>;\n/**\n * The DispenseExtensionManager is responsible for managing the extension points that are specific to the Dispense application.\n */\nexport class DispenseExtensionManager {\n core: CoreExtensionManager = new CoreExtensionManager();\n /**\n * Registers a data mapper for the {@link IngredientModel}.\n *\n * Ingredient service data often needs properties the base model does not carry. The mapper receives each\n * {@link IngredientResponse} and the data returned by the ingredient loader as context, and its result\n * becomes the model's `data` property.\n *\n * @param ingredientDataMapper - Mapping function that maps an {@link IngredientResponse} into additional model data\n * @param options - Optional {@link ExtensionOptions} to control failure behavior.\n * Defaults to `failurePolicy: \"throw\"`, which throws an {@link ExtensionException} on mapper failure.\n * Set to `\"continue\"` to log the error and continue processing remaining mappers.\n * @returns this instance for chaining\n */\n registerIngredientDataMapper(\n ingredientDataMapper: IngredientDataMapper,\n options?: ExtensionOptions\n ) {\n ExtensionManager.dataMapper.registerDataMapper(\n ExtensionType.IngredientMapper,\n ingredientDataMapper,\n options\n );\n\n return this;\n }\n\n /**\n * Registers a loader whose result is passed as context to the ingredient data and type mappers.\n *\n * @param ingredientLoader - Async function that loads and returns ingredient context data\n * @param options - Optional {@link ExtensionOptions} to control failure behavior.\n * Defaults to `failurePolicy: \"throw\"`, which throws an {@link ExtensionException} on loader failure.\n * Set to `\"continue\"` to log the error and return `undefined` instead.\n * @returns this instance for chaining\n */\n registerIngredientLoader(\n ingredientLoader: DataLoader,\n options?: ExtensionOptions\n ) {\n ExtensionManager.loader.registerLoader(\n ExtensionType.IngredientLoader,\n ingredientLoader,\n options\n );\n return this;\n }\n\n registerIngredientIndex(ingredientIndex: IndexExtension) {\n ExtensionManager.indexExtension.registerIndexExtension(\n ExtensionType.IngredientIndex,\n ingredientIndex\n );\n return this;\n }\n\n /**\n * Registers a property mapper that derives the `type` property of the {@link IngredientModel}\n * from an {@link IngredientResponse}.\n *\n * @param ingredientTypeMapper - Mapping function that extracts a type string from an {@link IngredientResponse}\n * @param options - Optional {@link ExtensionOptions} to control failure behavior.\n * Defaults to `failurePolicy: \"throw\"`, which throws an {@link ExtensionException} on mapper failure.\n * Set to `\"continue\"` to log the error and return a fallback value instead.\n * @returns this instance for chaining\n * */\n registerIngredientTypeMapper(\n ingredientTypeMapper: IngredientTypeMapper,\n options?: ExtensionOptions\n ) {\n ExtensionManager.propertyMapper.registerPropertyMapper(\n ExtensionType.IngredientTypeMapper,\n ingredientTypeMapper,\n options\n );\n return this;\n }\n\n /**\n * Registers a data mapper for the {@link HolderModel} model.\n *\n * @param holderDataMapper - Mapping function that maps additional data from a {@link HolderResponse}\n * @param options - Optional {@link ExtensionOptions} to control failure behavior.\n * Defaults to `failurePolicy: \"throw\"`, which throws an {@link ExtensionException} on mapper failure.\n * Set to `\"continue\"` to log the error and continue processing remaining mappers.\n * @returns this instance for chaining\n */\n registerHolderDataMapper(\n holderDataMapper: HolderDataMapper,\n options?: ExtensionOptions\n ) {\n ExtensionManager.dataMapper.registerDataMapper(\n ExtensionType.HolderMapper,\n holderDataMapper,\n options\n );\n return this;\n }\n\n /**\n * Registers a property mapper that derives the `type` property of the {@link HolderModel}\n * from a {@link HolderResponse}.\n *\n * @param holderTypeMapper - Mapping function that extracts a type string from a {@link HolderResponse}\n * @param options - Optional {@link ExtensionOptions} to control failure behavior.\n * Defaults to `failurePolicy: \"throw\"`, which throws an {@link ExtensionException} on mapper failure.\n * Set to `\"continue\"` to log the error and return a fallback value instead.\n * @returns this instance for chaining\n */\n registerHolderTypeMapper(\n holderTypeMapper: HolderTypeMapper,\n options?: ExtensionOptions\n ) {\n ExtensionManager.propertyMapper.registerPropertyMapper(\n ExtensionType.HolderTypeMapper,\n holderTypeMapper,\n options\n );\n return this;\n }\n\n /**\n * Maps the ingredientId property of the holder into the {@link HolderModel}.\n * If not provided, the ingredientId will assume that the value is mapped from the\n * ingredientId property of the service response.\n *\n * @param holderTypeMapper - Mapping function that extracts the ingredientId from a {@link HolderResponse}\n * @param options - Optional {@link ExtensionOptions} to control failure behavior.\n * Defaults to `failurePolicy: \"throw\"`, which throws an {@link ExtensionException} on mapper failure.\n * Set to `\"continue\"` to log the error and return a fallback value instead.\n * @returns this instance for chaining\n * */\n registerHolderIngredientMapper(\n holderTypeMapper: HolderTypeMapper,\n options?: ExtensionOptions\n ) {\n ExtensionManager.propertyMapper.registerPropertyMapper(\n ExtensionType.HolderTypeMapper,\n holderTypeMapper,\n options\n );\n return this;\n }\n\n registerHolderIndex<T extends HolderModel = HolderModel>(\n holderIndex: IndexExtension<T>\n ) {\n ExtensionManager.indexExtension.registerIndexExtension(\n ExtensionType.HolderIndex,\n holderIndex\n );\n return this;\n }\n\n /**\n * Registers a data mapper for the {@link AvailabilityModel}.\n *\n * The mapper receives each availability node, with its `groupId`, and the data returned by the\n * availability loader as context. Its result becomes the model's `data` property.\n *\n * @param availabilityMapper - Mapping function that maps a {@link GroupBeverageResponse} into additional availability data\n * @param options - Optional {@link ExtensionOptions} to control failure behavior.\n * Defaults to `failurePolicy: \"throw\"`, which throws an {@link ExtensionException} on mapper failure.\n * Set to `\"continue\"` to log the error and continue processing remaining mappers.\n * @returns this instance for chaining\n *\n * @example\n * ```typescript\n * const beverageDataMapper: AvailabilityDataMapper<BeverageData> = async (\n * data,\n * context?: Record<string, BrandsetIngredient>\n * ) => ({\n * iconUrl: context?.[data.altId]?.icon ?? \"\",\n * });\n * ```\n */\n registerAvailabilityDataMapper(\n availabilityMapper: AvailabilityDataMapper,\n options?: ExtensionOptions\n ) {\n ExtensionManager.dataMapper.registerDataMapper(\n ExtensionType.AvailabilityMapper,\n availabilityMapper,\n options\n );\n return this;\n }\n\n /**\n * Registers a loader whose result is passed as context to the availability data mapper. A common use is\n * loading UI-specific brandset data that the backend service does not provide.\n *\n * @param availabilityLoader - Async function that loads and returns availability context data\n * @param options - Optional {@link ExtensionOptions} to control failure behavior.\n * Defaults to `failurePolicy: \"throw\"`, which throws an {@link ExtensionException} on loader failure.\n * Set to `\"continue\"` to log the error and return `undefined` instead.\n * @returns this instance for chaining\n *\n * @example\n * ```typescript\n * const beverageContextLoader = async () => {\n * const response = await kosFetch(\"kos:/system/brandset/brandset.json\");\n * const json: BrandsetResponse = await response.json();\n * return Object.fromEntries(json.ingredients.map((i) => [i.ingredientId, i]));\n * };\n * ```\n */\n registerAvailabilityLoader(\n availabilityLoader: DataLoader,\n options?: ExtensionOptions\n ) {\n ExtensionManager.loader.registerLoader(\n ExtensionType.AvailabilityLoader,\n availabilityLoader,\n options\n );\n return this;\n }\n\n /**\n * Maps the abstract {@link SelectedPourable} data into a format that is specific to the nozzle.\n *\n * @param selectedPourableMapper - Mapping function that transforms {@link SelectedPourable} data\n * @param options - Optional {@link ExtensionOptions} to control failure behavior.\n * Defaults to `failurePolicy: \"throw\"`, which throws an {@link ExtensionException} on mapper failure.\n * Set to `\"continue\"` to log the error and continue processing remaining mappers.\n * @returns this instance for chaining\n * */\n registerSelectedPourableDataMapper(\n selectedPourableMapper: SelectedPourableMapper,\n options?: ExtensionOptions\n ) {\n ExtensionManager.dataMapper.registerDataMapper(\n ExtensionType.SelectedPourableMapper,\n selectedPourableMapper,\n options\n );\n return this;\n }\n\n /**\n * Registers a data mapper for the {@link AssemblyModel}, for backends that extend the assembly response\n * with additional properties. The mapper's result is merged into the assembly model.\n *\n * @param assemblyDataMapper - Mapping function that maps an {@link AssemblyTypes.AssemblyResponse} into additional assembly data\n * @param options - Optional {@link ExtensionOptions} to control failure behavior.\n * Defaults to `failurePolicy: \"throw\"`, which throws an {@link ExtensionException} on mapper failure.\n * Set to `\"continue\"` to log the error and continue processing remaining mappers.\n * @returns this instance for chaining\n *\n * @example\n * ```typescript\n * interface IceAgitatorExt {\n * iceAgitator?: { name: string; path: string };\n * }\n *\n * const assemblyDataMapper: AssemblyMapper<\n * { iceAgitatorPath?: string },\n * AssemblyTypes.AssemblyResponse<{ AssemblyExt: IceAgitatorExt }>\n * > = async (data) => ({\n * iceAgitatorPath: data.assemblies.find((a) => a.iceAgitator)?.iceAgitator?.path,\n * });\n * ```\n */\n registerAssemblyDataMapper(\n assemblyDataMapper: AssemblyMapper,\n options?: ExtensionOptions\n ) {\n ExtensionManager.dataMapper.registerDataMapper(\n ExtensionType.AssemblyMapper,\n assemblyDataMapper,\n options\n );\n return this;\n }\n\n registerBoardIndex(boardIndex: IndexExtension) {\n ExtensionManager.indexExtension.registerIndexExtension(\n ExtensionType.BoardIndex,\n boardIndex\n );\n return this;\n }\n\n /**\n * Registers a data mapper for the board model within an assembly.\n *\n * @param boardDataMapper - Mapping function that maps an {@link AssemblyTypes.AssemblyBoard} into additional board data\n * @param options - Optional {@link ExtensionOptions} to control failure behavior.\n * Defaults to `failurePolicy: \"throw\"`, which throws an {@link ExtensionException} on mapper failure.\n * Set to `\"continue\"` to log the error and continue processing remaining mappers.\n * @returns this instance for chaining\n */\n registerBoardDataMapper(\n boardDataMapper: BoardDataMapper<any, any>,\n options?: ExtensionOptions\n ) {\n ExtensionManager.dataMapper.registerDataMapper(\n ExtensionType.BoardMapper,\n boardDataMapper,\n options\n );\n return this;\n }\n\n registerAssemblyFeatureFlagResolver(\n assemblyFeatureFlagResolver: FlagResolver<AssemblyModel>\n ) {\n ExtensionManager[EXTENSION_FEATURE_FLAG_RESOLVER]?.register(\n ExtensionType.AssemblyFeatureFlags,\n assemblyFeatureFlagResolver\n );\n return this;\n }\n}\n\n/**\n * The KosExtensionManager provides access to the extension points that are provided in the SDK for Dispense applications.\n *\n * The extension points are divided into two categories:\n *\n * @param core - The core extension {@link CoreExtensionManager} points are used to extend the base models that are provided by the SDK.\n * @param dispense - The dispense extension {@link DispenseExtensionManager} points are used to extend the models that are specific to the Dispense SDK.\n */\nexport class KosExtensionManager {\n dispense: DispenseExtensionManager;\n core: CoreExtensionManager;\n constructor() {\n this.dispense = new DispenseExtensionManager();\n this.core = new CoreExtensionManager();\n }\n}\n"],"names":["useState","useEffect","kosAutoEffect","CoreExtensionManager","ExtensionManager","ExtensionType","EXTENSION_FEATURE_FLAG_RESOLVER"],"mappings":"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"}
|
|
@@ -79,55 +79,18 @@ const getFuelGaugeValue = (holder) => {
|
|
|
79
79
|
class DispenseExtensionManager {
|
|
80
80
|
core = new CoreExtensionManager();
|
|
81
81
|
/**
|
|
82
|
-
*
|
|
82
|
+
* Registers a data mapper for the {@link IngredientModel}.
|
|
83
83
|
*
|
|
84
|
-
*
|
|
85
|
-
*
|
|
86
|
-
*
|
|
84
|
+
* Ingredient service data often needs properties the base model does not carry. The mapper receives each
|
|
85
|
+
* {@link IngredientResponse} and the data returned by the ingredient loader as context, and its result
|
|
86
|
+
* becomes the model's `data` property.
|
|
87
87
|
*
|
|
88
88
|
* @param ingredientDataMapper - Mapping function that maps an {@link IngredientResponse} into additional model data
|
|
89
89
|
* @param options - Optional {@link ExtensionOptions} to control failure behavior.
|
|
90
90
|
* Defaults to `failurePolicy: "throw"`, which throws an {@link ExtensionException} on mapper failure.
|
|
91
91
|
* Set to `"continue"` to log the error and continue processing remaining mappers.
|
|
92
92
|
* @returns this instance for chaining
|
|
93
|
-
|
|
94
|
-
* @example
|
|
95
|
-
* The following example shows how to map the data from the service response into the {@link IngredientModel}.
|
|
96
|
-
* The context is provided by the {@link IngredientLoader} extension point with its data being used to optionally augment the
|
|
97
|
-
* ingredient data.
|
|
98
|
-
*
|
|
99
|
-
* The result of the mapping will be available in the `data` property of the {@link IngredientModel}.
|
|
100
|
-
*
|
|
101
|
-
* In this case the `IngedientReponseData` interface represents the data being returned by the ingredient service and the
|
|
102
|
-
* `IngredientData` interface represents the data that will be available in the {@link IngredientModel.data} property. The `ingredientDataMapper`
|
|
103
|
-
* is responsible for mapping from one format to the other.
|
|
104
|
-
*
|
|
105
|
-
* ```typescript
|
|
106
|
-
*
|
|
107
|
-
* interface IngredientResponseData extends NozzleServices.IngredientResponse {
|
|
108
|
-
* chilled: boolean;
|
|
109
|
-
* carbonated: boolean;
|
|
110
|
-
* highYield: boolean;
|
|
111
|
-
* }
|
|
112
|
-
*
|
|
113
|
-
* interface IngredientData {
|
|
114
|
-
* chilled: boolean;
|
|
115
|
-
* carbonated: boolean;
|
|
116
|
-
* highYield: boolean;
|
|
117
|
-
* }
|
|
118
|
-
*
|
|
119
|
-
* export const ingredientDataMapper = async (
|
|
120
|
-
* data: IngredientResponseData,
|
|
121
|
-
* context: IngredientContext
|
|
122
|
-
* ): Promise<IngredientData> => {
|
|
123
|
-
* return {
|
|
124
|
-
* chilled: data.chilled,
|
|
125
|
-
* carbonated: data.carbonated,
|
|
126
|
-
* highYield: data.highYield,
|
|
127
|
-
* }
|
|
128
|
-
* }
|
|
129
|
-
* ```
|
|
130
|
-
* */
|
|
93
|
+
*/
|
|
131
94
|
registerIngredientDataMapper(ingredientDataMapper, options) {
|
|
132
95
|
ExtensionManager.dataMapper.registerDataMapper(
|
|
133
96
|
ExtensionType.IngredientMapper,
|
|
@@ -137,34 +100,14 @@ class DispenseExtensionManager {
|
|
|
137
100
|
return this;
|
|
138
101
|
}
|
|
139
102
|
/**
|
|
140
|
-
*
|
|
103
|
+
* Registers a loader whose result is passed as context to the ingredient data and type mappers.
|
|
141
104
|
*
|
|
142
105
|
* @param ingredientLoader - Async function that loads and returns ingredient context data
|
|
143
106
|
* @param options - Optional {@link ExtensionOptions} to control failure behavior.
|
|
144
107
|
* Defaults to `failurePolicy: "throw"`, which throws an {@link ExtensionException} on loader failure.
|
|
145
108
|
* Set to `"continue"` to log the error and return `undefined` instead.
|
|
146
109
|
* @returns this instance for chaining
|
|
147
|
-
|
|
148
|
-
* @example
|
|
149
|
-
* The following example shows how to load the brandset data, normalize it into a map and then provide it back to the framework
|
|
150
|
-
* where it can be used by the other extension points.
|
|
151
|
-
*
|
|
152
|
-
* In the ingredient container model, the data is provided to the {@link IngredientMapper} extension point in order to augment ingredient data
|
|
153
|
-
* and also loaded into the ingredient container model context in order to make the data available throughout the code.
|
|
154
|
-
*
|
|
155
|
-
* ```typescript
|
|
156
|
-
* export const ingredientContextLoader = async (): Promise<BeverageContext> => {
|
|
157
|
-
* const response = await kosFetch('kos:/system/some/ingredient/endpoint.json');
|
|
158
|
-
*
|
|
159
|
-
* if (response.status !== 200) {
|
|
160
|
-
* KosLog.error('Failed to load ingredient data');
|
|
161
|
-
* return {};
|
|
162
|
-
* }
|
|
163
|
-
* const json = await response.json();
|
|
164
|
-
* return json;
|
|
165
|
-
* };
|
|
166
|
-
* ```
|
|
167
|
-
* */
|
|
110
|
+
*/
|
|
168
111
|
registerIngredientLoader(ingredientLoader, options) {
|
|
169
112
|
ExtensionManager.loader.registerLoader(
|
|
170
113
|
ExtensionType.IngredientLoader,
|
|
@@ -260,7 +203,10 @@ class DispenseExtensionManager {
|
|
|
260
203
|
return this;
|
|
261
204
|
}
|
|
262
205
|
/**
|
|
263
|
-
*
|
|
206
|
+
* Registers a data mapper for the {@link AvailabilityModel}.
|
|
207
|
+
*
|
|
208
|
+
* The mapper receives each availability node, with its `groupId`, and the data returned by the
|
|
209
|
+
* availability loader as context. Its result becomes the model's `data` property.
|
|
264
210
|
*
|
|
265
211
|
* @param availabilityMapper - Mapping function that maps a {@link GroupBeverageResponse} into additional availability data
|
|
266
212
|
* @param options - Optional {@link ExtensionOptions} to control failure behavior.
|
|
@@ -269,28 +215,15 @@ class DispenseExtensionManager {
|
|
|
269
215
|
* @returns this instance for chaining
|
|
270
216
|
*
|
|
271
217
|
* @example
|
|
272
|
-
* The following example shows how to map the data from the service response into the {@link AvailabilityModel}.
|
|
273
|
-
* The context is provided by the {@link AvailabilityLoader} extension point with its data being used to augment the
|
|
274
|
-
* availability data.
|
|
275
|
-
*
|
|
276
|
-
* The result of the mapping will be available in the `data` property of the {@link AvailabilityModel}.
|
|
277
|
-
*
|
|
278
218
|
* ```typescript
|
|
279
|
-
*
|
|
280
|
-
*
|
|
281
|
-
*
|
|
282
|
-
* )
|
|
283
|
-
*
|
|
284
|
-
*
|
|
285
|
-
* `http://localhost:8081/system/brandset/${context?.[id]?.icon}`
|
|
286
|
-
* );
|
|
287
|
-
* const cuiColorCode = context?.[id]?.cuiColorCode
|
|
288
|
-
* ? context?.[id]?.cuiColorCode
|
|
289
|
-
* : '';
|
|
290
|
-
* return { iconUrl, cuiColorCode };
|
|
291
|
-
* };
|
|
219
|
+
* const beverageDataMapper: AvailabilityDataMapper<BeverageData> = async (
|
|
220
|
+
* data,
|
|
221
|
+
* context?: Record<string, BrandsetIngredient>
|
|
222
|
+
* ) => ({
|
|
223
|
+
* iconUrl: context?.[data.altId]?.icon ?? "",
|
|
224
|
+
* });
|
|
292
225
|
* ```
|
|
293
|
-
|
|
226
|
+
*/
|
|
294
227
|
registerAvailabilityDataMapper(availabilityMapper, options) {
|
|
295
228
|
ExtensionManager.dataMapper.registerDataMapper(
|
|
296
229
|
ExtensionType.AvailabilityMapper,
|
|
@@ -300,7 +233,8 @@ class DispenseExtensionManager {
|
|
|
300
233
|
return this;
|
|
301
234
|
}
|
|
302
235
|
/**
|
|
303
|
-
*
|
|
236
|
+
* Registers a loader whose result is passed as context to the availability data mapper. A common use is
|
|
237
|
+
* loading UI-specific brandset data that the backend service does not provide.
|
|
304
238
|
*
|
|
305
239
|
* @param availabilityLoader - Async function that loads and returns availability context data
|
|
306
240
|
* @param options - Optional {@link ExtensionOptions} to control failure behavior.
|
|
@@ -309,32 +243,14 @@ class DispenseExtensionManager {
|
|
|
309
243
|
* @returns this instance for chaining
|
|
310
244
|
*
|
|
311
245
|
* @example
|
|
312
|
-
* A common use case is to load brandset data that is UI specific and not provided directly by the Java service.
|
|
313
|
-
*
|
|
314
|
-
* The following example shows how to load the brandset data, normalize it into a map and then provide it back to the framework
|
|
315
|
-
* where it can be used by the other extension points.
|
|
316
|
-
*
|
|
317
|
-
* In the nozzle model, the data is provided to the {@link AvailabilityMapper} extension point in order to augment availability data
|
|
318
|
-
* and also loaded into the nozzle model context in order to make the data available throughout the code.
|
|
319
|
-
*
|
|
320
246
|
* ```typescript
|
|
321
|
-
*
|
|
322
|
-
*
|
|
323
|
-
*
|
|
324
|
-
*
|
|
325
|
-
*
|
|
326
|
-
* return {};
|
|
327
|
-
* }
|
|
328
|
-
* const json: BrandsetResponse | null = await response.json();
|
|
329
|
-
* const initialBeverages: Record<string, BrandsetIngredient> = {};
|
|
330
|
-
* const beverages = json?.ingredients?.reduce((acc, beverage) => {
|
|
331
|
-
* acc[beverage.ingredientId] = beverage;
|
|
332
|
-
* return acc;
|
|
333
|
-
* }, initialBeverages);
|
|
334
|
-
* return beverages;
|
|
335
|
-
* };
|
|
247
|
+
* const beverageContextLoader = async () => {
|
|
248
|
+
* const response = await kosFetch("kos:/system/brandset/brandset.json");
|
|
249
|
+
* const json: BrandsetResponse = await response.json();
|
|
250
|
+
* return Object.fromEntries(json.ingredients.map((i) => [i.ingredientId, i]));
|
|
251
|
+
* };
|
|
336
252
|
* ```
|
|
337
|
-
|
|
253
|
+
*/
|
|
338
254
|
registerAvailabilityLoader(availabilityLoader, options) {
|
|
339
255
|
ExtensionManager.loader.registerLoader(
|
|
340
256
|
ExtensionType.AvailabilityLoader,
|
|
@@ -361,9 +277,8 @@ class DispenseExtensionManager {
|
|
|
361
277
|
return this;
|
|
362
278
|
}
|
|
363
279
|
/**
|
|
364
|
-
*
|
|
365
|
-
*
|
|
366
|
-
* point allows for the data to be mapped into the {@link AssemblyModel} and augmented with additional properties.
|
|
280
|
+
* Registers a data mapper for the {@link AssemblyModel}, for backends that extend the assembly response
|
|
281
|
+
* with additional properties. The mapper's result is merged into the assembly model.
|
|
367
282
|
*
|
|
368
283
|
* @param assemblyDataMapper - Mapping function that maps an {@link AssemblyTypes.AssemblyResponse} into additional assembly data
|
|
369
284
|
* @param options - Optional {@link ExtensionOptions} to control failure behavior.
|
|
@@ -372,60 +287,18 @@ class DispenseExtensionManager {
|
|
|
372
287
|
* @returns this instance for chaining
|
|
373
288
|
*
|
|
374
289
|
* @example
|
|
375
|
-
*
|
|
376
|
-
* In this example of an implementation of a {@link AssemblyMapper}, the {@link AssemblyResponse} data is mapped into
|
|
377
|
-
* a {@link FreestyleAssembly} object.
|
|
378
|
-
*
|
|
379
|
-
* The {@link FreestyleAssemblyResponse} interface represents the additional data being returned by the assembly service and is
|
|
380
|
-
* merged into the {@link AssemblyResponse} interface.
|
|
381
|
-
*
|
|
382
|
-
* The {@link FreestyleAssembly} interface represents the additional data, beyond the base data set, that will be merged into the {@link AssemblyModel}.
|
|
383
|
-
*
|
|
384
|
-
* The mapper is responsible for mapping from the {@link FreestyleAssemblyResponse} format to the {@link FreestyleAssembly} format.
|
|
385
290
|
* ```typescript
|
|
386
|
-
*
|
|
387
|
-
*
|
|
388
|
-
*
|
|
389
|
-
* // define the additional data being returned by the assembly service
|
|
390
|
-
* export interface FreestyleAssemblyResponse {
|
|
391
|
-
* iceAgitator?: {
|
|
392
|
-
* name: "iceAgitator";
|
|
393
|
-
* path: string;
|
|
394
|
-
* };
|
|
395
|
-
* }
|
|
396
|
-
*
|
|
397
|
-
* // define the additional data structure that will be merged into the assembly model
|
|
398
|
-
* export interface FreestyleAssembly {
|
|
399
|
-
* iceAgitator: {
|
|
400
|
-
* path: string;
|
|
401
|
-
* };
|
|
402
|
-
* carbAgitator: {
|
|
403
|
-
* path: string;
|
|
404
|
-
* };
|
|
405
|
-
* }
|
|
406
|
-
*
|
|
407
|
-
*
|
|
408
|
-
* // define the mapper that will map the data from the service response into the additional data structure
|
|
409
|
-
* // that will be merged into the assembly model.
|
|
410
|
-
* // In this case the mapper is responsible for mapping from the {@link FreestyleAssemblyResponse} format to the {@link FreestyleAssembly} format.
|
|
411
|
-
* export const assemblyDataMapper: DataMapper<
|
|
412
|
-
* AssemblyTypes.AssemblyResponse<FreestyleAssemblyResponse>,
|
|
413
|
-
* FreestyleAssembly
|
|
414
|
-
* > = async (data) => {
|
|
415
|
-
* const response = data.assemblies.reduce((acc, assembly) => {
|
|
416
|
-
* const agitatorKeys = ["iceAgitator", "carbAgitator"];
|
|
417
|
-
* agitatorKeys.forEach((key) => {
|
|
418
|
-
* const agitator = assembly[key];
|
|
419
|
-
* if (agitator) {
|
|
420
|
-
* acc[key] = agitator;
|
|
421
|
-
* }
|
|
422
|
-
* });
|
|
291
|
+
* interface IceAgitatorExt {
|
|
292
|
+
* iceAgitator?: { name: string; path: string };
|
|
293
|
+
* }
|
|
423
294
|
*
|
|
424
|
-
*
|
|
425
|
-
*
|
|
426
|
-
*
|
|
427
|
-
*
|
|
428
|
-
|
|
295
|
+
* const assemblyDataMapper: AssemblyMapper<
|
|
296
|
+
* { iceAgitatorPath?: string },
|
|
297
|
+
* AssemblyTypes.AssemblyResponse<{ AssemblyExt: IceAgitatorExt }>
|
|
298
|
+
* > = async (data) => ({
|
|
299
|
+
* iceAgitatorPath: data.assemblies.find((a) => a.iceAgitator)?.iceAgitator?.path,
|
|
300
|
+
* });
|
|
301
|
+
* ```
|
|
429
302
|
*/
|
|
430
303
|
registerAssemblyDataMapper(assemblyDataMapper, options) {
|
|
431
304
|
ExtensionManager.dataMapper.registerDataMapper(
|
|
@@ -487,4 +360,4 @@ export {
|
|
|
487
360
|
getFuelGaugeValue as g,
|
|
488
361
|
index$3 as i
|
|
489
362
|
};
|
|
490
|
-
//# sourceMappingURL=extension-utils-
|
|
363
|
+
//# sourceMappingURL=extension-utils-D_dnBLH6.js.map
|