@player-ui/player 0.0.1-next.1

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.
@@ -0,0 +1,1326 @@
1
+ export * from '@player-ui/types';
2
+ import { BindingInstance, isBinding, BindingParser } from '@player-ui/binding';
3
+ export * from '@player-ui/binding';
4
+ import { LocalModel, PipelinedDataModel } from '@player-ui/data';
5
+ export * from '@player-ui/data';
6
+ import { ExpressionEvaluator } from '@player-ui/expressions';
7
+ export * from '@player-ui/expressions';
8
+ import { FlowController } from '@player-ui/flow';
9
+ export * from '@player-ui/flow';
10
+ import { ProxyLogger, TapableLogger } from '@player-ui/logger';
11
+ export * from '@player-ui/logger';
12
+ import { SchemaController } from '@player-ui/schema';
13
+ export * from '@player-ui/schema';
14
+ import { resolveDataRefsInString, resolveDataRefs } from '@player-ui/string-resolver';
15
+ export * from '@player-ui/string-resolver';
16
+ import { ValidationMiddleware, ValidatorRegistry } from '@player-ui/validator';
17
+ export * from '@player-ui/validator';
18
+ import { NodeType, ViewInstance, caresAboutDataChanges } from '@player-ui/view';
19
+ export * from '@player-ui/view';
20
+ import { SyncWaterfallHook, SyncHook, SyncBailHook } from 'tapable';
21
+ import { removeAt, omit, setIn } from 'timm';
22
+ import deferred from 'p-defer';
23
+ import { ConstantsController } from '@player-ui/constants';
24
+ import queueMicrotask from 'queue-microtask';
25
+ import { Registry } from '@player-ui/partial-match-registry';
26
+ import { dequal } from 'dequal';
27
+ import { replaceParams } from '@player-ui/utils';
28
+
29
+ class LocalStateStore {
30
+ constructor(onUpdate) {
31
+ this.updateCallback = onUpdate;
32
+ this.state = new Map();
33
+ }
34
+ removeKey(key) {
35
+ this.state.delete(key);
36
+ }
37
+ reset() {
38
+ this.state.clear();
39
+ }
40
+ useSharedState(key) {
41
+ return (initialState) => {
42
+ if (!this.state.has(key)) {
43
+ this.state.set(key, initialState);
44
+ }
45
+ return [
46
+ this.state.get(key),
47
+ (newState) => {
48
+ var _a;
49
+ const current = this.state.get(key);
50
+ this.state.set(key, newState);
51
+ if (current !== newState) {
52
+ (_a = this.updateCallback) == null ? void 0 : _a.call(this);
53
+ }
54
+ }
55
+ ];
56
+ };
57
+ }
58
+ getLocalStateFunction(key, countKey) {
59
+ return (initialState) => {
60
+ if (!this.state.has(key)) {
61
+ this.state.set(key, []);
62
+ }
63
+ if (!this.state.has(countKey)) {
64
+ this.state.set(countKey, 0);
65
+ }
66
+ const localState = this.state.get(key);
67
+ const oldCount = this.state.get(countKey);
68
+ this.state.set(countKey, oldCount + 1);
69
+ if (localState.length <= oldCount) {
70
+ localState.push(initialState);
71
+ }
72
+ const value = localState[oldCount];
73
+ return [
74
+ value,
75
+ (newState) => {
76
+ var _a;
77
+ const oldValue = localState[oldCount];
78
+ localState[oldCount] = newState;
79
+ if (oldValue !== newState) {
80
+ (_a = this.updateCallback) == null ? void 0 : _a.call(this);
81
+ }
82
+ }
83
+ ];
84
+ };
85
+ }
86
+ }
87
+
88
+ function findUp(node, target) {
89
+ if (node === target) {
90
+ return true;
91
+ }
92
+ if (node.parent) {
93
+ return findUp(node.parent, target);
94
+ }
95
+ return false;
96
+ }
97
+ class AssetTransformCorePlugin {
98
+ constructor(registry) {
99
+ this.registry = registry;
100
+ this.stateStore = new Map();
101
+ this.beforeResolveSymbol = Symbol("before resolve");
102
+ this.resolveSymbol = Symbol("resolve");
103
+ this.beforeResolveCountSymbol = Symbol("before resolve count");
104
+ this.resolveCountSymbol = Symbol("resolve count");
105
+ }
106
+ apply(viewController) {
107
+ viewController.hooks.view.tap("asset-transform", (view) => {
108
+ this.stateStore.clear();
109
+ view.hooks.resolver.tap("asset-transform", (resolver) => {
110
+ let lastUpdatedNode;
111
+ const updateState = (node) => {
112
+ lastUpdatedNode = node;
113
+ view.update(new Set());
114
+ };
115
+ const getStore = (node, stepKey) => {
116
+ let store;
117
+ const countKey = stepKey === this.resolveSymbol ? this.resolveCountSymbol : this.beforeResolveCountSymbol;
118
+ const storedState = this.stateStore.get(node);
119
+ if (storedState) {
120
+ store = storedState;
121
+ store.removeKey(countKey);
122
+ } else {
123
+ store = new LocalStateStore(() => {
124
+ updateState(node);
125
+ });
126
+ this.stateStore.set(node, store);
127
+ }
128
+ return {
129
+ useSharedState: (key) => {
130
+ return store.useSharedState(key);
131
+ },
132
+ useLocalState: (initialState) => {
133
+ return store.getLocalStateFunction(stepKey, countKey)(initialState);
134
+ }
135
+ };
136
+ };
137
+ resolver.hooks.beforeResolve.tap("asset-transform", (node, options) => {
138
+ if (node && (node.type === "asset" || node.type === "view")) {
139
+ const transform = this.registry.get(node.value);
140
+ if (transform == null ? void 0 : transform.beforeResolve) {
141
+ const store = getStore(node, this.beforeResolveSymbol);
142
+ return transform.beforeResolve(node, options, store);
143
+ }
144
+ }
145
+ return node;
146
+ });
147
+ resolver.hooks.afterUpdate.tap("asset-transform", () => {
148
+ lastUpdatedNode = void 0;
149
+ });
150
+ resolver.hooks.skipResolve.tap("asset-transform", (skip, node) => {
151
+ if (!skip || !lastUpdatedNode) {
152
+ return skip;
153
+ }
154
+ const isParentOfUpdated = findUp(lastUpdatedNode, node);
155
+ const isChildOfUpdated = findUp(node, lastUpdatedNode);
156
+ return !isParentOfUpdated && !isChildOfUpdated;
157
+ });
158
+ resolver.hooks.afterResolve.tap("asset-transform", (value, node, options) => {
159
+ if (node.type !== NodeType.Asset && node.type !== NodeType.View) {
160
+ return value;
161
+ }
162
+ const originalNode = resolver.getSourceNode(node);
163
+ if (!originalNode) {
164
+ return value;
165
+ }
166
+ const transform = this.registry.get(value);
167
+ if (transform == null ? void 0 : transform.resolve) {
168
+ const store = getStore(originalNode, this.resolveSymbol);
169
+ return transform == null ? void 0 : transform.resolve(value, options, store);
170
+ }
171
+ return value;
172
+ });
173
+ });
174
+ });
175
+ }
176
+ }
177
+
178
+ var __defProp$3 = Object.defineProperty;
179
+ var __defProps$3 = Object.defineProperties;
180
+ var __getOwnPropDescs$3 = Object.getOwnPropertyDescriptors;
181
+ var __getOwnPropSymbols$3 = Object.getOwnPropertySymbols;
182
+ var __hasOwnProp$3 = Object.prototype.hasOwnProperty;
183
+ var __propIsEnum$3 = Object.prototype.propertyIsEnumerable;
184
+ var __defNormalProp$3 = (obj, key, value) => key in obj ? __defProp$3(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
185
+ var __spreadValues$3 = (a, b) => {
186
+ for (var prop in b || (b = {}))
187
+ if (__hasOwnProp$3.call(b, prop))
188
+ __defNormalProp$3(a, prop, b[prop]);
189
+ if (__getOwnPropSymbols$3)
190
+ for (var prop of __getOwnPropSymbols$3(b)) {
191
+ if (__propIsEnum$3.call(b, prop))
192
+ __defNormalProp$3(a, prop, b[prop]);
193
+ }
194
+ return a;
195
+ };
196
+ var __spreadProps$3 = (a, b) => __defProps$3(a, __getOwnPropDescs$3(b));
197
+ class ViewController {
198
+ constructor(initialViews, options) {
199
+ this.hooks = {
200
+ resolveView: new SyncWaterfallHook([
201
+ "view",
202
+ "viewRef",
203
+ "viewState"
204
+ ]),
205
+ view: new SyncHook(["view"])
206
+ };
207
+ this.transformRegistry = new Registry();
208
+ this.optimizeUpdates = true;
209
+ this.viewOptions = options;
210
+ this.viewMap = initialViews.reduce((viewMap, view) => __spreadProps$3(__spreadValues$3({}, viewMap), {
211
+ [view.id]: view
212
+ }), {});
213
+ new AssetTransformCorePlugin(this.transformRegistry).apply(this);
214
+ options.flowController.hooks.flow.tap("viewController", (flow) => {
215
+ flow.hooks.transition.tap("viewController", (_oldState, newState) => {
216
+ if (newState.value.state_type === "VIEW") {
217
+ this.onView(newState.value);
218
+ } else {
219
+ this.currentView = void 0;
220
+ }
221
+ });
222
+ });
223
+ options.model.hooks.onUpdate.tap("viewController", (updates) => {
224
+ if (this.currentView) {
225
+ if (this.optimizeUpdates) {
226
+ this.queueUpdate(new Set(updates.map((t) => t.binding)));
227
+ } else {
228
+ this.currentView.update();
229
+ }
230
+ }
231
+ });
232
+ }
233
+ queueUpdate(bindings) {
234
+ var _a;
235
+ if ((_a = this.pendingUpdate) == null ? void 0 : _a.changedBindings) {
236
+ this.pendingUpdate.changedBindings = new Set([
237
+ ...this.pendingUpdate.changedBindings,
238
+ ...bindings
239
+ ]);
240
+ } else {
241
+ this.pendingUpdate = { changedBindings: bindings };
242
+ queueMicrotask(() => {
243
+ var _a2, _b;
244
+ const updates = (_a2 = this.pendingUpdate) == null ? void 0 : _a2.changedBindings;
245
+ this.pendingUpdate = void 0;
246
+ (_b = this.currentView) == null ? void 0 : _b.update(updates);
247
+ });
248
+ }
249
+ }
250
+ getViewForRef(viewRef) {
251
+ if (this.viewMap[viewRef]) {
252
+ return this.viewMap[viewRef];
253
+ }
254
+ const matchingViewId = Object.keys(this.viewMap).find((possibleViewIdMatch) => viewRef === resolveDataRefsInString(possibleViewIdMatch, {
255
+ model: this.viewOptions.model,
256
+ evaluate: this.viewOptions.evaluator.evaluate
257
+ }));
258
+ if (matchingViewId && this.viewMap[matchingViewId]) {
259
+ return this.viewMap[matchingViewId];
260
+ }
261
+ }
262
+ onView(state) {
263
+ const viewId = state.ref;
264
+ const source = this.hooks.resolveView.call(this.getViewForRef(viewId), viewId, state);
265
+ if (!source) {
266
+ throw new Error(`No view with id ${viewId}`);
267
+ }
268
+ const view = new ViewInstance(source, this.viewOptions);
269
+ this.currentView = view;
270
+ this.hooks.view.call(view);
271
+ view.update();
272
+ }
273
+ }
274
+
275
+ class DataController {
276
+ constructor(model, options) {
277
+ this.hooks = {
278
+ resolve: new SyncWaterfallHook(["binding"]),
279
+ resolveDataStages: new SyncWaterfallHook(["pipeline"]),
280
+ resolveDefaultValue: new SyncBailHook(["binding"]),
281
+ onDelete: new SyncHook(["binding"]),
282
+ onSet: new SyncHook(["transaction"]),
283
+ onGet: new SyncHook(["binding", "result"]),
284
+ onUpdate: new SyncHook(["updates"]),
285
+ format: new SyncWaterfallHook(["value", "binding"]),
286
+ deformat: new SyncWaterfallHook(["value", "binding"]),
287
+ serialize: new SyncWaterfallHook(["data"])
288
+ };
289
+ this.logger = options.logger;
290
+ const middleware = options.middleware || [];
291
+ this.baseMiddleware = [new LocalModel(model), ...middleware];
292
+ this.trash = new Set();
293
+ this.pathResolver = options.pathResolver;
294
+ }
295
+ getModel() {
296
+ if (!this.model) {
297
+ const stages = this.hooks.resolveDataStages.call(this.baseMiddleware);
298
+ const model = new PipelinedDataModel();
299
+ model.setMiddleware(stages);
300
+ this.model = model;
301
+ }
302
+ return this.model;
303
+ }
304
+ resolveDataValue(binding, value, deformat) {
305
+ if (deformat) {
306
+ return this.hooks.deformat.call(value, binding);
307
+ }
308
+ return value;
309
+ }
310
+ set(transaction, options) {
311
+ let normalizedTransaction = [];
312
+ if (Array.isArray(transaction)) {
313
+ normalizedTransaction = transaction.map(([binding, value]) => {
314
+ const parsed = this.pathResolver.parse(binding);
315
+ return [
316
+ parsed,
317
+ this.resolveDataValue(parsed, value, Boolean(options == null ? void 0 : options.formatted))
318
+ ];
319
+ });
320
+ } else {
321
+ normalizedTransaction = Object.keys(transaction).map((binding) => {
322
+ const parsed = this.pathResolver.parse(binding);
323
+ const val = transaction[binding];
324
+ return [
325
+ parsed,
326
+ this.resolveDataValue(parsed, val, Boolean(options == null ? void 0 : options.formatted))
327
+ ];
328
+ });
329
+ }
330
+ const setUpdates = normalizedTransaction.reduce((updates, [binding, newVal]) => {
331
+ var _a;
332
+ const oldVal = this.get(binding, { includeInvalid: true });
333
+ if (!dequal(oldVal, newVal)) {
334
+ updates.push({
335
+ binding,
336
+ newValue: newVal,
337
+ oldValue: oldVal
338
+ });
339
+ }
340
+ (_a = this.logger) == null ? void 0 : _a.debug(`Setting path: ${binding.asString()} from: ${oldVal} to: ${newVal}`);
341
+ return updates;
342
+ }, []);
343
+ const result = this.getModel().set(normalizedTransaction, options);
344
+ const setUpdateBindings = new Set(setUpdates.map((su) => su.binding));
345
+ result.forEach((tr) => {
346
+ var _a;
347
+ if (!setUpdateBindings.has(tr.binding) && (tr.force === true || !dequal(tr.oldValue, tr.newValue))) {
348
+ (_a = this.logger) == null ? void 0 : _a.debug(`Path: ${tr.binding.asString()} was changed from: ${tr.oldValue} to: ${tr.newValue}`);
349
+ setUpdates.push(tr);
350
+ }
351
+ });
352
+ this.hooks.onSet.call(normalizedTransaction);
353
+ if (setUpdates.length > 0) {
354
+ this.hooks.onUpdate.call(setUpdates);
355
+ }
356
+ return result;
357
+ }
358
+ resolve(binding) {
359
+ return Array.isArray(binding) || typeof binding === "string" ? this.pathResolver.parse(binding) : binding;
360
+ }
361
+ get(binding, options) {
362
+ const resolved = binding instanceof BindingInstance ? binding : this.resolve(binding);
363
+ let result = this.getModel().get(resolved, options);
364
+ if (result === void 0 && !(options == null ? void 0 : options.ignoreDefaultValue)) {
365
+ const defaultVal = this.hooks.resolveDefaultValue.call(resolved);
366
+ if (defaultVal !== result) {
367
+ result = defaultVal;
368
+ }
369
+ }
370
+ if (options == null ? void 0 : options.formatted) {
371
+ result = this.hooks.format.call(result, resolved);
372
+ }
373
+ this.hooks.onGet.call(binding, result);
374
+ return result;
375
+ }
376
+ delete(binding) {
377
+ if (binding === void 0 || binding === null) {
378
+ throw new Error(`Invalid arguments: delete expects a data path (string)`);
379
+ }
380
+ const resolved = this.resolve(binding);
381
+ this.hooks.onDelete.call(resolved);
382
+ this.deleteData(resolved);
383
+ }
384
+ getTrash() {
385
+ return this.trash;
386
+ }
387
+ addToTrash(binding) {
388
+ this.trash.add(binding);
389
+ }
390
+ deleteData(binding) {
391
+ const parentBinding = binding.parent();
392
+ const parentPath = parentBinding.asString();
393
+ const property = binding.key();
394
+ const existedBeforeDelete = Object.prototype.hasOwnProperty.call(this.get(parentBinding), property);
395
+ if (property !== void 0) {
396
+ const parent = parentBinding ? this.get(parentBinding) : void 0;
397
+ if (parentPath && Array.isArray(parent)) {
398
+ if (parent.length > property) {
399
+ this.set([[parentBinding, removeAt(parent, property)]]);
400
+ }
401
+ } else if (parentPath && parent[property]) {
402
+ this.set([[parentBinding, omit(parent, property)]]);
403
+ } else if (!parentPath) {
404
+ this.getModel().reset(omit(this.get(""), property));
405
+ }
406
+ }
407
+ if (existedBeforeDelete && !this.get(binding)) {
408
+ this.addToTrash(binding);
409
+ }
410
+ }
411
+ serialize() {
412
+ return this.hooks.serialize.call(this.get(""));
413
+ }
414
+ }
415
+
416
+ var __defProp$2 = Object.defineProperty;
417
+ var __defProps$2 = Object.defineProperties;
418
+ var __getOwnPropDescs$2 = Object.getOwnPropertyDescriptors;
419
+ var __getOwnPropSymbols$2 = Object.getOwnPropertySymbols;
420
+ var __hasOwnProp$2 = Object.prototype.hasOwnProperty;
421
+ var __propIsEnum$2 = Object.prototype.propertyIsEnumerable;
422
+ var __defNormalProp$2 = (obj, key, value) => key in obj ? __defProp$2(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
423
+ var __spreadValues$2 = (a, b) => {
424
+ for (var prop in b || (b = {}))
425
+ if (__hasOwnProp$2.call(b, prop))
426
+ __defNormalProp$2(a, prop, b[prop]);
427
+ if (__getOwnPropSymbols$2)
428
+ for (var prop of __getOwnPropSymbols$2(b)) {
429
+ if (__propIsEnum$2.call(b, prop))
430
+ __defNormalProp$2(a, prop, b[prop]);
431
+ }
432
+ return a;
433
+ };
434
+ var __spreadProps$2 = (a, b) => __defProps$2(a, __getOwnPropDescs$2(b));
435
+ const CONTEXT = "validation-binding-tracker";
436
+ class ValidationBindingTrackerViewPlugin {
437
+ constructor(options) {
438
+ this.trackedBindings = new Set();
439
+ this.options = options;
440
+ }
441
+ getBindings() {
442
+ return this.trackedBindings;
443
+ }
444
+ applyResolver(resolver) {
445
+ this.trackedBindings.clear();
446
+ const tracked = new Map();
447
+ const sections = new Map();
448
+ const seenBindings = new Set();
449
+ let lastViewUpdateChangeSet;
450
+ const nodeTree = new Map();
451
+ let lastComputedBindingTree = new Map();
452
+ let currentBindingTree = new Map();
453
+ const lastSectionBindingTree = new Map();
454
+ function addToTree(child, parent) {
455
+ var _a;
456
+ if (nodeTree.has(parent)) {
457
+ (_a = nodeTree.get(parent)) == null ? void 0 : _a.add(child);
458
+ return;
459
+ }
460
+ nodeTree.set(parent, new Set([child]));
461
+ }
462
+ resolver.hooks.beforeUpdate.tap(CONTEXT, (changes) => {
463
+ lastViewUpdateChangeSet = changes;
464
+ });
465
+ resolver.hooks.skipResolve.tap(CONTEXT, (shouldSkip, node) => {
466
+ const trackedBindingsForNode = lastComputedBindingTree.get(node);
467
+ if (!shouldSkip || !lastViewUpdateChangeSet || !trackedBindingsForNode) {
468
+ return shouldSkip;
469
+ }
470
+ const intersection = new Set([...lastViewUpdateChangeSet].filter((b) => trackedBindingsForNode.has(b)));
471
+ return intersection.size === 0;
472
+ });
473
+ resolver.hooks.resolveOptions.tap(CONTEXT, (options, node) => {
474
+ if (options.validation === void 0) {
475
+ return options;
476
+ }
477
+ tracked.delete(node);
478
+ const track = (binding) => {
479
+ var _a, _b, _c, _d;
480
+ const parsed = isBinding(binding) ? binding : this.options.parseBinding(binding);
481
+ if (tracked.has(node)) {
482
+ (_a = tracked.get(node)) == null ? void 0 : _a.add(parsed);
483
+ } else {
484
+ tracked.set(node, new Set([parsed]));
485
+ }
486
+ let { parent } = node;
487
+ while (parent) {
488
+ if (sections.has(parent)) {
489
+ (_b = sections.get(parent)) == null ? void 0 : _b.add(node);
490
+ break;
491
+ } else {
492
+ parent = parent.parent;
493
+ }
494
+ }
495
+ if (!seenBindings.has(parsed)) {
496
+ seenBindings.add(parsed);
497
+ (_d = (_c = this.options.callbacks) == null ? void 0 : _c.onAdd) == null ? void 0 : _d.call(_c, parsed);
498
+ }
499
+ };
500
+ return __spreadProps$2(__spreadValues$2({}, options), {
501
+ validation: __spreadProps$2(__spreadValues$2({}, options.validation), {
502
+ get: (binding, getOptions) => {
503
+ var _a;
504
+ if (getOptions == null ? void 0 : getOptions.track) {
505
+ track(binding);
506
+ }
507
+ const eow = (_a = options.validation) == null ? void 0 : _a._getValidationForBinding(binding);
508
+ if ((eow == null ? void 0 : eow.displayTarget) === void 0 || (eow == null ? void 0 : eow.displayTarget) === "field") {
509
+ return eow;
510
+ }
511
+ return void 0;
512
+ },
513
+ getChildren: (type) => {
514
+ var _a;
515
+ const validations = new Array();
516
+ (_a = lastComputedBindingTree.get(node)) == null ? void 0 : _a.forEach((binding) => {
517
+ var _a2;
518
+ const eow = (_a2 = options.validation) == null ? void 0 : _a2._getValidationForBinding(binding);
519
+ if (eow && type === eow.displayTarget) {
520
+ validations.push(eow);
521
+ }
522
+ });
523
+ return validations;
524
+ },
525
+ getValidationsForSection: () => {
526
+ var _a;
527
+ const validations = new Array();
528
+ (_a = lastSectionBindingTree.get(node)) == null ? void 0 : _a.forEach((binding) => {
529
+ var _a2;
530
+ const eow = (_a2 = options.validation) == null ? void 0 : _a2._getValidationForBinding(binding);
531
+ if (eow && eow.displayTarget === "section") {
532
+ validations.push(eow);
533
+ }
534
+ });
535
+ return validations;
536
+ },
537
+ register: (registerOptions) => {
538
+ if ((registerOptions == null ? void 0 : registerOptions.type) === "section") {
539
+ if (!sections.has(node)) {
540
+ sections.set(node, new Set());
541
+ }
542
+ }
543
+ },
544
+ track
545
+ })
546
+ });
547
+ });
548
+ resolver.hooks.afterNodeUpdate.tap(CONTEXT, (node, parent, update) => {
549
+ var _a, _b, _c;
550
+ if (parent) {
551
+ addToTree(node, parent);
552
+ }
553
+ if (update.updated) {
554
+ const newlyComputed = new Set(tracked.get(node));
555
+ (_a = nodeTree.get(node)) == null ? void 0 : _a.forEach((child) => {
556
+ var _a2;
557
+ (_a2 = currentBindingTree.get(child)) == null ? void 0 : _a2.forEach((b) => newlyComputed.add(b));
558
+ });
559
+ currentBindingTree.set(node, newlyComputed);
560
+ } else {
561
+ currentBindingTree.set(node, (_b = lastComputedBindingTree.get(node)) != null ? _b : new Set());
562
+ }
563
+ if (node === resolver.root) {
564
+ this.trackedBindings = (_c = currentBindingTree.get(node)) != null ? _c : new Set();
565
+ lastComputedBindingTree = currentBindingTree;
566
+ lastSectionBindingTree.clear();
567
+ sections.forEach((nodeSet, sectionNode) => {
568
+ const temp = new Set();
569
+ nodeSet.forEach((n) => {
570
+ var _a2;
571
+ (_a2 = tracked.get(n)) == null ? void 0 : _a2.forEach(temp.add, temp);
572
+ });
573
+ lastSectionBindingTree.set(sectionNode, temp);
574
+ });
575
+ nodeTree.clear();
576
+ tracked.clear();
577
+ sections.clear();
578
+ currentBindingTree = new Map();
579
+ }
580
+ });
581
+ }
582
+ apply(view) {
583
+ view.hooks.resolver.tap(CONTEXT, this.applyResolver.bind(this));
584
+ }
585
+ }
586
+
587
+ var __defProp$1 = Object.defineProperty;
588
+ var __defProps$1 = Object.defineProperties;
589
+ var __getOwnPropDescs$1 = Object.getOwnPropertyDescriptors;
590
+ var __getOwnPropSymbols$1 = Object.getOwnPropertySymbols;
591
+ var __hasOwnProp$1 = Object.prototype.hasOwnProperty;
592
+ var __propIsEnum$1 = Object.prototype.propertyIsEnumerable;
593
+ var __defNormalProp$1 = (obj, key, value) => key in obj ? __defProp$1(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
594
+ var __spreadValues$1 = (a, b) => {
595
+ for (var prop in b || (b = {}))
596
+ if (__hasOwnProp$1.call(b, prop))
597
+ __defNormalProp$1(a, prop, b[prop]);
598
+ if (__getOwnPropSymbols$1)
599
+ for (var prop of __getOwnPropSymbols$1(b)) {
600
+ if (__propIsEnum$1.call(b, prop))
601
+ __defNormalProp$1(a, prop, b[prop]);
602
+ }
603
+ return a;
604
+ };
605
+ var __spreadProps$1 = (a, b) => __defProps$1(a, __getOwnPropDescs$1(b));
606
+ function createStatefulValidationObject(obj) {
607
+ return {
608
+ value: obj,
609
+ type: obj.severity,
610
+ state: "none"
611
+ };
612
+ }
613
+ class ValidatedBinding {
614
+ constructor(possibleValidations, onDismiss, log, weakBindings) {
615
+ this.applicableValidations = [];
616
+ this.validationsByState = {
617
+ load: [],
618
+ change: [],
619
+ navigation: []
620
+ };
621
+ this.onDismiss = onDismiss;
622
+ possibleValidations.forEach((vObj) => {
623
+ const { trigger } = vObj;
624
+ if (this.validationsByState[trigger]) {
625
+ this.validationsByState[trigger].push(createStatefulValidationObject(vObj));
626
+ } else {
627
+ log == null ? void 0 : log.warn(`Unknown validation trigger: ${trigger}`);
628
+ }
629
+ });
630
+ this.weakBindings = weakBindings != null ? weakBindings : new Set();
631
+ }
632
+ get() {
633
+ const firstError = this.applicableValidations.find((statefulObj) => {
634
+ const blocking = this.currentPhase === "navigation" ? statefulObj.value.blocking : true;
635
+ return statefulObj.state === "active" && blocking !== false;
636
+ });
637
+ if ((firstError == null ? void 0 : firstError.state) === "active") {
638
+ return firstError.response;
639
+ }
640
+ }
641
+ runApplicableValidations(runner, canDismiss) {
642
+ this.applicableValidations = this.applicableValidations.map((obj) => {
643
+ var _a, _b, _c;
644
+ if (obj.state === "dismissed") {
645
+ return obj;
646
+ }
647
+ const blocking = (_a = obj.value.blocking) != null ? _a : obj.value.severity === "warning" && "once" || obj.value.severity === "error" && true;
648
+ const dismissable = canDismiss && blocking === "once";
649
+ if (this.currentPhase === "navigation" && obj.state === "active" && dismissable) {
650
+ if (obj.value.severity === "warning") {
651
+ const warn = obj;
652
+ if (warn.dismissable && warn.response.dismiss) {
653
+ warn.response.dismiss();
654
+ } else {
655
+ warn.dismissable = true;
656
+ }
657
+ return obj;
658
+ }
659
+ if (obj.value.severity === "error") {
660
+ const err = obj;
661
+ err.state = "none";
662
+ return obj;
663
+ }
664
+ }
665
+ const response = runner(obj.value);
666
+ const newState = {
667
+ type: obj.type,
668
+ value: obj.value,
669
+ state: response ? "active" : "none",
670
+ dismissable: obj.value.severity === "warning" && this.currentPhase === "navigation",
671
+ response: response ? __spreadProps$1(__spreadValues$1({}, obj.value), {
672
+ message: (_b = response.message) != null ? _b : "Something is broken",
673
+ severity: obj.value.severity,
674
+ displayTarget: (_c = obj.value.displayTarget) != null ? _c : "field"
675
+ }) : void 0
676
+ };
677
+ if (newState.state === "active" && obj.value.severity === "warning") {
678
+ newState.response.dismiss = () => {
679
+ var _a2;
680
+ newState.state = "dismissed";
681
+ (_a2 = this.onDismiss) == null ? void 0 : _a2.call(this);
682
+ };
683
+ }
684
+ return newState;
685
+ });
686
+ }
687
+ update(phase, canDismiss, runner) {
688
+ if (phase === "load" && this.currentPhase !== void 0) {
689
+ return;
690
+ }
691
+ if (this.currentPhase === "navigation" || phase === this.currentPhase) {
692
+ this.runApplicableValidations(runner, canDismiss);
693
+ return;
694
+ }
695
+ if (phase === "load") {
696
+ this.currentPhase = "load";
697
+ this.applicableValidations = [...this.validationsByState.load];
698
+ } else if (phase === "change" && this.currentPhase === "load") {
699
+ this.currentPhase = "change";
700
+ this.applicableValidations = [
701
+ ...this.applicableValidations,
702
+ ...this.validationsByState.change
703
+ ];
704
+ } else if (phase === "navigation" && (this.currentPhase === "load" || this.currentPhase === "change")) {
705
+ this.applicableValidations = [
706
+ ...this.applicableValidations,
707
+ ...this.currentPhase === "load" ? this.validationsByState.change : [],
708
+ ...this.validationsByState.navigation
709
+ ];
710
+ this.currentPhase = "navigation";
711
+ }
712
+ this.runApplicableValidations(runner, canDismiss);
713
+ }
714
+ }
715
+ class ValidationController {
716
+ constructor(schema, options) {
717
+ this.hooks = {
718
+ createValidatorRegistry: new SyncHook(["registry"]),
719
+ onAddValidation: new SyncWaterfallHook(["validation", "binding"]),
720
+ onRemoveValidation: new SyncWaterfallHook(["validation", "binding"])
721
+ };
722
+ this.validations = new Map();
723
+ this.weakBindingTracker = new Set();
724
+ this.lastActiveBindings = new Set();
725
+ this.schema = schema;
726
+ this.options = options;
727
+ this.providers = [schema];
728
+ }
729
+ setOptions(options) {
730
+ this.options = options;
731
+ }
732
+ getDataMiddleware() {
733
+ return [
734
+ new ValidationMiddleware((binding) => {
735
+ if (!this.options) {
736
+ return;
737
+ }
738
+ this.updateValidationsForBinding(binding, "change", this.options);
739
+ const strongValidation = this.getValidationForBinding(binding);
740
+ if (strongValidation == null ? void 0 : strongValidation.get())
741
+ return strongValidation.get();
742
+ const newInvalidBindings = new Set();
743
+ for (const [, weakValidation] of Array.from(this.validations)) {
744
+ if (caresAboutDataChanges(new Set([binding]), weakValidation.weakBindings) && (weakValidation == null ? void 0 : weakValidation.get())) {
745
+ weakValidation == null ? void 0 : weakValidation.weakBindings.forEach(newInvalidBindings.add, newInvalidBindings);
746
+ }
747
+ }
748
+ if (newInvalidBindings.size > 0) {
749
+ return newInvalidBindings;
750
+ }
751
+ }, { logger: new ProxyLogger(() => {
752
+ var _a;
753
+ return (_a = this.options) == null ? void 0 : _a.logger;
754
+ }) })
755
+ ];
756
+ }
757
+ onView(view) {
758
+ this.validations.clear();
759
+ if (!this.options) {
760
+ return;
761
+ }
762
+ const bindingTrackerPlugin = new ValidationBindingTrackerViewPlugin(__spreadProps$1(__spreadValues$1({}, this.options), {
763
+ callbacks: {
764
+ onAdd: (binding) => {
765
+ if (!this.options) {
766
+ return;
767
+ }
768
+ const originalValue = this.options.model.get(binding);
769
+ const withoutDefault = this.options.model.get(binding, {
770
+ ignoreDefaultValue: true
771
+ });
772
+ if (originalValue !== withoutDefault) {
773
+ this.options.model.set([[binding, originalValue]]);
774
+ }
775
+ this.updateValidationsForBinding(binding, "load", this.options, () => {
776
+ view.update(new Set([binding]));
777
+ });
778
+ }
779
+ }
780
+ }));
781
+ this.tracker = bindingTrackerPlugin;
782
+ this.providers = [this.schema, view];
783
+ bindingTrackerPlugin.apply(view);
784
+ }
785
+ updateValidationsForBinding(binding, trigger, context, onDismiss) {
786
+ var _a;
787
+ if (trigger === "load") {
788
+ const possibleValidations = this.providers.reduce((vals, provider) => {
789
+ var _a2, _b;
790
+ return [
791
+ ...vals,
792
+ ...(_b = (_a2 = provider.getValidationsForBinding) == null ? void 0 : _a2.call(provider, binding)) != null ? _b : []
793
+ ];
794
+ }, []);
795
+ if (possibleValidations.length === 0) {
796
+ return;
797
+ }
798
+ this.validations.set(binding, new ValidatedBinding(possibleValidations, onDismiss, (_a = this.options) == null ? void 0 : _a.logger));
799
+ }
800
+ const trackedValidations = this.validations.get(binding);
801
+ trackedValidations == null ? void 0 : trackedValidations.update(trigger, true, (validationObj) => {
802
+ const response = this.validationRunner(validationObj, context, binding);
803
+ if (this.weakBindingTracker.size > 0) {
804
+ const t = this.validations.get(binding);
805
+ this.weakBindingTracker.forEach((b) => t.weakBindings.add(b));
806
+ }
807
+ return response ? { message: response.message } : void 0;
808
+ });
809
+ if (trigger !== "load") {
810
+ this.validations.forEach((validation, vBinding) => {
811
+ if (vBinding !== binding && caresAboutDataChanges(new Set([binding]), validation.weakBindings)) {
812
+ validation.update(trigger, true, (validationObj) => {
813
+ const response = this.validationRunner(validationObj, context, binding);
814
+ return response ? { message: response.message } : void 0;
815
+ });
816
+ }
817
+ });
818
+ }
819
+ }
820
+ validationRunner(validationObj, context, binding) {
821
+ const handler = this.getValidator(validationObj.type);
822
+ const weakBindings = new Set();
823
+ const model = {
824
+ get(b, options = { includeInvalid: true }) {
825
+ weakBindings.add(isBinding(b) ? binding : context.parseBinding(b));
826
+ return context.model.get(b, options);
827
+ },
828
+ set: context.model.set
829
+ };
830
+ const result = handler == null ? void 0 : handler(__spreadProps$1(__spreadValues$1({}, context), {
831
+ evaluate: (exp, options = { model }) => context.evaluate(exp, options),
832
+ model,
833
+ validation: validationObj
834
+ }), context.model.get(binding, {
835
+ includeInvalid: true,
836
+ formatted: validationObj.dataTarget === "formatted"
837
+ }), validationObj);
838
+ this.weakBindingTracker = weakBindings;
839
+ if (result) {
840
+ let { message } = result;
841
+ const { parameters } = result;
842
+ if (validationObj.message) {
843
+ message = resolveDataRefs(validationObj.message, {
844
+ model,
845
+ evaluate: context.evaluate
846
+ });
847
+ if (parameters) {
848
+ message = replaceParams(message, parameters);
849
+ }
850
+ }
851
+ return {
852
+ message
853
+ };
854
+ }
855
+ }
856
+ updateValidationsForView(trigger) {
857
+ const { activeBindings } = this;
858
+ const canDismiss = trigger !== "navigation" || this.setCompare(this.lastActiveBindings, activeBindings);
859
+ this.getBindings().forEach((binding) => {
860
+ var _a;
861
+ (_a = this.validations.get(binding)) == null ? void 0 : _a.update(trigger, canDismiss, (obj) => {
862
+ if (!this.options) {
863
+ return;
864
+ }
865
+ return this.validationRunner(obj, this.options, binding);
866
+ });
867
+ });
868
+ if (trigger === "navigation") {
869
+ this.lastActiveBindings = activeBindings;
870
+ }
871
+ }
872
+ setCompare(set1, set2) {
873
+ if (set1.size !== set2.size)
874
+ return false;
875
+ for (const entry of set1)
876
+ if (!set2.has(entry))
877
+ return false;
878
+ return true;
879
+ }
880
+ get activeBindings() {
881
+ return new Set(Array.from(this.getBindings()).filter((b) => {
882
+ var _a;
883
+ return ((_a = this.validations.get(b)) == null ? void 0 : _a.get()) !== void 0;
884
+ }));
885
+ }
886
+ getValidator(type) {
887
+ if (this.validatorRegistry) {
888
+ return this.validatorRegistry.get(type);
889
+ }
890
+ const registry = new ValidatorRegistry();
891
+ this.hooks.createValidatorRegistry.call(registry);
892
+ this.validatorRegistry = registry;
893
+ return registry.get(type);
894
+ }
895
+ getBindings() {
896
+ var _a, _b;
897
+ return (_b = (_a = this.tracker) == null ? void 0 : _a.getBindings()) != null ? _b : new Set();
898
+ }
899
+ validateView(trigger = "navigation") {
900
+ var _a, _b;
901
+ this.updateValidationsForView(trigger);
902
+ const validations = new Map();
903
+ for (const b of this.getBindings()) {
904
+ const invalid = (_a = this.getValidationForBinding(b)) == null ? void 0 : _a.get();
905
+ if (invalid) {
906
+ (_b = this.options) == null ? void 0 : _b.logger.debug(`Validation on binding: ${b.asString()} is preventing navigation. ${JSON.stringify(invalid)}`);
907
+ validations.set(b, invalid);
908
+ }
909
+ }
910
+ return {
911
+ canTransition: validations.size === 0,
912
+ validations: validations.size ? validations : void 0
913
+ };
914
+ }
915
+ getValidationForBinding(binding) {
916
+ return this.validations.get(binding);
917
+ }
918
+ forView(parser) {
919
+ return {
920
+ _getValidationForBinding: (binding) => {
921
+ var _a;
922
+ return (_a = this.getValidationForBinding(isBinding(binding) ? binding : parser(binding))) == null ? void 0 : _a.get();
923
+ },
924
+ getAll: () => {
925
+ const bindings = this.getBindings();
926
+ if (bindings.size === 0) {
927
+ return void 0;
928
+ }
929
+ const validationMapping = new Map();
930
+ bindings.forEach((b) => {
931
+ var _a;
932
+ const validation = (_a = this.getValidationForBinding(b)) == null ? void 0 : _a.get();
933
+ if (validation) {
934
+ validationMapping.set(b, validation);
935
+ }
936
+ });
937
+ return validationMapping.size === 0 ? void 0 : validationMapping;
938
+ },
939
+ get() {
940
+ throw new Error("Error Access be provided by the view plugin");
941
+ },
942
+ getChildren() {
943
+ throw new Error("Error rollup should be provided by the view plugin");
944
+ },
945
+ getValidationsForSection() {
946
+ throw new Error("Error rollup should be provided by the view plugin");
947
+ },
948
+ track: () => {
949
+ throw new Error("Tracking should be provided by the view plugin");
950
+ },
951
+ register: () => {
952
+ throw new Error("Section funcationality hould be provided by the view plugin");
953
+ },
954
+ type: (binding) => this.schema.getType(isBinding(binding) ? binding : parser(binding))
955
+ };
956
+ }
957
+ }
958
+
959
+ class FlowExpPlugin {
960
+ constructor() {
961
+ this.name = "flow-exp-plugin";
962
+ }
963
+ apply(player) {
964
+ let expressionEvaluator;
965
+ const handleEval = (exp) => {
966
+ if (exp) {
967
+ if (typeof exp === "object" && "exp" in exp) {
968
+ expressionEvaluator == null ? void 0 : expressionEvaluator.evaluate(exp.exp);
969
+ } else {
970
+ expressionEvaluator == null ? void 0 : expressionEvaluator.evaluate(exp);
971
+ }
972
+ }
973
+ };
974
+ player.hooks.expressionEvaluator.tap(this.name, (evaluator) => {
975
+ expressionEvaluator = evaluator;
976
+ });
977
+ player.hooks.flowController.tap(this.name, (fc) => {
978
+ fc.hooks.flow.tap(this.name, (flow) => {
979
+ flow.hooks.onStart.tap(this.name, (exp) => handleEval(exp));
980
+ flow.hooks.onEnd.tap(this.name, (exp) => handleEval(exp));
981
+ flow.hooks.resolveTransitionNode.intercept({
982
+ call: (nextState) => {
983
+ var _a;
984
+ const currentState = () => player.getState();
985
+ const currentFlowState = (_a = currentState().controllers.flow.current) == null ? void 0 : _a.currentState;
986
+ if (currentFlowState == null ? void 0 : currentFlowState.value.onEnd) {
987
+ handleEval(currentFlowState.value.onEnd);
988
+ }
989
+ if (nextState == null ? void 0 : nextState.onStart) {
990
+ handleEval(nextState.onStart);
991
+ }
992
+ }
993
+ });
994
+ });
995
+ });
996
+ }
997
+ }
998
+
999
+ const NOT_STARTED_STATE = {
1000
+ ref: Symbol("not-started"),
1001
+ status: "not-started"
1002
+ };
1003
+
1004
+ var __defProp = Object.defineProperty;
1005
+ var __defProps = Object.defineProperties;
1006
+ var __getOwnPropDescs = Object.getOwnPropertyDescriptors;
1007
+ var __getOwnPropSymbols = Object.getOwnPropertySymbols;
1008
+ var __hasOwnProp = Object.prototype.hasOwnProperty;
1009
+ var __propIsEnum = Object.prototype.propertyIsEnumerable;
1010
+ var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
1011
+ var __spreadValues = (a, b) => {
1012
+ for (var prop in b || (b = {}))
1013
+ if (__hasOwnProp.call(b, prop))
1014
+ __defNormalProp(a, prop, b[prop]);
1015
+ if (__getOwnPropSymbols)
1016
+ for (var prop of __getOwnPropSymbols(b)) {
1017
+ if (__propIsEnum.call(b, prop))
1018
+ __defNormalProp(a, prop, b[prop]);
1019
+ }
1020
+ return a;
1021
+ };
1022
+ var __spreadProps = (a, b) => __defProps(a, __getOwnPropDescs(b));
1023
+ var __async = (__this, __arguments, generator) => {
1024
+ return new Promise((resolve, reject) => {
1025
+ var fulfilled = (value) => {
1026
+ try {
1027
+ step(generator.next(value));
1028
+ } catch (e) {
1029
+ reject(e);
1030
+ }
1031
+ };
1032
+ var rejected = (value) => {
1033
+ try {
1034
+ step(generator.throw(value));
1035
+ } catch (e) {
1036
+ reject(e);
1037
+ }
1038
+ };
1039
+ var step = (x) => x.done ? resolve(x.value) : Promise.resolve(x.value).then(fulfilled, rejected);
1040
+ step((generator = generator.apply(__this, __arguments)).next());
1041
+ });
1042
+ };
1043
+ const PLAYER_VERSION = "!!STABLE_VERSION!!";
1044
+ const COMMIT = "!!STABLE_GIT_COMMIT!!";
1045
+ const _Player = class {
1046
+ constructor(config) {
1047
+ this.logger = new TapableLogger();
1048
+ this.constantsController = new ConstantsController();
1049
+ this.state = NOT_STARTED_STATE;
1050
+ this.hooks = {
1051
+ flowController: new SyncHook(["flowController"]),
1052
+ viewController: new SyncHook(["viewController"]),
1053
+ view: new SyncHook(["view"]),
1054
+ expressionEvaluator: new SyncHook([
1055
+ "expressionEvaluator"
1056
+ ]),
1057
+ dataController: new SyncHook(["dataController"]),
1058
+ schema: new SyncHook(["schema"]),
1059
+ validationController: new SyncHook([
1060
+ "validationController"
1061
+ ]),
1062
+ bindingParser: new SyncHook(["bindingParser"]),
1063
+ state: new SyncHook(["state"]),
1064
+ onStart: new SyncHook(["flow"]),
1065
+ onEnd: new SyncHook(),
1066
+ resolveFlowContent: new SyncWaterfallHook(["content"])
1067
+ };
1068
+ var _a;
1069
+ const initialPlugins = [];
1070
+ const flowExpPlugin = new FlowExpPlugin();
1071
+ initialPlugins.push(flowExpPlugin);
1072
+ if (config == null ? void 0 : config.logger) {
1073
+ this.logger.addHandler(config.logger);
1074
+ }
1075
+ this.config = config || {};
1076
+ this.config.plugins = [...this.config.plugins || [], ...initialPlugins];
1077
+ (_a = this.config.plugins) == null ? void 0 : _a.forEach((plugin) => {
1078
+ plugin.apply(this);
1079
+ });
1080
+ }
1081
+ findPlugin(symbol) {
1082
+ var _a;
1083
+ return (_a = this.config.plugins) == null ? void 0 : _a.find((el) => el.symbol === symbol);
1084
+ }
1085
+ applyTo(symbol, apply) {
1086
+ const plugin = this.findPlugin(symbol);
1087
+ if (plugin) {
1088
+ apply(plugin);
1089
+ }
1090
+ }
1091
+ registerPlugin(plugin) {
1092
+ var _a;
1093
+ plugin.apply(this);
1094
+ (_a = this.config.plugins) == null ? void 0 : _a.push(plugin);
1095
+ }
1096
+ getVersion() {
1097
+ return _Player.info.version;
1098
+ }
1099
+ getCommit() {
1100
+ return _Player.info.commit;
1101
+ }
1102
+ getState() {
1103
+ return this.state;
1104
+ }
1105
+ setState(state) {
1106
+ this.state = state;
1107
+ this.hooks.state.call(state);
1108
+ }
1109
+ setupFlow(userContent) {
1110
+ const userFlow = this.hooks.resolveFlowContent.call(userContent);
1111
+ const flowController = new FlowController(userFlow.navigation, {
1112
+ logger: this.logger
1113
+ });
1114
+ this.hooks.onStart.call(userFlow);
1115
+ this.hooks.flowController.call(flowController);
1116
+ let expressionEvaluator;
1117
+ let dataController;
1118
+ const pathResolver = new BindingParser({
1119
+ get: (binding) => {
1120
+ return dataController.get(binding);
1121
+ },
1122
+ set: (transaction) => {
1123
+ return dataController.set(transaction);
1124
+ },
1125
+ evaluate: (expression) => {
1126
+ return expressionEvaluator.evaluate(expression);
1127
+ }
1128
+ });
1129
+ this.hooks.bindingParser.call(pathResolver);
1130
+ const parseBinding = pathResolver.parse;
1131
+ const flowResultDeferred = deferred();
1132
+ const schema = new SchemaController(userFlow.schema);
1133
+ this.hooks.schema.call(schema);
1134
+ const validationController = new ValidationController(schema);
1135
+ this.hooks.validationController.call(validationController);
1136
+ dataController = new DataController(userFlow.data, {
1137
+ pathResolver,
1138
+ middleware: validationController.getDataMiddleware(),
1139
+ logger: this.logger
1140
+ });
1141
+ dataController.hooks.format.tap("player", (value, binding) => {
1142
+ const formatter = schema.getFormatter(binding);
1143
+ return formatter ? formatter.format(value) : value;
1144
+ });
1145
+ dataController.hooks.deformat.tap("player", (value, binding) => {
1146
+ const formatter = schema.getFormatter(binding);
1147
+ return formatter ? formatter.deformat(value) : value;
1148
+ });
1149
+ dataController.hooks.resolveDefaultValue.tap("player", (binding) => {
1150
+ var _a;
1151
+ return (_a = schema.getApparentType(binding)) == null ? void 0 : _a.default;
1152
+ });
1153
+ let viewController;
1154
+ expressionEvaluator = new ExpressionEvaluator({
1155
+ model: dataController,
1156
+ logger: this.logger
1157
+ });
1158
+ this.hooks.expressionEvaluator.call(expressionEvaluator);
1159
+ expressionEvaluator.hooks.onError.tap("player", (e) => {
1160
+ flowResultDeferred.reject(e);
1161
+ return true;
1162
+ });
1163
+ function resolveStrings(val) {
1164
+ return resolveDataRefs(val, {
1165
+ model: dataController,
1166
+ evaluate: expressionEvaluator.evaluate
1167
+ });
1168
+ }
1169
+ flowController.hooks.flow.tap("player", (flow) => {
1170
+ flow.hooks.beforeTransition.tap("player", (state, transitionVal) => {
1171
+ if (!("transitions" in state) || !state.transitions[transitionVal]) {
1172
+ return state;
1173
+ }
1174
+ return setIn(state, ["transitions", transitionVal], resolveStrings(state.transitions[transitionVal]));
1175
+ });
1176
+ flow.hooks.skipTransition.tap("validation", (currentState) => {
1177
+ var _a;
1178
+ if ((currentState == null ? void 0 : currentState.value.state_type) === "VIEW") {
1179
+ const { canTransition, validations } = validationController.validateView("navigation");
1180
+ if (!canTransition && validations) {
1181
+ const bindings = new Set(validations.keys());
1182
+ (_a = viewController == null ? void 0 : viewController.currentView) == null ? void 0 : _a.update(bindings);
1183
+ return true;
1184
+ }
1185
+ }
1186
+ return void 0;
1187
+ });
1188
+ flow.hooks.resolveTransitionNode.tap("player", (state) => {
1189
+ let newState = state;
1190
+ if ("ref" in state) {
1191
+ newState = setIn(state, ["ref"], resolveStrings(state.ref));
1192
+ }
1193
+ if ("param" in state) {
1194
+ newState = setIn(state, ["param"], resolveStrings(state.param));
1195
+ }
1196
+ return newState;
1197
+ });
1198
+ flow.hooks.transition.tap("player", (_oldState, newState) => {
1199
+ if (newState.value.state_type === "ACTION") {
1200
+ const { exp } = newState.value;
1201
+ queueMicrotask(() => {
1202
+ flowController == null ? void 0 : flowController.transition(String(expressionEvaluator == null ? void 0 : expressionEvaluator.evaluate(exp)));
1203
+ });
1204
+ }
1205
+ expressionEvaluator.reset();
1206
+ });
1207
+ });
1208
+ this.hooks.dataController.call(dataController);
1209
+ validationController.setOptions({
1210
+ parseBinding,
1211
+ model: dataController,
1212
+ logger: this.logger,
1213
+ evaluate: expressionEvaluator.evaluate,
1214
+ constants: this.constantsController
1215
+ });
1216
+ viewController = new ViewController(userFlow.views || [], {
1217
+ evaluator: expressionEvaluator,
1218
+ parseBinding,
1219
+ transition: flowController.transition,
1220
+ model: dataController,
1221
+ logger: this.logger,
1222
+ flowController,
1223
+ schema,
1224
+ format: (binding, value) => {
1225
+ const formatter = schema.getFormatter(binding);
1226
+ return (formatter == null ? void 0 : formatter.format) ? formatter.format(value) : value;
1227
+ },
1228
+ formatValue: (ref, value) => {
1229
+ const formatter = schema.getFormatterForType(ref);
1230
+ return (formatter == null ? void 0 : formatter.format) ? formatter.format(value) : value;
1231
+ },
1232
+ validation: __spreadProps(__spreadValues({}, validationController.forView(parseBinding)), {
1233
+ type: (b) => schema.getType(parseBinding(b))
1234
+ })
1235
+ });
1236
+ viewController.hooks.view.tap("player", (view) => {
1237
+ validationController.onView(view);
1238
+ this.hooks.view.call(view);
1239
+ });
1240
+ this.hooks.viewController.call(viewController);
1241
+ const formatFunction = (ctx, value, formatName) => {
1242
+ var _a, _b;
1243
+ return (_b = (_a = schema.getFormatterForType({ type: formatName })) == null ? void 0 : _a.format(value)) != null ? _b : value;
1244
+ };
1245
+ expressionEvaluator.addExpressionFunction("format", formatFunction);
1246
+ return {
1247
+ start: () => {
1248
+ flowController.start().then((endState) => {
1249
+ const flowResult = {
1250
+ endState: resolveStrings(endState),
1251
+ data: dataController.serialize()
1252
+ };
1253
+ return flowResult;
1254
+ }).then(flowResultDeferred.resolve).catch((e) => {
1255
+ this.logger.error(`Something went wrong: ${e.message}`);
1256
+ throw e;
1257
+ }).catch(flowResultDeferred.reject).finally(() => this.hooks.onEnd.call());
1258
+ },
1259
+ state: {
1260
+ status: "in-progress",
1261
+ flowResult: flowResultDeferred.promise,
1262
+ controllers: {
1263
+ data: dataController,
1264
+ view: viewController,
1265
+ flow: flowController,
1266
+ schema,
1267
+ expression: expressionEvaluator,
1268
+ binding: pathResolver,
1269
+ validation: validationController
1270
+ },
1271
+ fail: flowResultDeferred.reject,
1272
+ flow: userFlow,
1273
+ logger: this.logger
1274
+ }
1275
+ };
1276
+ }
1277
+ start(payload) {
1278
+ return __async(this, null, function* () {
1279
+ var _a;
1280
+ const ref = Symbol((_a = payload == null ? void 0 : payload.id) != null ? _a : "payload");
1281
+ const maybeUpdateState = (newState) => {
1282
+ if (this.state.ref !== ref) {
1283
+ this.logger.warn(`Received update for a flow that's not the current one`);
1284
+ return newState;
1285
+ }
1286
+ this.setState(newState);
1287
+ return newState;
1288
+ };
1289
+ this.setState({
1290
+ status: "not-started",
1291
+ ref
1292
+ });
1293
+ try {
1294
+ const { state, start } = this.setupFlow(payload);
1295
+ this.setState(__spreadValues({
1296
+ ref
1297
+ }, state));
1298
+ start();
1299
+ const endProps = {
1300
+ ref,
1301
+ status: "completed",
1302
+ flow: state.flow,
1303
+ dataModel: state.controllers.data.getModel()
1304
+ };
1305
+ return maybeUpdateState(__spreadValues(__spreadValues({}, yield state.flowResult), endProps));
1306
+ } catch (error) {
1307
+ const errorState = {
1308
+ status: "error",
1309
+ ref,
1310
+ flow: payload,
1311
+ error
1312
+ };
1313
+ maybeUpdateState(errorState);
1314
+ throw error;
1315
+ }
1316
+ });
1317
+ }
1318
+ };
1319
+ let Player = _Player;
1320
+ Player.info = {
1321
+ version: PLAYER_VERSION,
1322
+ commit: COMMIT
1323
+ };
1324
+
1325
+ export { AssetTransformCorePlugin, DataController, FlowExpPlugin, LocalStateStore, NOT_STARTED_STATE, Player, ValidationBindingTrackerViewPlugin, ValidationController, ViewController };
1326
+ //# sourceMappingURL=index.esm.js.map