@player-ui/player 0.4.0-next.7 → 0.4.0-next.9

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.
Files changed (38) hide show
  1. package/dist/index.cjs.js +622 -325
  2. package/dist/index.d.ts +188 -72
  3. package/dist/index.esm.js +619 -327
  4. package/dist/player.dev.js +623 -326
  5. package/dist/player.prod.js +1 -1
  6. package/package.json +11 -3
  7. package/src/binding/binding.ts +8 -0
  8. package/src/binding/index.ts +1 -1
  9. package/src/controllers/constants/index.ts +9 -5
  10. package/src/controllers/data.ts +49 -52
  11. package/src/controllers/flow/controller.ts +16 -12
  12. package/src/controllers/flow/flow.ts +6 -1
  13. package/src/controllers/validation/binding-tracker.ts +42 -19
  14. package/src/controllers/validation/controller.ts +265 -85
  15. package/src/controllers/view/asset-transform.ts +4 -1
  16. package/src/controllers/view/controller.ts +19 -2
  17. package/src/data/dependency-tracker.ts +14 -0
  18. package/src/data/local-model.ts +25 -1
  19. package/src/data/model.ts +55 -8
  20. package/src/data/noop-model.ts +2 -0
  21. package/src/expressions/evaluator-functions.ts +24 -2
  22. package/src/expressions/evaluator.ts +35 -31
  23. package/src/expressions/types.ts +17 -5
  24. package/src/expressions/utils.ts +19 -0
  25. package/src/player.ts +26 -29
  26. package/src/plugins/flow-exp-plugin.ts +2 -2
  27. package/src/string-resolver/index.ts +7 -2
  28. package/src/types.ts +1 -4
  29. package/src/validator/binding-map-splice.ts +59 -0
  30. package/src/validator/index.ts +1 -0
  31. package/src/validator/types.ts +11 -3
  32. package/src/validator/validation-middleware.ts +34 -3
  33. package/src/view/parser/index.ts +44 -2
  34. package/src/view/plugins/applicability.ts +1 -1
  35. package/src/view/plugins/string-resolver.ts +8 -4
  36. package/src/view/plugins/template-plugin.ts +1 -6
  37. package/src/view/resolver/index.ts +119 -54
  38. package/src/view/resolver/types.ts +48 -7
@@ -245,12 +245,15 @@ __webpack_require__.r(__webpack_exports__);
245
245
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ProxyLogger", function() { return ProxyLogger; });
246
246
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ROOT_BINDING", function() { return ROOT_BINDING; });
247
247
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Resolver", function() { return Resolver; });
248
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SCHEMA_VALIDATION_PROVIDER_NAME", function() { return SCHEMA_VALIDATION_PROVIDER_NAME; });
248
249
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SIMPLE_BINDING_REGEX", function() { return SIMPLE_BINDING_REGEX; });
249
250
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SchemaController", function() { return SchemaController; });
250
251
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StringResolverPlugin", function() { return StringResolverPlugin; });
251
252
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SwitchPlugin", function() { return SwitchPlugin; });
252
253
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TapableLogger", function() { return TapableLogger; });
253
254
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TemplatePlugin", function() { return TemplatePlugin; });
255
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VALIDATION_PROVIDER_NAME_SYMBOL", function() { return VALIDATION_PROVIDER_NAME_SYMBOL; });
256
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VIEW_VALIDATION_PROVIDER_NAME", function() { return VIEW_VALIDATION_PROVIDER_NAME; });
254
257
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ValidationBindingTrackerViewPlugin", function() { return ValidationBindingTrackerViewPlugin; });
255
258
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ValidationController", function() { return ValidationController; });
256
259
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ValidationMiddleware", function() { return ValidationMiddleware; });
@@ -265,9 +268,11 @@ __webpack_require__.r(__webpack_exports__);
265
268
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getBindingSegments", function() { return getBindingSegments; });
266
269
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isBinding", function() { return isBinding; });
267
270
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isExpressionNode", function() { return isExpressionNode; });
271
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isObjectExpression", function() { return isObjectExpression; });
268
272
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "maybeConvertToNum", function() { return maybeConvertToNum; });
269
273
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parse", function() { return parse; });
270
274
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseExpression", function() { return parseExpression; });
275
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removeBindingAndChildrenFromMap", function() { return removeBindingAndChildrenFromMap; });
271
276
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resolveDataRefs", function() { return resolveDataRefs; });
272
277
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resolveDataRefsInString", function() { return resolveDataRefsInString; });
273
278
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resolveExpressionsInString", function() { return resolveExpressionsInString; });
@@ -278,7 +283,7 @@ __webpack_require__.r(__webpack_exports__);
278
283
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "withoutContext", function() { return withoutContext; });
279
284
  /* harmony import */ var _player_ui_types__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @player-ui/types */ "./bazel-out/k8-fastbuild/bin/core/types/dist/index.esm.js");
280
285
  /* harmony import */ var _player_ui_types__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_player_ui_types__WEBPACK_IMPORTED_MODULE_0__);
281
- /* harmony reexport (unknown) */ for(var __WEBPACK_IMPORT_KEY__ in _player_ui_types__WEBPACK_IMPORTED_MODULE_0__) if(["default","ApplicabilityPlugin","AssetTransformCorePlugin","BindingInstance","BindingParser","Builder","ConsoleLogger","ConstantsController","DataController","DependencyMiddleware","DependencyModel","DependencyTracker","EMPTY_NODE","ExpNodeOpaqueIdentifier","ExpressionEvaluator","FlowController","FlowExpPlugin","FlowInstance","LocalModel","LocalStateStore","NOOPDataModel","NOOP_MODEL","NOT_STARTED_STATE","NodeType","NoopLogger","Parser","PipelinedDataModel","Player","ProxyLogger","ROOT_BINDING","Resolver","SIMPLE_BINDING_REGEX","SchemaController","StringResolverPlugin","SwitchPlugin","TapableLogger","TemplatePlugin","ValidationBindingTrackerViewPlugin","ValidationController","ValidationMiddleware","ValidatorRegistry","ViewController","ViewInstance","caresAboutDataChanges","constructModelForPipeline","findClosestNodeAtPosition","findInArray","findNextExp","getBindingSegments","isBinding","isExpressionNode","maybeConvertToNum","parse","parseExpression","resolveDataRefs","resolveDataRefsInString","resolveExpressionsInString","severities","toModel","toNodeResolveOptions","withParser","withoutContext"].indexOf(__WEBPACK_IMPORT_KEY__) < 0) (function(key) { __webpack_require__.d(__webpack_exports__, key, function() { return _player_ui_types__WEBPACK_IMPORTED_MODULE_0__[key]; }) }(__WEBPACK_IMPORT_KEY__));
286
+ /* harmony reexport (unknown) */ for(var __WEBPACK_IMPORT_KEY__ in _player_ui_types__WEBPACK_IMPORTED_MODULE_0__) if(["default","ApplicabilityPlugin","AssetTransformCorePlugin","BindingInstance","BindingParser","Builder","ConsoleLogger","ConstantsController","DataController","DependencyMiddleware","DependencyModel","DependencyTracker","EMPTY_NODE","ExpNodeOpaqueIdentifier","ExpressionEvaluator","FlowController","FlowExpPlugin","FlowInstance","LocalModel","LocalStateStore","NOOPDataModel","NOOP_MODEL","NOT_STARTED_STATE","NodeType","NoopLogger","Parser","PipelinedDataModel","Player","ProxyLogger","ROOT_BINDING","Resolver","SCHEMA_VALIDATION_PROVIDER_NAME","SIMPLE_BINDING_REGEX","SchemaController","StringResolverPlugin","SwitchPlugin","TapableLogger","TemplatePlugin","VALIDATION_PROVIDER_NAME_SYMBOL","VIEW_VALIDATION_PROVIDER_NAME","ValidationBindingTrackerViewPlugin","ValidationController","ValidationMiddleware","ValidatorRegistry","ViewController","ViewInstance","caresAboutDataChanges","constructModelForPipeline","findClosestNodeAtPosition","findInArray","findNextExp","getBindingSegments","isBinding","isExpressionNode","isObjectExpression","maybeConvertToNum","parse","parseExpression","removeBindingAndChildrenFromMap","resolveDataRefs","resolveDataRefsInString","resolveExpressionsInString","severities","toModel","toNodeResolveOptions","withParser","withoutContext"].indexOf(__WEBPACK_IMPORT_KEY__) < 0) (function(key) { __webpack_require__.d(__webpack_exports__, key, function() { return _player_ui_types__WEBPACK_IMPORTED_MODULE_0__[key]; }) }(__WEBPACK_IMPORT_KEY__));
282
287
  /* harmony import */ var tapable_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tapable-ts */ "./node_modules/tapable-ts/dist/hooks.mjs");
283
288
  /* harmony import */ var nested_error_stacks__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! nested-error-stacks */ "./node_modules/nested-error-stacks/index.js");
284
289
  /* harmony import */ var nested_error_stacks__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(nested_error_stacks__WEBPACK_IMPORTED_MODULE_2__);
@@ -842,7 +847,7 @@ class BindingParser {
842
847
  updates = __spreadValues$d(__spreadValues$d({}, updates), normalized.updates);
843
848
  }
844
849
  const updateKeys = Object.keys(updates);
