@player-ui/common-expressions-plugin 0.4.0-next.8 → 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.
@@ -224,12 +224,15 @@ __webpack_require__.r(__webpack_exports__);
224
224
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ProxyLogger", function() { return ProxyLogger; });
225
225
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ROOT_BINDING", function() { return ROOT_BINDING; });
226
226
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "Resolver", function() { return Resolver; });
227
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SCHEMA_VALIDATION_PROVIDER_NAME", function() { return SCHEMA_VALIDATION_PROVIDER_NAME; });
227
228
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SIMPLE_BINDING_REGEX", function() { return SIMPLE_BINDING_REGEX; });
228
229
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SchemaController", function() { return SchemaController; });
229
230
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "StringResolverPlugin", function() { return StringResolverPlugin; });
230
231
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "SwitchPlugin", function() { return SwitchPlugin; });
231
232
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TapableLogger", function() { return TapableLogger; });
232
233
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "TemplatePlugin", function() { return TemplatePlugin; });
234
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VALIDATION_PROVIDER_NAME_SYMBOL", function() { return VALIDATION_PROVIDER_NAME_SYMBOL; });
235
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "VIEW_VALIDATION_PROVIDER_NAME", function() { return VIEW_VALIDATION_PROVIDER_NAME; });
233
236
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ValidationBindingTrackerViewPlugin", function() { return ValidationBindingTrackerViewPlugin; });
234
237
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ValidationController", function() { return ValidationController; });
235
238
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "ValidationMiddleware", function() { return ValidationMiddleware; });
@@ -244,9 +247,11 @@ __webpack_require__.r(__webpack_exports__);
244
247
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "getBindingSegments", function() { return getBindingSegments; });
245
248
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isBinding", function() { return isBinding; });
246
249
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isExpressionNode", function() { return isExpressionNode; });
250
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "isObjectExpression", function() { return isObjectExpression; });
247
251
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "maybeConvertToNum", function() { return maybeConvertToNum; });
248
252
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parse", function() { return parse; });
249
253
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "parseExpression", function() { return parseExpression; });
254
+ /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "removeBindingAndChildrenFromMap", function() { return removeBindingAndChildrenFromMap; });
250
255
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resolveDataRefs", function() { return resolveDataRefs; });
251
256
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resolveDataRefsInString", function() { return resolveDataRefsInString; });
252
257
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "resolveExpressionsInString", function() { return resolveExpressionsInString; });
@@ -257,7 +262,7 @@ __webpack_require__.r(__webpack_exports__);
257
262
  /* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, "withoutContext", function() { return withoutContext; });
258
263
  /* 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");
259
264
  /* harmony import */ var _player_ui_types__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_player_ui_types__WEBPACK_IMPORTED_MODULE_0__);
260
- /* 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__));
265
+ /* 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__));
261
266
  /* harmony import */ var tapable_ts__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! tapable-ts */ "./node_modules/tapable-ts/dist/hooks.mjs");
262
267
  /* harmony import */ var nested_error_stacks__WEBPACK_IMPORTED_MODULE_2__ = __webpack_require__(/*! nested-error-stacks */ "./node_modules/nested-error-stacks/index.js");
263
268
  /* harmony import */ var nested_error_stacks__WEBPACK_IMPORTED_MODULE_2___default = /*#__PURE__*/__webpack_require__.n(nested_error_stacks__WEBPACK_IMPORTED_MODULE_2__);
@@ -821,7 +826,7 @@ class BindingParser {
821
826
  updates = __spreadValues$d(__spreadValues$d({}, updates), normalized.updates);
822
827
  }
823
828
  const updateKeys = Object.keys(updates);
