@wise/dynamic-flow-client 5.25.3 → 5.26.0-experimental-6048bca
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/build/main.css +1 -0
- package/build/main.js +219 -14
- package/build/main.mjs +216 -9
- package/build/tsconfig.types.tsbuildinfo +1 -1
- package/build/types/controller/FlowController.d.ts.map +1 -1
- package/build/types/domain/components/UpdatableComponent.d.ts +16 -0
- package/build/types/domain/components/UpdatableComponent.d.ts.map +1 -0
- package/build/types/domain/components/step/StepDomainComponent.d.ts +3 -0
- package/build/types/domain/components/step/StepDomainComponent.d.ts.map +1 -1
- package/build/types/domain/features/domain-event-bus/DomainEventBus.d.ts +9 -0
- package/build/types/domain/features/domain-event-bus/DomainEventBus.d.ts.map +1 -0
- package/build/types/domain/features/domain-event-bus/index.d.ts +3 -0
- package/build/types/domain/features/domain-event-bus/index.d.ts.map +1 -0
- package/build/types/domain/features/domain-event-bus/types.d.ts +9 -0
- package/build/types/domain/features/domain-event-bus/types.d.ts.map +1 -0
- package/build/types/domain/features/eventNames.d.ts +1 -1
- package/build/types/domain/features/eventNames.d.ts.map +1 -1
- package/build/types/domain/features/updatable/getPerformUpdateQuery.d.ts +12 -0
- package/build/types/domain/features/updatable/getPerformUpdateQuery.d.ts.map +1 -0
- package/build/types/domain/mappers/layout/updatableLayoutToComponent.d.ts +6 -0
- package/build/types/domain/mappers/layout/updatableLayoutToComponent.d.ts.map +1 -0
- package/build/types/domain/mappers/mapLayoutToComponent.d.ts.map +1 -1
- package/build/types/domain/mappers/mapStepToComponent.d.ts +1 -1
- package/build/types/domain/mappers/mapStepToComponent.d.ts.map +1 -1
- package/build/types/domain/mappers/schema/types.d.ts +3 -1
- package/build/types/domain/mappers/schema/types.d.ts.map +1 -1
- package/build/types/domain/mappers/utils/behavior-utils.d.ts.map +1 -1
- package/build/types/domain/types.d.ts +4 -3
- package/build/types/domain/types.d.ts.map +1 -1
- package/build/types/renderers/mappers/componentToRendererProps.d.ts.map +1 -1
- package/build/types/renderers/mappers/updatableComponentToProps.d.ts +5 -0
- package/build/types/renderers/mappers/updatableComponentToProps.d.ts.map +1 -0
- package/build/types/test-utils/getMergedTestRenderers.d.ts +1 -1
- package/build/types/test-utils/getMergedTestRenderers.d.ts.map +1 -1
- package/package.json +2 -2
package/build/main.css
CHANGED
package/build/main.js
CHANGED
|
@@ -870,6 +870,7 @@ var getChildren = (node) => {
|
|
|
870
870
|
case "step":
|
|
871
871
|
case "modal":
|
|
872
872
|
case "section":
|
|
873
|
+
case "updatable":
|
|
873
874
|
return node.childrenProps;
|
|
874
875
|
case "columns":
|
|
875
876
|
return [...node.startChildrenProps, ...node.endChildrenProps];
|
|
@@ -1377,12 +1378,6 @@ var normaliseBehavior = (behavior, stepActions) => {
|
|
|
1377
1378
|
track: true
|
|
1378
1379
|
});
|
|
1379
1380
|
}
|
|
1380
|
-
if (behavior.type === "dispatch-event") {
|
|
1381
|
-
return {
|
|
1382
|
-
type: "none",
|
|
1383
|
-
track: false
|
|
1384
|
-
};
|
|
1385
|
-
}
|
|
1386
1381
|
if (behavior.type === "link") {
|
|
1387
1382
|
return __spreadProps(__spreadValues({}, behavior), {
|
|
1388
1383
|
type: "link",
|
|
@@ -3100,6 +3095,157 @@ var mapTabs = (tabs, uid, mapperProps, schemaComponents) => tabs.map(({ componen
|
|
|
3100
3095
|
)
|
|
3101
3096
|
}));
|
|
3102
3097
|
|
|
3098
|
+
// src/domain/components/UpdatableComponent.ts
|
|
3099
|
+
var createUpdatableComponent = (props, query, onComponentUpdate, subscribe, unsubscribe) => {
|
|
3100
|
+
const updateComponent = getInputUpdateFunction(onComponentUpdate);
|
|
3101
|
+
let abortController = new AbortController();
|
|
3102
|
+
const triggerUpdate = (data) => {
|
|
3103
|
+
abortController.abort();
|
|
3104
|
+
abortController = new AbortController();
|
|
3105
|
+
const { signal } = abortController;
|
|
3106
|
+
query({ data, signal }).then((state) => {
|
|
3107
|
+
component.update(state);
|
|
3108
|
+
}).catch(() => {
|
|
3109
|
+
});
|
|
3110
|
+
};
|
|
3111
|
+
const component = __spreadProps(__spreadValues({}, props), {
|
|
3112
|
+
type: "updatable",
|
|
3113
|
+
kind: "layout",
|
|
3114
|
+
getChildren() {
|
|
3115
|
+
return component.state.components;
|
|
3116
|
+
},
|
|
3117
|
+
update(newState) {
|
|
3118
|
+
if (!newState) {
|
|
3119
|
+
return;
|
|
3120
|
+
}
|
|
3121
|
+
component.getChildren().forEach((c) => c.stop());
|
|
3122
|
+
updateComponent(component, (draft) => {
|
|
3123
|
+
draft.state = newState;
|
|
3124
|
+
});
|
|
3125
|
+
component.getChildren().forEach((c) => c.start());
|
|
3126
|
+
},
|
|
3127
|
+
start() {
|
|
3128
|
+
subscribe(triggerUpdate);
|
|
3129
|
+
},
|
|
3130
|
+
stop() {
|
|
3131
|
+
unsubscribe(triggerUpdate);
|
|
3132
|
+
abortController.abort();
|
|
3133
|
+
}
|
|
3134
|
+
});
|
|
3135
|
+
return component;
|
|
3136
|
+
};
|
|
3137
|
+
|
|
3138
|
+
// src/domain/features/updatable/getPerformUpdateQuery.ts
|
|
3139
|
+
var import_spec = require("@wise/dynamic-flow-types/spec");
|
|
3140
|
+
var getPerformUpdateQuery = (httpClient, baseRequest, fallbackLayout, mapState, trackEvent) => {
|
|
3141
|
+
return async (props) => {
|
|
3142
|
+
const { signal } = props;
|
|
3143
|
+
trackEvent("Updatable Update Triggered");
|
|
3144
|
+
try {
|
|
3145
|
+
const response = await performRequest2(baseRequest, props, httpClient);
|
|
3146
|
+
if (response.ok) {
|
|
3147
|
+
const results = await parseResponse3(response);
|
|
3148
|
+
if (signal.aborted || !results.components) {
|
|
3149
|
+
return null;
|
|
3150
|
+
}
|
|
3151
|
+
const mappedState = mapState(results);
|
|
3152
|
+
trackEvent("Updatable Update Succeeded");
|
|
3153
|
+
return mappedState;
|
|
3154
|
+
}
|
|
3155
|
+
throw Error("error response", { cause: response });
|
|
3156
|
+
} catch (e) {
|
|
3157
|
+
if (signal.aborted) {
|
|
3158
|
+
return null;
|
|
3159
|
+
}
|
|
3160
|
+
trackEvent("Updatable Update Failed");
|
|
3161
|
+
return fallbackLayout != null ? fallbackLayout : null;
|
|
3162
|
+
}
|
|
3163
|
+
};
|
|
3164
|
+
};
|
|
3165
|
+
var performRequest2 = (request, queryProps, httpClient) => {
|
|
3166
|
+
const { url, method, body, headers } = request;
|
|
3167
|
+
return httpClient(url, {
|
|
3168
|
+
method,
|
|
3169
|
+
headers: __spreadProps(__spreadValues({}, headers), { "Content-Type": "application/json" }),
|
|
3170
|
+
signal: queryProps.signal,
|
|
3171
|
+
body: methodSupportsBody(method) ? JSON.stringify(recursiveMerge(body != null ? body : null, queryProps.data)) : void 0
|
|
3172
|
+
});
|
|
3173
|
+
};
|
|
3174
|
+
var parseResponse3 = async (response) => {
|
|
3175
|
+
if (response.ok) {
|
|
3176
|
+
const body = await response.json();
|
|
3177
|
+
const r = (0, import_spec.validateUpdatableResponse)(body);
|
|
3178
|
+
if (r.valid) {
|
|
3179
|
+
return body;
|
|
3180
|
+
}
|
|
3181
|
+
throw Error(`invalid response body: ${r.errors}`);
|
|
3182
|
+
}
|
|
3183
|
+
throw Error("error response");
|
|
3184
|
+
};
|
|
3185
|
+
var methodSupportsBody = (method) => ["POST", "PUT", "PATCH"].includes(method.toUpperCase());
|
|
3186
|
+
|
|
3187
|
+
// src/domain/mappers/layout/updatableLayoutToComponent.ts
|
|
3188
|
+
var updatableLayoutToComponent = (uid, {
|
|
3189
|
+
analyticsId,
|
|
3190
|
+
baseRequest,
|
|
3191
|
+
control,
|
|
3192
|
+
margin,
|
|
3193
|
+
tags,
|
|
3194
|
+
trigger,
|
|
3195
|
+
initialState,
|
|
3196
|
+
onError
|
|
3197
|
+
}, mapperProps, schemaComponents) => {
|
|
3198
|
+
const { httpClient, onComponentUpdate } = mapperProps;
|
|
3199
|
+
const mapLayout = (layout, index) => mapLayoutToComponent(`${uid}-updatable-${index}`, layout, mapperProps, schemaComponents);
|
|
3200
|
+
const mapState = (state) => {
|
|
3201
|
+
var _a;
|
|
3202
|
+
return {
|
|
3203
|
+
components: ((_a = state == null ? void 0 : state.components) != null ? _a : []).map((component2, index) => mapLayout(component2, index))
|
|
3204
|
+
};
|
|
3205
|
+
};
|
|
3206
|
+
const trackEvent = (name, data) => mapperProps.trackEvent(name, __spreadProps(__spreadValues({}, data), { analyticsId }));
|
|
3207
|
+
const fallbackLayout = (onError == null ? void 0 : onError.fallbackLayout) ? mapState({ components: onError.fallbackLayout }) : null;
|
|
3208
|
+
const queryFunction = getPerformUpdateQuery(
|
|
3209
|
+
httpClient,
|
|
3210
|
+
baseRequest,
|
|
3211
|
+
fallbackLayout,
|
|
3212
|
+
mapState,
|
|
3213
|
+
trackEvent
|
|
3214
|
+
);
|
|
3215
|
+
const { subscribe, unsubscribe } = getTriggerFunction(trigger, mapperProps);
|
|
3216
|
+
const component = createUpdatableComponent(
|
|
3217
|
+
{
|
|
3218
|
+
uid,
|
|
3219
|
+
analyticsId,
|
|
3220
|
+
control,
|
|
3221
|
+
margin: margin != null ? margin : "md",
|
|
3222
|
+
tags,
|
|
3223
|
+
state: mapState(initialState)
|
|
3224
|
+
},
|
|
3225
|
+
queryFunction,
|
|
3226
|
+
onComponentUpdate,
|
|
3227
|
+
subscribe,
|
|
3228
|
+
unsubscribe
|
|
3229
|
+
);
|
|
3230
|
+
return component;
|
|
3231
|
+
};
|
|
3232
|
+
var getTriggerFunction = (trigger, mapperProps) => {
|
|
3233
|
+
const { stepEventSubscriber } = mapperProps;
|
|
3234
|
+
if (trigger.type === "on-event") {
|
|
3235
|
+
return {
|
|
3236
|
+
subscribe: (handler) => {
|
|
3237
|
+
stepEventSubscriber.addEventListener(trigger.eventName, handler);
|
|
3238
|
+
},
|
|
3239
|
+
unsubscribe: (handler) => {
|
|
3240
|
+
stepEventSubscriber.removeEventListener(trigger.eventName, handler);
|
|
3241
|
+
}
|
|
3242
|
+
};
|
|
3243
|
+
}
|
|
3244
|
+
return { subscribe() {
|
|
3245
|
+
}, unsubscribe() {
|
|
3246
|
+
} };
|
|
3247
|
+
};
|
|
3248
|
+
|
|
3103
3249
|
// src/domain/components/UpsellComponent.ts
|
|
3104
3250
|
var createUpsellComponent = (props, onComponentUpdate) => {
|
|
3105
3251
|
const update = getInputUpdateFunction(onComponentUpdate);
|
|
@@ -3195,6 +3341,8 @@ var mapLayoutToComponent = (uid, layout, mapperProps, schemaComponents) => {
|
|
|
3195
3341
|
return tabsLayoutToComponent(uid, layout, mapperProps, schemaComponents);
|
|
3196
3342
|
case "upsell":
|
|
3197
3343
|
return upsellLayoutToComponent(uid, layout, mapperProps);
|
|
3344
|
+
case "updatable":
|
|
3345
|
+
return updatableLayoutToComponent(uid, layout, mapperProps, schemaComponents);
|
|
3198
3346
|
default:
|
|
3199
3347
|
throw new Error(`Invalid layout type in ${JSON.stringify(layout)}`);
|
|
3200
3348
|
}
|
|
@@ -3392,6 +3540,7 @@ var createStepComponent = (props) => {
|
|
|
3392
3540
|
});
|
|
3393
3541
|
},
|
|
3394
3542
|
start() {
|
|
3543
|
+
getAllSubcomponents(component).forEach((child) => child.start());
|
|
3395
3544
|
if (component.state === "initial") {
|
|
3396
3545
|
onLoad == null ? void 0 : onLoad();
|
|
3397
3546
|
}
|
|
@@ -3401,7 +3550,9 @@ var createStepComponent = (props) => {
|
|
|
3401
3550
|
stepPolling == null ? void 0 : stepPolling.start();
|
|
3402
3551
|
stepRefreshAfter == null ? void 0 : stepRefreshAfter.start();
|
|
3403
3552
|
stepPrefetch.start(component.getSubmittableValueSync());
|
|
3404
|
-
|
|
3553
|
+
},
|
|
3554
|
+
dispatchStepEvent(eventName) {
|
|
3555
|
+
props.eventPublisher.dispatchEvent(eventName, component.getSubmittableValueSync());
|
|
3405
3556
|
},
|
|
3406
3557
|
stop() {
|
|
3407
3558
|
stepPolling == null ? void 0 : stepPolling.stop();
|
|
@@ -3447,6 +3598,32 @@ var validateInputComponent = (component, inputComponent, isStrict, logEvent) =>
|
|
|
3447
3598
|
return isSchemaReferenced || isStrict ? isValid : true;
|
|
3448
3599
|
};
|
|
3449
3600
|
|
|
3601
|
+
// src/domain/features/domain-event-bus/DomainEventBus.ts
|
|
3602
|
+
var DomainEventBus = class {
|
|
3603
|
+
constructor() {
|
|
3604
|
+
this.listeners = /* @__PURE__ */ new Map();
|
|
3605
|
+
}
|
|
3606
|
+
dispatchEvent(eventName, data) {
|
|
3607
|
+
const eventListeners = this.listeners.get(eventName);
|
|
3608
|
+
if (eventListeners) {
|
|
3609
|
+
eventListeners.forEach((callback) => callback(data));
|
|
3610
|
+
}
|
|
3611
|
+
}
|
|
3612
|
+
addEventListener(eventName, callback) {
|
|
3613
|
+
var _a;
|
|
3614
|
+
if (!this.listeners.has(eventName)) {
|
|
3615
|
+
this.listeners.set(eventName, /* @__PURE__ */ new Set());
|
|
3616
|
+
}
|
|
3617
|
+
(_a = this.listeners.get(eventName)) == null ? void 0 : _a.add(callback);
|
|
3618
|
+
}
|
|
3619
|
+
removeEventListener(eventName, callback) {
|
|
3620
|
+
const eventListeners = this.listeners.get(eventName);
|
|
3621
|
+
if (eventListeners) {
|
|
3622
|
+
eventListeners.delete(callback);
|
|
3623
|
+
}
|
|
3624
|
+
}
|
|
3625
|
+
};
|
|
3626
|
+
|
|
3450
3627
|
// src/domain/features/polling/getStepPolling.ts
|
|
3451
3628
|
var getStepPolling = ({
|
|
3452
3629
|
pollingConfig,
|
|
@@ -3509,7 +3686,7 @@ var getErrorMessage = (error) => {
|
|
|
3509
3686
|
};
|
|
3510
3687
|
|
|
3511
3688
|
// src/controller/response-utils.ts
|
|
3512
|
-
var
|
|
3689
|
+
var import_spec2 = require("@wise/dynamic-flow-types/spec");
|
|
3513
3690
|
var parseResponseBodyAsJsonElement = async (response) => {
|
|
3514
3691
|
assertResponseIsValid(response);
|
|
3515
3692
|
try {
|
|
@@ -3526,7 +3703,7 @@ var parseResponseBodyAsText = async (response) => {
|
|
|
3526
3703
|
}
|
|
3527
3704
|
};
|
|
3528
3705
|
function isActionResponseBody(body) {
|
|
3529
|
-
return (0,
|
|
3706
|
+
return (0, import_spec2.validateActionResponse)(body).valid;
|
|
3530
3707
|
}
|
|
3531
3708
|
function assertActionResponseBody(body) {
|
|
3532
3709
|
if (!isObject(body) || !isObject(body.action)) {
|
|
@@ -3546,7 +3723,7 @@ function assertModalResponseBody(body) {
|
|
|
3546
3723
|
);
|
|
3547
3724
|
}
|
|
3548
3725
|
function assertSubflowResponseBody(body) {
|
|
3549
|
-
const { valid } = (0,
|
|
3726
|
+
const { valid } = (0, import_spec2.validateSubflowResponse)(body);
|
|
3550
3727
|
if (valid) {
|
|
3551
3728
|
return;
|
|
3552
3729
|
}
|
|
@@ -7315,8 +7492,10 @@ var mapStepToComponent = (_a) => {
|
|
|
7315
7492
|
const registerSubmissionBehavior = (behavior) => {
|
|
7316
7493
|
submissionBehaviors.push(behavior);
|
|
7317
7494
|
};
|
|
7495
|
+
const stepEventBus = new DomainEventBus();
|
|
7318
7496
|
const mapperProps = __spreadProps(__spreadValues({}, restProps), {
|
|
7319
7497
|
features,
|
|
7498
|
+
stepEventSubscriber: stepEventBus,
|
|
7320
7499
|
trackEvent,
|
|
7321
7500
|
onBehavior,
|
|
7322
7501
|
registerSubmissionBehavior
|
|
@@ -7377,6 +7556,7 @@ var mapStepToComponent = (_a) => {
|
|
|
7377
7556
|
step,
|
|
7378
7557
|
referencedSchemaIds,
|
|
7379
7558
|
features,
|
|
7559
|
+
eventPublisher: stepEventBus,
|
|
7380
7560
|
onComponentUpdate,
|
|
7381
7561
|
trackEvent,
|
|
7382
7562
|
logEvent,
|
|
@@ -7437,13 +7617,13 @@ var getLayoutAndFooter = (step, features) => {
|
|
|
7437
7617
|
};
|
|
7438
7618
|
|
|
7439
7619
|
// src/utils/analyse-step.ts
|
|
7440
|
-
var
|
|
7620
|
+
var import_spec3 = require("@wise/dynamic-flow-types/spec");
|
|
7441
7621
|
var analyseStep = (step, logEvent) => {
|
|
7442
7622
|
validateStepTypes(step, logEvent);
|
|
7443
7623
|
};
|
|
7444
7624
|
var validateStepTypes = (step, logEvent) => {
|
|
7445
7625
|
var _a;
|
|
7446
|
-
const validationResult = (0,
|
|
7626
|
+
const validationResult = (0, import_spec3.validateStep)(step);
|
|
7447
7627
|
if (!validationResult.valid) {
|
|
7448
7628
|
logEvent("info", "The provided step does not conform to the specification.", {
|
|
7449
7629
|
stepId: (_a = step.id) != null ? _a : step.key,
|
|
@@ -7979,7 +8159,7 @@ var createFlowController = (props) => {
|
|
|
7979
8159
|
onCancellation == null ? void 0 : onCancellation();
|
|
7980
8160
|
};
|
|
7981
8161
|
const onBehavior = async (behavior) => {
|
|
7982
|
-
var _a;
|
|
8162
|
+
var _a, _b;
|
|
7983
8163
|
trackBehaviorTriggered(trackEvent, behavior);
|
|
7984
8164
|
switch (behavior.type) {
|
|
7985
8165
|
case "delay": {
|
|
@@ -8081,6 +8261,10 @@ var createFlowController = (props) => {
|
|
|
8081
8261
|
step: currentStep,
|
|
8082
8262
|
stepLocalValue: rootComponent.getLocalValue()
|
|
8083
8263
|
}, getMapperProps()), {
|
|
8264
|
+
stepEventSubscriber: { addEventListener: () => {
|
|
8265
|
+
}, removeEventListener: () => {
|
|
8266
|
+
} },
|
|
8267
|
+
// IMPORTANT! this means that components in modal responses won't be able to listen to step events
|
|
8084
8268
|
registerSubmissionBehavior: () => {
|
|
8085
8269
|
}
|
|
8086
8270
|
// this means actions in modal responses won't have prefetching
|
|
@@ -8115,6 +8299,10 @@ var createFlowController = (props) => {
|
|
|
8115
8299
|
}
|
|
8116
8300
|
break;
|
|
8117
8301
|
}
|
|
8302
|
+
case "dispatch-event": {
|
|
8303
|
+
(_b = rootComponent.getStep()) == null ? void 0 : _b.dispatchStepEvent(behavior.eventName);
|
|
8304
|
+
break;
|
|
8305
|
+
}
|
|
8118
8306
|
case "none":
|
|
8119
8307
|
break;
|
|
8120
8308
|
}
|
|
@@ -9398,6 +9586,17 @@ var uploadInputComponentToProps = (component, rendererMapperProps) => {
|
|
|
9398
9586
|
});
|
|
9399
9587
|
};
|
|
9400
9588
|
|
|
9589
|
+
// src/renderers/mappers/updatableComponentToProps.ts
|
|
9590
|
+
var updatableComponentToProps = (component, rendererMapperProps) => {
|
|
9591
|
+
const childrenProps = component.state.components.map(
|
|
9592
|
+
(c) => componentToRendererProps(c, rendererMapperProps)
|
|
9593
|
+
);
|
|
9594
|
+
return __spreadProps(__spreadValues(__spreadValues({}, pick(component, "uid", "analyticsId", "type", "control", "margin", "tags")), rendererMapperProps), {
|
|
9595
|
+
children: childrenProps.map(rendererMapperProps.render),
|
|
9596
|
+
childrenProps
|
|
9597
|
+
});
|
|
9598
|
+
};
|
|
9599
|
+
|
|
9401
9600
|
// src/renderers/mappers/upsellComponentToProps.ts
|
|
9402
9601
|
var upsellComponentToProps = (component, rendererMapperProps) => __spreadValues(__spreadProps(__spreadValues({}, pick(component, "uid", "analyticsId", "type", "control", "margin", "media", "tags", "text")), {
|
|
9403
9602
|
callToAction: mapCallToAction(component.callToAction),
|
|
@@ -9514,6 +9713,8 @@ var getComponentProps = (component, rendererMapperProps) => {
|
|
|
9514
9713
|
return uploadInputComponentToProps(component, rendererMapperProps);
|
|
9515
9714
|
case "upsell":
|
|
9516
9715
|
return upsellComponentToProps(component, rendererMapperProps);
|
|
9716
|
+
case "updatable":
|
|
9717
|
+
return updatableComponentToProps(component, rendererMapperProps);
|
|
9517
9718
|
case "persist-async":
|
|
9518
9719
|
return persistAsyncComponentToProps(component, rendererMapperProps);
|
|
9519
9720
|
case "root":
|
|
@@ -9916,7 +10117,11 @@ var eventNames = [
|
|
|
9916
10117
|
"Collection Filter Failed",
|
|
9917
10118
|
"Collection Pagination Triggered",
|
|
9918
10119
|
"Collection Pagination Succeeded",
|
|
9919
|
-
"Collection Pagination Failed"
|
|
10120
|
+
"Collection Pagination Failed",
|
|
10121
|
+
"Updatable Update Triggered",
|
|
10122
|
+
// agree on these names
|
|
10123
|
+
"Updatable Update Succeeded",
|
|
10124
|
+
"Updatable Update Failed"
|
|
9920
10125
|
];
|
|
9921
10126
|
|
|
9922
10127
|
// src/renderers/subflow/getDynamicSubflowRenderer.tsx
|
package/build/main.mjs
CHANGED
|
@@ -839,6 +839,7 @@ var getChildren = (node) => {
|
|
|
839
839
|
case "step":
|
|
840
840
|
case "modal":
|
|
841
841
|
case "section":
|
|
842
|
+
case "updatable":
|
|
842
843
|
return node.childrenProps;
|
|
843
844
|
case "columns":
|
|
844
845
|
return [...node.startChildrenProps, ...node.endChildrenProps];
|
|
@@ -1346,12 +1347,6 @@ var normaliseBehavior = (behavior, stepActions) => {
|
|
|
1346
1347
|
track: true
|
|
1347
1348
|
});
|
|
1348
1349
|
}
|
|
1349
|
-
if (behavior.type === "dispatch-event") {
|
|
1350
|
-
return {
|
|
1351
|
-
type: "none",
|
|
1352
|
-
track: false
|
|
1353
|
-
};
|
|
1354
|
-
}
|
|
1355
1350
|
if (behavior.type === "link") {
|
|
1356
1351
|
return __spreadProps(__spreadValues({}, behavior), {
|
|
1357
1352
|
type: "link",
|
|
@@ -3069,6 +3064,159 @@ var mapTabs = (tabs, uid, mapperProps, schemaComponents) => tabs.map(({ componen
|
|
|
3069
3064
|
)
|
|
3070
3065
|
}));
|
|
3071
3066
|
|
|
3067
|
+
// src/domain/components/UpdatableComponent.ts
|
|
3068
|
+
var createUpdatableComponent = (props, query, onComponentUpdate, subscribe, unsubscribe) => {
|
|
3069
|
+
const updateComponent = getInputUpdateFunction(onComponentUpdate);
|
|
3070
|
+
let abortController = new AbortController();
|
|
3071
|
+
const triggerUpdate = (data) => {
|
|
3072
|
+
abortController.abort();
|
|
3073
|
+
abortController = new AbortController();
|
|
3074
|
+
const { signal } = abortController;
|
|
3075
|
+
query({ data, signal }).then((state) => {
|
|
3076
|
+
component.update(state);
|
|
3077
|
+
}).catch(() => {
|
|
3078
|
+
});
|
|
3079
|
+
};
|
|
3080
|
+
const component = __spreadProps(__spreadValues({}, props), {
|
|
3081
|
+
type: "updatable",
|
|
3082
|
+
kind: "layout",
|
|
3083
|
+
getChildren() {
|
|
3084
|
+
return component.state.components;
|
|
3085
|
+
},
|
|
3086
|
+
update(newState) {
|
|
3087
|
+
if (!newState) {
|
|
3088
|
+
return;
|
|
3089
|
+
}
|
|
3090
|
+
component.getChildren().forEach((c) => c.stop());
|
|
3091
|
+
updateComponent(component, (draft) => {
|
|
3092
|
+
draft.state = newState;
|
|
3093
|
+
});
|
|
3094
|
+
component.getChildren().forEach((c) => c.start());
|
|
3095
|
+
},
|
|
3096
|
+
start() {
|
|
3097
|
+
subscribe(triggerUpdate);
|
|
3098
|
+
},
|
|
3099
|
+
stop() {
|
|
3100
|
+
unsubscribe(triggerUpdate);
|
|
3101
|
+
abortController.abort();
|
|
3102
|
+
}
|
|
3103
|
+
});
|
|
3104
|
+
return component;
|
|
3105
|
+
};
|
|
3106
|
+
|
|
3107
|
+
// src/domain/features/updatable/getPerformUpdateQuery.ts
|
|
3108
|
+
import {
|
|
3109
|
+
validateUpdatableResponse
|
|
3110
|
+
} from "@wise/dynamic-flow-types/spec";
|
|
3111
|
+
var getPerformUpdateQuery = (httpClient, baseRequest, fallbackLayout, mapState, trackEvent) => {
|
|
3112
|
+
return async (props) => {
|
|
3113
|
+
const { signal } = props;
|
|
3114
|
+
trackEvent("Updatable Update Triggered");
|
|
3115
|
+
try {
|
|
3116
|
+
const response = await performRequest2(baseRequest, props, httpClient);
|
|
3117
|
+
if (response.ok) {
|
|
3118
|
+
const results = await parseResponse3(response);
|
|
3119
|
+
if (signal.aborted || !results.components) {
|
|
3120
|
+
return null;
|
|
3121
|
+
}
|
|
3122
|
+
const mappedState = mapState(results);
|
|
3123
|
+
trackEvent("Updatable Update Succeeded");
|
|
3124
|
+
return mappedState;
|
|
3125
|
+
}
|
|
3126
|
+
throw Error("error response", { cause: response });
|
|
3127
|
+
} catch (e) {
|
|
3128
|
+
if (signal.aborted) {
|
|
3129
|
+
return null;
|
|
3130
|
+
}
|
|
3131
|
+
trackEvent("Updatable Update Failed");
|
|
3132
|
+
return fallbackLayout != null ? fallbackLayout : null;
|
|
3133
|
+
}
|
|
3134
|
+
};
|
|
3135
|
+
};
|
|
3136
|
+
var performRequest2 = (request, queryProps, httpClient) => {
|
|
3137
|
+
const { url, method, body, headers } = request;
|
|
3138
|
+
return httpClient(url, {
|
|
3139
|
+
method,
|
|
3140
|
+
headers: __spreadProps(__spreadValues({}, headers), { "Content-Type": "application/json" }),
|
|
3141
|
+
signal: queryProps.signal,
|
|
3142
|
+
body: methodSupportsBody(method) ? JSON.stringify(recursiveMerge(body != null ? body : null, queryProps.data)) : void 0
|
|
3143
|
+
});
|
|
3144
|
+
};
|
|
3145
|
+
var parseResponse3 = async (response) => {
|
|
3146
|
+
if (response.ok) {
|
|
3147
|
+
const body = await response.json();
|
|
3148
|
+
const r = validateUpdatableResponse(body);
|
|
3149
|
+
if (r.valid) {
|
|
3150
|
+
return body;
|
|
3151
|
+
}
|
|
3152
|
+
throw Error(`invalid response body: ${r.errors}`);
|
|
3153
|
+
}
|
|
3154
|
+
throw Error("error response");
|
|
3155
|
+
};
|
|
3156
|
+
var methodSupportsBody = (method) => ["POST", "PUT", "PATCH"].includes(method.toUpperCase());
|
|
3157
|
+
|
|
3158
|
+
// src/domain/mappers/layout/updatableLayoutToComponent.ts
|
|
3159
|
+
var updatableLayoutToComponent = (uid, {
|
|
3160
|
+
analyticsId,
|
|
3161
|
+
baseRequest,
|
|
3162
|
+
control,
|
|
3163
|
+
margin,
|
|
3164
|
+
tags,
|
|
3165
|
+
trigger,
|
|
3166
|
+
initialState,
|
|
3167
|
+
onError
|
|
3168
|
+
}, mapperProps, schemaComponents) => {
|
|
3169
|
+
const { httpClient, onComponentUpdate } = mapperProps;
|
|
3170
|
+
const mapLayout = (layout, index) => mapLayoutToComponent(`${uid}-updatable-${index}`, layout, mapperProps, schemaComponents);
|
|
3171
|
+
const mapState = (state) => {
|
|
3172
|
+
var _a;
|
|
3173
|
+
return {
|
|
3174
|
+
components: ((_a = state == null ? void 0 : state.components) != null ? _a : []).map((component2, index) => mapLayout(component2, index))
|
|
3175
|
+
};
|
|
3176
|
+
};
|
|
3177
|
+
const trackEvent = (name, data) => mapperProps.trackEvent(name, __spreadProps(__spreadValues({}, data), { analyticsId }));
|
|
3178
|
+
const fallbackLayout = (onError == null ? void 0 : onError.fallbackLayout) ? mapState({ components: onError.fallbackLayout }) : null;
|
|
3179
|
+
const queryFunction = getPerformUpdateQuery(
|
|
3180
|
+
httpClient,
|
|
3181
|
+
baseRequest,
|
|
3182
|
+
fallbackLayout,
|
|
3183
|
+
mapState,
|
|
3184
|
+
trackEvent
|
|
3185
|
+
);
|
|
3186
|
+
const { subscribe, unsubscribe } = getTriggerFunction(trigger, mapperProps);
|
|
3187
|
+
const component = createUpdatableComponent(
|
|
3188
|
+
{
|
|
3189
|
+
uid,
|
|
3190
|
+
analyticsId,
|
|
3191
|
+
control,
|
|
3192
|
+
margin: margin != null ? margin : "md",
|
|
3193
|
+
tags,
|
|
3194
|
+
state: mapState(initialState)
|
|
3195
|
+
},
|
|
3196
|
+
queryFunction,
|
|
3197
|
+
onComponentUpdate,
|
|
3198
|
+
subscribe,
|
|
3199
|
+
unsubscribe
|
|
3200
|
+
);
|
|
3201
|
+
return component;
|
|
3202
|
+
};
|
|
3203
|
+
var getTriggerFunction = (trigger, mapperProps) => {
|
|
3204
|
+
const { stepEventSubscriber } = mapperProps;
|
|
3205
|
+
if (trigger.type === "on-event") {
|
|
3206
|
+
return {
|
|
3207
|
+
subscribe: (handler) => {
|
|
3208
|
+
stepEventSubscriber.addEventListener(trigger.eventName, handler);
|
|
3209
|
+
},
|
|
3210
|
+
unsubscribe: (handler) => {
|
|
3211
|
+
stepEventSubscriber.removeEventListener(trigger.eventName, handler);
|
|
3212
|
+
}
|
|
3213
|
+
};
|
|
3214
|
+
}
|
|
3215
|
+
return { subscribe() {
|
|
3216
|
+
}, unsubscribe() {
|
|
3217
|
+
} };
|
|
3218
|
+
};
|
|
3219
|
+
|
|
3072
3220
|
// src/domain/components/UpsellComponent.ts
|
|
3073
3221
|
var createUpsellComponent = (props, onComponentUpdate) => {
|
|
3074
3222
|
const update = getInputUpdateFunction(onComponentUpdate);
|
|
@@ -3164,6 +3312,8 @@ var mapLayoutToComponent = (uid, layout, mapperProps, schemaComponents) => {
|
|
|
3164
3312
|
return tabsLayoutToComponent(uid, layout, mapperProps, schemaComponents);
|
|
3165
3313
|
case "upsell":
|
|
3166
3314
|
return upsellLayoutToComponent(uid, layout, mapperProps);
|
|
3315
|
+
case "updatable":
|
|
3316
|
+
return updatableLayoutToComponent(uid, layout, mapperProps, schemaComponents);
|
|
3167
3317
|
default:
|
|
3168
3318
|
throw new Error(`Invalid layout type in ${JSON.stringify(layout)}`);
|
|
3169
3319
|
}
|
|
@@ -3361,6 +3511,7 @@ var createStepComponent = (props) => {
|
|
|
3361
3511
|
});
|
|
3362
3512
|
},
|
|
3363
3513
|
start() {
|
|
3514
|
+
getAllSubcomponents(component).forEach((child) => child.start());
|
|
3364
3515
|
if (component.state === "initial") {
|
|
3365
3516
|
onLoad == null ? void 0 : onLoad();
|
|
3366
3517
|
}
|
|
@@ -3370,7 +3521,9 @@ var createStepComponent = (props) => {
|
|
|
3370
3521
|
stepPolling == null ? void 0 : stepPolling.start();
|
|
3371
3522
|
stepRefreshAfter == null ? void 0 : stepRefreshAfter.start();
|
|
3372
3523
|
stepPrefetch.start(component.getSubmittableValueSync());
|
|
3373
|
-
|
|
3524
|
+
},
|
|
3525
|
+
dispatchStepEvent(eventName) {
|
|
3526
|
+
props.eventPublisher.dispatchEvent(eventName, component.getSubmittableValueSync());
|
|
3374
3527
|
},
|
|
3375
3528
|
stop() {
|
|
3376
3529
|
stepPolling == null ? void 0 : stepPolling.stop();
|
|
@@ -3416,6 +3569,32 @@ var validateInputComponent = (component, inputComponent, isStrict, logEvent) =>
|
|
|
3416
3569
|
return isSchemaReferenced || isStrict ? isValid : true;
|
|
3417
3570
|
};
|
|
3418
3571
|
|
|
3572
|
+
// src/domain/features/domain-event-bus/DomainEventBus.ts
|
|
3573
|
+
var DomainEventBus = class {
|
|
3574
|
+
constructor() {
|
|
3575
|
+
this.listeners = /* @__PURE__ */ new Map();
|
|
3576
|
+
}
|
|
3577
|
+
dispatchEvent(eventName, data) {
|
|
3578
|
+
const eventListeners = this.listeners.get(eventName);
|
|
3579
|
+
if (eventListeners) {
|
|
3580
|
+
eventListeners.forEach((callback) => callback(data));
|
|
3581
|
+
}
|
|
3582
|
+
}
|
|
3583
|
+
addEventListener(eventName, callback) {
|
|
3584
|
+
var _a;
|
|
3585
|
+
if (!this.listeners.has(eventName)) {
|
|
3586
|
+
this.listeners.set(eventName, /* @__PURE__ */ new Set());
|
|
3587
|
+
}
|
|
3588
|
+
(_a = this.listeners.get(eventName)) == null ? void 0 : _a.add(callback);
|
|
3589
|
+
}
|
|
3590
|
+
removeEventListener(eventName, callback) {
|
|
3591
|
+
const eventListeners = this.listeners.get(eventName);
|
|
3592
|
+
if (eventListeners) {
|
|
3593
|
+
eventListeners.delete(callback);
|
|
3594
|
+
}
|
|
3595
|
+
}
|
|
3596
|
+
};
|
|
3597
|
+
|
|
3419
3598
|
// src/domain/features/polling/getStepPolling.ts
|
|
3420
3599
|
var getStepPolling = ({
|
|
3421
3600
|
pollingConfig,
|
|
@@ -7284,8 +7463,10 @@ var mapStepToComponent = (_a) => {
|
|
|
7284
7463
|
const registerSubmissionBehavior = (behavior) => {
|
|
7285
7464
|
submissionBehaviors.push(behavior);
|
|
7286
7465
|
};
|
|
7466
|
+
const stepEventBus = new DomainEventBus();
|
|
7287
7467
|
const mapperProps = __spreadProps(__spreadValues({}, restProps), {
|
|
7288
7468
|
features,
|
|
7469
|
+
stepEventSubscriber: stepEventBus,
|
|
7289
7470
|
trackEvent,
|
|
7290
7471
|
onBehavior,
|
|
7291
7472
|
registerSubmissionBehavior
|
|
@@ -7346,6 +7527,7 @@ var mapStepToComponent = (_a) => {
|
|
|
7346
7527
|
step,
|
|
7347
7528
|
referencedSchemaIds,
|
|
7348
7529
|
features,
|
|
7530
|
+
eventPublisher: stepEventBus,
|
|
7349
7531
|
onComponentUpdate,
|
|
7350
7532
|
trackEvent,
|
|
7351
7533
|
logEvent,
|
|
@@ -7948,7 +8130,7 @@ var createFlowController = (props) => {
|
|
|
7948
8130
|
onCancellation == null ? void 0 : onCancellation();
|
|
7949
8131
|
};
|
|
7950
8132
|
const onBehavior = async (behavior) => {
|
|
7951
|
-
var _a;
|
|
8133
|
+
var _a, _b;
|
|
7952
8134
|
trackBehaviorTriggered(trackEvent, behavior);
|
|
7953
8135
|
switch (behavior.type) {
|
|
7954
8136
|
case "delay": {
|
|
@@ -8050,6 +8232,10 @@ var createFlowController = (props) => {
|
|
|
8050
8232
|
step: currentStep,
|
|
8051
8233
|
stepLocalValue: rootComponent.getLocalValue()
|
|
8052
8234
|
}, getMapperProps()), {
|
|
8235
|
+
stepEventSubscriber: { addEventListener: () => {
|
|
8236
|
+
}, removeEventListener: () => {
|
|
8237
|
+
} },
|
|
8238
|
+
// IMPORTANT! this means that components in modal responses won't be able to listen to step events
|
|
8053
8239
|
registerSubmissionBehavior: () => {
|
|
8054
8240
|
}
|
|
8055
8241
|
// this means actions in modal responses won't have prefetching
|
|
@@ -8084,6 +8270,10 @@ var createFlowController = (props) => {
|
|
|
8084
8270
|
}
|
|
8085
8271
|
break;
|
|
8086
8272
|
}
|
|
8273
|
+
case "dispatch-event": {
|
|
8274
|
+
(_b = rootComponent.getStep()) == null ? void 0 : _b.dispatchStepEvent(behavior.eventName);
|
|
8275
|
+
break;
|
|
8276
|
+
}
|
|
8087
8277
|
case "none":
|
|
8088
8278
|
break;
|
|
8089
8279
|
}
|
|
@@ -9367,6 +9557,17 @@ var uploadInputComponentToProps = (component, rendererMapperProps) => {
|
|
|
9367
9557
|
});
|
|
9368
9558
|
};
|
|
9369
9559
|
|
|
9560
|
+
// src/renderers/mappers/updatableComponentToProps.ts
|
|
9561
|
+
var updatableComponentToProps = (component, rendererMapperProps) => {
|
|
9562
|
+
const childrenProps = component.state.components.map(
|
|
9563
|
+
(c) => componentToRendererProps(c, rendererMapperProps)
|
|
9564
|
+
);
|
|
9565
|
+
return __spreadProps(__spreadValues(__spreadValues({}, pick(component, "uid", "analyticsId", "type", "control", "margin", "tags")), rendererMapperProps), {
|
|
9566
|
+
children: childrenProps.map(rendererMapperProps.render),
|
|
9567
|
+
childrenProps
|
|
9568
|
+
});
|
|
9569
|
+
};
|
|
9570
|
+
|
|
9370
9571
|
// src/renderers/mappers/upsellComponentToProps.ts
|
|
9371
9572
|
var upsellComponentToProps = (component, rendererMapperProps) => __spreadValues(__spreadProps(__spreadValues({}, pick(component, "uid", "analyticsId", "type", "control", "margin", "media", "tags", "text")), {
|
|
9372
9573
|
callToAction: mapCallToAction(component.callToAction),
|
|
@@ -9483,6 +9684,8 @@ var getComponentProps = (component, rendererMapperProps) => {
|
|
|
9483
9684
|
return uploadInputComponentToProps(component, rendererMapperProps);
|
|
9484
9685
|
case "upsell":
|
|
9485
9686
|
return upsellComponentToProps(component, rendererMapperProps);
|
|
9687
|
+
case "updatable":
|
|
9688
|
+
return updatableComponentToProps(component, rendererMapperProps);
|
|
9486
9689
|
case "persist-async":
|
|
9487
9690
|
return persistAsyncComponentToProps(component, rendererMapperProps);
|
|
9488
9691
|
case "root":
|
|
@@ -9885,7 +10088,11 @@ var eventNames = [
|
|
|
9885
10088
|
"Collection Filter Failed",
|
|
9886
10089
|
"Collection Pagination Triggered",
|
|
9887
10090
|
"Collection Pagination Succeeded",
|
|
9888
|
-
"Collection Pagination Failed"
|
|
10091
|
+
"Collection Pagination Failed",
|
|
10092
|
+
"Updatable Update Triggered",
|
|
10093
|
+
// agree on these names
|
|
10094
|
+
"Updatable Update Succeeded",
|
|
10095
|
+
"Updatable Update Failed"
|
|
9889
10096
|
];
|
|
9890
10097
|
|
|
9891
10098
|
// src/renderers/subflow/getDynamicSubflowRenderer.tsx
|