845
- if (updateKeys.length > 0) {
850
+ if (!options.readOnly && updateKeys.length > 0) {
846
851
  const updateTransaction = updateKeys.map((updatedBinding) => [
847
852
  this.parse(updatedBinding),
848
853
  updates[updatedBinding]
@@ -938,6 +943,10 @@ class DependencyMiddleware extends DependencyTracker {
938
943
  this.addReadDep(binding);
939
944
  return next == null ? void 0 : next.get(binding, options);
940
945
  }
946
+ delete(binding, options, next) {
947
+ this.addWriteDep(binding);
948
+ return next == null ? void 0 : next.delete(binding, options);
949
+ }
941
950
  }
942
951
  class DependencyModel extends DependencyTracker {
943
952
  constructor(rootModel) {
@@ -954,6 +963,10 @@ class DependencyModel extends DependencyTracker {
954
963
  this.addReadDep(binding);
955
964
  return this.rootModel.get(binding, options);
956
965
  }
966
+ delete(binding, options) {
967
+ this.addWriteDep(binding);
968
+ return this.rootModel.delete(binding, options);
969
+ }
957
970
  }
958
971
 
959
972
  class NOOPDataModel {
@@ -963,15 +976,18 @@ class NOOPDataModel {
963
976
  set() {
964
977
  return [];
965
978
  }
979
+ delete() {
980
+ }
966
981
  }
967
982
  const NOOP_MODEL = new NOOPDataModel();
968
983
 
969
984
  const ROOT_BINDING = new BindingInstance([]);
970
985
  function withParser(model, parseBinding) {
971
- function maybeParse(binding) {
986
+ function maybeParse(binding, readOnly) {
972
987
  const parsed = isBinding(binding) ? binding : parseBinding(binding, {
973
988
  get: model.get,
974
- set: model.set
989
+ set: model.set,
990
+ readOnly
975
991
  });
976
992
  if (!parsed) {
977
993
  throw new Error("Unable to parse binding");
@@ -980,10 +996,13 @@ function withParser(model, parseBinding) {
980
996
  }
981
997
  return {
982
998
  get(binding, options) {
983
- return model.get(maybeParse(binding), options);
999
+ return model.get(maybeParse(binding, true), options);
984
1000
  },
985
1001
  set(transaction, options) {
986
- return model.set(transaction.map(([key, val]) => [maybeParse(key), val]), options);
1002
+ return model.set(transaction.map(([key, val]) => [maybeParse(key, false), val]), options);
1003
+ },
1004
+ delete(binding, options) {
1005
+ return model.delete(maybeParse(binding, false), options);
987
1006
  }
988
1007
  };
989
1008
  }
@@ -992,8 +1011,27 @@ function toModel(middleware, defaultOptions, next) {
992
1011
  return middleware;
993
1012
  }
994
1013
  return {
995
- get: (binding, options) => middleware.get(binding, options != null ? options : defaultOptions, next),
996
- set: (transaction, options) => middleware.set(transaction, options != null ? options : defaultOptions, next)
1014
+ get: (binding, options) => {
1015
+ const resolvedOptions = options != null ? options : defaultOptions;
1016
+ if (middleware.get) {
1017
+ return middleware.get(binding, resolvedOptions, next);
1018
+ }
1019
+ return next == null ? void 0 : next.get(binding, resolvedOptions);
1020
+ },
1021
+ set: (transaction, options) => {
1022
+ const resolvedOptions = options != null ? options : defaultOptions;
1023
+ if (middleware.set) {
1024
+ return middleware.set(transaction, resolvedOptions, next);
1025
+ }
1026
+ return next == null ? void 0 : next.set(transaction, resolvedOptions);
1027
+ },
1028
+ delete: (binding, options) => {
1029
+ const resolvedOptions = options != null ? options : defaultOptions;
1030
+ if (middleware.delete) {
1031
+ return middleware.delete(binding, resolvedOptions, next);
1032
+ }
1033
+ return next == null ? void 0 : next.delete(binding, resolvedOptions);
1034
+ }
997
1035
  };
998
1036
  }
999
1037
  function constructModelForPipeline(pipeline) {
@@ -1001,7 +1039,7 @@ function constructModelForPipeline(pipeline) {
1001
1039
  return NOOP_MODEL;
1002
1040
  }
1003
1041
  if (pipeline.length === 1) {
1004
- return pipeline[0];
1042
+ return toModel(pipeline[0]);
1005
1043
  }
1006
1044
  function createModelWithOptions(options) {
1007
1045
  var _a;
@@ -1016,6 +1054,10 @@ function constructModelForPipeline(pipeline) {
1016
1054
  set: (transaction, options) => {
1017
1055
  var _a;
1018
1056
  return (_a = createModelWithOptions(options)) == null ? void 0 : _a.set(transaction, options);
1057
+ },
1058
+ delete: (binding, options) => {
1059
+ var _a;
1060
+ return (_a = createModelWithOptions(options)) == null ? void 0 : _a.delete(binding, options);
1019
1061
  }
1020
1062
  };
1021
1063
  }
@@ -1052,6 +1094,9 @@ class PipelinedDataModel {
1052
1094
  get(binding, options) {
1053
1095
  return this.effectiveDataModel.get(binding, options);
1054
1096
  }
1097
+ delete(binding, options) {
1098
+ return this.effectiveDataModel.delete(binding, options);
1099
+ }
1055
1100
  }
1056
1101
 
1057
1102
  class LocalModel {
@@ -1078,11 +1123,24 @@ class LocalModel {
1078
1123
  });
1079
1124
  return effectiveOperations;
1080
1125
  }
1126
+ delete(binding) {
1127
+ const parentBinding = binding.parent();
1128
+ if (parentBinding) {
1129
+ const parentValue = this.get(parentBinding);
1130
+ if (parentValue !== void 0) {
1131
+ if (Array.isArray(parentValue)) {
1132
+ this.model = Object(timm__WEBPACK_IMPORTED_MODULE_7__["setIn"])(this.model, parentBinding.asArray(), Object(timm__WEBPACK_IMPORTED_MODULE_7__["removeAt"])(parentValue, binding.key()));
1133
+ } else {
1134
+ this.model = Object(timm__WEBPACK_IMPORTED_MODULE_7__["setIn"])(this.model, parentBinding.asArray(), Object(timm__WEBPACK_IMPORTED_MODULE_7__["omit"])(parentValue, binding.key()));
1135
+ }
1136
+ }
1137
+ }
1138
+ }
1081
1139
  }
1082
1140
 
1083
1141
  const ExpNodeOpaqueIdentifier = Symbol("Expression Node ID");
1084
1142
  function isExpressionNode(x) {
1085
- return typeof x === "object" && x.__id === ExpNodeOpaqueIdentifier;
1143
+ return typeof x === "object" && x !== null && !Array.isArray(x) && x.__id === ExpNodeOpaqueIdentifier;
1086
1144
  }
1087
1145
 
1088
1146
  const PERIOD_CODE = 46;
@@ -1709,16 +1767,108 @@ const getDataVal = (_context, binding) => {
1709
1767
  return _context.model.get(binding);
1710
1768
  };
1711
1769
  const deleteDataVal = (_context, binding) => {
1712
- return _context.model.set([[binding, void 0]]);
1770
+ return _context.model.delete(binding);
1713
1771
  };
1772
+ const conditional = (ctx, condition, ifTrue, ifFalse) => {
1773
+ const resolution = ctx.evaluate(condition);
1774
+ if (resolution) {
1775
+ return ctx.evaluate(ifTrue);
1776
+ }
1777
+ if (ifFalse) {
1778
+ return ctx.evaluate(ifFalse);
1779
+ }
1780
+ return null;
1781
+ };
1782
+ conditional.resolveParams = false;
1714
1783
 
1715
1784
  var DEFAULT_EXPRESSION_HANDLERS = /*#__PURE__*/Object.freeze({
1716
1785
  __proto__: null,
1717
1786
  setDataVal: setDataVal,
1718
1787
  getDataVal: getDataVal,
1719
- deleteDataVal: deleteDataVal
1788
+ deleteDataVal: deleteDataVal,
1789
+ conditional: conditional
1720
1790
  });
1721
1791
 
1792
+ function withoutContext(fn) {
1793
+ return (_context, ...args) => fn(...args);
1794
+ }
1795
+ function isInRange(position, location) {
1796
+ return position.character >= location.start.character && position.character <= location.end.character;
1797
+ }
1798
+ function findClosestNodeAtPosition(node, position) {
1799
+ var _a, _b, _c, _d, _e;
1800
+ switch (node.type) {
1801
+ case "Modification":
1802
+ case "Assignment":
1803
+ case "LogicalExpression":
1804
+ case "BinaryExpression": {
1805
+ const check = (_a = findClosestNodeAtPosition(node.left, position)) != null ? _a : findClosestNodeAtPosition(node.right, position);
1806
+ if (check) {
1807
+ return check;
1808
+ }
1809
+ break;
1810
+ }
1811
+ case "UnaryExpression": {
1812
+ const checkArg = findClosestNodeAtPosition(node.argument, position);
1813
+ if (checkArg) {
1814
+ return checkArg;
1815
+ }
1816
+ break;
1817
+ }
1818
+ case "MemberExpression": {
1819
+ const checkObject = (_b = findClosestNodeAtPosition(node.object, position)) != null ? _b : findClosestNodeAtPosition(node.property, position);
1820
+ if (checkObject) {
1821
+ return checkObject;
1822
+ }
1823
+ break;
1824
+ }
1825
+ case "ConditionalExpression": {
1826
+ const checkObject = (_d = (_c = findClosestNodeAtPosition(node.test, position)) != null ? _c : findClosestNodeAtPosition(node.consequent, position)) != null ? _d : findClosestNodeAtPosition(node.alternate, position);
1827
+ if (checkObject) {
1828
+ return checkObject;
1829
+ }
1830
+ break;
1831
+ }
1832
+ case "ArrayExpression":
1833
+ case "Compound": {
1834
+ const elements = node.type === "ArrayExpression" ? node.elements : node.body;
1835
+ const anyElements = elements.find((e) => findClosestNodeAtPosition(e, position));
1836
+ if (anyElements) {
1837
+ return anyElements;
1838
+ }
1839
+ break;
1840
+ }
1841
+ case "Object": {
1842
+ const checkObject = node.attributes.reduce((found, next) => {
1843
+ var _a2;
1844
+ return (_a2 = found != null ? found : findClosestNodeAtPosition(next.key, position)) != null ? _a2 : findClosestNodeAtPosition(next.value, position);
1845
+ }, void 0);
1846
+ if (checkObject) {
1847
+ return checkObject;
1848
+ }
1849
+ break;
1850
+ }
1851
+ case "CallExpression": {
1852
+ const anyArgs = (_e = node.args.find((arg) => {
1853
+ return findClosestNodeAtPosition(arg, position);
1854
+ })) != null ? _e : findClosestNodeAtPosition(node.callTarget, position);
1855
+ if (anyArgs) {
1856
+ return anyArgs;
1857
+ }
1858
+ break;
1859
+ }
1860
+ }
1861
+ if (node.location && isInRange(position, node.location)) {
1862
+ return node;
1863
+ }
1864
+ }
1865
+ function isObjectExpression(expr) {
1866
+ if (isExpressionNode(expr)) {
1867
+ return false;
1868
+ }
1869
+ return typeof expr === "object" && expr !== null && !Array.isArray(expr) && "value" in expr;
1870
+ }
1871
+
1722
1872
  var __defProp$c = Object.defineProperty;
1723
1873
  var __defProps$a = Object.defineProperties;
1724
1874
  var __getOwnPropDescs$a = Object.getOwnPropertyDescriptors;
@@ -1779,6 +1929,8 @@ class ExpressionEvaluator {
1779
1929
  this.vars = {};
1780
1930
  this.hooks = {
1781
1931
  resolve: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"](),
1932
+ resolveOptions: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"](),
1933
+ beforeEvaluate: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"](),
1782
1934
  onError: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncBailHook"]()
1783
1935
  };
1784
1936
  this.expressionsCache = new Map();
@@ -1797,21 +1949,25 @@ class ExpressionEvaluator {
1797
1949
  reset() {
1798
1950
  this.expressionsCache.clear();
1799
1951
  }
1800
- evaluate(expression, options) {
1801
- const opts = __spreadProps$a(__spreadValues$c(__spreadValues$c({}, this.defaultHookOptions), options), {
1802
- resolveNode: (node) => this._execAST(node, opts)
1803
- });
1952
+ evaluate(expr, options) {
1953
+ var _a;
1954
+ const resolvedOpts = this.hooks.resolveOptions.call(__spreadProps$a(__spreadValues$c(__spreadValues$c({}, this.defaultHookOptions), options), {
1955
+ resolveNode: (node) => this._execAST(node, resolvedOpts)
1956
+ }));
1957
+ let expression = (_a = this.hooks.beforeEvaluate.call(expr, resolvedOpts)) != null ? _a : expr;
1958
+ while (isObjectExpression(expression)) {
1959
+ expression = expression.value;
1960
+ }
1804
1961
  if (typeof expression === "number" || typeof expression === "boolean" || expression === void 0 || expression === null) {
1805
1962
  return expression;
1806
1963
  }
1807
1964
  if (isExpressionNode(expression)) {
1808
- return this._execAST(expression, opts);
1965
+ return this._execAST(expression, resolvedOpts);
1809
1966
  }
1810
- if (typeof expression === "object") {
1811
- const values = Array.isArray(expression) ? expression : Object.values(expression);
1812
- return values.reduce((_nothing, exp) => this.evaluate(exp, options), null);
1967
+ if (Array.isArray(expression)) {
1968
+ return expression.reduce((_nothing, exp) => this.evaluate(exp, options), null);
1813
1969
  }
1814
- return this._execString(String(expression), opts);
1970
+ return this._execString(String(expression), resolvedOpts);
1815
1971
  }
1816
1972
  addExpressionFunction(name, handler) {
1817
1973
  this.operators.expressions.set(name, handler);
@@ -1849,7 +2005,7 @@ class ExpressionEvaluator {
1849
2005
  this.expressionsCache.set(matchedExp, expAST);
1850
2006
  return this._execAST(expAST, options);
1851
2007
  } catch (e) {
1852
- if (!this.hooks.onError.call(e)) {
2008
+ if (options.throwErrors || !this.hooks.onError.call(e)) {
1853
2009
  throw e;
1854
2010
  }
1855
2011
  }
@@ -1903,25 +2059,18 @@ class ExpressionEvaluator {
1903
2059
  }
1904
2060
  if (node.type === "CallExpression") {
1905
2061
  const expressionName = node.callTarget.name;
1906
- if (expressionName === "conditional") {
1907
- const condition = resolveNode(node.args[0]);
1908
- if (condition) {
1909
- return resolveNode(node.args[1]);
1910
- }
1911
- if (node.args[2]) {
1912
- return resolveNode(node.args[2]);
1913
- }
1914
- return null;
1915
- }
1916
2062
  const operator = this.operators.expressions.get(expressionName);
1917
2063
  if (!operator) {
1918
2064
  throw new Error(`Unknown expression function: ${expressionName}`);
1919
2065
  }
2066
+ if ("resolveParams" in operator && operator.resolveParams === false) {
2067
+ return operator(expressionContext, ...node.args);
2068
+ }
1920
2069
  const args = node.args.map((n) => resolveNode(n));
1921
2070
  return operator(expressionContext, ...args);
1922
2071
  }
1923
2072
  if (node.type === "ModelRef") {
1924
- return model.get(node.ref);
2073
+ return model.get(node.ref, { context: { model: options.model } });
1925
2074
  }
1926
2075
  if (node.type === "MemberExpression") {
1927
2076
  const obj = resolveNode(node.object);
@@ -1973,80 +2122,6 @@ class ExpressionEvaluator {
1973
2122
  }
1974
2123
  }
1975
2124
 
1976
- function withoutContext(fn) {
1977
- return (_context, ...args) => fn(...args);
1978
- }
1979
- function isInRange(position, location) {
1980
- return position.character >= location.start.character && position.character <= location.end.character;
1981
- }
1982
- function findClosestNodeAtPosition(node, position) {
1983
- var _a, _b, _c, _d, _e;
1984
- switch (node.type) {
1985
- case "Modification":
1986
- case "Assignment":
1987
- case "LogicalExpression":
1988
- case "BinaryExpression": {
1989
- const check = (_a = findClosestNodeAtPosition(node.left, position)) != null ? _a : findClosestNodeAtPosition(node.right, position);
1990
- if (check) {
1991
- return check;
1992
- }
1993
- break;
1994
- }
1995
- case "UnaryExpression": {
1996
- const checkArg = findClosestNodeAtPosition(node.argument, position);
1997
- if (checkArg) {
1998
- return checkArg;
1999
- }
2000
- break;
2001
- }
2002
- case "MemberExpression": {
2003
- const checkObject = (_b = findClosestNodeAtPosition(node.object, position)) != null ? _b : findClosestNodeAtPosition(node.property, position);
2004
- if (checkObject) {
2005
- return checkObject;
2006
- }
2007
- break;
2008
- }
2009
- case "ConditionalExpression": {
2010
- const checkObject = (_d = (_c = findClosestNodeAtPosition(node.test, position)) != null ? _c : findClosestNodeAtPosition(node.consequent, position)) != null ? _d : findClosestNodeAtPosition(node.alternate, position);
2011
- if (checkObject) {
2012
- return checkObject;
2013
- }
2014
- break;
2015
- }
2016
- case "ArrayExpression":
2017
- case "Compound": {
2018
- const elements = node.type === "ArrayExpression" ? node.elements : node.body;
2019
- const anyElements = elements.find((e) => findClosestNodeAtPosition(e, position));
2020
- if (anyElements) {
2021
- return anyElements;
2022
- }
2023
- break;
2024
- }
2025
- case "Object": {
2026
- const checkObject = node.attributes.reduce((found, next) => {
2027
- var _a2;
2028
- return (_a2 = found != null ? found : findClosestNodeAtPosition(next.key, position)) != null ? _a2 : findClosestNodeAtPosition(next.value, position);
2029
- }, void 0);
2030
- if (checkObject) {
2031
- return checkObject;
2032
- }
2033
- break;
2034
- }
2035
- case "CallExpression": {
2036
- const anyArgs = (_e = node.args.find((arg) => {
2037
- return findClosestNodeAtPosition(arg, position);
2038
- })) != null ? _e : findClosestNodeAtPosition(node.callTarget, position);
2039
- if (anyArgs) {
2040
- return anyArgs;
2041
- }
2042
- break;
2043
- }
2044
- }
2045
- if (node.location && isInRange(position, node.location)) {
2046
- return node;
2047
- }
2048
- }
2049
-
2050
2125
  const severities = ["trace", "debug", "info", "warn", "error"];
2051
2126
 
2052
2127
  class ConsoleLogger {
@@ -2374,7 +2449,7 @@ function resolveExpressionsInString(val, { evaluate }) {
2374
2449
  return newVal;
2375
2450
  }
2376
2451
  function resolveDataRefsInString(val, options) {
2377
- const { model } = options;
2452
+ const { model, formatted = true } = options;
2378
2453
  let workingString = resolveExpressionsInString(val, options);
2379
2454
  if (!model || typeof workingString !== "string" || workingString.indexOf(DOUBLE_OPEN_CURLY) === -1) {
2380
2455
  return workingString;
@@ -2386,7 +2461,7 @@ function resolveDataRefsInString(val, options) {
2386
2461
  }
2387
2462
  const { start, end } = expLocation;
2388
2463
  const binding = workingString.substring(start + DOUBLE_OPEN_CURLY.length, end - DOUBLE_OPEN_CURLY.length).trim();
2389
- const evaledVal = model.get(binding, { formatted: true });
2464
+ const evaledVal = model.get(binding, { formatted });
2390
2465
  if (start === 0 && end === workingString.length && typeof evaledVal !== "string") {
2391
2466
  return evaledVal;
2392
2467
  }
@@ -2419,6 +2494,36 @@ function resolveDataRefs(val, options) {
2419
2494
  return traverseObject(val, options);
2420
2495
  }
2421
2496
 
2497
+ function removeBindingAndChildrenFromMap(sourceMap, binding) {
2498
+ const targetMap = new Map(sourceMap);
2499
+ const parentBinding = binding.parent();
2500
+ const property = binding.key();
2501
+ targetMap.forEach((_value, trackedBinding) => {
2502
+ if (binding === trackedBinding || binding.contains(trackedBinding)) {
2503
+ targetMap.delete(trackedBinding);
2504
+ }
2505
+ });
2506
+ if (typeof property === "number") {
2507
+ const bindingsToRewrite = Array.from(sourceMap.keys()).filter((b) => {
2508
+ if (parentBinding.contains(b)) {
2509
+ const [childIndex] = b.relative(parentBinding);
2510
+ return typeof childIndex === "number" && childIndex > property;
2511
+ }
2512
+ return false;
2513
+ }).sort();
2514
+ bindingsToRewrite.forEach((trackedBinding) => {
2515
+ const [childIndex, ...childPath] = trackedBinding.relative(parentBinding);
2516
+ if (typeof childIndex === "number") {
2517
+ const newSegments = [childIndex - 1, ...childPath];
2518
+ const newChildBinding = parentBinding.descendent(newSegments);
2519
+ targetMap.set(newChildBinding, targetMap.get(trackedBinding));
2520
+ targetMap.delete(trackedBinding);
2521
+ }
2522
+ });
2523
+ }
2524
+ return targetMap;
2525
+ }
2526
+
2422
2527
  var __defProp$a = Object.defineProperty;
2423
2528
  var __defProps$8 = Object.defineProperties;
2424
2529
  var __getOwnPropDescs$8 = Object.getOwnPropertyDescriptors;
@@ -2443,12 +2548,15 @@ class ValidationMiddleware {
2443
2548
  this.validator = validator;
2444
2549
  this.shadowModelPaths = new Map();
2445
2550
  this.logger = options == null ? void 0 : options.logger;
2551
+ this.shouldIncludeInvalid = options == null ? void 0 : options.shouldIncludeInvalid;
2446
2552
  }
2447
2553
  set(transaction, options, next) {
2448
2554
  const asModel = toModel(this, __spreadProps$8(__spreadValues$a({}, options), { includeInvalid: true }), next);
2449
2555
  const nextTransaction = [];
2556
+ const includedBindings = new Set();
2450
2557
  transaction.forEach(([binding, value]) => {
2451
2558
  this.shadowModelPaths.set(binding, value);
2559
+ includedBindings.add(binding);
2452
2560
  });
2453
2561
  const invalidBindings = [];
2454
2562
  this.shadowModelPaths.forEach((value, binding) => {
@@ -2463,18 +2571,21 @@ class ValidationMiddleware {
2463
2571
  nextTransaction.push([validation.binding, value]);
2464
2572
  }
2465
2573
  });
2466
- } else {
2574
+ } else if (includedBindings.has(binding)) {
2575
+ invalidBindings.push(binding);
2467
2576
  (_a = this.logger) == null ? void 0 : _a.debug(`Invalid value for path: ${binding.asString()} - ${validations.severity} - ${validations.message}`);
2468
2577
  }
2469
2578
  });
2579
+ let validResults = [];
2470
2580
  if (next && nextTransaction.length > 0) {
2471
2581
  nextTransaction.forEach(([binding]) => this.shadowModelPaths.delete(binding));
2472
2582
  const result = next.set(nextTransaction, options);
2473
2583
  if (invalidBindings.length === 0) {
2474
2584
  return result;
2475
2585
  }
2586
+ validResults = result;
2476
2587
  }
2477
- return invalidBindings.map((binding) => {
2588
+ const invalidResults = invalidBindings.map((binding) => {
2478
2589
  return {
2479
2590
  binding,
2480
2591
  oldValue: asModel.get(binding),
@@ -2482,10 +2593,12 @@ class ValidationMiddleware {
2482
2593
  force: true
2483
2594
  };
2484
2595
  });
2596
+ return [...validResults, ...invalidResults];
2485
2597
  }
2486
2598
  get(binding, options, next) {
2599
+ var _a, _b;
2487
2600
  let val = next == null ? void 0 : next.get(binding, options);
2488
- if ((options == null ? void 0 : options.includeInvalid) === true) {
2601
+ if ((_b = (_a = this.shouldIncludeInvalid) == null ? void 0 : _a.call(this, options)) != null ? _b : (options == null ? void 0 : options.includeInvalid) === true) {
2489
2602
  this.shadowModelPaths.forEach((shadowValue, shadowBinding) => {
2490
2603
  if (shadowBinding === binding) {
2491
2604
  val = shadowValue;
@@ -2498,6 +2611,10 @@ class ValidationMiddleware {
2498
2611
  }
2499
2612
  return val;
2500
2613
  }
2614
+ delete(binding, options, next) {
2615
+ this.shadowModelPaths = removeBindingAndChildrenFromMap(this.shadowModelPaths, binding);
2616
+ return next == null ? void 0 : next.delete(binding, options);
2617
+ }
2501
2618
  }
2502
2619
 
2503
2620
  class ValidatorRegistry {
@@ -2582,6 +2699,9 @@ class Parser {
2582
2699
  }
2583
2700
  return tapped;
2584
2701
  }
2702
+ hasTemplateValues(obj, localKey) {
2703
+ return Object.hasOwnProperty.call(obj, "template") && Array.isArray(obj == null ? void 0 : obj.template) && obj.template.length && obj.template.find((tmpl) => tmpl.output === localKey);
2704
+ }
2585
2705
  parseObject(obj, type = NodeType.Value, options = { templateDepth: 0 }) {
2586
2706
  var _a;
2587
2707
  const nodeType = this.hooks.determineNodeType.call(obj);
@@ -2611,6 +2731,7 @@ class Parser {
2611
2731
  value: currentValue
2612
2732
  };
2613
2733
  const newValue = objEntries.reduce((accumulation, current) => {
2734
+ var _b;
2614
2735
  const _a2 = accumulation, { children: children2 } = _a2, rest = __objRest$1(_a2, ["children"]);
2615
2736
  const [localKey, localValue] = current;
2616
2737
  if (localKey === "asset" && typeof localValue === "object") {
@@ -2628,14 +2749,19 @@ class Parser {
2628
2749
  }
2629
2750
  } else if (this.hooks.determineNodeType.call(localKey) === NodeType.Template && Array.isArray(localValue)) {
2630
2751
  const templateChildren = localValue.map((template) => {
2631
- var _a3, _b;
2752
+ var _a3, _b2;
2632
2753
  const templateAST = this.hooks.onCreateASTNode.call({
2633
2754
  type: NodeType.Template,
2634
2755
  depth: (_a3 = options.templateDepth) != null ? _a3 : 0,
2635
2756
  data: template.data,
2636
2757
  template: template.value,
2637
- dynamic: (_b = template.dynamic) != null ? _b : false
2758
+ dynamic: (_b2 = template.dynamic) != null ? _b2 : false
2638
2759
  }, template);
2760
+ if ((templateAST == null ? void 0 : templateAST.type) === NodeType.MultiNode) {
2761
+ templateAST.values.forEach((v) => {
2762
+ v.parent = templateAST;
2763
+ });
2764
+ }
2639
2765
  if (templateAST) {
2640
2766
  return {
2641
2767
  path: [...path, template.output],
@@ -2649,6 +2775,18 @@ class Parser {
2649
2775
  });
2650
2776
  } else if (localValue && this.hooks.determineNodeType.call(localValue) === NodeType.Switch) {
2651
2777
  const localSwitch = this.hooks.parseNode.call(localValue, NodeType.Value, options, NodeType.Switch);
2778
+ if (localSwitch && localSwitch.type === NodeType.Value && ((_b = localSwitch.children) == null ? void 0 : _b.length) === 1 && localSwitch.value === void 0) {
2779
+ const firstChild = localSwitch.children[0];
2780
+ return __spreadProps$7(__spreadValues$9({}, rest), {
2781
+ children: [
2782
+ ...children2,
2783
+ {
2784
+ path: [...path, localKey, ...firstChild.path],
2785
+ value: firstChild.value
2786
+ }
2787
+ ]
2788
+ });
2789
+ }
2652
2790
  if (localSwitch) {
2653
2791
  return __spreadProps$7(__spreadValues$9({}, rest), {
2654
2792
  children: [
@@ -2665,7 +2803,7 @@ class Parser {
2665
2803
  if (childValues.length > 0) {
2666
2804
  const multiNode = this.hooks.onCreateASTNode.call({
2667
2805
  type: NodeType.MultiNode,
2668
- override: true,
2806
+ override: !this.hasTemplateValues(localObj, localKey),
2669
2807
  values: childValues
2670
2808
  }, localValue);
2671
2809
  if ((multiNode == null ? void 0 : multiNode.type) === NodeType.MultiNode) {
@@ -2688,7 +2826,7 @@ class Parser {
2688
2826
  } else if (localValue && typeof localValue === "object") {
2689
2827
  const determineNodeType = this.hooks.determineNodeType.call(localValue);
2690
2828
  if (determineNodeType === NodeType.Applicability) {
2691
- const parsedNode = this.hooks.parseNode.call(localValue, type, options, determineNodeType);
2829
+ const parsedNode = this.hooks.parseNode.call(localValue, NodeType.Value, options, determineNodeType);
2692
2830
  if (parsedNode) {
2693
2831
  return __spreadProps$7(__spreadValues$9({}, rest), {
2694
2832
  children: [
@@ -2810,6 +2948,11 @@ const withContext = (model) => {
2810
2948
  return model.set(transaction, __spreadValues$7({
2811
2949
  context: { model }
2812
2950
  }, options));
2951
+ },
2952
+ delete: (binding, options) => {
2953
+ return model.delete(binding, __spreadValues$7({
2954
+ context: { model }
2955
+ }, options));
2813
2956
  }
2814
2957
  };
2815
2958
  };
@@ -2839,12 +2982,16 @@ class Resolver {
2839
2982
  this.hooks.beforeUpdate.call(changes);
2840
2983
  const resolveCache = new Map();
2841
2984
  this.idCache.clear();
2985
+ const prevASTMap = new Map(this.ASTMap);
2842
2986
  this.ASTMap.clear();
2843
- const updated = this.computeTree(this.root, void 0, changes, resolveCache, toNodeResolveOptions(this.options));
2987
+ const updated = this.computeTree(this.root, void 0, changes, resolveCache, toNodeResolveOptions(this.options), void 0, prevASTMap);
2844
2988
  this.resolveCache = resolveCache;
2845
2989
  this.hooks.afterUpdate.call(updated.value);
2846
2990
  return updated.value;
2847
2991
  }
2992
+ getResolveCache() {
2993
+ return new Map(this.resolveCache);
2994
+ }
2848
2995
  getNodeID(node) {
2849
2996
  var _a;
2850
2997
  if (!node) {
@@ -2876,7 +3023,19 @@ class Resolver {
2876
3023
  }
2877
3024
  return this.resolveCache.get(node);
2878
3025
  }
2879
- computeTree(node, parent, dataChanges, cacheUpdate, options) {
3026
+ cloneNode(node) {
3027
+ const clonedNode = Object(timm__WEBPACK_IMPORTED_MODULE_7__["clone"])(node);
3028
+ Object.keys(clonedNode).forEach((key) => {
3029
+ if (key === "parent")
3030
+ return;
3031
+ const value = clonedNode[key];
3032
+ if (typeof value === "object" && value !== null) {
3033
+ clonedNode[key] = Array.isArray(value) ? [...value] : __spreadValues$7({}, value);
3034
+ }
3035
+ });
3036
+ return clonedNode;
3037
+ }
3038
+ computeTree(node, parent, dataChanges, cacheUpdate, options, parentNode, prevASTMap) {
2880
3039
  var _a, _b;
2881
3040
  const dependencyModel = new DependencyModel(options.data.model);
2882
3041
  dependencyModel.trackSubset("core");
@@ -2897,34 +3056,40 @@ class Resolver {
2897
3056
  updated: false
2898
3057
  });
2899
3058
  cacheUpdate.set(node, update2);
2900
- const repopulateASTMapFromCache = (resolvedAST3, AST) => {
3059
+ const repopulateASTMapFromCache = (resolvedNode, AST, ASTParent) => {
2901
3060
  var _a2;
2902
- this.ASTMap.set(resolvedAST3, AST);
2903
- if ("children" in resolvedAST3) {
2904
- (_a2 = resolvedAST3.children) == null ? void 0 : _a2.forEach(({ value: childAST }) => {
2905
- const { node: childResolvedAST } = this.getPreviousResult(childAST) || {};
2906
- if (!childResolvedAST)
2907
- return;
2908
- repopulateASTMapFromCache(childResolvedAST, childAST);
2909
- if (childResolvedAST.type === NodeType.MultiNode) {
2910
- childResolvedAST.values.forEach((mChildAST) => {
2911
- const { node: mChildResolvedAST } = this.getPreviousResult(mChildAST) || {};
2912
- if (!mChildResolvedAST)
2913
- return;
2914
- repopulateASTMapFromCache(mChildResolvedAST, mChildAST);
2915
- });
2916
- }
2917
- });
3061
+ const { node: resolvedAST2 } = resolvedNode;
3062
+ this.ASTMap.set(resolvedAST2, AST);
3063
+ const resolvedUpdate = __spreadProps$5(__spreadValues$7({}, resolvedNode), {
3064
+ updated: false
3065
+ });
3066
+ cacheUpdate.set(AST, resolvedUpdate);
3067
+ const handleChildNode = (childNode) => {
3068
+ var _a3;
3069
+ const originalChildNode = (_a3 = prevASTMap.get(childNode)) != null ? _a3 : childNode;
3070
+ const previousChildResult = this.getPreviousResult(originalChildNode);
3071
+ if (!previousChildResult)
3072
+ return;
3073
+ repopulateASTMapFromCache(previousChildResult, originalChildNode, AST);
3074
+ };
3075
+ if ("children" in resolvedAST2) {
3076
+ (_a2 = resolvedAST2.children) == null ? void 0 : _a2.forEach(({ value: childAST }) => handleChildNode(childAST));
3077
+ } else if (resolvedAST2.type === NodeType.MultiNode) {
3078
+ resolvedAST2.values.forEach(handleChildNode);
2918
3079
  }
3080
+ this.hooks.afterNodeUpdate.call(AST, ASTParent, resolvedUpdate);
2919
3081
  };
2920
- const resolvedAST2 = previousResult.node;
2921
- repopulateASTMapFromCache(resolvedAST2, node);
2922
- this.hooks.afterNodeUpdate.call(node, parent, update2);
3082
+ previousResult.node.parent = parentNode;
3083
+ repopulateASTMapFromCache(previousResult, node, parent);
2923
3084
  return update2;
2924
3085
  }
2925
- const resolvedAST = (_a = this.hooks.beforeResolve.call(node, resolveOptions)) != null ? _a : {
3086
+ const clonedNode = __spreadProps$5(__spreadValues$7({}, this.cloneNode(node)), {
3087
+ parent: parentNode
3088
+ });
3089
+ const resolvedAST = (_a = this.hooks.beforeResolve.call(clonedNode, resolveOptions)) != null ? _a : {
2926
3090
  type: NodeType.Empty
2927
3091
  };
3092
+ resolvedAST.parent = parentNode;
2928
3093
  resolveOptions.node = resolvedAST;
2929
3094
  this.ASTMap.set(resolvedAST, node);
2930
3095
  let resolved = this.hooks.resolve.call(void 0, resolvedAST, resolveOptions);
@@ -2935,22 +3100,15 @@ class Resolver {
2935
3100
  const childDependencies = new Set();
2936
3101
  dependencyModel.trackSubset("children");
2937
3102
  if ("children" in resolvedAST) {
2938
- (_b = resolvedAST.children) == null ? void 0 : _b.forEach((child) => {
2939
- const computedChildTree = this.computeTree(child.value, node, dataChanges, cacheUpdate, resolveOptions);
2940
- let { updated: childUpdated, value: childValue } = computedChildTree;
2941
- const { node: childNode, dependencies: childTreeDeps } = computedChildTree;
3103
+ const newChildren = (_b = resolvedAST.children) == null ? void 0 : _b.map((child) => {
3104
+ const computedChildTree = this.computeTree(child.value, node, dataChanges, cacheUpdate, resolveOptions, resolvedAST, prevASTMap);
3105
+ const {
3106
+ dependencies: childTreeDeps,
3107
+ node: childNode,
3108
+ updated: childUpdated,
3109
+ value: childValue
3110
+ } = computedChildTree;
2942
3111
  childTreeDeps.forEach((binding) => childDependencies.add(binding));
2943
- if (childNode.type === NodeType.MultiNode) {
2944
- childValue = [];
2945
- childNode.values.forEach((mValue) => {
2946
- const mTree = this.computeTree(mValue, node, dataChanges, cacheUpdate, resolveOptions);
2947
- if (mTree.value !== void 0 && mTree.value !== null) {
2948
- childValue.push(mTree.value);
2949
- }
2950
- mTree.dependencies.forEach((bindingDep) => childDependencies.add(bindingDep));
2951
- childUpdated = childUpdated || mTree.updated;
2952
- });
2953
- }
2954
3112
  if (childValue) {
2955
3113
  if (childNode.type === NodeType.MultiNode && !childNode.override) {
2956
3114
  const arr = Object(timm__WEBPACK_IMPORTED_MODULE_7__["addLast"])(dlv__WEBPACK_IMPORTED_MODULE_6___default()(resolved, child.path, []), childValue);
@@ -2960,7 +3118,22 @@ class Resolver {
2960
3118
  }
2961
3119
  }
2962
3120
  updated = updated || childUpdated;
3121
+ return __spreadProps$5(__spreadValues$7({}, child), { value: childNode });
3122
+ });
3123
+ resolvedAST.children = newChildren;
3124
+ } else if (resolvedAST.type === NodeType.MultiNode) {
3125
+ const childValue = [];
3126
+ const newValues = resolvedAST.values.map((mValue) => {
3127
+ const mTree = this.computeTree(mValue, node, dataChanges, cacheUpdate, resolveOptions, resolvedAST, prevASTMap);
3128
+ if (mTree.value !== void 0 && mTree.value !== null) {
3129
+ childValue.push(mTree.value);
3130
+ }
3131
+ mTree.dependencies.forEach((bindingDep) => childDependencies.add(bindingDep));
3132
+ updated = updated || mTree.updated;
3133
+ return mTree.node;
2963
3134
  });
3135
+ resolvedAST.values = newValues;
3136
+ resolved = childValue;
2964
3137
  }
2965
3138
  childDependencies.forEach((bindingDep) => dependencyModel.addChildReadDep(bindingDep));
2966
3139
  dependencyModel.trackSubset("core");
@@ -3029,13 +3202,10 @@ class TemplatePlugin {
3029
3202
  }
3030
3203
  });
3031
3204
  const result = {
3032
- parent: node.parent,
3033
3205
  type: NodeType.MultiNode,
3206
+ override: false,
3034
3207
  values
3035
3208
  };
3036
- result.values.forEach((innerNode) => {
3037
- innerNode.parent = result;
3038
- });
3039
3209
  return result;
3040
3210
  }
3041
3211
  applyParser(parser) {
@@ -3129,19 +3299,20 @@ function resolveAllRefs(node, resolveOptions, propertiesToSkip) {
3129
3299
  });
3130
3300
  return newNode;
3131
3301
  }
3132
- const findBasePath = (node) => {
3302
+ const findBasePath = (node, resolver) => {
3133
3303
  var _a, _b, _c;
3134
3304
  const parentNode = node.parent;
3135
3305
  if (!parentNode) {
3136
3306
  return [];
3137
3307
  }
3138
3308
  if ("children" in parentNode) {
3139
- return (_c = (_b = (_a = parentNode.children) == null ? void 0 : _a.find((child) => child.value === node)) == null ? void 0 : _b.path) != null ? _c : [];
3309
+ const original = resolver.getSourceNode(node);
3310
+ return (_c = (_b = (_a = parentNode.children) == null ? void 0 : _a.find((child) => child.value === original)) == null ? void 0 : _b.path) != null ? _c : [];
3140
3311
  }
3141
3312
  if (parentNode.type !== NodeType.MultiNode) {
3142
3313
  return [];
3143
3314
  }
3144
- return findBasePath(parentNode);
3315
+ return findBasePath(parentNode, resolver);
3145
3316
  };
3146
3317
  class StringResolverPlugin {
3147
3318
  constructor() {
@@ -3165,7 +3336,7 @@ class StringResolverPlugin {
3165
3336
  } else {
3166
3337
  propsToSkip = new Set(["exp"]);
3167
3338
  }
3168
- const nodePath = findBasePath(node);
3339
+ const nodePath = findBasePath(node, resolver);
3169
3340
  if (nodePath.length > 0 && nodePath.some((segment) => propsToSkip.has(segment.toString()))) {
3170
3341
  return node.value;
3171
3342
  }
@@ -3185,7 +3356,7 @@ class ApplicabilityPlugin {
3185
3356
  let newNode = node;
3186
3357
  if ((node == null ? void 0 : node.type) === NodeType.Applicability) {
3187
3358
  const isApplicable = options.evaluate(node.expression);
3188
- if (!isApplicable) {
3359
+ if (isApplicable === false) {
3189
3360
  return null;
3190
3361
  }
3191
3362
  newNode = node.value;
@@ -3491,7 +3662,8 @@ class FlowInstance {
3491
3662
  skipTransition: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncBailHook"](),
3492
3663
  beforeTransition: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"](),
3493
3664
  resolveTransitionNode: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"](),
3494
- transition: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncHook"]()
3665
+ transition: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncHook"](),
3666
+ afterTransition: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncHook"]()
3495
3667
  };
3496
3668
  this.id = id;
3497
3669
  this.flow = flow;
@@ -3538,7 +3710,7 @@ class FlowInstance {
3538
3710
  } else {
3539
3711
  const skipTransition = this.hooks.skipTransition.call(this.currentState);
3540
3712
  if (skipTransition) {
3541
- (_d = this.log) == null ? void 0 : _d.debug(`Skipping transition from ${this.currentState} b/c hook told us to`);
3713
+ (_d = this.log) == null ? void 0 : _d.debug(`Skipping transition from ${this.currentState.name} b/c hook told us to`);
3542
3714
  return;
3543
3715
  }
3544
3716
  }
@@ -3577,6 +3749,7 @@ class FlowInstance {
3577
3749
  this.hooks.onEnd.call(this.flow.onEnd);
3578
3750
  }
3579
3751
  this.hooks.transition.call(prevState, __spreadValues$5({}, newCurrentState));
3752
+ this.hooks.afterTransition.call(this);
3580
3753
  }
3581
3754
  }
3582
3755
 
@@ -3611,6 +3784,7 @@ class FlowController {
3611
3784
  this.start = this.start.bind(this);
3612
3785
  this.run = this.run.bind(this);
3613
3786
  this.transition = this.transition.bind(this);
3787
+ this.addNewFlow = this.addNewFlow.bind(this);
3614
3788
  }
3615
3789
  transition(stateTransition, options) {
3616
3790
  if (this.current === void 0) {
@@ -3619,20 +3793,9 @@ class FlowController {
3619
3793
  this.current.transition(stateTransition, options);
3620
3794
  }
3621
3795
  addNewFlow(flow) {
3622
- return __async$1(this, null, function* () {
3623
- this.navStack.push(flow);
3624
- this.current = flow;
3625
- flow.hooks.transition.tap("flow-controller", (_oldState, newState) => __async$1(this, null, function* () {
3626
- var _a, _b;
3627
- if (newState.value.state_type === "FLOW") {
3628
- (_a = this.log) == null ? void 0 : _a.debug(`Got FLOW state. Loading flow ${newState.value.ref}`);
3629
- const endState = yield this.run(newState.value.ref);
3630
- (_b = this.log) == null ? void 0 : _b.debug(`Flow ended. Using outcome: ${endState.outcome}`);
3631
- flow.transition(endState.outcome);
3632
- }
3633
- }));
3634
- this.hooks.flow.call(flow);
3635
- });
3796
+ this.navStack.push(flow);
3797
+ this.current = flow;
3798
+ this.hooks.flow.call(flow);
3636
3799
  }
3637
3800
  run(startState) {
3638
3801
  return __async$1(this, null, function* () {
@@ -3647,6 +3810,18 @@ class FlowController {
3647
3810
  (_a = this.log) == null ? void 0 : _a.debug(`Starting flow: ${startState}`);
3648
3811
  const flow = new FlowInstance(startState, startFlow, { logger: this.log });
3649
3812
  this.addNewFlow(flow);
3813
+ flow.hooks.afterTransition.tap("flow-controller", (flowInstance) => {
3814
+ var _a2, _b, _c;
3815
+ if (((_a2 = flowInstance.currentState) == null ? void 0 : _a2.value.state_type) === "FLOW") {
3816
+ const subflowId = (_b = flowInstance.currentState) == null ? void 0 : _b.value.ref;
3817
+ (_c = this.log) == null ? void 0 : _c.debug(`Loading subflow ${subflowId}`);
3818
+ this.run(subflowId).then((subFlowEndState) => {
3819
+ var _a3;
3820
+ (_a3 = this.log) == null ? void 0 : _a3.debug(`Subflow ended. Using outcome: ${subFlowEndState.outcome}`);
3821
+ flowInstance.transition(subFlowEndState == null ? void 0 : subFlowEndState.outcome);
3822
+ });
3823
+ }
3824
+ });
3650
3825
  const end = yield flow.start();
3651
3826
  this.navStack.pop();
3652
3827
  if (this.navStack.length > 0) {
@@ -3699,11 +3874,18 @@ class ValidationBindingTrackerViewPlugin {
3699
3874
  getBindings() {
3700
3875
  return this.trackedBindings;
3701
3876
  }
3877
+ trackBinding(binding) {
3878
+ var _a, _b;
3879
+ if (this.trackedBindings.has(binding)) {
3880
+ return;
3881
+ }
3882
+ this.trackedBindings.add(binding);
3883
+ (_b = (_a = this.options.callbacks) == null ? void 0 : _a.onAdd) == null ? void 0 : _b.call(_a, binding);
3884
+ }
3702
3885
  applyResolver(resolver) {
3703
3886
  this.trackedBindings.clear();
3704
3887
  const tracked = new Map();
3705
3888
  const sections = new Map();
3706
- const seenBindings = new Set();
3707
3889
  let lastViewUpdateChangeSet;
3708
3890
  const nodeTree = new Map();
3709
3891
  let lastComputedBindingTree = new Map();
@@ -3750,31 +3932,34 @@ class ValidationBindingTrackerViewPlugin {
3750
3932
  parent = parent.parent;
3751
3933
  }
3752
3934
  }
3753
- if (!seenBindings.has(parsed)) {
3754
- seenBindings.add(parsed);
3755
- (_d = (_c = this.options.callbacks) == null ? void 0 : _c.onAdd) == null ? void 0 : _d.call(_c, parsed);
3756
- }
3935
+ this.trackedBindings.add(parsed);
3936
+ (_d = (_c = this.options.callbacks) == null ? void 0 : _c.onAdd) == null ? void 0 : _d.call(_c, parsed);
3757
3937
  };
3758
3938
  return __spreadProps$3(__spreadValues$4({}, options), {
3759
3939
  validation: __spreadProps$3(__spreadValues$4({}, options.validation), {
3760
3940
  get: (binding, getOptions) => {
3761
- var _a;
3941
+ var _a, _b;
3762
3942
  if (getOptions == null ? void 0 : getOptions.track) {
3763
3943
  track(binding);
3764
3944
  }
3765
- const eow = (_a = options.validation) == null ? void 0 : _a._getValidationForBinding(binding);
3766
- if ((eow == null ? void 0 : eow.displayTarget) === void 0 || (eow == null ? void 0 : eow.displayTarget) === "field") {
3767
- return eow;
3945
+ const eows = (_b = (_a = options.validation) == null ? void 0 : _a._getValidationForBinding(binding)) == null ? void 0 : _b.getAll(getOptions);
3946
+ const firstFieldEOW = eows == null ? void 0 : eows.find((eow) => eow.displayTarget === "field" || eow.displayTarget === void 0);
3947
+ return firstFieldEOW;
3948
+ },
3949
+ getValidationsForBinding(binding, getOptions) {
3950
+ var _a, _b, _c;
3951
+ if (getOptions == null ? void 0 : getOptions.track) {
3952
+ track(binding);
3768
3953
  }
3769
- return void 0;
3954
+ return (_c = (_b = (_a = options.validation) == null ? void 0 : _a._getValidationForBinding(binding)) == null ? void 0 : _b.getAll(getOptions)) != null ? _c : [];
3770
3955
  },
3771
3956
  getChildren: (type) => {
3772
3957
  var _a;
3773
3958
  const validations = new Array();
3774
3959
  (_a = lastComputedBindingTree.get(node)) == null ? void 0 : _a.forEach((binding) => {
3775
- var _a2;
3776
- const eow = (_a2 = options.validation) == null ? void 0 : _a2._getValidationForBinding(binding);
3777
- if (eow && type === eow.displayTarget) {
3960
+ var _a2, _b;
3961
+ const eow = (_b = (_a2 = options.validation) == null ? void 0 : _a2._getValidationForBinding(binding)) == null ? void 0 : _b.get();
3962
+ if (eow && (type === void 0 || type === eow.displayTarget)) {
3778
3963
  validations.push(eow);
3779
3964
  }
3780
3965
  });
@@ -3784,8 +3969,8 @@ class ValidationBindingTrackerViewPlugin {
3784
3969
  var _a;
3785
3970
  const validations = new Array();
3786
3971
  (_a = lastSectionBindingTree.get(node)) == null ? void 0 : _a.forEach((binding) => {
3787
- var _a2;
3788
- const eow = (_a2 = options.validation) == null ? void 0 : _a2._getValidationForBinding(binding);
3972
+ var _a2, _b;
3973
+ const eow = (_b = (_a2 = options.validation) == null ? void 0 : _a2._getValidationForBinding(binding)) == null ? void 0 : _b.get();
3789
3974
  if (eow && eow.displayTarget === "section") {
3790
3975
  validations.push(eow);
3791
3976
  }
@@ -3804,7 +3989,7 @@ class ValidationBindingTrackerViewPlugin {
3804
3989
  });
3805
3990
  });
3806
3991
  resolver.hooks.afterNodeUpdate.tap(CONTEXT, (node, parent, update) => {
3807
- var _a, _b, _c;
3992
+ var _a, _b;
3808
3993
  if (parent) {
3809
3994
  addToTree(node, parent);
3810
3995
  }
@@ -3819,7 +4004,7 @@ class ValidationBindingTrackerViewPlugin {
3819
4004
  currentBindingTree.set(node, (_b = lastComputedBindingTree.get(node)) != null ? _b : new Set());
3820
4005
  }
3821
4006
  if (node === resolver.root) {
3822
- this.trackedBindings = (_c = currentBindingTree.get(node)) != null ? _c : new Set();
4007
+ this.trackedBindings = new Set(currentBindingTree.get(node));
3823
4008
  lastComputedBindingTree = currentBindingTree;
3824
4009
  lastSectionBindingTree.clear();
3825
4010
  sections.forEach((nodeSet, sectionNode) => {
@@ -3861,11 +4046,15 @@ var __spreadValues$3 = (a, b) => {
3861
4046
  return a;
3862
4047
  };
3863
4048
  var __spreadProps$2 = (a, b) => __defProps$2(a, __getOwnPropDescs$2(b));
4049
+ const SCHEMA_VALIDATION_PROVIDER_NAME = "schema";
4050
+ const VIEW_VALIDATION_PROVIDER_NAME = "view";
4051
+ const VALIDATION_PROVIDER_NAME_SYMBOL = Symbol.for("validation-provider-name");
3864
4052
  function createStatefulValidationObject(obj) {
3865
4053
  return {
3866
4054
  value: obj,
3867
4055
  type: obj.severity,
3868
- state: "none"
4056
+ state: "none",
4057
+ isBlockingNavigation: false
3869
4058
  };
3870
4059
  }
3871
4060
  class ValidatedBinding {
@@ -3880,20 +4069,45 @@ class ValidatedBinding {
3880
4069
  possibleValidations.forEach((vObj) => {
3881
4070
  const { trigger } = vObj;
3882
4071
  if (this.validationsByState[trigger]) {
3883
- this.validationsByState[trigger].push(createStatefulValidationObject(vObj));
4072
+ const statefulValidationObject = createStatefulValidationObject(vObj);
4073
+ this.validationsByState[trigger].push(statefulValidationObject);
3884
4074
  } else {
3885
4075
  log == null ? void 0 : log.warn(`Unknown validation trigger: ${trigger}`);
3886
4076
  }
3887
4077
  });
3888
4078
  this.weakBindings = weakBindings != null ? weakBindings : new Set();
3889
4079
  }
4080
+ get allValidations() {
4081
+ return Object.values(this.validationsByState).flat();
4082
+ }
4083
+ checkIfBlocking(statefulObj) {
4084
+ if (statefulObj.state === "active") {
4085
+ const { isBlockingNavigation } = statefulObj;
4086
+ return isBlockingNavigation;
4087
+ }
4088
+ return false;
4089
+ }
4090
+ getAll() {
4091
+ return this.applicableValidations.reduce((all, statefulObj) => {
4092
+ if (statefulObj.state === "active" && statefulObj.response) {
4093
+ return [
4094
+ ...all,
4095
+ __spreadProps$2(__spreadValues$3({}, statefulObj.response), {
4096
+ blocking: this.checkIfBlocking(statefulObj)
4097
+ })
4098
+ ];
4099
+ }
4100
+ return all;
4101
+ }, []);
4102
+ }
3890
4103
  get() {
3891
- const firstError = this.applicableValidations.find((statefulObj) => {
3892
- const blocking = this.currentPhase === "navigation" ? statefulObj.value.blocking : true;
3893
- return statefulObj.state === "active" && blocking !== false;
4104
+ const firstInvalid = this.applicableValidations.find((statefulObj) => {
4105
+ return statefulObj.state === "active" && statefulObj.response;
3894
4106
  });
3895
- if ((firstError == null ? void 0 : firstError.state) === "active") {
3896
- return firstError.response;
4107
+ if ((firstInvalid == null ? void 0 : firstInvalid.state) === "active") {
4108
+ return __spreadProps$2(__spreadValues$3({}, firstInvalid.response), {
4109
+ blocking: this.checkIfBlocking(firstInvalid)
4110
+ });
3897
4111
  }
3898
4112
  }
3899
4113
  runApplicableValidations(runner, canDismiss) {
@@ -3902,7 +4116,8 @@ class ValidatedBinding {
3902
4116
  if (obj.state === "dismissed") {
3903
4117
  return obj;
3904
4118
  }
3905
- const blocking = (_a = obj.value.blocking) != null ? _a : obj.value.severity === "warning" && "once" || obj.value.severity === "error" && true;
4119
+ const blocking = (_a = obj.value.blocking) != null ? _a : obj.value.severity === "warning" && "once" || true;
4120
+ const isBlockingNavigation = blocking === true || blocking === "once" && !canDismiss;
3906
4121
  const dismissable = canDismiss && blocking === "once";
3907
4122
  if (this.currentPhase === "navigation" && obj.state === "active" && dismissable) {
3908
4123
  if (obj.value.severity === "warning") {
@@ -3914,17 +4129,13 @@ class ValidatedBinding {
3914
4129
  }
3915
4130
  return obj;
3916
4131
  }
3917
- if (obj.value.severity === "error") {
3918
- const err = obj;
3919
- err.state = "none";
3920
- return obj;
3921
- }
3922
4132
  }
3923
4133
  const response = runner(obj.value);
3924
4134
  const newState = {
3925
4135
  type: obj.type,
3926
4136
  value: obj.value,
3927
4137
  state: response ? "active" : "none",
4138
+ isBlockingNavigation,
3928
4139
  dismissable: obj.value.severity === "warning" && this.currentPhase === "navigation",
3929
4140
  response: response ? __spreadProps$2(__spreadValues$3({}, obj.value), {
3930
4141
  message: (_b = response.message) != null ? _b : "Something is broken",
@@ -3975,20 +4186,34 @@ class ValidationController {
3975
4186
  this.hooks = {
3976
4187
  createValidatorRegistry: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncHook"](),
3977
4188
  onAddValidation: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"](),
3978
- onRemoveValidation: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"]()
4189
+ onRemoveValidation: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"](),
4190
+ resolveValidationProviders: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"](),
4191
+ onTrackBinding: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncHook"]()
3979
4192
  };
3980
4193
  this.validations = new Map();
3981
4194
  this.weakBindingTracker = new Set();
3982
- this.lastActiveBindings = new Set();
3983
4195
  this.schema = schema;
3984
4196
  this.options = options;
3985
- this.providers = [schema];
4197
+ this.reset();
3986
4198
  }
3987
4199
  setOptions(options) {
3988
4200
  this.options = options;
3989
4201
  }
3990
4202
  getDataMiddleware() {
3991
4203
  return [
4204
+ {
4205
+ set: (transaction, options, next) => {
4206
+ var _a;
4207
+ return (_a = next == null ? void 0 : next.set(transaction, options)) != null ? _a : [];
4208
+ },
4209
+ get: (binding, options, next) => {
4210
+ return next == null ? void 0 : next.get(binding, options);
4211
+ },
4212
+ delete: (binding, options, next) => {
4213
+ this.validations = removeBindingAndChildrenFromMap(this.validations, binding);
4214
+ return next == null ? void 0 : next.delete(binding, options);
4215
+ }
4216
+ },
3992
4217
  new ValidationMiddleware((binding) => {
3993
4218
  var _a;
3994
4219
  if (!this.options) {
@@ -4004,13 +4229,17 @@ class ValidationController {
4004
4229
  var _a2;
4005
4230
  if (caresAboutDataChanges(new Set([binding]), weakValidation.weakBindings) && ((_a2 = weakValidation == null ? void 0 : weakValidation.get()) == null ? void 0 : _a2.severity) === "error") {
4006
4231
  weakValidation == null ? void 0 : weakValidation.weakBindings.forEach((weakBinding) => {
4007
- weakBinding === strongBinding ? newInvalidBindings.add({
4008
- binding: weakBinding,
4009
- isStrong: true
4010
- }) : newInvalidBindings.add({
4011
- binding: weakBinding,
4012
- isStrong: false
4013
- });
4232
+ if (weakBinding === strongBinding) {
4233
+ newInvalidBindings.add({
4234
+ binding: weakBinding,
4235
+ isStrong: true
4236
+ });
4237
+ } else {
4238
+ newInvalidBindings.add({
4239
+ binding: weakBinding,
4240
+ isStrong: false
4241
+ });
4242
+ }
4014
4243
  });
4015
4244
  }
4016
4245
  });
@@ -4023,6 +4252,35 @@ class ValidationController {
4023
4252
  }) })
4024
4253
  ];
4025
4254
  }
4255
+ getValidationProviders() {
4256
+ if (this.providers) {
4257
+ return this.providers;
4258
+ }
4259
+ this.providers = this.hooks.resolveValidationProviders.call([
4260
+ {
4261
+ source: SCHEMA_VALIDATION_PROVIDER_NAME,
4262
+ provider: this.schema
4263
+ },
4264
+ {
4265
+ source: VIEW_VALIDATION_PROVIDER_NAME,
4266
+ provider: {
4267
+ getValidationsForBinding: (binding) => {
4268
+ var _a, _b;
4269
+ return (_b = (_a = this.viewValidationProvider) == null ? void 0 : _a.getValidationsForBinding) == null ? void 0 : _b.call(_a, binding);
4270
+ },
4271
+ getValidationsForView: () => {
4272
+ var _a, _b;
4273
+ return (_b = (_a = this.viewValidationProvider) == null ? void 0 : _a.getValidationsForView) == null ? void 0 : _b.call(_a);
4274
+ }
4275
+ }
4276
+ }
4277
+ ]);
4278
+ return this.providers;
4279
+ }
4280
+ reset() {
4281
+ this.validations.clear();
4282
+ this.tracker = void 0;
4283
+ }
4026
4284
  onView(view) {
4027
4285
  this.validations.clear();
4028
4286
  if (!this.options) {
@@ -4031,7 +4289,7 @@ class ValidationController {
4031
4289
  const bindingTrackerPlugin = new ValidationBindingTrackerViewPlugin(__spreadProps$2(__spreadValues$3({}, this.options), {
4032
4290
  callbacks: {
4033
4291
  onAdd: (binding) => {
4034
- if (!this.options) {
4292
+ if (!this.options || this.getValidationForBinding(binding) !== void 0) {
4035
4293
  return;
4036
4294
  }
4037
4295
  const originalValue = this.options.model.get(binding);
@@ -4046,21 +4304,28 @@ class ValidationController {
4046
4304
  this.updateValidationsForBinding(binding, "load", this.options, () => {
4047
4305
  view.update(new Set([binding]));
4048
4306
  });
4307
+ this.hooks.onTrackBinding.call(binding);
4049
4308
  }
4050
4309
  }
4051
4310
  }));
4052
4311
  this.tracker = bindingTrackerPlugin;
4053
- this.providers = [this.schema, view];
4312
+ this.viewValidationProvider = view;
4054
4313
  bindingTrackerPlugin.apply(view);
4055
4314
  }
4056
- updateValidationsForBinding(binding, trigger, context, onDismiss) {
4315
+ updateValidationsForBinding(binding, trigger, validationContext, onDismiss) {
4057
4316
  var _a;
4317
+ const context = validationContext != null ? validationContext : this.options;
4318
+ if (!context) {
4319
+ throw new Error(`Context is required for executing validations`);
4320
+ }
4058
4321
  if (trigger === "load") {
4059
- const possibleValidations = this.providers.reduce((vals, provider) => {
4060
- var _a2, _b;
4322
+ const possibleValidations = this.getValidationProviders().reduce((vals, provider) => {
4323
+ var _a2, _b, _c, _d;
4061
4324
  return [
4062
4325
  ...vals,
4063
- ...(_b = (_a2 = provider.getValidationsForBinding) == null ? void 0 : _a2.call(provider, binding)) != null ? _b : []
4326
+ ...(_d = (_c = (_b = (_a2 = provider.provider).getValidationsForBinding) == null ? void 0 : _b.call(_a2, binding)) == null ? void 0 : _c.map((valObj) => __spreadProps$2(__spreadValues$3({}, valObj), {
4327
+ [VALIDATION_PROVIDER_NAME_SYMBOL]: provider.source
4328
+ }))) != null ? _d : []
4064
4329
  ];
4065
4330
  }, []);
4066
4331
  if (possibleValidations.length === 0) {
@@ -4070,7 +4335,7 @@ class ValidationController {
4070
4335
  }
4071
4336
  const trackedValidations = this.validations.get(binding);
4072
4337
  trackedValidations == null ? void 0 : trackedValidations.update(trigger, true, (validationObj) => {
4073
- const response = this.validationRunner(validationObj, context, binding);
4338
+ const response = this.validationRunner(validationObj, binding, context);
4074
4339
  if (this.weakBindingTracker.size > 0) {
4075
4340
  const t = this.validations.get(binding);
4076
4341
  this.weakBindingTracker.forEach((b) => t.weakBindings.add(b));
@@ -4081,27 +4346,33 @@ class ValidationController {
4081
4346
  this.validations.forEach((validation, vBinding) => {
4082
4347
  if (vBinding !== binding && caresAboutDataChanges(new Set([binding]), validation.weakBindings)) {
4083
4348
  validation.update(trigger, true, (validationObj) => {
4084
- const response = this.validationRunner(validationObj, context, vBinding);
4349
+ const response = this.validationRunner(validationObj, vBinding, context);
4085
4350
  return response ? { message: response.message } : void 0;
4086
4351
  });
4087
4352
  }
4088
4353
  });
4089
4354
  }
4090
4355
  }
4091
- validationRunner(validationObj, context, binding) {
4092
- const handler = this.getValidator(validationObj.type);
4356
+ validationRunner(validationObj, binding, context = this.options) {
4357
+ var _a;
4358
+ if (!context) {
4359
+ throw new Error("No context provided to validation runner");
4360
+ }
4361
+ const handler = (_a = validationObj.handler) != null ? _a : this.getValidator(validationObj.type);
4093
4362
  const weakBindings = new Set();
4094
4363
  const model = {
4095
- get(b, options = { includeInvalid: true }) {
4364
+ get(b, options) {
4096
4365
  weakBindings.add(isBinding(b) ? binding : context.parseBinding(b));
4097
- return context.model.get(b, options);
4366
+ return context.model.get(b, __spreadProps$2(__spreadValues$3({}, options), { includeInvalid: true }));
4098
4367
  },
4099
- set: context.model.set
4368
+ set: context.model.set,
4369
+ delete: context.model.delete
4100
4370
  };
4101
4371
  const result = handler == null ? void 0 : handler(__spreadProps$2(__spreadValues$3({}, context), {
4102
4372
  evaluate: (exp, options = { model }) => context.evaluate(exp, options),
4103
4373
  model,
4104
- validation: validationObj
4374
+ validation: validationObj,
4375
+ schemaType: this.schema.getType(binding)
4105
4376
  }), context.model.get(binding, {
4106
4377
  includeInvalid: true,
4107
4378
  formatted: validationObj.dataTarget === "formatted"
@@ -4125,19 +4396,25 @@ class ValidationController {
4125
4396
  }
4126
4397
  }
4127
4398
  updateValidationsForView(trigger) {
4128
- const { activeBindings } = this;
4129
- const canDismiss = trigger !== "navigation" || this.setCompare(this.lastActiveBindings, activeBindings);
4130
- this.getBindings().forEach((binding) => {
4131
- var _a;
4132
- (_a = this.validations.get(binding)) == null ? void 0 : _a.update(trigger, canDismiss, (obj) => {
4133
- if (!this.options) {
4134
- return;
4135
- }
4136
- return this.validationRunner(obj, this.options, binding);
4399
+ const isNavigationTrigger = trigger === "navigation";
4400
+ const lastActiveBindings = this.activeBindings;
4401
+ const updateValidations = (dismissValidations) => {
4402
+ this.getBindings().forEach((binding) => {
4403
+ var _a;
4404
+ (_a = this.validations.get(binding)) == null ? void 0 : _a.update(trigger, dismissValidations, (obj) => {
4405
+ if (!this.options) {
4406
+ return;
4407
+ }
4408
+ return this.validationRunner(obj, binding, this.options);
4409
+ });
4137
4410
  });
4138
- });
4139
- if (trigger === "navigation") {
4140
- this.lastActiveBindings = activeBindings;
4411
+ };
4412
+ updateValidations(!isNavigationTrigger);
4413
+ if (isNavigationTrigger) {
4414
+ const { activeBindings } = this;
4415
+ if (this.setCompare(lastActiveBindings, activeBindings)) {
4416
+ updateValidations(true);
4417
+ }
4141
4418
  }
4142
4419
  }
4143
4420
  setCompare(set1, set2) {
@@ -4167,19 +4444,30 @@ class ValidationController {
4167
4444
  var _a, _b;
4168
4445
  return (_b = (_a = this.tracker) == null ? void 0 : _a.getBindings()) != null ? _b : new Set();
4169
4446
  }
4447
+ trackBinding(binding) {
4448
+ var _a;
4449
+ (_a = this.tracker) == null ? void 0 : _a.trackBinding(binding);
4450
+ }
4170
4451
  validateView(trigger = "navigation") {
4171
4452
  this.updateValidationsForView(trigger);
4172
4453
  const validations = new Map();
4454
+ let canTransition = true;
4173
4455
  this.getBindings().forEach((b) => {
4174
- var _a, _b;
4175
- const invalid = (_a = this.getValidationForBinding(b)) == null ? void 0 : _a.get();
4176
- if (invalid) {
4177
- (_b = this.options) == null ? void 0 : _b.logger.debug(`Validation on binding: ${b.asString()} is preventing navigation. ${JSON.stringify(invalid)}`);
4178
- validations.set(b, invalid);
4179
- }
4456
+ var _a;
4457
+ const allValidations = (_a = this.getValidationForBinding(b)) == null ? void 0 : _a.getAll();
4458
+ allValidations == null ? void 0 : allValidations.forEach((v) => {
4459
+ var _a2;
4460
+ if (trigger === "navigation" && v.blocking) {
4461
+ (_a2 = this.options) == null ? void 0 : _a2.logger.debug(`Validation on binding: ${b.asString()} is preventing navigation. ${JSON.stringify(v)}`);
4462
+ canTransition = false;
4463
+ }
4464
+ if (!validations.has(b)) {
4465
+ validations.set(b, v);
4466
+ }
4467
+ });
4180
4468
  });
4181
4469
  return {
4182
- canTransition: validations.size === 0,
4470
+ canTransition,
4183
4471
  validations: validations.size ? validations : void 0
4184
4472
  };
4185
4473
  }
@@ -4189,8 +4477,7 @@ class ValidationController {
4189
4477
  forView(parser) {
4190
4478
  return {
4191
4479
  _getValidationForBinding: (binding) => {
4192
- var _a;
4193
- return (_a = this.getValidationForBinding(isBinding(binding) ? binding : parser(binding))) == null ? void 0 : _a.get();
4480
+ return this.getValidationForBinding(isBinding(binding) ? binding : parser(binding));
4194
4481
  },
4195
4482
  getAll: () => {
4196
4483
  const bindings = this.getBindings();
@@ -4210,6 +4497,9 @@ class ValidationController {
4210
4497
  get() {
4211
4498
  throw new Error("Error Access be provided by the view plugin");
4212
4499
  },
4500
+ getValidationsForBinding() {
4501
+ throw new Error("Error rollup should be provided by the view plugin");
4502
+ },
4213
4503
  getChildren() {
4214
4504
  throw new Error("Error rollup should be provided by the view plugin");
4215
4505
  },
@@ -4220,7 +4510,7 @@ class ValidationController {
4220
4510
  throw new Error("Tracking should be provided by the view plugin");
4221
4511
  },
4222
4512
  register: () => {
4223
- throw new Error("Section funcationality hould be provided by the view plugin");
4513
+ throw new Error("Section functionality should be provided by the view plugin");
4224
4514
  },
4225
4515
  type: (binding) => this.schema.getType(isBinding(binding) ? binding : parser(binding))
4226
4516
  };
@@ -4336,10 +4626,11 @@ class AssetTransformCorePlugin {
4336
4626
  };
4337
4627
  };
4338
4628
  resolver.hooks.beforeResolve.tap("asset-transform", (node, options) => {
4629
+ var _a;
4339
4630
  if (node && (node.type === "asset" || node.type === "view")) {
4340
4631
  const transform = this.registry.get(node.value);
4341
4632
  if (transform == null ? void 0 : transform.beforeResolve) {
4342
- const store = getStore(node, this.beforeResolveSymbol);
4633
+ const store = getStore((_a = options.node) != null ? _a : node, this.beforeResolveSymbol);
4343
4634
  return transform.beforeResolve(node, options, store);
4344
4635
  }
4345
4636
  }
@@ -4417,14 +4708,26 @@ class ViewController {
4417
4708
  }
4418
4709
  });
4419
4710
  });
4420
- options.model.hooks.onUpdate.tap("viewController", (updates) => {
4711
+ const update = (updates) => {
4421
4712
  if (this.currentView) {
4422
4713
  if (this.optimizeUpdates) {
4423
- this.queueUpdate(new Set(updates.map((t) => t.binding)));
4714
+ this.queueUpdate(updates);
4424
4715
  } else {
4425
4716
  this.currentView.update();
4426
4717
  }
4427
4718
  }
4719
+ };
4720
+ options.model.hooks.onUpdate.tap("viewController", (updates) => {
4721
+ update(new Set(updates.map((t) => t.binding)));
4722
+ });
4723
+ options.model.hooks.onDelete.tap("viewController", (binding) => {
4724
+ const parentBinding = binding.parent();
4725
+ const property = binding.key();
4726
+ if (typeof property === "number" && parentBinding) {
4727
+ update(new Set([parentBinding]));
4728
+ } else {
4729
+ update(new Set([binding]));
4730
+ }
4428
4731
  });
4429
4732
  }
4430
4733
  queueUpdate(bindings) {
@@ -4525,16 +4828,19 @@ class DataController {
4525
4828
  });
4526
4829
  }
4527
4830
  const setUpdates = normalizedTransaction.reduce((updates, [binding, newVal]) => {
4528
- var _a;
4831
+ var _a, _b;
4529
4832
  const oldVal = this.get(binding, { includeInvalid: true });
4530
- if (!Object(dequal__WEBPACK_IMPORTED_MODULE_8__["dequal"])(oldVal, newVal)) {
4531
- updates.push({
4532
- binding,
4533
- newValue: newVal,
4534
- oldValue: oldVal
4535
- });
4833
+ const update = {
4834
+ binding,
4835
+ newValue: newVal,
4836
+ oldValue: oldVal
4837
+ };
4838
+ if (Object(dequal__WEBPACK_IMPORTED_MODULE_8__["dequal"])(oldVal, newVal)) {
4839
+ (_a = this.logger) == null ? void 0 : _a.debug(`Skipping update for path: ${binding.asString()}. Value was unchanged: ${oldVal}`);
4840
+ } else {
4841
+ updates.push(update);
4842
+ (_b = this.logger) == null ? void 0 : _b.debug(`Setting path: ${binding.asString()} from: ${oldVal} to: ${newVal}`);
4536
4843
  }
4537
- (_a = this.logger) == null ? void 0 : _a.debug(`Setting path: ${binding.asString()} from: ${oldVal} to: ${newVal}`);
4538
4844
  return updates;
4539
4845
  }, []);
4540
4846
  const result = this.getModel().set(normalizedTransaction, options);
@@ -4552,11 +4858,11 @@ class DataController {
4552
4858
  }
4553
4859
  return result;
4554
4860
  }
4555
- resolve(binding) {
4556
- return Array.isArray(binding) || typeof binding === "string" ? this.pathResolver.parse(binding) : binding;
4861
+ resolve(binding, readOnly) {
4862
+ return Array.isArray(binding) || typeof binding === "string" ? this.pathResolver.parse(binding, { readOnly }) : binding;
4557
4863
  }
4558
4864
  get(binding, options) {
4559
- const resolved = binding instanceof BindingInstance ? binding : this.resolve(binding);
4865
+ const resolved = binding instanceof BindingInstance ? binding : this.resolve(binding, true);
4560
4866
  let result = this.getModel().get(resolved, options);
4561
4867
  if (result === void 0 && !(options == null ? void 0 : options.ignoreDefaultValue)) {
4562
4868
  const defaultVal = this.hooks.resolveDefaultValue.call(resolved);
@@ -4566,44 +4872,26 @@ class DataController {
4566
4872
  }
4567
4873
  if (options == null ? void 0 : options.formatted) {
4568
4874
  result = this.hooks.format.call(result, resolved);
4875
+ } else if ((options == null ? void 0 : options.formatted) === false) {
4876
+ result = this.hooks.deformat.call(result, resolved);
4569
4877
  }
4570
4878
  this.hooks.onGet.call(binding, result);
4571
4879
  return result;
4572
4880
  }
4573
- delete(binding) {
4574
- if (binding === void 0 || binding === null) {
4575
- throw new Error(`Invalid arguments: delete expects a data path (string)`);
4881
+ delete(binding, options) {
4882
+ if (typeof binding !== "string" && !Array.isArray(binding) && !(binding instanceof BindingInstance)) {
4883
+ throw new Error("Invalid arguments: delete expects a data path (string)");
4576
4884
  }
4577
- const resolved = this.resolve(binding);
4578
- this.hooks.onDelete.call(resolved);
4579
- this.deleteData(resolved);
4580
- }
4581
- getTrash() {
4582
- return this.trash;
4583
- }
4584
- addToTrash(binding) {
4585
- this.trash.add(binding);
4586
- }
4587
- deleteData(binding) {
4588
- const parentBinding = binding.parent();
4589
- const parentPath = parentBinding.asString();
4590
- const property = binding.key();
4591
- const existedBeforeDelete = Object.prototype.hasOwnProperty.call(this.get(parentBinding), property);
4592
- if (property !== void 0) {
4593
- const parent = parentBinding ? this.get(parentBinding) : void 0;
4594
- if (parentPath && Array.isArray(parent)) {
4595
- if (parent.length > property) {
4596
- this.set([[parentBinding, Object(timm__WEBPACK_IMPORTED_MODULE_7__["removeAt"])(parent, property)]]);
4597
- }
4598
- } else if (parentPath && parent[property]) {
4599
- this.set([[parentBinding, Object(timm__WEBPACK_IMPORTED_MODULE_7__["omit"])(parent, property)]]);
4600
- } else if (!parentPath) {
4601
- this.getModel().reset(Object(timm__WEBPACK_IMPORTED_MODULE_7__["omit"])(this.get(""), property));
4602
- }
4603
- }
4604
- if (existedBeforeDelete && !this.get(binding)) {
4605
- this.addToTrash(binding);
4885
+ const resolved = binding instanceof BindingInstance ? binding : this.resolve(binding, false);
4886
+ const parentBinding = resolved.parent();
4887
+ const property = resolved.key();
4888
+ const parentValue = this.get(parentBinding);
4889
+ const existedBeforeDelete = typeof parentValue === "object" && parentValue !== null && Object.prototype.hasOwnProperty.call(parentValue, property);
4890
+ this.getModel().delete(resolved, options);
4891
+ if (existedBeforeDelete && !this.get(resolved)) {
4892
+ this.trash.add(resolved);
4606
4893
  }
4894
+ this.hooks.onDelete.call(resolved);
4607
4895
  }
4608
4896
  serialize() {
4609
4897
  return this.hooks.serialize.call(this.get(""));
@@ -4664,10 +4952,15 @@ class ConstantsController {
4664
4952
  this.tempStore.set(namespace, new LocalModel(data));
4665
4953
  }
4666
4954
  }
4667
- clearTemporaryValues() {
4668
- this.tempStore.forEach((value) => {
4669
- value.reset();
4670
- });
4955
+ clearTemporaryValues(namespace) {
4956
+ var _a;
4957
+ if (namespace) {
4958
+ (_a = this.tempStore.get(namespace)) == null ? void 0 : _a.reset();
4959
+ } else {
4960
+ this.tempStore.forEach((value) => {
4961
+ value.reset();
4962
+ });
4963
+ }
4671
4964
  }
4672
4965
  }
4673
4966
 
@@ -4782,8 +5075,8 @@ var __async = (__this, __arguments, generator) => {
4782
5075
  step((generator = generator.apply(__this, __arguments)).next());
4783
5076
  });
4784
5077
  };
4785
- const PLAYER_VERSION = "0.4.0-next.7";
4786
- const COMMIT = "d187c654ea192038fcd5eb00f88d7244bb2cafff";
5078
+ const PLAYER_VERSION = "0.4.0-next.9";
5079
+ const COMMIT = "e7681a2757fe0ab15d0c0e27c11d0ed33334d63f";
4787
5080
  const _Player = class {
4788
5081
  constructor(config) {
4789
5082
  this.logger = new TapableLogger();
@@ -4903,10 +5196,11 @@ const _Player = class {
4903
5196
  flowResultDeferred.reject(e);
4904
5197
  return true;
4905
5198
  });
4906
- function resolveStrings(val) {
5199
+ function resolveStrings(val, formatted) {
4907
5200
  return resolveDataRefs(val, {
4908
5201
  model: dataController,
4909
- evaluate: expressionEvaluator.evaluate
5202
+ evaluate: expressionEvaluator.evaluate,
5203
+ formatted
4910
5204
  });
4911
5205
  }
4912
5206
  flowController.hooks.flow.tap("player", (flow) => {
@@ -4942,23 +5236,21 @@ const _Player = class {
4942
5236
  newState = Object(timm__WEBPACK_IMPORTED_MODULE_7__["setIn"])(state, ["ref"], resolveStrings(state.ref));
4943
5237
  }
4944
5238
  if ("param" in state) {
4945
- newState = Object(timm__WEBPACK_IMPORTED_MODULE_7__["setIn"])(state, ["param"], resolveStrings(state.param));
5239
+ newState = Object(timm__WEBPACK_IMPORTED_MODULE_7__["setIn"])(state, ["param"], resolveStrings(state.param, false));
4946
5240
  }
4947
5241
  return newState;
4948
5242
  });
4949
5243
  flow.hooks.transition.tap("player", (_oldState, newState) => {
4950
- if (newState.value.state_type === "ACTION") {
4951
- const { exp } = newState.value;
4952
- queue_microtask__WEBPACK_IMPORTED_MODULE_10___default()(() => {
4953
- try {
4954
- flowController == null ? void 0 : flowController.transition(String(expressionEvaluator == null ? void 0 : expressionEvaluator.evaluate(exp)));
4955
- } catch (error) {
4956
- const state = this.getState();
4957
- if (error instanceof Error && state.status === "in-progress") {
4958
- state.fail(error);
4959
- }
4960
- }
4961
- });
5244
+ if (newState.value.state_type !== "VIEW") {
5245
+ validationController.reset();
5246
+ }
5247
+ });
5248
+ flow.hooks.afterTransition.tap("player", (flowInstance) => {
5249
+ var _a;
5250
+ const value = (_a = flowInstance.currentState) == null ? void 0 : _a.value;
5251
+ if (value && value.state_type === "ACTION") {
5252
+ const { exp } = value;
5253
+ flowController == null ? void 0 : flowController.transition(String(expressionEvaluator == null ? void 0 : expressionEvaluator.evaluate(exp)));
4962
5254
  }
4963
5255
  expressionEvaluator.reset();
4964
5256
  });
@@ -4976,6 +5268,11 @@ const _Player = class {
4976
5268
  parseBinding,
4977
5269
  transition: flowController.transition,
4978
5270
  model: dataController,
5271
+ utils: {
5272
+ findPlugin: (pluginSymbol) => {
5273
+ return this.findPlugin(pluginSymbol);
5274
+ }
5275
+ },
4979
5276
  logger: this.logger,
4980
5277
  flowController,
4981
5278
  schema,
@@ -4989,7 +5286,8 @@ const _Player = class {
4989
5286
  },
4990
5287
  validation: __spreadProps(__spreadValues({}, validationController.forView(parseBinding)), {
4991
5288
  type: (b) => schema.getType(parseBinding(b))
4992
- })
5289
+ }),
5290
+ constants: this.constantsController
4993
5291
  });
4994
5292
  viewController.hooks.view.tap("player", (view) => {
4995
5293
  validationController.onView(view);
@@ -5000,7 +5298,7 @@ const _Player = class {
5000
5298
  start: () => {
5001
5299
  flowController.start().then((endState) => {
5002
5300
  const flowResult = {
5003
- endState: resolveStrings(endState),
5301
+ endState: resolveStrings(endState, false),
5004
5302
  data: dataController.serialize()
5005
5303
  };
5006
5304
  return flowResult;
@@ -5052,8 +5350,7 @@ const _Player = class {
5052
5350
  const endProps = {
5053
5351
  ref,
5054
5352
  status: "completed",
5055
- flow: state.flow,
5056
- dataModel: state.controllers.data.getModel()
5353
+ flow: state.flow
5057
5354
  };
5058
5355
  return maybeUpdateState(__spreadValues(__spreadValues({}, yield state.flowResult), endProps));
5059
5356
  } catch (error) {