824
- if (updateKeys.length > 0) {
829
+ if (!options.readOnly && updateKeys.length > 0) {
825
830
  const updateTransaction = updateKeys.map((updatedBinding) => [
826
831
  this.parse(updatedBinding),
827
832
  updates[updatedBinding]
@@ -917,6 +922,10 @@ class DependencyMiddleware extends DependencyTracker {
917
922
  this.addReadDep(binding);
918
923
  return next == null ? void 0 : next.get(binding, options);
919
924
  }
925
+ delete(binding, options, next) {
926
+ this.addWriteDep(binding);
927
+ return next == null ? void 0 : next.delete(binding, options);
928
+ }
920
929
  }
921
930
  class DependencyModel extends DependencyTracker {
922
931
  constructor(rootModel) {
@@ -933,6 +942,10 @@ class DependencyModel extends DependencyTracker {
933
942
  this.addReadDep(binding);
934
943
  return this.rootModel.get(binding, options);
935
944
  }
945
+ delete(binding, options) {
946
+ this.addWriteDep(binding);
947
+ return this.rootModel.delete(binding, options);
948
+ }
936
949
  }
937
950
 
938
951
  class NOOPDataModel {
@@ -942,15 +955,18 @@ class NOOPDataModel {
942
955
  set() {
943
956
  return [];
944
957
  }
958
+ delete() {
959
+ }
945
960
  }
946
961
  const NOOP_MODEL = new NOOPDataModel();
947
962
 
948
963
  const ROOT_BINDING = new BindingInstance([]);
949
964
  function withParser(model, parseBinding) {
950
- function maybeParse(binding) {
965
+ function maybeParse(binding, readOnly) {
951
966
  const parsed = isBinding(binding) ? binding : parseBinding(binding, {
952
967
  get: model.get,
953
- set: model.set
968
+ set: model.set,
969
+ readOnly
954
970
  });
955
971
  if (!parsed) {
956
972
  throw new Error("Unable to parse binding");
@@ -959,10 +975,13 @@ function withParser(model, parseBinding) {
959
975
  }
960
976
  return {
961
977
  get(binding, options) {
962
- return model.get(maybeParse(binding), options);
978
+ return model.get(maybeParse(binding, true), options);
963
979
  },
964
980
  set(transaction, options) {
965
- return model.set(transaction.map(([key, val]) => [maybeParse(key), val]), options);
981
+ return model.set(transaction.map(([key, val]) => [maybeParse(key, false), val]), options);
982
+ },
983
+ delete(binding, options) {
984
+ return model.delete(maybeParse(binding, false), options);
966
985
  }
967
986
  };
968
987
  }
@@ -971,8 +990,27 @@ function toModel(middleware, defaultOptions, next) {
971
990
  return middleware;
972
991
  }
973
992
  return {
974
- get: (binding, options) => middleware.get(binding, options != null ? options : defaultOptions, next),
975
- set: (transaction, options) => middleware.set(transaction, options != null ? options : defaultOptions, next)
993
+ get: (binding, options) => {
994
+ const resolvedOptions = options != null ? options : defaultOptions;
995
+ if (middleware.get) {
996
+ return middleware.get(binding, resolvedOptions, next);
997
+ }
998
+ return next == null ? void 0 : next.get(binding, resolvedOptions);
999
+ },
1000
+ set: (transaction, options) => {
1001
+ const resolvedOptions = options != null ? options : defaultOptions;
1002
+ if (middleware.set) {
1003
+ return middleware.set(transaction, resolvedOptions, next);
1004
+ }
1005
+ return next == null ? void 0 : next.set(transaction, resolvedOptions);
1006
+ },
1007
+ delete: (binding, options) => {
1008
+ const resolvedOptions = options != null ? options : defaultOptions;
1009
+ if (middleware.delete) {
1010
+ return middleware.delete(binding, resolvedOptions, next);
1011
+ }
1012
+ return next == null ? void 0 : next.delete(binding, resolvedOptions);
1013
+ }
976
1014
  };
977
1015
  }
978
1016
  function constructModelForPipeline(pipeline) {
@@ -980,7 +1018,7 @@ function constructModelForPipeline(pipeline) {
980
1018
  return NOOP_MODEL;
981
1019
  }
982
1020
  if (pipeline.length === 1) {
983
- return pipeline[0];
1021
+ return toModel(pipeline[0]);
984
1022
  }
985
1023
  function createModelWithOptions(options) {
986
1024
  var _a;
@@ -995,6 +1033,10 @@ function constructModelForPipeline(pipeline) {
995
1033
  set: (transaction, options) => {
996
1034
  var _a;
997
1035
  return (_a = createModelWithOptions(options)) == null ? void 0 : _a.set(transaction, options);
1036
+ },
1037
+ delete: (binding, options) => {
1038
+ var _a;
1039
+ return (_a = createModelWithOptions(options)) == null ? void 0 : _a.delete(binding, options);
998
1040
  }
999
1041
  };
1000
1042
  }
@@ -1031,6 +1073,9 @@ class PipelinedDataModel {
1031
1073
  get(binding, options) {
1032
1074
  return this.effectiveDataModel.get(binding, options);
1033
1075
  }
1076
+ delete(binding, options) {
1077
+ return this.effectiveDataModel.delete(binding, options);
1078
+ }
1034
1079
  }
1035
1080
 
1036
1081
  class LocalModel {
@@ -1057,11 +1102,24 @@ class LocalModel {
1057
1102
  });
1058
1103
  return effectiveOperations;
1059
1104
  }
1105
+ delete(binding) {
1106
+ const parentBinding = binding.parent();
1107
+ if (parentBinding) {
1108
+ const parentValue = this.get(parentBinding);
1109
+ if (parentValue !== void 0) {
1110
+ if (Array.isArray(parentValue)) {
1111
+ this.model = Object(timm__WEBPACK_IMPORTED_MODULE_7__["setIn"])(this.model, parentBinding.asArray(), Object(timm__WEBPACK_IMPORTED_MODULE_7__["removeAt"])(parentValue, binding.key()));
1112
+ } else {
1113
+ this.model = Object(timm__WEBPACK_IMPORTED_MODULE_7__["setIn"])(this.model, parentBinding.asArray(), Object(timm__WEBPACK_IMPORTED_MODULE_7__["omit"])(parentValue, binding.key()));
1114
+ }
1115
+ }
1116
+ }
1117
+ }
1060
1118
  }
1061
1119
 
1062
1120
  const ExpNodeOpaqueIdentifier = Symbol("Expression Node ID");
1063
1121
  function isExpressionNode(x) {
1064
- return typeof x === "object" && x.__id === ExpNodeOpaqueIdentifier;
1122
+ return typeof x === "object" && x !== null && !Array.isArray(x) && x.__id === ExpNodeOpaqueIdentifier;
1065
1123
  }
1066
1124
 
1067
1125
  const PERIOD_CODE = 46;
@@ -1688,16 +1746,108 @@ const getDataVal = (_context, binding) => {
1688
1746
  return _context.model.get(binding);
1689
1747
  };
1690
1748
  const deleteDataVal = (_context, binding) => {
1691
- return _context.model.set([[binding, void 0]]);
1749
+ return _context.model.delete(binding);
1692
1750
  };
1751
+ const conditional = (ctx, condition, ifTrue, ifFalse) => {
1752
+ const resolution = ctx.evaluate(condition);
1753
+ if (resolution) {
1754
+ return ctx.evaluate(ifTrue);
1755
+ }
1756
+ if (ifFalse) {
1757
+ return ctx.evaluate(ifFalse);
1758
+ }
1759
+ return null;
1760
+ };
1761
+ conditional.resolveParams = false;
1693
1762
 
1694
1763
  var DEFAULT_EXPRESSION_HANDLERS = /*#__PURE__*/Object.freeze({
1695
1764
  __proto__: null,
1696
1765
  setDataVal: setDataVal,
1697
1766
  getDataVal: getDataVal,
1698
- deleteDataVal: deleteDataVal
1767
+ deleteDataVal: deleteDataVal,
1768
+ conditional: conditional
1699
1769
  });
1700
1770
 
1771
+ function withoutContext(fn) {
1772
+ return (_context, ...args) => fn(...args);
1773
+ }
1774
+ function isInRange(position, location) {
1775
+ return position.character >= location.start.character && position.character <= location.end.character;
1776
+ }
1777
+ function findClosestNodeAtPosition(node, position) {
1778
+ var _a, _b, _c, _d, _e;
1779
+ switch (node.type) {
1780
+ case "Modification":
1781
+ case "Assignment":
1782
+ case "LogicalExpression":
1783
+ case "BinaryExpression": {
1784
+ const check = (_a = findClosestNodeAtPosition(node.left, position)) != null ? _a : findClosestNodeAtPosition(node.right, position);
1785
+ if (check) {
1786
+ return check;
1787
+ }
1788
+ break;
1789
+ }
1790
+ case "UnaryExpression": {
1791
+ const checkArg = findClosestNodeAtPosition(node.argument, position);
1792
+ if (checkArg) {
1793
+ return checkArg;
1794
+ }
1795
+ break;
1796
+ }
1797
+ case "MemberExpression": {
1798
+ const checkObject = (_b = findClosestNodeAtPosition(node.object, position)) != null ? _b : findClosestNodeAtPosition(node.property, position);
1799
+ if (checkObject) {
1800
+ return checkObject;
1801
+ }
1802
+ break;
1803
+ }
1804
+ case "ConditionalExpression": {
1805
+ const checkObject = (_d = (_c = findClosestNodeAtPosition(node.test, position)) != null ? _c : findClosestNodeAtPosition(node.consequent, position)) != null ? _d : findClosestNodeAtPosition(node.alternate, position);
1806
+ if (checkObject) {
1807
+ return checkObject;
1808
+ }
1809
+ break;
1810
+ }
1811
+ case "ArrayExpression":
1812
+ case "Compound": {
1813
+ const elements = node.type === "ArrayExpression" ? node.elements : node.body;
1814
+ const anyElements = elements.find((e) => findClosestNodeAtPosition(e, position));
1815
+ if (anyElements) {
1816
+ return anyElements;
1817
+ }
1818
+ break;
1819
+ }
1820
+ case "Object": {
1821
+ const checkObject = node.attributes.reduce((found, next) => {
1822
+ var _a2;
1823
+ return (_a2 = found != null ? found : findClosestNodeAtPosition(next.key, position)) != null ? _a2 : findClosestNodeAtPosition(next.value, position);
1824
+ }, void 0);
1825
+ if (checkObject) {
1826
+ return checkObject;
1827
+ }
1828
+ break;
1829
+ }
1830
+ case "CallExpression": {
1831
+ const anyArgs = (_e = node.args.find((arg) => {
1832
+ return findClosestNodeAtPosition(arg, position);
1833
+ })) != null ? _e : findClosestNodeAtPosition(node.callTarget, position);
1834
+ if (anyArgs) {
1835
+ return anyArgs;
1836
+ }
1837
+ break;
1838
+ }
1839
+ }
1840
+ if (node.location && isInRange(position, node.location)) {
1841
+ return node;
1842
+ }
1843
+ }
1844
+ function isObjectExpression(expr) {
1845
+ if (isExpressionNode(expr)) {
1846
+ return false;
1847
+ }
1848
+ return typeof expr === "object" && expr !== null && !Array.isArray(expr) && "value" in expr;
1849
+ }
1850
+
1701
1851
  var __defProp$c = Object.defineProperty;
1702
1852
  var __defProps$a = Object.defineProperties;
1703
1853
  var __getOwnPropDescs$a = Object.getOwnPropertyDescriptors;
@@ -1758,6 +1908,8 @@ class ExpressionEvaluator {
1758
1908
  this.vars = {};
1759
1909
  this.hooks = {
1760
1910
  resolve: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"](),
1911
+ resolveOptions: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"](),
1912
+ beforeEvaluate: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"](),
1761
1913
  onError: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncBailHook"]()
1762
1914
  };
1763
1915
  this.expressionsCache = new Map();
@@ -1776,21 +1928,25 @@ class ExpressionEvaluator {
1776
1928
  reset() {
1777
1929
  this.expressionsCache.clear();
1778
1930
  }
1779
- evaluate(expression, options) {
1780
- const opts = __spreadProps$a(__spreadValues$c(__spreadValues$c({}, this.defaultHookOptions), options), {
1781
- resolveNode: (node) => this._execAST(node, opts)
1782
- });
1931
+ evaluate(expr, options) {
1932
+ var _a;
1933
+ const resolvedOpts = this.hooks.resolveOptions.call(__spreadProps$a(__spreadValues$c(__spreadValues$c({}, this.defaultHookOptions), options), {
1934
+ resolveNode: (node) => this._execAST(node, resolvedOpts)
1935
+ }));
1936
+ let expression = (_a = this.hooks.beforeEvaluate.call(expr, resolvedOpts)) != null ? _a : expr;
1937
+ while (isObjectExpression(expression)) {
1938
+ expression = expression.value;
1939
+ }
1783
1940
  if (typeof expression === "number" || typeof expression === "boolean" || expression === void 0 || expression === null) {
1784
1941
  return expression;
1785
1942
  }
1786
1943
  if (isExpressionNode(expression)) {
1787
- return this._execAST(expression, opts);
1944
+ return this._execAST(expression, resolvedOpts);
1788
1945
  }
1789
- if (typeof expression === "object") {
1790
- const values = Array.isArray(expression) ? expression : Object.values(expression);
1791
- return values.reduce((_nothing, exp) => this.evaluate(exp, options), null);
1946
+ if (Array.isArray(expression)) {
1947
+ return expression.reduce((_nothing, exp) => this.evaluate(exp, options), null);
1792
1948
  }
1793
- return this._execString(String(expression), opts);
1949
+ return this._execString(String(expression), resolvedOpts);
1794
1950
  }
1795
1951
  addExpressionFunction(name, handler) {
1796
1952
  this.operators.expressions.set(name, handler);
@@ -1828,7 +1984,7 @@ class ExpressionEvaluator {
1828
1984
  this.expressionsCache.set(matchedExp, expAST);
1829
1985
  return this._execAST(expAST, options);
1830
1986
  } catch (e) {
1831
- if (!this.hooks.onError.call(e)) {
1987
+ if (options.throwErrors || !this.hooks.onError.call(e)) {
1832
1988
  throw e;
1833
1989
  }
1834
1990
  }
@@ -1882,25 +2038,18 @@ class ExpressionEvaluator {
1882
2038
  }
1883
2039
  if (node.type === "CallExpression") {
1884
2040
  const expressionName = node.callTarget.name;
1885
- if (expressionName === "conditional") {
1886
- const condition = resolveNode(node.args[0]);
1887
- if (condition) {
1888
- return resolveNode(node.args[1]);
1889
- }
1890
- if (node.args[2]) {
1891
- return resolveNode(node.args[2]);
1892
- }
1893
- return null;
1894
- }
1895
2041
  const operator = this.operators.expressions.get(expressionName);
1896
2042
  if (!operator) {
1897
2043
  throw new Error(`Unknown expression function: ${expressionName}`);
1898
2044
  }
2045
+ if ("resolveParams" in operator && operator.resolveParams === false) {
2046
+ return operator(expressionContext, ...node.args);
2047
+ }
1899
2048
  const args = node.args.map((n) => resolveNode(n));
1900
2049
  return operator(expressionContext, ...args);
1901
2050
  }
1902
2051
  if (node.type === "ModelRef") {
1903
- return model.get(node.ref);
2052
+ return model.get(node.ref, { context: { model: options.model } });
1904
2053
  }
1905
2054
  if (node.type === "MemberExpression") {
1906
2055
  const obj = resolveNode(node.object);
@@ -1952,80 +2101,6 @@ class ExpressionEvaluator {
1952
2101
  }
1953
2102
  }
1954
2103
 
1955
- function withoutContext(fn) {
1956
- return (_context, ...args) => fn(...args);
1957
- }
1958
- function isInRange(position, location) {
1959
- return position.character >= location.start.character && position.character <= location.end.character;
1960
- }
1961
- function findClosestNodeAtPosition(node, position) {
1962
- var _a, _b, _c, _d, _e;
1963
- switch (node.type) {
1964
- case "Modification":
1965
- case "Assignment":
1966
- case "LogicalExpression":
1967
- case "BinaryExpression": {
1968
- const check = (_a = findClosestNodeAtPosition(node.left, position)) != null ? _a : findClosestNodeAtPosition(node.right, position);
1969
- if (check) {
1970
- return check;
1971
- }
1972
- break;
1973
- }
1974
- case "UnaryExpression": {
1975
- const checkArg = findClosestNodeAtPosition(node.argument, position);
1976
- if (checkArg) {
1977
- return checkArg;
1978
- }
1979
- break;
1980
- }
1981
- case "MemberExpression": {
1982
- const checkObject = (_b = findClosestNodeAtPosition(node.object, position)) != null ? _b : findClosestNodeAtPosition(node.property, position);
1983
- if (checkObject) {
1984
- return checkObject;
1985
- }
1986
- break;
1987
- }
1988
- case "ConditionalExpression": {
1989
- const checkObject = (_d = (_c = findClosestNodeAtPosition(node.test, position)) != null ? _c : findClosestNodeAtPosition(node.consequent, position)) != null ? _d : findClosestNodeAtPosition(node.alternate, position);
1990
- if (checkObject) {
1991
- return checkObject;
1992
- }
1993
- break;
1994
- }
1995
- case "ArrayExpression":
1996
- case "Compound": {
1997
- const elements = node.type === "ArrayExpression" ? node.elements : node.body;
1998
- const anyElements = elements.find((e) => findClosestNodeAtPosition(e, position));
1999
- if (anyElements) {
2000
- return anyElements;
2001
- }
2002
- break;
2003
- }
2004
- case "Object": {
2005
- const checkObject = node.attributes.reduce((found, next) => {
2006
- var _a2;
2007
- return (_a2 = found != null ? found : findClosestNodeAtPosition(next.key, position)) != null ? _a2 : findClosestNodeAtPosition(next.value, position);
2008
- }, void 0);
2009
- if (checkObject) {
2010
- return checkObject;
2011
- }
2012
- break;
2013
- }
2014
- case "CallExpression": {
2015
- const anyArgs = (_e = node.args.find((arg) => {
2016
- return findClosestNodeAtPosition(arg, position);
2017
- })) != null ? _e : findClosestNodeAtPosition(node.callTarget, position);
2018
- if (anyArgs) {
2019
- return anyArgs;
2020
- }
2021
- break;
2022
- }
2023
- }
2024
- if (node.location && isInRange(position, node.location)) {
2025
- return node;
2026
- }
2027
- }
2028
-
2029
2104
  const severities = ["trace", "debug", "info", "warn", "error"];
2030
2105
 
2031
2106
  class ConsoleLogger {
@@ -2353,7 +2428,7 @@ function resolveExpressionsInString(val, { evaluate }) {
2353
2428
  return newVal;
2354
2429
  }
2355
2430
  function resolveDataRefsInString(val, options) {
2356
- const { model } = options;
2431
+ const { model, formatted = true } = options;
2357
2432
  let workingString = resolveExpressionsInString(val, options);
2358
2433
  if (!model || typeof workingString !== "string" || workingString.indexOf(DOUBLE_OPEN_CURLY) === -1) {
2359
2434
  return workingString;
@@ -2365,7 +2440,7 @@ function resolveDataRefsInString(val, options) {
2365
2440
  }
2366
2441
  const { start, end } = expLocation;
2367
2442
  const binding = workingString.substring(start + DOUBLE_OPEN_CURLY.length, end - DOUBLE_OPEN_CURLY.length).trim();
2368
- const evaledVal = model.get(binding, { formatted: true });
2443
+ const evaledVal = model.get(binding, { formatted });
2369
2444
  if (start === 0 && end === workingString.length && typeof evaledVal !== "string") {
2370
2445
  return evaledVal;
2371
2446
  }
@@ -2398,6 +2473,36 @@ function resolveDataRefs(val, options) {
2398
2473
  return traverseObject(val, options);
2399
2474
  }
2400
2475
 
2476
+ function removeBindingAndChildrenFromMap(sourceMap, binding) {
2477
+ const targetMap = new Map(sourceMap);
2478
+ const parentBinding = binding.parent();
2479
+ const property = binding.key();
2480
+ targetMap.forEach((_value, trackedBinding) => {
2481
+ if (binding === trackedBinding || binding.contains(trackedBinding)) {
2482
+ targetMap.delete(trackedBinding);
2483
+ }
2484
+ });
2485
+ if (typeof property === "number") {
2486
+ const bindingsToRewrite = Array.from(sourceMap.keys()).filter((b) => {
2487
+ if (parentBinding.contains(b)) {
2488
+ const [childIndex] = b.relative(parentBinding);
2489
+ return typeof childIndex === "number" && childIndex > property;
2490
+ }
2491
+ return false;
2492
+ }).sort();
2493
+ bindingsToRewrite.forEach((trackedBinding) => {
2494
+ const [childIndex, ...childPath] = trackedBinding.relative(parentBinding);
2495
+ if (typeof childIndex === "number") {
2496
+ const newSegments = [childIndex - 1, ...childPath];
2497
+ const newChildBinding = parentBinding.descendent(newSegments);
2498
+ targetMap.set(newChildBinding, targetMap.get(trackedBinding));
2499
+ targetMap.delete(trackedBinding);
2500
+ }
2501
+ });
2502
+ }
2503
+ return targetMap;
2504
+ }
2505
+
2401
2506
  var __defProp$a = Object.defineProperty;
2402
2507
  var __defProps$8 = Object.defineProperties;
2403
2508
  var __getOwnPropDescs$8 = Object.getOwnPropertyDescriptors;
@@ -2422,12 +2527,15 @@ class ValidationMiddleware {
2422
2527
  this.validator = validator;
2423
2528
  this.shadowModelPaths = new Map();
2424
2529
  this.logger = options == null ? void 0 : options.logger;
2530
+ this.shouldIncludeInvalid = options == null ? void 0 : options.shouldIncludeInvalid;
2425
2531
  }
2426
2532
  set(transaction, options, next) {
2427
2533
  const asModel = toModel(this, __spreadProps$8(__spreadValues$a({}, options), { includeInvalid: true }), next);
2428
2534
  const nextTransaction = [];
2535
+ const includedBindings = new Set();
2429
2536
  transaction.forEach(([binding, value]) => {
2430
2537
  this.shadowModelPaths.set(binding, value);
2538
+ includedBindings.add(binding);
2431
2539
  });
2432
2540
  const invalidBindings = [];
2433
2541
  this.shadowModelPaths.forEach((value, binding) => {
@@ -2442,18 +2550,21 @@ class ValidationMiddleware {
2442
2550
  nextTransaction.push([validation.binding, value]);
2443
2551
  }
2444
2552
  });
2445
- } else {
2553
+ } else if (includedBindings.has(binding)) {
2554
+ invalidBindings.push(binding);
2446
2555
  (_a = this.logger) == null ? void 0 : _a.debug(`Invalid value for path: ${binding.asString()} - ${validations.severity} - ${validations.message}`);
2447
2556
  }
2448
2557
  });
2558
+ let validResults = [];
2449
2559
  if (next && nextTransaction.length > 0) {
2450
2560
  nextTransaction.forEach(([binding]) => this.shadowModelPaths.delete(binding));
2451
2561
  const result = next.set(nextTransaction, options);
2452
2562
  if (invalidBindings.length === 0) {
2453
2563
  return result;
2454
2564
  }
2565
+ validResults = result;
2455
2566
  }
2456
- return invalidBindings.map((binding) => {
2567
+ const invalidResults = invalidBindings.map((binding) => {
2457
2568
  return {
2458
2569
  binding,
2459
2570
  oldValue: asModel.get(binding),
@@ -2461,10 +2572,12 @@ class ValidationMiddleware {
2461
2572
  force: true
2462
2573
  };
2463
2574
  });
2575
+ return [...validResults, ...invalidResults];
2464
2576
  }
2465
2577
  get(binding, options, next) {
2578
+ var _a, _b;
2466
2579
  let val = next == null ? void 0 : next.get(binding, options);
2467
- if ((options == null ? void 0 : options.includeInvalid) === true) {
2580
+ if ((_b = (_a = this.shouldIncludeInvalid) == null ? void 0 : _a.call(this, options)) != null ? _b : (options == null ? void 0 : options.includeInvalid) === true) {
2468
2581
  this.shadowModelPaths.forEach((shadowValue, shadowBinding) => {
2469
2582
  if (shadowBinding === binding) {
2470
2583
  val = shadowValue;
@@ -2477,6 +2590,10 @@ class ValidationMiddleware {
2477
2590
  }
2478
2591
  return val;
2479
2592
  }
2593
+ delete(binding, options, next) {
2594
+ this.shadowModelPaths = removeBindingAndChildrenFromMap(this.shadowModelPaths, binding);
2595
+ return next == null ? void 0 : next.delete(binding, options);
2596
+ }
2480
2597
  }
2481
2598
 
2482
2599
  class ValidatorRegistry {
@@ -2561,6 +2678,9 @@ class Parser {
2561
2678
  }
2562
2679
  return tapped;
2563
2680
  }
2681
+ hasTemplateValues(obj, localKey) {
2682
+ return Object.hasOwnProperty.call(obj, "template") && Array.isArray(obj == null ? void 0 : obj.template) && obj.template.length && obj.template.find((tmpl) => tmpl.output === localKey);
2683
+ }
2564
2684
  parseObject(obj, type = NodeType.Value, options = { templateDepth: 0 }) {
2565
2685
  var _a;
2566
2686
  const nodeType = this.hooks.determineNodeType.call(obj);
@@ -2590,6 +2710,7 @@ class Parser {
2590
2710
  value: currentValue
2591
2711
  };
2592
2712
  const newValue = objEntries.reduce((accumulation, current) => {
2713
+ var _b;
2593
2714
  const _a2 = accumulation, { children: children2 } = _a2, rest = __objRest$1(_a2, ["children"]);
2594
2715
  const [localKey, localValue] = current;
2595
2716
  if (localKey === "asset" && typeof localValue === "object") {
@@ -2607,14 +2728,19 @@ class Parser {
2607
2728
  }
2608
2729
  } else if (this.hooks.determineNodeType.call(localKey) === NodeType.Template && Array.isArray(localValue)) {
2609
2730
  const templateChildren = localValue.map((template) => {
2610
- var _a3, _b;
2731
+ var _a3, _b2;
2611
2732
  const templateAST = this.hooks.onCreateASTNode.call({
2612
2733
  type: NodeType.Template,
2613
2734
  depth: (_a3 = options.templateDepth) != null ? _a3 : 0,
2614
2735
  data: template.data,
2615
2736
  template: template.value,
2616
- dynamic: (_b = template.dynamic) != null ? _b : false
2737
+ dynamic: (_b2 = template.dynamic) != null ? _b2 : false
2617
2738
  }, template);
2739
+ if ((templateAST == null ? void 0 : templateAST.type) === NodeType.MultiNode) {
2740
+ templateAST.values.forEach((v) => {
2741
+ v.parent = templateAST;
2742
+ });
2743
+ }
2618
2744
  if (templateAST) {
2619
2745
  return {
2620
2746
  path: [...path, template.output],
@@ -2628,6 +2754,18 @@ class Parser {
2628
2754
  });
2629
2755
  } else if (localValue && this.hooks.determineNodeType.call(localValue) === NodeType.Switch) {
2630
2756
  const localSwitch = this.hooks.parseNode.call(localValue, NodeType.Value, options, NodeType.Switch);
2757
+ if (localSwitch && localSwitch.type === NodeType.Value && ((_b = localSwitch.children) == null ? void 0 : _b.length) === 1 && localSwitch.value === void 0) {
2758
+ const firstChild = localSwitch.children[0];
2759
+ return __spreadProps$7(__spreadValues$9({}, rest), {
2760
+ children: [
2761
+ ...children2,
2762
+ {
2763
+ path: [...path, localKey, ...firstChild.path],
2764
+ value: firstChild.value
2765
+ }
2766
+ ]
2767
+ });
2768
+ }
2631
2769
  if (localSwitch) {
2632
2770
  return __spreadProps$7(__spreadValues$9({}, rest), {
2633
2771
  children: [
@@ -2644,7 +2782,7 @@ class Parser {
2644
2782
  if (childValues.length > 0) {
2645
2783
  const multiNode = this.hooks.onCreateASTNode.call({
2646
2784
  type: NodeType.MultiNode,
2647
- override: true,
2785
+ override: !this.hasTemplateValues(localObj, localKey),
2648
2786
  values: childValues
2649
2787
  }, localValue);
2650
2788
  if ((multiNode == null ? void 0 : multiNode.type) === NodeType.MultiNode) {
@@ -2667,7 +2805,7 @@ class Parser {
2667
2805
  } else if (localValue && typeof localValue === "object") {
2668
2806
  const determineNodeType = this.hooks.determineNodeType.call(localValue);
2669
2807
  if (determineNodeType === NodeType.Applicability) {
2670
- const parsedNode = this.hooks.parseNode.call(localValue, type, options, determineNodeType);
2808
+ const parsedNode = this.hooks.parseNode.call(localValue, NodeType.Value, options, determineNodeType);
2671
2809
  if (parsedNode) {
2672
2810
  return __spreadProps$7(__spreadValues$9({}, rest), {
2673
2811
  children: [
@@ -2789,6 +2927,11 @@ const withContext = (model) => {
2789
2927
  return model.set(transaction, __spreadValues$7({
2790
2928
  context: { model }
2791
2929
  }, options));
2930
+ },
2931
+ delete: (binding, options) => {
2932
+ return model.delete(binding, __spreadValues$7({
2933
+ context: { model }
2934
+ }, options));
2792
2935
  }
2793
2936
  };
2794
2937
  };
@@ -2818,12 +2961,16 @@ class Resolver {
2818
2961
  this.hooks.beforeUpdate.call(changes);
2819
2962
  const resolveCache = new Map();
2820
2963
  this.idCache.clear();
2964
+ const prevASTMap = new Map(this.ASTMap);
2821
2965
  this.ASTMap.clear();
2822
- const updated = this.computeTree(this.root, void 0, changes, resolveCache, toNodeResolveOptions(this.options));
2966
+ const updated = this.computeTree(this.root, void 0, changes, resolveCache, toNodeResolveOptions(this.options), void 0, prevASTMap);
2823
2967
  this.resolveCache = resolveCache;
2824
2968
  this.hooks.afterUpdate.call(updated.value);
2825
2969
  return updated.value;
2826
2970
  }
2971
+ getResolveCache() {
2972
+ return new Map(this.resolveCache);
2973
+ }
2827
2974
  getNodeID(node) {
2828
2975
  var _a;
2829
2976
  if (!node) {
@@ -2855,7 +3002,19 @@ class Resolver {
2855
3002
  }
2856
3003
  return this.resolveCache.get(node);
2857
3004
  }
2858
- computeTree(node, parent, dataChanges, cacheUpdate, options) {
3005
+ cloneNode(node) {
3006
+ const clonedNode = Object(timm__WEBPACK_IMPORTED_MODULE_7__["clone"])(node);
3007
+ Object.keys(clonedNode).forEach((key) => {
3008
+ if (key === "parent")
3009
+ return;
3010
+ const value = clonedNode[key];
3011
+ if (typeof value === "object" && value !== null) {
3012
+ clonedNode[key] = Array.isArray(value) ? [...value] : __spreadValues$7({}, value);
3013
+ }
3014
+ });
3015
+ return clonedNode;
3016
+ }
3017
+ computeTree(node, parent, dataChanges, cacheUpdate, options, parentNode, prevASTMap) {
2859
3018
  var _a, _b;
2860
3019
  const dependencyModel = new DependencyModel(options.data.model);
2861
3020
  dependencyModel.trackSubset("core");
@@ -2876,34 +3035,40 @@ class Resolver {
2876
3035
  updated: false
2877
3036
  });
2878
3037
  cacheUpdate.set(node, update2);
2879
- const repopulateASTMapFromCache = (resolvedAST3, AST) => {
3038
+ const repopulateASTMapFromCache = (resolvedNode, AST, ASTParent) => {
2880
3039
  var _a2;
2881
- this.ASTMap.set(resolvedAST3, AST);
2882
- if ("children" in resolvedAST3) {
2883
- (_a2 = resolvedAST3.children) == null ? void 0 : _a2.forEach(({ value: childAST }) => {
2884
- const { node: childResolvedAST } = this.getPreviousResult(childAST) || {};
2885
- if (!childResolvedAST)
2886
- return;
2887
- repopulateASTMapFromCache(childResolvedAST, childAST);
2888
- if (childResolvedAST.type === NodeType.MultiNode) {
2889
- childResolvedAST.values.forEach((mChildAST) => {
2890
- const { node: mChildResolvedAST } = this.getPreviousResult(mChildAST) || {};
2891
- if (!mChildResolvedAST)
2892
- return;
2893
- repopulateASTMapFromCache(mChildResolvedAST, mChildAST);
2894
- });
2895
- }
2896
- });
3040
+ const { node: resolvedAST2 } = resolvedNode;
3041
+ this.ASTMap.set(resolvedAST2, AST);
3042
+ const resolvedUpdate = __spreadProps$5(__spreadValues$7({}, resolvedNode), {
3043
+ updated: false
3044
+ });
3045
+ cacheUpdate.set(AST, resolvedUpdate);
3046
+ const handleChildNode = (childNode) => {
3047
+ var _a3;
3048
+ const originalChildNode = (_a3 = prevASTMap.get(childNode)) != null ? _a3 : childNode;
3049
+ const previousChildResult = this.getPreviousResult(originalChildNode);
3050
+ if (!previousChildResult)
3051
+ return;
3052
+ repopulateASTMapFromCache(previousChildResult, originalChildNode, AST);
3053
+ };
3054
+ if ("children" in resolvedAST2) {
3055
+ (_a2 = resolvedAST2.children) == null ? void 0 : _a2.forEach(({ value: childAST }) => handleChildNode(childAST));
3056
+ } else if (resolvedAST2.type === NodeType.MultiNode) {
3057
+ resolvedAST2.values.forEach(handleChildNode);
2897
3058
  }
3059
+ this.hooks.afterNodeUpdate.call(AST, ASTParent, resolvedUpdate);
2898
3060
  };
2899
- const resolvedAST2 = previousResult.node;
2900
- repopulateASTMapFromCache(resolvedAST2, node);
2901
- this.hooks.afterNodeUpdate.call(node, parent, update2);
3061
+ previousResult.node.parent = parentNode;
3062
+ repopulateASTMapFromCache(previousResult, node, parent);
2902
3063
  return update2;
2903
3064
  }
2904
- const resolvedAST = (_a = this.hooks.beforeResolve.call(node, resolveOptions)) != null ? _a : {
3065
+ const clonedNode = __spreadProps$5(__spreadValues$7({}, this.cloneNode(node)), {
3066
+ parent: parentNode
3067
+ });
3068
+ const resolvedAST = (_a = this.hooks.beforeResolve.call(clonedNode, resolveOptions)) != null ? _a : {
2905
3069
  type: NodeType.Empty
2906
3070
  };
3071
+ resolvedAST.parent = parentNode;
2907
3072
  resolveOptions.node = resolvedAST;
2908
3073
  this.ASTMap.set(resolvedAST, node);
2909
3074
  let resolved = this.hooks.resolve.call(void 0, resolvedAST, resolveOptions);
@@ -2914,22 +3079,15 @@ class Resolver {
2914
3079
  const childDependencies = new Set();
2915
3080
  dependencyModel.trackSubset("children");
2916
3081
  if ("children" in resolvedAST) {
2917
- (_b = resolvedAST.children) == null ? void 0 : _b.forEach((child) => {
2918
- const computedChildTree = this.computeTree(child.value, node, dataChanges, cacheUpdate, resolveOptions);
2919
- let { updated: childUpdated, value: childValue } = computedChildTree;
2920
- const { node: childNode, dependencies: childTreeDeps } = computedChildTree;
3082
+ const newChildren = (_b = resolvedAST.children) == null ? void 0 : _b.map((child) => {
3083
+ const computedChildTree = this.computeTree(child.value, node, dataChanges, cacheUpdate, resolveOptions, resolvedAST, prevASTMap);
3084
+ const {
3085
+ dependencies: childTreeDeps,
3086
+ node: childNode,
3087
+ updated: childUpdated,
3088
+ value: childValue
3089
+ } = computedChildTree;
2921
3090
  childTreeDeps.forEach((binding) => childDependencies.add(binding));
2922
- if (childNode.type === NodeType.MultiNode) {
2923
- childValue = [];
2924
- childNode.values.forEach((mValue) => {
2925
- const mTree = this.computeTree(mValue, node, dataChanges, cacheUpdate, resolveOptions);
2926
- if (mTree.value !== void 0 && mTree.value !== null) {
2927
- childValue.push(mTree.value);
2928
- }
2929
- mTree.dependencies.forEach((bindingDep) => childDependencies.add(bindingDep));
2930
- childUpdated = childUpdated || mTree.updated;
2931
- });
2932
- }
2933
3091
  if (childValue) {
2934
3092
  if (childNode.type === NodeType.MultiNode && !childNode.override) {
2935
3093
  const arr = Object(timm__WEBPACK_IMPORTED_MODULE_7__["addLast"])(dlv__WEBPACK_IMPORTED_MODULE_6___default()(resolved, child.path, []), childValue);
@@ -2939,7 +3097,22 @@ class Resolver {
2939
3097
  }
2940
3098
  }
2941
3099
  updated = updated || childUpdated;
3100
+ return __spreadProps$5(__spreadValues$7({}, child), { value: childNode });
2942
3101
  });
3102
+ resolvedAST.children = newChildren;
3103
+ } else if (resolvedAST.type === NodeType.MultiNode) {
3104
+ const childValue = [];
3105
+ const newValues = resolvedAST.values.map((mValue) => {
3106
+ const mTree = this.computeTree(mValue, node, dataChanges, cacheUpdate, resolveOptions, resolvedAST, prevASTMap);
3107
+ if (mTree.value !== void 0 && mTree.value !== null) {
3108
+ childValue.push(mTree.value);
3109
+ }
3110
+ mTree.dependencies.forEach((bindingDep) => childDependencies.add(bindingDep));
3111
+ updated = updated || mTree.updated;
3112
+ return mTree.node;
3113
+ });
3114
+ resolvedAST.values = newValues;
3115
+ resolved = childValue;
2943
3116
  }
2944
3117
  childDependencies.forEach((bindingDep) => dependencyModel.addChildReadDep(bindingDep));
2945
3118
  dependencyModel.trackSubset("core");
@@ -3008,13 +3181,10 @@ class TemplatePlugin {
3008
3181
  }
3009
3182
  });
3010
3183
  const result = {
3011
- parent: node.parent,
3012
3184
  type: NodeType.MultiNode,
3185
+ override: false,
3013
3186
  values
3014
3187
  };
3015
- result.values.forEach((innerNode) => {
3016
- innerNode.parent = result;
3017
- });
3018
3188
  return result;
3019
3189
  }
3020
3190
  applyParser(parser) {
@@ -3108,19 +3278,20 @@ function resolveAllRefs(node, resolveOptions, propertiesToSkip) {
3108
3278
  });
3109
3279
  return newNode;
3110
3280
  }
3111
- const findBasePath = (node) => {
3281
+ const findBasePath = (node, resolver) => {
3112
3282
  var _a, _b, _c;
3113
3283
  const parentNode = node.parent;
3114
3284
  if (!parentNode) {
3115
3285
  return [];
3116
3286
  }
3117
3287
  if ("children" in parentNode) {
3118
- return (_c = (_b = (_a = parentNode.children) == null ? void 0 : _a.find((child) => child.value === node)) == null ? void 0 : _b.path) != null ? _c : [];
3288
+ const original = resolver.getSourceNode(node);
3289
+ return (_c = (_b = (_a = parentNode.children) == null ? void 0 : _a.find((child) => child.value === original)) == null ? void 0 : _b.path) != null ? _c : [];
3119
3290
  }
3120
3291
  if (parentNode.type !== NodeType.MultiNode) {
3121
3292
  return [];
3122
3293
  }
3123
- return findBasePath(parentNode);
3294
+ return findBasePath(parentNode, resolver);
3124
3295
  };
3125
3296
  class StringResolverPlugin {
3126
3297
  constructor() {
@@ -3144,7 +3315,7 @@ class StringResolverPlugin {
3144
3315
  } else {
3145
3316
  propsToSkip = new Set(["exp"]);
3146
3317
  }
3147
- const nodePath = findBasePath(node);
3318
+ const nodePath = findBasePath(node, resolver);
3148
3319
  if (nodePath.length > 0 && nodePath.some((segment) => propsToSkip.has(segment.toString()))) {
3149
3320
  return node.value;
3150
3321
  }
@@ -3164,7 +3335,7 @@ class ApplicabilityPlugin {
3164
3335
  let newNode = node;
3165
3336
  if ((node == null ? void 0 : node.type) === NodeType.Applicability) {
3166
3337
  const isApplicable = options.evaluate(node.expression);
3167
- if (!isApplicable) {
3338
+ if (isApplicable === false) {
3168
3339
  return null;
3169
3340
  }
3170
3341
  newNode = node.value;
@@ -3470,7 +3641,8 @@ class FlowInstance {
3470
3641
  skipTransition: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncBailHook"](),
3471
3642
  beforeTransition: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"](),
3472
3643
  resolveTransitionNode: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"](),
3473
- transition: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncHook"]()
3644
+ transition: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncHook"](),
3645
+ afterTransition: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncHook"]()
3474
3646
  };
3475
3647
  this.id = id;
3476
3648
  this.flow = flow;
@@ -3517,7 +3689,7 @@ class FlowInstance {
3517
3689
  } else {
3518
3690
  const skipTransition = this.hooks.skipTransition.call(this.currentState);
3519
3691
  if (skipTransition) {
3520
- (_d = this.log) == null ? void 0 : _d.debug(`Skipping transition from ${this.currentState} b/c hook told us to`);
3692
+ (_d = this.log) == null ? void 0 : _d.debug(`Skipping transition from ${this.currentState.name} b/c hook told us to`);
3521
3693
  return;
3522
3694
  }
3523
3695
  }
@@ -3556,6 +3728,7 @@ class FlowInstance {
3556
3728
  this.hooks.onEnd.call(this.flow.onEnd);
3557
3729
  }
3558
3730
  this.hooks.transition.call(prevState, __spreadValues$5({}, newCurrentState));
3731
+ this.hooks.afterTransition.call(this);
3559
3732
  }
3560
3733
  }
3561
3734
 
@@ -3590,6 +3763,7 @@ class FlowController {
3590
3763
  this.start = this.start.bind(this);
3591
3764
  this.run = this.run.bind(this);
3592
3765
  this.transition = this.transition.bind(this);
3766
+ this.addNewFlow = this.addNewFlow.bind(this);
3593
3767
  }
3594
3768
  transition(stateTransition, options) {
3595
3769
  if (this.current === void 0) {
@@ -3598,20 +3772,9 @@ class FlowController {
3598
3772
  this.current.transition(stateTransition, options);
3599
3773
  }
3600
3774
  addNewFlow(flow) {
3601
- return __async$1(this, null, function* () {
3602
- this.navStack.push(flow);
3603
- this.current = flow;
3604
- flow.hooks.transition.tap("flow-controller", (_oldState, newState) => __async$1(this, null, function* () {
3605
- var _a, _b;
3606
- if (newState.value.state_type === "FLOW") {
3607
- (_a = this.log) == null ? void 0 : _a.debug(`Got FLOW state. Loading flow ${newState.value.ref}`);
3608
- const endState = yield this.run(newState.value.ref);
3609
- (_b = this.log) == null ? void 0 : _b.debug(`Flow ended. Using outcome: ${endState.outcome}`);
3610
- flow.transition(endState.outcome);
3611
- }
3612
- }));
3613
- this.hooks.flow.call(flow);
3614
- });
3775
+ this.navStack.push(flow);
3776
+ this.current = flow;
3777
+ this.hooks.flow.call(flow);
3615
3778
  }
3616
3779
  run(startState) {
3617
3780
  return __async$1(this, null, function* () {
@@ -3626,6 +3789,18 @@ class FlowController {
3626
3789
  (_a = this.log) == null ? void 0 : _a.debug(`Starting flow: ${startState}`);
3627
3790
  const flow = new FlowInstance(startState, startFlow, { logger: this.log });
3628
3791
  this.addNewFlow(flow);
3792
+ flow.hooks.afterTransition.tap("flow-controller", (flowInstance) => {
3793
+ var _a2, _b, _c;
3794
+ if (((_a2 = flowInstance.currentState) == null ? void 0 : _a2.value.state_type) === "FLOW") {
3795
+ const subflowId = (_b = flowInstance.currentState) == null ? void 0 : _b.value.ref;
3796
+ (_c = this.log) == null ? void 0 : _c.debug(`Loading subflow ${subflowId}`);
3797
+ this.run(subflowId).then((subFlowEndState) => {
3798
+ var _a3;
3799
+ (_a3 = this.log) == null ? void 0 : _a3.debug(`Subflow ended. Using outcome: ${subFlowEndState.outcome}`);
3800
+ flowInstance.transition(subFlowEndState == null ? void 0 : subFlowEndState.outcome);
3801
+ });
3802
+ }
3803
+ });
3629
3804
  const end = yield flow.start();
3630
3805
  this.navStack.pop();
3631
3806
  if (this.navStack.length > 0) {
@@ -3678,11 +3853,18 @@ class ValidationBindingTrackerViewPlugin {
3678
3853
  getBindings() {
3679
3854
  return this.trackedBindings;
3680
3855
  }
3856
+ trackBinding(binding) {
3857
+ var _a, _b;
3858
+ if (this.trackedBindings.has(binding)) {
3859
+ return;
3860
+ }
3861
+ this.trackedBindings.add(binding);
3862
+ (_b = (_a = this.options.callbacks) == null ? void 0 : _a.onAdd) == null ? void 0 : _b.call(_a, binding);
3863
+ }
3681
3864
  applyResolver(resolver) {
3682
3865
  this.trackedBindings.clear();
3683
3866
  const tracked = new Map();
3684
3867
  const sections = new Map();
3685
- const seenBindings = new Set();
3686
3868
  let lastViewUpdateChangeSet;
3687
3869
  const nodeTree = new Map();
3688
3870
  let lastComputedBindingTree = new Map();
@@ -3729,31 +3911,34 @@ class ValidationBindingTrackerViewPlugin {
3729
3911
  parent = parent.parent;
3730
3912
  }
3731
3913
  }
3732
- if (!seenBindings.has(parsed)) {
3733
- seenBindings.add(parsed);
3734
- (_d = (_c = this.options.callbacks) == null ? void 0 : _c.onAdd) == null ? void 0 : _d.call(_c, parsed);
3735
- }
3914
+ this.trackedBindings.add(parsed);
3915
+ (_d = (_c = this.options.callbacks) == null ? void 0 : _c.onAdd) == null ? void 0 : _d.call(_c, parsed);
3736
3916
  };
3737
3917
  return __spreadProps$3(__spreadValues$4({}, options), {
3738
3918
  validation: __spreadProps$3(__spreadValues$4({}, options.validation), {
3739
3919
  get: (binding, getOptions) => {
3740
- var _a;
3920
+ var _a, _b;
3741
3921
  if (getOptions == null ? void 0 : getOptions.track) {
3742
3922
  track(binding);
3743
3923
  }
3744
- const eow = (_a = options.validation) == null ? void 0 : _a._getValidationForBinding(binding);
3745
- if ((eow == null ? void 0 : eow.displayTarget) === void 0 || (eow == null ? void 0 : eow.displayTarget) === "field") {
3746
- return eow;
3924
+ const eows = (_b = (_a = options.validation) == null ? void 0 : _a._getValidationForBinding(binding)) == null ? void 0 : _b.getAll(getOptions);
3925
+ const firstFieldEOW = eows == null ? void 0 : eows.find((eow) => eow.displayTarget === "field" || eow.displayTarget === void 0);
3926
+ return firstFieldEOW;
3927
+ },
3928
+ getValidationsForBinding(binding, getOptions) {
3929
+ var _a, _b, _c;
3930
+ if (getOptions == null ? void 0 : getOptions.track) {
3931
+ track(binding);
3747
3932
  }
3748
- return void 0;
3933
+ return (_c = (_b = (_a = options.validation) == null ? void 0 : _a._getValidationForBinding(binding)) == null ? void 0 : _b.getAll(getOptions)) != null ? _c : [];
3749
3934
  },
3750
3935
  getChildren: (type) => {
3751
3936
  var _a;
3752
3937
  const validations = new Array();
3753
3938
  (_a = lastComputedBindingTree.get(node)) == null ? void 0 : _a.forEach((binding) => {
3754
- var _a2;
3755
- const eow = (_a2 = options.validation) == null ? void 0 : _a2._getValidationForBinding(binding);
3756
- if (eow && type === eow.displayTarget) {
3939
+ var _a2, _b;
3940
+ const eow = (_b = (_a2 = options.validation) == null ? void 0 : _a2._getValidationForBinding(binding)) == null ? void 0 : _b.get();
3941
+ if (eow && (type === void 0 || type === eow.displayTarget)) {
3757
3942
  validations.push(eow);
3758
3943
  }
3759
3944
  });
@@ -3763,8 +3948,8 @@ class ValidationBindingTrackerViewPlugin {
3763
3948
  var _a;
3764
3949
  const validations = new Array();
3765
3950
  (_a = lastSectionBindingTree.get(node)) == null ? void 0 : _a.forEach((binding) => {
3766
- var _a2;
3767
- const eow = (_a2 = options.validation) == null ? void 0 : _a2._getValidationForBinding(binding);
3951
+ var _a2, _b;
3952
+ const eow = (_b = (_a2 = options.validation) == null ? void 0 : _a2._getValidationForBinding(binding)) == null ? void 0 : _b.get();
3768
3953
  if (eow && eow.displayTarget === "section") {
3769
3954
  validations.push(eow);
3770
3955
  }
@@ -3783,7 +3968,7 @@ class ValidationBindingTrackerViewPlugin {
3783
3968
  });
3784
3969
  });
3785
3970
  resolver.hooks.afterNodeUpdate.tap(CONTEXT, (node, parent, update) => {
3786
- var _a, _b, _c;
3971
+ var _a, _b;
3787
3972
  if (parent) {
3788
3973
  addToTree(node, parent);
3789
3974
  }
@@ -3798,7 +3983,7 @@ class ValidationBindingTrackerViewPlugin {
3798
3983
  currentBindingTree.set(node, (_b = lastComputedBindingTree.get(node)) != null ? _b : new Set());
3799
3984
  }
3800
3985
  if (node === resolver.root) {
3801
- this.trackedBindings = (_c = currentBindingTree.get(node)) != null ? _c : new Set();
3986
+ this.trackedBindings = new Set(currentBindingTree.get(node));
3802
3987
  lastComputedBindingTree = currentBindingTree;
3803
3988
  lastSectionBindingTree.clear();
3804
3989
  sections.forEach((nodeSet, sectionNode) => {
@@ -3840,11 +4025,15 @@ var __spreadValues$3 = (a, b) => {
3840
4025
  return a;
3841
4026
  };
3842
4027
  var __spreadProps$2 = (a, b) => __defProps$2(a, __getOwnPropDescs$2(b));
4028
+ const SCHEMA_VALIDATION_PROVIDER_NAME = "schema";
4029
+ const VIEW_VALIDATION_PROVIDER_NAME = "view";
4030
+ const VALIDATION_PROVIDER_NAME_SYMBOL = Symbol.for("validation-provider-name");
3843
4031
  function createStatefulValidationObject(obj) {
3844
4032
  return {
3845
4033
  value: obj,
3846
4034
  type: obj.severity,
3847
- state: "none"
4035
+ state: "none",
4036
+ isBlockingNavigation: false
3848
4037
  };
3849
4038
  }
3850
4039
  class ValidatedBinding {
@@ -3859,20 +4048,45 @@ class ValidatedBinding {
3859
4048
  possibleValidations.forEach((vObj) => {
3860
4049
  const { trigger } = vObj;
3861
4050
  if (this.validationsByState[trigger]) {
3862
- this.validationsByState[trigger].push(createStatefulValidationObject(vObj));
4051
+ const statefulValidationObject = createStatefulValidationObject(vObj);
4052
+ this.validationsByState[trigger].push(statefulValidationObject);
3863
4053
  } else {
3864
4054
  log == null ? void 0 : log.warn(`Unknown validation trigger: ${trigger}`);
3865
4055
  }
3866
4056
  });
3867
4057
  this.weakBindings = weakBindings != null ? weakBindings : new Set();
3868
4058
  }
4059
+ get allValidations() {
4060
+ return Object.values(this.validationsByState).flat();
4061
+ }
4062
+ checkIfBlocking(statefulObj) {
4063
+ if (statefulObj.state === "active") {
4064
+ const { isBlockingNavigation } = statefulObj;
4065
+ return isBlockingNavigation;
4066
+ }
4067
+ return false;
4068
+ }
4069
+ getAll() {
4070
+ return this.applicableValidations.reduce((all, statefulObj) => {
4071
+ if (statefulObj.state === "active" && statefulObj.response) {
4072
+ return [
4073
+ ...all,
4074
+ __spreadProps$2(__spreadValues$3({}, statefulObj.response), {
4075
+ blocking: this.checkIfBlocking(statefulObj)
4076
+ })
4077
+ ];
4078
+ }
4079
+ return all;
4080
+ }, []);
4081
+ }
3869
4082
  get() {
3870
- const firstError = this.applicableValidations.find((statefulObj) => {
3871
- const blocking = this.currentPhase === "navigation" ? statefulObj.value.blocking : true;
3872
- return statefulObj.state === "active" && blocking !== false;
4083
+ const firstInvalid = this.applicableValidations.find((statefulObj) => {
4084
+ return statefulObj.state === "active" && statefulObj.response;
3873
4085
  });
3874
- if ((firstError == null ? void 0 : firstError.state) === "active") {
3875
- return firstError.response;
4086
+ if ((firstInvalid == null ? void 0 : firstInvalid.state) === "active") {
4087
+ return __spreadProps$2(__spreadValues$3({}, firstInvalid.response), {
4088
+ blocking: this.checkIfBlocking(firstInvalid)
4089
+ });
3876
4090
  }
3877
4091
  }
3878
4092
  runApplicableValidations(runner, canDismiss) {
@@ -3881,7 +4095,8 @@ class ValidatedBinding {
3881
4095
  if (obj.state === "dismissed") {
3882
4096
  return obj;
3883
4097
  }
3884
- const blocking = (_a = obj.value.blocking) != null ? _a : obj.value.severity === "warning" && "once" || obj.value.severity === "error" && true;
4098
+ const blocking = (_a = obj.value.blocking) != null ? _a : obj.value.severity === "warning" && "once" || true;
4099
+ const isBlockingNavigation = blocking === true || blocking === "once" && !canDismiss;
3885
4100
  const dismissable = canDismiss && blocking === "once";
3886
4101
  if (this.currentPhase === "navigation" && obj.state === "active" && dismissable) {
3887
4102
  if (obj.value.severity === "warning") {
@@ -3893,17 +4108,13 @@ class ValidatedBinding {
3893
4108
  }
3894
4109
  return obj;
3895
4110
  }
3896
- if (obj.value.severity === "error") {
3897
- const err = obj;
3898
- err.state = "none";
3899
- return obj;
3900
- }
3901
4111
  }
3902
4112
  const response = runner(obj.value);
3903
4113
  const newState = {
3904
4114
  type: obj.type,
3905
4115
  value: obj.value,
3906
4116
  state: response ? "active" : "none",
4117
+ isBlockingNavigation,
3907
4118
  dismissable: obj.value.severity === "warning" && this.currentPhase === "navigation",
3908
4119
  response: response ? __spreadProps$2(__spreadValues$3({}, obj.value), {
3909
4120
  message: (_b = response.message) != null ? _b : "Something is broken",
@@ -3954,20 +4165,34 @@ class ValidationController {
3954
4165
  this.hooks = {
3955
4166
  createValidatorRegistry: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncHook"](),
3956
4167
  onAddValidation: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"](),
3957
- onRemoveValidation: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"]()
4168
+ onRemoveValidation: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"](),
4169
+ resolveValidationProviders: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncWaterfallHook"](),
4170
+ onTrackBinding: new tapable_ts__WEBPACK_IMPORTED_MODULE_1__["SyncHook"]()
3958
4171
  };
3959
4172
  this.validations = new Map();
3960
4173
  this.weakBindingTracker = new Set();
3961
- this.lastActiveBindings = new Set();
3962
4174
  this.schema = schema;
3963
4175
  this.options = options;
3964
- this.providers = [schema];
4176
+ this.reset();
3965
4177
  }
3966
4178
  setOptions(options) {
3967
4179
  this.options = options;
3968
4180
  }
3969
4181
  getDataMiddleware() {
3970
4182
  return [
4183
+ {
4184
+ set: (transaction, options, next) => {
4185
+ var _a;
4186
+ return (_a = next == null ? void 0 : next.set(transaction, options)) != null ? _a : [];
4187
+ },
4188
+ get: (binding, options, next) => {
4189
+ return next == null ? void 0 : next.get(binding, options);
4190
+ },
4191
+ delete: (binding, options, next) => {
4192
+ this.validations = removeBindingAndChildrenFromMap(this.validations, binding);
4193
+ return next == null ? void 0 : next.delete(binding, options);
4194
+ }
4195
+ },
3971
4196
  new ValidationMiddleware((binding) => {
3972
4197
  var _a;
3973
4198
  if (!this.options) {
@@ -3983,13 +4208,17 @@ class ValidationController {
3983
4208
  var _a2;
3984
4209
  if (caresAboutDataChanges(new Set([binding]), weakValidation.weakBindings) && ((_a2 = weakValidation == null ? void 0 : weakValidation.get()) == null ? void 0 : _a2.severity) === "error") {
3985
4210
  weakValidation == null ? void 0 : weakValidation.weakBindings.forEach((weakBinding) => {
3986
- weakBinding === strongBinding ? newInvalidBindings.add({
3987
- binding: weakBinding,
3988
- isStrong: true
3989
- }) : newInvalidBindings.add({
3990
- binding: weakBinding,
3991
- isStrong: false
3992
- });
4211
+ if (weakBinding === strongBinding) {
4212
+ newInvalidBindings.add({
4213
+ binding: weakBinding,
4214
+ isStrong: true
4215
+ });
4216
+ } else {
4217
+ newInvalidBindings.add({
4218
+ binding: weakBinding,
4219
+ isStrong: false
4220
+ });
4221
+ }
3993
4222
  });
3994
4223
  }
3995
4224
  });
@@ -4002,6 +4231,35 @@ class ValidationController {
4002
4231
  }) })
4003
4232
  ];
4004
4233
  }
4234
+ getValidationProviders() {
4235
+ if (this.providers) {
4236
+ return this.providers;
4237
+ }
4238
+ this.providers = this.hooks.resolveValidationProviders.call([
4239
+ {
4240
+ source: SCHEMA_VALIDATION_PROVIDER_NAME,
4241
+ provider: this.schema
4242
+ },
4243
+ {
4244
+ source: VIEW_VALIDATION_PROVIDER_NAME,
4245
+ provider: {
4246
+ getValidationsForBinding: (binding) => {
4247
+ var _a, _b;
4248
+ return (_b = (_a = this.viewValidationProvider) == null ? void 0 : _a.getValidationsForBinding) == null ? void 0 : _b.call(_a, binding);
4249
+ },
4250
+ getValidationsForView: () => {
4251
+ var _a, _b;
4252
+ return (_b = (_a = this.viewValidationProvider) == null ? void 0 : _a.getValidationsForView) == null ? void 0 : _b.call(_a);
4253
+ }
4254
+ }
4255
+ }
4256
+ ]);
4257
+ return this.providers;
4258
+ }
4259
+ reset() {
4260
+ this.validations.clear();
4261
+ this.tracker = void 0;
4262
+ }
4005
4263
  onView(view) {
4006
4264
  this.validations.clear();
4007
4265
  if (!this.options) {
@@ -4010,7 +4268,7 @@ class ValidationController {
4010
4268
  const bindingTrackerPlugin = new ValidationBindingTrackerViewPlugin(__spreadProps$2(__spreadValues$3({}, this.options), {
4011
4269
  callbacks: {
4012
4270
  onAdd: (binding) => {
4013
- if (!this.options) {
4271
+ if (!this.options || this.getValidationForBinding(binding) !== void 0) {
4014
4272
  return;
4015
4273
  }
4016
4274
  const originalValue = this.options.model.get(binding);
@@ -4025,21 +4283,28 @@ class ValidationController {
4025
4283
  this.updateValidationsForBinding(binding, "load", this.options, () => {
4026
4284
  view.update(new Set([binding]));
4027
4285
  });
4286
+ this.hooks.onTrackBinding.call(binding);
4028
4287
  }
4029
4288
  }
4030
4289
  }));
4031
4290
  this.tracker = bindingTrackerPlugin;
4032
- this.providers = [this.schema, view];
4291
+ this.viewValidationProvider = view;
4033
4292
  bindingTrackerPlugin.apply(view);
4034
4293
  }
4035
- updateValidationsForBinding(binding, trigger, context, onDismiss) {
4294
+ updateValidationsForBinding(binding, trigger, validationContext, onDismiss) {
4036
4295
  var _a;
4296
+ const context = validationContext != null ? validationContext : this.options;
4297
+ if (!context) {
4298
+ throw new Error(`Context is required for executing validations`);
4299
+ }
4037
4300
  if (trigger === "load") {
4038
- const possibleValidations = this.providers.reduce((vals, provider) => {
4039
- var _a2, _b;
4301
+ const possibleValidations = this.getValidationProviders().reduce((vals, provider) => {
4302
+ var _a2, _b, _c, _d;
4040
4303
  return [
4041
4304
  ...vals,
4042
- ...(_b = (_a2 = provider.getValidationsForBinding) == null ? void 0 : _a2.call(provider, binding)) != null ? _b : []
4305
+ ...(_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), {
4306
+ [VALIDATION_PROVIDER_NAME_SYMBOL]: provider.source
4307
+ }))) != null ? _d : []
4043
4308
  ];
4044
4309
  }, []);
4045
4310
  if (possibleValidations.length === 0) {
@@ -4049,7 +4314,7 @@ class ValidationController {
4049
4314
  }
4050
4315
  const trackedValidations = this.validations.get(binding);
4051
4316
  trackedValidations == null ? void 0 : trackedValidations.update(trigger, true, (validationObj) => {
4052
- const response = this.validationRunner(validationObj, context, binding);
4317
+ const response = this.validationRunner(validationObj, binding, context);
4053
4318
  if (this.weakBindingTracker.size > 0) {
4054
4319
  const t = this.validations.get(binding);
4055
4320
  this.weakBindingTracker.forEach((b) => t.weakBindings.add(b));
@@ -4060,27 +4325,33 @@ class ValidationController {
4060
4325
  this.validations.forEach((validation, vBinding) => {
4061
4326
  if (vBinding !== binding && caresAboutDataChanges(new Set([binding]), validation.weakBindings)) {
4062
4327
  validation.update(trigger, true, (validationObj) => {
4063
- const response = this.validationRunner(validationObj, context, vBinding);
4328
+ const response = this.validationRunner(validationObj, vBinding, context);
4064
4329
  return response ? { message: response.message } : void 0;
4065
4330
  });
4066
4331
  }
4067
4332
  });
4068
4333
  }
4069
4334
  }
4070
- validationRunner(validationObj, context, binding) {
4071
- const handler = this.getValidator(validationObj.type);
4335
+ validationRunner(validationObj, binding, context = this.options) {
4336
+ var _a;
4337
+ if (!context) {
4338
+ throw new Error("No context provided to validation runner");
4339
+ }
4340
+ const handler = (_a = validationObj.handler) != null ? _a : this.getValidator(validationObj.type);
4072
4341
  const weakBindings = new Set();
4073
4342
  const model = {
4074
- get(b, options = { includeInvalid: true }) {
4343
+ get(b, options) {
4075
4344
  weakBindings.add(isBinding(b) ? binding : context.parseBinding(b));
4076
- return context.model.get(b, options);
4345
+ return context.model.get(b, __spreadProps$2(__spreadValues$3({}, options), { includeInvalid: true }));
4077
4346
  },
4078
- set: context.model.set
4347
+ set: context.model.set,
4348
+ delete: context.model.delete
4079
4349
  };
4080
4350
  const result = handler == null ? void 0 : handler(__spreadProps$2(__spreadValues$3({}, context), {
4081
4351
  evaluate: (exp, options = { model }) => context.evaluate(exp, options),
4082
4352
  model,
4083
- validation: validationObj
4353
+ validation: validationObj,
4354
+ schemaType: this.schema.getType(binding)
4084
4355
  }), context.model.get(binding, {
4085
4356
  includeInvalid: true,
4086
4357
  formatted: validationObj.dataTarget === "formatted"
@@ -4104,19 +4375,25 @@ class ValidationController {
4104
4375
  }
4105
4376
  }
4106
4377
  updateValidationsForView(trigger) {
4107
- const { activeBindings } = this;
4108
- const canDismiss = trigger !== "navigation" || this.setCompare(this.lastActiveBindings, activeBindings);
4109
- this.getBindings().forEach((binding) => {
4110
- var _a;
4111
- (_a = this.validations.get(binding)) == null ? void 0 : _a.update(trigger, canDismiss, (obj) => {
4112
- if (!this.options) {
4113
- return;
4114
- }
4115
- return this.validationRunner(obj, this.options, binding);
4378
+ const isNavigationTrigger = trigger === "navigation";
4379
+ const lastActiveBindings = this.activeBindings;
4380
+ const updateValidations = (dismissValidations) => {
4381
+ this.getBindings().forEach((binding) => {
4382
+ var _a;
4383
+ (_a = this.validations.get(binding)) == null ? void 0 : _a.update(trigger, dismissValidations, (obj) => {
4384
+ if (!this.options) {
4385
+ return;
4386
+ }
4387
+ return this.validationRunner(obj, binding, this.options);
4388
+ });
4116
4389
  });
4117
- });
4118
- if (trigger === "navigation") {
4119
- this.lastActiveBindings = activeBindings;
4390
+ };
4391
+ updateValidations(!isNavigationTrigger);
4392
+ if (isNavigationTrigger) {
4393
+ const { activeBindings } = this;
4394
+ if (this.setCompare(lastActiveBindings, activeBindings)) {
4395
+ updateValidations(true);
4396
+ }
4120
4397
  }
4121
4398
  }
4122
4399
  setCompare(set1, set2) {
@@ -4146,19 +4423,30 @@ class ValidationController {
4146
4423
  var _a, _b;
4147
4424
  return (_b = (_a = this.tracker) == null ? void 0 : _a.getBindings()) != null ? _b : new Set();
4148
4425
  }
4426
+ trackBinding(binding) {
4427
+ var _a;
4428
+ (_a = this.tracker) == null ? void 0 : _a.trackBinding(binding);
4429
+ }
4149
4430
  validateView(trigger = "navigation") {
4150
4431
  this.updateValidationsForView(trigger);
4151
4432
  const validations = new Map();
4433
+ let canTransition = true;
4152
4434
  this.getBindings().forEach((b) => {
4153
- var _a, _b;
4154
- const invalid = (_a = this.getValidationForBinding(b)) == null ? void 0 : _a.get();
4155
- if (invalid) {
4156
- (_b = this.options) == null ? void 0 : _b.logger.debug(`Validation on binding: ${b.asString()} is preventing navigation. ${JSON.stringify(invalid)}`);
4157
- validations.set(b, invalid);
4158
- }
4435
+ var _a;
4436
+ const allValidations = (_a = this.getValidationForBinding(b)) == null ? void 0 : _a.getAll();
4437
+ allValidations == null ? void 0 : allValidations.forEach((v) => {
4438
+ var _a2;
4439
+ if (trigger === "navigation" && v.blocking) {
4440
+ (_a2 = this.options) == null ? void 0 : _a2.logger.debug(`Validation on binding: ${b.asString()} is preventing navigation. ${JSON.stringify(v)}`);
4441
+ canTransition = false;
4442
+ }
4443
+ if (!validations.has(b)) {
4444
+ validations.set(b, v);
4445
+ }
4446
+ });
4159
4447
  });
4160
4448
  return {
4161
- canTransition: validations.size === 0,
4449
+ canTransition,
4162
4450
  validations: validations.size ? validations : void 0
4163
4451
  };
4164
4452
  }
@@ -4168,8 +4456,7 @@ class ValidationController {
4168
4456
  forView(parser) {
4169
4457
  return {
4170
4458
  _getValidationForBinding: (binding) => {
4171
- var _a;
4172
- return (_a = this.getValidationForBinding(isBinding(binding) ? binding : parser(binding))) == null ? void 0 : _a.get();
4459
+ return this.getValidationForBinding(isBinding(binding) ? binding : parser(binding));
4173
4460
  },
4174
4461
  getAll: () => {
4175
4462
  const bindings = this.getBindings();
@@ -4189,6 +4476,9 @@ class ValidationController {
4189
4476
  get() {
4190
4477
  throw new Error("Error Access be provided by the view plugin");
4191
4478
  },
4479
+ getValidationsForBinding() {
4480
+ throw new Error("Error rollup should be provided by the view plugin");
4481
+ },
4192
4482
  getChildren() {
4193
4483
  throw new Error("Error rollup should be provided by the view plugin");
4194
4484
  },
@@ -4199,7 +4489,7 @@ class ValidationController {
4199
4489
  throw new Error("Tracking should be provided by the view plugin");
4200
4490
  },
4201
4491
  register: () => {
4202
- throw new Error("Section funcationality hould be provided by the view plugin");
4492
+ throw new Error("Section functionality should be provided by the view plugin");
4203
4493
  },
4204
4494
  type: (binding) => this.schema.getType(isBinding(binding) ? binding : parser(binding))
4205
4495
  };
@@ -4315,10 +4605,11 @@ class AssetTransformCorePlugin {
4315
4605
  };
4316
4606
  };
4317
4607
  resolver.hooks.beforeResolve.tap("asset-transform", (node, options) => {
4608
+ var _a;
4318
4609
  if (node && (node.type === "asset" || node.type === "view")) {
4319
4610
  const transform = this.registry.get(node.value);
4320
4611
  if (transform == null ? void 0 : transform.beforeResolve) {
4321
- const store = getStore(node, this.beforeResolveSymbol);
4612
+ const store = getStore((_a = options.node) != null ? _a : node, this.beforeResolveSymbol);
4322
4613
  return transform.beforeResolve(node, options, store);
4323
4614
  }
4324
4615
  }
@@ -4396,14 +4687,26 @@ class ViewController {
4396
4687
  }
4397
4688
  });
4398
4689
  });
4399
- options.model.hooks.onUpdate.tap("viewController", (updates) => {
4690
+ const update = (updates) => {
4400
4691
  if (this.currentView) {
4401
4692
  if (this.optimizeUpdates) {
4402
- this.queueUpdate(new Set(updates.map((t) => t.binding)));
4693
+ this.queueUpdate(updates);
4403
4694
  } else {
4404
4695
  this.currentView.update();
4405
4696
  }
4406
4697
  }
4698
+ };
4699
+ options.model.hooks.onUpdate.tap("viewController", (updates) => {
4700
+ update(new Set(updates.map((t) => t.binding)));
4701
+ });
4702
+ options.model.hooks.onDelete.tap("viewController", (binding) => {
4703
+ const parentBinding = binding.parent();
4704
+ const property = binding.key();
4705
+ if (typeof property === "number" && parentBinding) {
4706
+ update(new Set([parentBinding]));
4707
+ } else {
4708
+ update(new Set([binding]));
4709
+ }
4407
4710
  });
4408
4711
  }
4409
4712
  queueUpdate(bindings) {
@@ -4504,16 +4807,19 @@ class DataController {
4504
4807
  });
4505
4808
  }
4506
4809
  const setUpdates = normalizedTransaction.reduce((updates, [binding, newVal]) => {
4507
- var _a;
4810
+ var _a, _b;
4508
4811
  const oldVal = this.get(binding, { includeInvalid: true });
4509
- if (!Object(dequal__WEBPACK_IMPORTED_MODULE_8__["dequal"])(oldVal, newVal)) {
4510
- updates.push({
4511
- binding,
4512
- newValue: newVal,
4513
- oldValue: oldVal
4514
- });
4812
+ const update = {
4813
+ binding,
4814
+ newValue: newVal,
4815
+ oldValue: oldVal
4816
+ };
4817
+ if (Object(dequal__WEBPACK_IMPORTED_MODULE_8__["dequal"])(oldVal, newVal)) {
4818
+ (_a = this.logger) == null ? void 0 : _a.debug(`Skipping update for path: ${binding.asString()}. Value was unchanged: ${oldVal}`);
4819
+ } else {
4820
+ updates.push(update);
4821
+ (_b = this.logger) == null ? void 0 : _b.debug(`Setting path: ${binding.asString()} from: ${oldVal} to: ${newVal}`);
4515
4822
  }
4516
- (_a = this.logger) == null ? void 0 : _a.debug(`Setting path: ${binding.asString()} from: ${oldVal} to: ${newVal}`);
4517
4823
  return updates;
4518
4824
  }, []);
4519
4825
  const result = this.getModel().set(normalizedTransaction, options);
@@ -4531,11 +4837,11 @@ class DataController {
4531
4837
  }
4532
4838
  return result;
4533
4839
  }
4534
- resolve(binding) {
4535
- return Array.isArray(binding) || typeof binding === "string" ? this.pathResolver.parse(binding) : binding;
4840
+ resolve(binding, readOnly) {
4841
+ return Array.isArray(binding) || typeof binding === "string" ? this.pathResolver.parse(binding, { readOnly }) : binding;
4536
4842
  }
4537
4843
  get(binding, options) {
4538
- const resolved = binding instanceof BindingInstance ? binding : this.resolve(binding);
4844
+ const resolved = binding instanceof BindingInstance ? binding : this.resolve(binding, true);
4539
4845
  let result = this.getModel().get(resolved, options);
4540
4846
  if (result === void 0 && !(options == null ? void 0 : options.ignoreDefaultValue)) {
4541
4847
  const defaultVal = this.hooks.resolveDefaultValue.call(resolved);
@@ -4545,44 +4851,26 @@ class DataController {
4545
4851
  }
4546
4852
  if (options == null ? void 0 : options.formatted) {
4547
4853
  result = this.hooks.format.call(result, resolved);
4854
+ } else if ((options == null ? void 0 : options.formatted) === false) {
4855
+ result = this.hooks.deformat.call(result, resolved);
4548
4856
  }
4549
4857
  this.hooks.onGet.call(binding, result);
4550
4858
  return result;
4551
4859
  }
4552
- delete(binding) {
4553
- if (binding === void 0 || binding === null) {
4554
- throw new Error(`Invalid arguments: delete expects a data path (string)`);
4860
+ delete(binding, options) {
4861
+ if (typeof binding !== "string" && !Array.isArray(binding) && !(binding instanceof BindingInstance)) {
4862
+ throw new Error("Invalid arguments: delete expects a data path (string)");
4555
4863
  }
4556
- const resolved = this.resolve(binding);
4557
- this.hooks.onDelete.call(resolved);
4558
- this.deleteData(resolved);
4559
- }
4560
- getTrash() {
4561
- return this.trash;
4562
- }
4563
- addToTrash(binding) {
4564
- this.trash.add(binding);
4565
- }
4566
- deleteData(binding) {
4567
- const parentBinding = binding.parent();
4568
- const parentPath = parentBinding.asString();
4569
- const property = binding.key();
4570
- const existedBeforeDelete = Object.prototype.hasOwnProperty.call(this.get(parentBinding), property);
4571
- if (property !== void 0) {
4572
- const parent = parentBinding ? this.get(parentBinding) : void 0;
4573
- if (parentPath && Array.isArray(parent)) {
4574
- if (parent.length > property) {
4575
- this.set([[parentBinding, Object(timm__WEBPACK_IMPORTED_MODULE_7__["removeAt"])(parent, property)]]);
4576
- }
4577
- } else if (parentPath && parent[property]) {
4578
- this.set([[parentBinding, Object(timm__WEBPACK_IMPORTED_MODULE_7__["omit"])(parent, property)]]);
4579
- } else if (!parentPath) {
4580
- this.getModel().reset(Object(timm__WEBPACK_IMPORTED_MODULE_7__["omit"])(this.get(""), property));
4581
- }
4582
- }
4583
- if (existedBeforeDelete && !this.get(binding)) {
4584
- this.addToTrash(binding);
4864
+ const resolved = binding instanceof BindingInstance ? binding : this.resolve(binding, false);
4865
+ const parentBinding = resolved.parent();
4866
+ const property = resolved.key();
4867
+ const parentValue = this.get(parentBinding);
4868
+ const existedBeforeDelete = typeof parentValue === "object" && parentValue !== null && Object.prototype.hasOwnProperty.call(parentValue, property);
4869
+ this.getModel().delete(resolved, options);
4870
+ if (existedBeforeDelete && !this.get(resolved)) {
4871
+ this.trash.add(resolved);
4585
4872
  }
4873
+ this.hooks.onDelete.call(resolved);
4586
4874
  }
4587
4875
  serialize() {
4588
4876
  return this.hooks.serialize.call(this.get(""));
@@ -4643,10 +4931,15 @@ class ConstantsController {
4643
4931
  this.tempStore.set(namespace, new LocalModel(data));
4644
4932
  }
4645
4933
  }
4646
- clearTemporaryValues() {
4647
- this.tempStore.forEach((value) => {
4648
- value.reset();
4649
- });
4934
+ clearTemporaryValues(namespace) {
4935
+ var _a;
4936
+ if (namespace) {
4937
+ (_a = this.tempStore.get(namespace)) == null ? void 0 : _a.reset();
4938
+ } else {
4939
+ this.tempStore.forEach((value) => {
4940
+ value.reset();
4941
+ });
4942
+ }
4650
4943
  }
4651
4944
  }
4652
4945
 
@@ -4761,8 +5054,8 @@ var __async = (__this, __arguments, generator) => {
4761
5054
  step((generator = generator.apply(__this, __arguments)).next());
4762
5055
  });
4763
5056
  };
4764
- const PLAYER_VERSION = "0.4.0-next.8";
4765
- const COMMIT = "766bb5a5d65b00da16285cf36b62c441568ac9a3";
5057
+ const PLAYER_VERSION = "0.4.0-next.9";
5058
+ const COMMIT = "e7681a2757fe0ab15d0c0e27c11d0ed33334d63f";
4766
5059
  const _Player = class {
4767
5060
  constructor(config) {
4768
5061
  this.logger = new TapableLogger();
@@ -4882,10 +5175,11 @@ const _Player = class {
4882
5175
  flowResultDeferred.reject(e);
4883
5176
  return true;
4884
5177
  });
4885
- function resolveStrings(val) {
5178
+ function resolveStrings(val, formatted) {
4886
5179
  return resolveDataRefs(val, {
4887
5180
  model: dataController,
4888
- evaluate: expressionEvaluator.evaluate
5181
+ evaluate: expressionEvaluator.evaluate,
5182
+ formatted
4889
5183
  });
4890
5184
  }
4891
5185
  flowController.hooks.flow.tap("player", (flow) => {
@@ -4921,23 +5215,21 @@ const _Player = class {
4921
5215
  newState = Object(timm__WEBPACK_IMPORTED_MODULE_7__["setIn"])(state, ["ref"], resolveStrings(state.ref));
4922
5216
  }
4923
5217
  if ("param" in state) {
4924
- newState = Object(timm__WEBPACK_IMPORTED_MODULE_7__["setIn"])(state, ["param"], resolveStrings(state.param));
5218
+ newState = Object(timm__WEBPACK_IMPORTED_MODULE_7__["setIn"])(state, ["param"], resolveStrings(state.param, false));
4925
5219
  }
4926
5220
  return newState;
4927
5221
  });
4928
5222
  flow.hooks.transition.tap("player", (_oldState, newState) => {
4929
- if (newState.value.state_type === "ACTION") {
4930
- const { exp } = newState.value;
4931
- queue_microtask__WEBPACK_IMPORTED_MODULE_10___default()(() => {
4932
- try {
4933
- flowController == null ? void 0 : flowController.transition(String(expressionEvaluator == null ? void 0 : expressionEvaluator.evaluate(exp)));
4934
- } catch (error) {
4935
- const state = this.getState();
4936
- if (error instanceof Error && state.status === "in-progress") {
4937
- state.fail(error);
4938
- }
4939
- }
4940
- });
5223
+ if (newState.value.state_type !== "VIEW") {
5224
+ validationController.reset();
5225
+ }
5226
+ });
5227
+ flow.hooks.afterTransition.tap("player", (flowInstance) => {
5228
+ var _a;
5229
+ const value = (_a = flowInstance.currentState) == null ? void 0 : _a.value;
5230
+ if (value && value.state_type === "ACTION") {
5231
+ const { exp } = value;
5232
+ flowController == null ? void 0 : flowController.transition(String(expressionEvaluator == null ? void 0 : expressionEvaluator.evaluate(exp)));
4941
5233
  }
4942
5234
  expressionEvaluator.reset();
4943
5235
  });
@@ -4955,6 +5247,11 @@ const _Player = class {
4955
5247
  parseBinding,
4956
5248
  transition: flowController.transition,
4957
5249
  model: dataController,
5250
+ utils: {
5251
+ findPlugin: (pluginSymbol) => {
5252
+ return this.findPlugin(pluginSymbol);
5253
+ }
5254
+ },
4958
5255
  logger: this.logger,
4959
5256
  flowController,
4960
5257
  schema,
@@ -4968,7 +5265,8 @@ const _Player = class {
4968
5265
  },
4969
5266
  validation: __spreadProps(__spreadValues({}, validationController.forView(parseBinding)), {
4970
5267
  type: (b) => schema.getType(parseBinding(b))
4971
- })
5268
+ }),
5269
+ constants: this.constantsController
4972
5270
  });
4973
5271
  viewController.hooks.view.tap("player", (view) => {
4974
5272
  validationController.onView(view);
@@ -4979,7 +5277,7 @@ const _Player = class {
4979
5277
  start: () => {
4980
5278
  flowController.start().then((endState) => {
4981
5279
  const flowResult = {
4982
- endState: resolveStrings(endState),
5280
+ endState: resolveStrings(endState, false),
4983
5281
  data: dataController.serialize()
4984
5282
  };
4985
5283
  return flowResult;
@@ -5031,8 +5329,7 @@ const _Player = class {
5031
5329
  const endProps = {
5032
5330
  ref,
5033
5331
  status: "completed",
5034
- flow: state.flow,
5035
- dataModel: state.controllers.data.getModel()
5332
+ flow: state.flow
5036
5333
  };
5037
5334
  return maybeUpdateState(__spreadValues(__spreadValues({}, yield state.flowResult), endProps));
5038
5335
  } catch (error) {
@@ -5171,6 +5468,9 @@ const sum = Object(_player_ui_player__WEBPACK_IMPORTED_MODULE_1__["withoutContex
5171
5468
  }, 0);
5172
5469
  });
5173
5470
  const findPropertyIndex = (context, bindingOrModel, propToCheck, valueToCheck) => {
5471
+ if (bindingOrModel === void 0) {
5472
+ return -1;
5473
+ }
5174
5474
  const searchArray = Array.isArray(bindingOrModel) ? bindingOrModel : context.model.get(bindingOrModel);
5175
5475
  if (!Array.isArray(searchArray)) {
5176
5476
  return -1;