@revisium/schema-toolkit-ui 0.2.0 → 0.2.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -44,7 +44,6 @@ let _chakra_ui_react_menu = require("@chakra-ui/react/menu");
44
44
  let react_icons_lu = require("react-icons/lu");
45
45
  let _atlaskit_drag_and_drop_adapter_element = require("@atlaskit/drag-and-drop/adapter/element");
46
46
  let _chakra_ui_react_dialog = require("@chakra-ui/react/dialog");
47
- let _revisium_formula = require("@revisium/formula");
48
47
 
49
48
  //#region src/schema-editor/model/state/TreeState.ts
50
49
  var TreeState = class {
@@ -1409,6 +1408,7 @@ var CollapseManager = class {
1409
1408
  var KeyboardNavigation = class {
1410
1409
  _mode = "TREE_NAV";
1411
1410
  _skipNextEscape = false;
1411
+ _suppressNextReturnFocus = false;
1412
1412
  _containerRef = null;
1413
1413
  _disposers = [];
1414
1414
  constructor(_treeState, _navigator, _accessors) {
@@ -1425,7 +1425,8 @@ var KeyboardNavigation = class {
1425
1425
  if (!isFocused && wasFocused) {
1426
1426
  this._mode = "TREE_NAV";
1427
1427
  this._skipNextEscape = true;
1428
- this.deferReturnFocus();
1428
+ if (this._suppressNextReturnFocus) this._suppressNextReturnFocus = false;
1429
+ else this.deferReturnFocus();
1429
1430
  }
1430
1431
  }));
1431
1432
  }
@@ -1506,10 +1507,12 @@ var KeyboardNavigation = class {
1506
1507
  const target = event.target;
1507
1508
  if (!(target instanceof HTMLElement)) return;
1508
1509
  if (this._containerRef?.contains(target)) {
1510
+ this._suppressNextReturnFocus = true;
1509
1511
  if (!target.closest("[data-node-id]")) this._treeState.setActiveNodeId(null);
1510
1512
  return;
1511
1513
  }
1512
- if (!target.closest("[role=\"menu\"], [role=\"listbox\"], [role=\"dialog\"]")) this._treeState.setActiveNodeId(null);
1514
+ if (target.closest("[role=\"menu\"], [role=\"listbox\"], [role=\"dialog\"]")) this._suppressNextReturnFocus = true;
1515
+ else this._treeState.setActiveNodeId(null);
1513
1516
  };
1514
1517
  handleEditEnter() {
1515
1518
  this.insertField();
@@ -3215,11 +3218,13 @@ const DescriptionSubmenu = (0, mobx_react_lite.observer)(({ accessor, dataTestId
3215
3218
  onKeyDown: stopPropagation,
3216
3219
  onKeyUp: stopPropagation,
3217
3220
  rows: 3,
3218
- autoFocus: true,
3219
- onFocus: (e) => {
3220
- const len = e.currentTarget.value.length;
3221
- e.currentTarget.setSelectionRange(len, len);
3222
- },
3221
+ ref: (0, react.useCallback)((el) => {
3222
+ if (el) requestAnimationFrame(() => {
3223
+ el.focus({ preventScroll: true });
3224
+ const len = el.value.length;
3225
+ el.setSelectionRange(len, len);
3226
+ });
3227
+ }, []),
3223
3228
  "data-testid": `${dataTestId}-description-input`
3224
3229
  })
3225
3230
  }) }) })]
@@ -3274,11 +3279,13 @@ const FormulaInput = (0, mobx_react_lite.observer)(({ accessor, dataTestId }) =>
3274
3279
  onChange: handleChange,
3275
3280
  onKeyDown: stopPropagation,
3276
3281
  onKeyUp: stopPropagation,
3277
- autoFocus: true,
3278
- onFocus: (e) => {
3279
- const len = e.currentTarget.value.length;
3280
- e.currentTarget.setSelectionRange(len, len);
3281
- },
3282
+ ref: (0, react.useCallback)((el) => {
3283
+ if (el) requestAnimationFrame(() => {
3284
+ el.focus({ preventScroll: true });
3285
+ const len = el.value.length;
3286
+ el.setSelectionRange(len, len);
3287
+ });
3288
+ }, []),
3282
3289
  rows: 2,
3283
3290
  borderColor: hasError ? "red.300" : void 0,
3284
3291
  "data-testid": `${dataTestId}-formula-input`
@@ -3405,7 +3412,11 @@ const DefaultValueSubmenu = (0, mobx_react_lite.observer)(({ accessor, dataTestI
3405
3412
  onBlur: handleBlur,
3406
3413
  onKeyDown: stopPropagation,
3407
3414
  onKeyUp: stopPropagation,
3408
- autoFocus: true,
3415
+ ref: (0, react.useCallback)((el) => {
3416
+ if (el) requestAnimationFrame(() => {
3417
+ el.focus({ preventScroll: true });
3418
+ });
3419
+ }, []),
3409
3420
  "data-testid": `${dataTestId}-default-input`
3410
3421
  })
3411
3422
  }) }) })]
@@ -4602,1512 +4613,13 @@ const UpdatingSchemaEditor = (0, mobx_react_lite.observer)(({ vm }) => {
4602
4613
  });
4603
4614
 
4604
4615
  //#endregion
4605
- //#region src/value-model/node/BaseValueNode.ts
4606
- let nodeIdCounter = 0;
4607
- function generateNodeId() {
4608
- return `node-${++nodeIdCounter}`;
4609
- }
4610
- var BaseValueNode = class {
4611
- id;
4612
- schema;
4613
- _parent = null;
4614
- _name;
4615
- constructor(id, name, schema) {
4616
- this.id = id ?? generateNodeId();
4617
- this._name = name;
4618
- this.schema = schema;
4619
- }
4620
- get parent() {
4621
- return this._parent;
4622
- }
4623
- set parent(value) {
4624
- this._parent = value;
4625
- }
4626
- get name() {
4627
- return this._name;
4628
- }
4629
- isObject() {
4630
- return false;
4631
- }
4632
- isArray() {
4633
- return false;
4634
- }
4635
- isPrimitive() {
4636
- return false;
4637
- }
4638
- get errors() {
4639
- return [];
4640
- }
4641
- get warnings() {
4642
- return [];
4643
- }
4644
- get isValid() {
4645
- return this.errors.length === 0;
4646
- }
4647
- get hasWarnings() {
4648
- return this.warnings.length > 0;
4649
- }
4650
- };
4651
-
4652
- //#endregion
4653
- //#region src/value-model/node/BasePrimitiveValueNode.ts
4654
- var BasePrimitiveValueNode = class extends BaseValueNode {
4655
- _value;
4656
- _baseValue;
4657
- _formulaWarning = null;
4658
- constructor(id, name, schema, value, defaultValue) {
4659
- super(id, name, schema);
4660
- const initialValue = value ?? schema.default ?? defaultValue;
4661
- this._value = initialValue;
4662
- this._baseValue = initialValue;
4663
- }
4664
- initObservable() {
4665
- (0, mobx.makeObservable)(this, {
4666
- _value: mobx.observable,
4667
- _baseValue: mobx.observable,
4668
- _formulaWarning: mobx.observable,
4669
- value: mobx.computed,
4670
- baseValue: mobx.computed,
4671
- isDirty: mobx.computed,
4672
- errors: mobx.computed,
4673
- warnings: mobx.computed,
4674
- setValue: mobx.action,
4675
- setFormulaWarning: mobx.action,
4676
- commit: mobx.action,
4677
- revert: mobx.action
4678
- });
4679
- }
4680
- get value() {
4681
- return this._value;
4682
- }
4683
- set value(newValue) {
4684
- if (this.isReadOnly) throw new Error(`Cannot set value on read-only field: ${this.name}`);
4685
- this._value = newValue;
4686
- }
4687
- get baseValue() {
4688
- return this._baseValue;
4689
- }
4690
- get isDirty() {
4691
- return this._value !== this._baseValue;
4692
- }
4693
- get formula() {
4694
- const xFormula = this.schema["x-formula"];
4695
- if (xFormula) return {
4696
- expression: xFormula.expression,
4697
- version: xFormula.version
4698
- };
4699
- }
4700
- get formulaWarning() {
4701
- return this._formulaWarning;
4702
- }
4703
- get isReadOnly() {
4704
- return this.schema.readOnly === true || this.formula !== void 0;
4705
- }
4706
- getPlainValue() {
4707
- return this._value;
4708
- }
4709
- setValue(value, options) {
4710
- if (this.isReadOnly && !options?.internal) throw new Error(`Cannot set value on read-only field: ${this.name}`);
4711
- this._value = this.coerceValue(value);
4712
- }
4713
- setFormulaWarning(warning) {
4714
- this._formulaWarning = warning;
4715
- }
4716
- commit() {
4717
- this._baseValue = this._value;
4718
- }
4719
- revert() {
4720
- this._value = this._baseValue;
4721
- }
4722
- isPrimitive() {
4723
- return true;
4724
- }
4725
- get errors() {
4726
- return this.computeErrors();
4727
- }
4728
- computeErrors() {
4729
- return [];
4730
- }
4731
- get warnings() {
4732
- if (!this._formulaWarning) return [];
4733
- return [{
4734
- severity: "warning",
4735
- type: this._formulaWarning.type,
4736
- message: this._formulaWarning.message,
4737
- path: this.name,
4738
- params: {
4739
- expression: this._formulaWarning.expression,
4740
- computedValue: this._formulaWarning.computedValue
4741
- }
4742
- }];
4743
- }
4744
- };
4745
-
4746
- //#endregion
4747
- //#region src/value-model/core/types.ts
4748
- let ValueType = /* @__PURE__ */ function(ValueType) {
4749
- ValueType["String"] = "string";
4750
- ValueType["Number"] = "number";
4751
- ValueType["Boolean"] = "boolean";
4752
- ValueType["Object"] = "object";
4753
- ValueType["Array"] = "array";
4754
- ValueType["Ref"] = "ref";
4755
- return ValueType;
4756
- }({});
4757
-
4758
- //#endregion
4759
- //#region src/value-model/node/StringValueNode.ts
4760
- var StringValueNode = class extends BasePrimitiveValueNode {
4761
- type = ValueType.String;
4762
- constructor(id, name, schema, value) {
4763
- super(id, name, schema, value, "");
4764
- this.initObservable();
4765
- }
4766
- get defaultValue() {
4767
- return this.schema.default ?? "";
4768
- }
4769
- coerceValue(value) {
4770
- if (typeof value === "string") return value;
4771
- if (value === null || value === void 0) return "";
4772
- return String(value);
4773
- }
4774
- computeErrors() {
4775
- const errors = [];
4776
- this.validateRequired(errors);
4777
- this.validateForeignKey(errors);
4778
- this.validateMinLength(errors);
4779
- this.validateMaxLength(errors);
4780
- this.validatePattern(errors);
4781
- this.validateEnum(errors);
4782
- return errors;
4783
- }
4784
- validateRequired(errors) {
4785
- if (this.schema.required && this._value === "") errors.push({
4786
- severity: "error",
4787
- type: "required",
4788
- message: "Field is required",
4789
- path: this.name
4790
- });
4791
- }
4792
- validateForeignKey(errors) {
4793
- const foreignKey = this.schema.foreignKey;
4794
- if (foreignKey && this._value === "") errors.push({
4795
- severity: "error",
4796
- type: "foreignKey",
4797
- message: `Reference to ${foreignKey} is required`,
4798
- path: this.name,
4799
- params: { table: foreignKey }
4800
- });
4801
- }
4802
- validateMinLength(errors) {
4803
- const minLength = this.schema.minLength;
4804
- if (minLength !== void 0 && this._value.length > 0 && this._value.length < minLength) errors.push({
4805
- severity: "error",
4806
- type: "minLength",
4807
- message: `Minimum length is ${minLength}`,
4808
- path: this.name,
4809
- params: {
4810
- min: minLength,
4811
- actual: this._value.length
4812
- }
4813
- });
4814
- }
4815
- validateMaxLength(errors) {
4816
- const maxLength = this.schema.maxLength;
4817
- if (maxLength !== void 0 && this._value.length > maxLength) errors.push({
4818
- severity: "error",
4819
- type: "maxLength",
4820
- message: `Maximum length is ${maxLength}`,
4821
- path: this.name,
4822
- params: {
4823
- max: maxLength,
4824
- actual: this._value.length
4825
- }
4826
- });
4827
- }
4828
- validatePattern(errors) {
4829
- const pattern = this.schema.pattern;
4830
- if (!pattern || this._value.length === 0) return;
4831
- try {
4832
- if (!new RegExp(pattern).test(this._value)) errors.push({
4833
- severity: "error",
4834
- type: "pattern",
4835
- message: "Value does not match pattern",
4836
- path: this.name,
4837
- params: { pattern }
4838
- });
4839
- } catch {
4840
- errors.push({
4841
- severity: "error",
4842
- type: "invalidPattern",
4843
- message: "Invalid regex pattern in schema",
4844
- path: this.name,
4845
- params: { pattern }
4846
- });
4847
- }
4848
- }
4849
- validateEnum(errors) {
4850
- const enumValues = this.schema.enum;
4851
- if (enumValues && enumValues.length > 0 && !enumValues.includes(this._value)) errors.push({
4852
- severity: "error",
4853
- type: "enum",
4854
- message: "Value is not in allowed list",
4855
- path: this.name,
4856
- params: {
4857
- allowed: enumValues,
4858
- actual: this._value
4859
- }
4860
- });
4861
- }
4862
- };
4863
-
4864
- //#endregion
4865
- //#region src/value-model/node/NumberValueNode.ts
4866
- var NumberValueNode = class extends BasePrimitiveValueNode {
4867
- type = ValueType.Number;
4868
- constructor(id, name, schema, value) {
4869
- super(id, name, schema, value, 0);
4870
- this.initObservable();
4871
- }
4872
- get defaultValue() {
4873
- return this.schema.default ?? 0;
4874
- }
4875
- coerceValue(value) {
4876
- if (typeof value === "number") return value;
4877
- return Number(value) || 0;
4878
- }
4879
- computeErrors() {
4880
- const errors = [];
4881
- const minimum = this.schema.minimum;
4882
- if (minimum !== void 0 && this._value < minimum) errors.push({
4883
- severity: "error",
4884
- type: "min",
4885
- message: `Value must be at least ${minimum}`,
4886
- path: this.name,
4887
- params: {
4888
- min: minimum,
4889
- actual: this._value
4890
- }
4891
- });
4892
- const maximum = this.schema.maximum;
4893
- if (maximum !== void 0 && this._value > maximum) errors.push({
4894
- severity: "error",
4895
- type: "max",
4896
- message: `Value must be at most ${maximum}`,
4897
- path: this.name,
4898
- params: {
4899
- max: maximum,
4900
- actual: this._value
4901
- }
4902
- });
4903
- const enumValues = this.schema.enum;
4904
- if (enumValues && enumValues.length > 0 && !enumValues.includes(this._value)) errors.push({
4905
- severity: "error",
4906
- type: "enum",
4907
- message: "Value is not in allowed list",
4908
- path: this.name,
4909
- params: {
4910
- allowed: enumValues,
4911
- actual: this._value
4912
- }
4913
- });
4914
- return errors;
4915
- }
4916
- };
4917
-
4918
- //#endregion
4919
- //#region src/value-model/node/BooleanValueNode.ts
4920
- var BooleanValueNode = class extends BasePrimitiveValueNode {
4921
- type = ValueType.Boolean;
4922
- constructor(id, name, schema, value) {
4923
- super(id, name, schema, value, false);
4924
- this.initObservable();
4925
- }
4926
- get defaultValue() {
4927
- return this.schema.default ?? false;
4928
- }
4929
- coerceValue(value) {
4930
- if (typeof value === "boolean") return value;
4931
- return Boolean(value);
4932
- }
4933
- };
4934
-
4935
- //#endregion
4936
- //#region src/value-model/node/ObjectValueNode.ts
4937
- var ObjectValueNode = class extends BaseValueNode {
4938
- type = ValueType.Object;
4939
- _children = /* @__PURE__ */ new Map();
4940
- _baseChildren = /* @__PURE__ */ new Map();
4941
- constructor(id, name, schema, children) {
4942
- super(id, name, schema);
4943
- if (children) for (const child of children) {
4944
- this._children.set(child.name, child);
4945
- child.parent = this;
4946
- }
4947
- this._baseChildren = new Map(this._children);
4948
- (0, mobx.makeObservable)(this, {
4949
- _children: mobx.observable,
4950
- _baseChildren: mobx.observable,
4951
- value: mobx.computed,
4952
- children: mobx.computed,
4953
- isDirty: mobx.computed,
4954
- errors: mobx.computed,
4955
- warnings: mobx.computed,
4956
- addChild: mobx.action,
4957
- removeChild: mobx.action,
4958
- commit: mobx.action,
4959
- revert: mobx.action
4960
- });
4961
- }
4962
- get value() {
4963
- return Object.fromEntries(this._children);
4964
- }
4965
- get children() {
4966
- return Array.from(this._children.values());
4967
- }
4968
- getPlainValue() {
4969
- const result = {};
4970
- for (const [key, node] of this._children) result[key] = node.getPlainValue();
4971
- return result;
4972
- }
4973
- child(name) {
4974
- return this._children.get(name);
4975
- }
4976
- hasChild(name) {
4977
- return this._children.has(name);
4978
- }
4979
- addChild(node) {
4980
- const existing = this._children.get(node.name);
4981
- if (existing) existing.parent = null;
4982
- node.parent = this;
4983
- this._children.set(node.name, node);
4984
- }
4985
- removeChild(name) {
4986
- const node = this._children.get(name);
4987
- if (node) {
4988
- node.parent = null;
4989
- this._children.delete(name);
4990
- }
4991
- }
4992
- get isDirty() {
4993
- if (this._children.size !== this._baseChildren.size) return true;
4994
- for (const [key, child] of this._children) if (this._baseChildren.get(key) !== child) return true;
4995
- for (const child of this._children.values()) if ("isDirty" in child && child.isDirty) return true;
4996
- return false;
4997
- }
4998
- commit() {
4999
- this._baseChildren = new Map(this._children);
5000
- for (const child of this._children.values()) if ("commit" in child && typeof child.commit === "function") child.commit();
5001
- }
5002
- revert() {
5003
- for (const child of this._children.values()) child.parent = null;
5004
- this._children = new Map(this._baseChildren);
5005
- for (const child of this._children.values()) {
5006
- child.parent = this;
5007
- if ("revert" in child && typeof child.revert === "function") child.revert();
5008
- }
5009
- }
5010
- isObject() {
5011
- return true;
5012
- }
5013
- get errors() {
5014
- const errors = [];
5015
- for (const child of this._children.values()) errors.push(...child.errors);
5016
- return errors;
5017
- }
5018
- get warnings() {
5019
- const warnings = [];
5020
- for (const child of this._children.values()) warnings.push(...child.warnings);
5021
- return warnings;
5022
- }
5023
- };
5024
-
5025
- //#endregion
5026
- //#region src/value-model/node/ArrayValueNode.ts
5027
- var ArrayValueNode = class extends BaseValueNode {
5028
- type = ValueType.Array;
5029
- _items = [];
5030
- _baseItems = [];
5031
- _nodeFactory = null;
5032
- constructor(id, name, schema, items) {
5033
- super(id, name, schema);
5034
- if (items) for (const item of items) {
5035
- item.parent = this;
5036
- this._items.push(item);
5037
- }
5038
- this._baseItems = [...this._items];
5039
- (0, mobx.makeObservable)(this, {
5040
- _items: mobx.observable,
5041
- _baseItems: mobx.observable,
5042
- value: mobx.computed,
5043
- length: mobx.computed,
5044
- isDirty: mobx.computed,
5045
- errors: mobx.computed,
5046
- warnings: mobx.computed,
5047
- push: mobx.action,
5048
- insertAt: mobx.action,
5049
- removeAt: mobx.action,
5050
- move: mobx.action,
5051
- replaceAt: mobx.action,
5052
- clear: mobx.action,
5053
- commit: mobx.action,
5054
- revert: mobx.action,
5055
- pushValue: mobx.action,
5056
- insertValueAt: mobx.action
5057
- });
5058
- }
5059
- get value() {
5060
- return this._items;
5061
- }
5062
- get length() {
5063
- return this._items.length;
5064
- }
5065
- getPlainValue() {
5066
- return this._items.map((item) => item.getPlainValue());
5067
- }
5068
- at(index) {
5069
- if (index < 0) return this._items[this._items.length + index];
5070
- return this._items[index];
5071
- }
5072
- push(node) {
5073
- node.parent = this;
5074
- this._items.push(node);
5075
- }
5076
- insertAt(index, node) {
5077
- if (index < 0 || index > this._items.length) throw new Error(`Index out of bounds: ${index}`);
5078
- node.parent = this;
5079
- this._items.splice(index, 0, node);
5080
- }
5081
- removeAt(index) {
5082
- if (index < 0 || index >= this._items.length) throw new Error(`Index out of bounds: ${index}`);
5083
- const removed = this._items.splice(index, 1)[0];
5084
- if (removed) removed.parent = null;
5085
- }
5086
- move(fromIndex, toIndex) {
5087
- if (fromIndex < 0 || fromIndex >= this._items.length) throw new Error(`Source index out of bounds: ${fromIndex}`);
5088
- if (toIndex < 0 || toIndex >= this._items.length) throw new Error(`Target index out of bounds: ${toIndex}`);
5089
- if (fromIndex === toIndex) return;
5090
- const [item] = this._items.splice(fromIndex, 1);
5091
- if (item) this._items.splice(toIndex, 0, item);
5092
- }
5093
- replaceAt(index, node) {
5094
- if (index < 0 || index >= this._items.length) throw new Error(`Index out of bounds: ${index}`);
5095
- const oldNode = this._items[index];
5096
- if (oldNode) oldNode.parent = null;
5097
- node.parent = this;
5098
- this._items[index] = node;
5099
- }
5100
- clear() {
5101
- for (const item of this._items) item.parent = null;
5102
- this._items.length = 0;
5103
- }
5104
- setNodeFactory(factory) {
5105
- this._nodeFactory = factory;
5106
- }
5107
- pushValue(value) {
5108
- const node = this.createItemNode(this._items.length, value);
5109
- this.push(node);
5110
- }
5111
- insertValueAt(index, value) {
5112
- const node = this.createItemNode(index, value);
5113
- this.insertAt(index, node);
5114
- }
5115
- createItemNode(index, value) {
5116
- if (!this._nodeFactory) throw new Error("NodeFactory not set");
5117
- const itemSchema = this.schema.items;
5118
- if (!itemSchema) throw new Error("No items schema");
5119
- const itemValue = value === void 0 ? itemSchema.default : value;
5120
- const node = this._nodeFactory.create(String(index), itemSchema, itemValue);
5121
- this.propagateFactory(node);
5122
- return node;
5123
- }
5124
- propagateFactory(node) {
5125
- if (!this._nodeFactory) return;
5126
- if (node.isArray()) {
5127
- node.setNodeFactory(this._nodeFactory);
5128
- for (const item of node.value) this.propagateFactory(item);
5129
- } else if (node.isObject()) for (const child of node.children) this.propagateFactory(child);
5130
- }
5131
- get isDirty() {
5132
- if (this._items.length !== this._baseItems.length) return true;
5133
- for (let i = 0; i < this._items.length; i++) if (this._items[i] !== this._baseItems[i]) return true;
5134
- for (const item of this._items) if ("isDirty" in item && item.isDirty) return true;
5135
- return false;
5136
- }
5137
- commit() {
5138
- this._baseItems = [...this._items];
5139
- for (const item of this._items) if ("commit" in item && typeof item.commit === "function") item.commit();
5140
- }
5141
- revert() {
5142
- for (const item of this._items) item.parent = null;
5143
- this._items = [...this._baseItems];
5144
- for (const item of this._items) {
5145
- item.parent = this;
5146
- if ("revert" in item && typeof item.revert === "function") item.revert();
5147
- }
5148
- }
5149
- isArray() {
5150
- return true;
5151
- }
5152
- get errors() {
5153
- const errors = [];
5154
- for (const item of this._items) errors.push(...item.errors);
5155
- return errors;
5156
- }
5157
- get warnings() {
5158
- const warnings = [];
5159
- for (const item of this._items) warnings.push(...item.warnings);
5160
- return warnings;
5161
- }
5162
- };
5163
-
5164
- //#endregion
5165
- //#region src/value-model/node/NodeFactory.ts
5166
- var NodeFactoryRegistry = class {
5167
- factories = /* @__PURE__ */ new Map();
5168
- register(schemaType, factory) {
5169
- this.factories.set(schemaType, factory);
5170
- return this;
5171
- }
5172
- get(schemaType) {
5173
- return this.factories.get(schemaType);
5174
- }
5175
- has(schemaType) {
5176
- return this.factories.has(schemaType);
5177
- }
5178
- };
5179
- var NodeFactory = class {
5180
- constructor(registry) {
5181
- this.registry = registry;
5182
- }
5183
- create(name, schema, value, id) {
5184
- const schemaType = schema.type ?? "object";
5185
- const factory = this.registry.get(schemaType);
5186
- if (!factory) throw new Error(`Unknown schema type: ${schemaType}`);
5187
- return factory(name, schema, value, id);
5188
- }
5189
- createTree(schema, value) {
5190
- return this.create("", schema, value);
5191
- }
5192
- };
5193
- const stringFactory = (name, schema, value, id) => {
5194
- return new StringValueNode(id, name, schema, value);
5195
- };
5196
- const numberFactory = (name, schema, value, id) => {
5197
- return new NumberValueNode(id, name, schema, value);
5198
- };
5199
- const booleanFactory = (name, schema, value, id) => {
5200
- return new BooleanValueNode(id, name, schema, value);
5201
- };
5202
- function createObjectFactory(nodeFactory) {
5203
- return (name, schema, value, id) => {
5204
- const objValue = value ?? {};
5205
- const children = [];
5206
- const properties = schema.properties ?? {};
5207
- for (const [propName, propSchema] of Object.entries(properties)) {
5208
- const propValue = objValue[propName];
5209
- const childNode = nodeFactory.create(propName, propSchema, propValue);
5210
- children.push(childNode);
5211
- }
5212
- return new ObjectValueNode(id, name, schema, children);
5213
- };
5214
- }
5215
- function createArrayFactory(nodeFactory) {
5216
- return (name, schema, value, id) => {
5217
- const arrValue = value ?? [];
5218
- const itemSchema = schema.items ?? { type: "string" };
5219
- const items = [];
5220
- for (let i = 0; i < arrValue.length; i++) {
5221
- const itemValue = arrValue[i];
5222
- const itemNode = nodeFactory.create(String(i), itemSchema, itemValue);
5223
- items.push(itemNode);
5224
- }
5225
- return new ArrayValueNode(id, name, schema, items);
5226
- };
5227
- }
5228
- function createDefaultRegistry() {
5229
- const registry = new NodeFactoryRegistry();
5230
- registry.register("string", stringFactory);
5231
- registry.register("number", numberFactory);
5232
- registry.register("boolean", booleanFactory);
5233
- return registry;
5234
- }
5235
- function createNodeFactory() {
5236
- const registry = createDefaultRegistry();
5237
- const factory = new NodeFactory(registry);
5238
- registry.register("object", createObjectFactory(factory));
5239
- registry.register("array", createArrayFactory(factory));
5240
- return factory;
5241
- }
5242
-
5243
- //#endregion
5244
- //#region src/value-model/core/Path.ts
5245
- var Path = class Path {
5246
- constructor(_segments) {
5247
- this._segments = _segments;
5248
- }
5249
- static empty() {
5250
- return new Path([]);
5251
- }
5252
- static INDEX_REGEX = /^\[(\d+)\]/;
5253
- static PROP_REGEX = /^\.?([a-zA-Z_]\w*)/;
5254
- static fromString(path) {
5255
- if (!path || path === "") return Path.empty();
5256
- const segments = [];
5257
- let current = path;
5258
- while (current.length > 0) {
5259
- const indexMatch = Path.INDEX_REGEX.exec(current);
5260
- if (indexMatch?.[1] !== void 0) {
5261
- segments.push({
5262
- type: "index",
5263
- index: Number.parseInt(indexMatch[1], 10)
5264
- });
5265
- current = current.slice(indexMatch[0].length);
5266
- continue;
5267
- }
5268
- if (current.startsWith("[*]")) {
5269
- segments.push({ type: "items" });
5270
- current = current.slice(3);
5271
- continue;
5272
- }
5273
- const propMatch = Path.PROP_REGEX.exec(current);
5274
- if (propMatch?.[1] !== void 0) {
5275
- segments.push({
5276
- type: "property",
5277
- name: propMatch[1]
5278
- });
5279
- current = current.slice(propMatch[0].length);
5280
- continue;
5281
- }
5282
- throw new Error(`Invalid path segment: ${current}`);
5283
- }
5284
- return new Path(segments);
5285
- }
5286
- static fromSegments(segments) {
5287
- return new Path([...segments]);
5288
- }
5289
- segments() {
5290
- return this._segments;
5291
- }
5292
- isEmpty() {
5293
- return this._segments.length === 0;
5294
- }
5295
- length() {
5296
- return this._segments.length;
5297
- }
5298
- first() {
5299
- return this._segments[0];
5300
- }
5301
- last() {
5302
- return this._segments.at(-1);
5303
- }
5304
- parent() {
5305
- if (this._segments.length === 0) return this;
5306
- return new Path(this._segments.slice(0, -1));
5307
- }
5308
- child(name) {
5309
- return new Path([...this._segments, {
5310
- type: "property",
5311
- name
5312
- }]);
5313
- }
5314
- childIndex(index) {
5315
- return new Path([...this._segments, {
5316
- type: "index",
5317
- index
5318
- }]);
5319
- }
5320
- childItems() {
5321
- return new Path([...this._segments, { type: "items" }]);
5322
- }
5323
- isChildOf(parent) {
5324
- if (parent._segments.length >= this._segments.length) return false;
5325
- for (let i = 0; i < parent._segments.length; i++) {
5326
- const parentSeg = parent._segments[i];
5327
- const thisSeg = this._segments[i];
5328
- if (!parentSeg || !thisSeg || !this.segmentEquals(parentSeg, thisSeg)) return false;
5329
- }
5330
- return true;
5331
- }
5332
- equals(other) {
5333
- if (this._segments.length !== other._segments.length) return false;
5334
- for (let i = 0; i < this._segments.length; i++) {
5335
- const thisSeg = this._segments[i];
5336
- const otherSeg = other._segments[i];
5337
- if (!thisSeg || !otherSeg || !this.segmentEquals(thisSeg, otherSeg)) return false;
5338
- }
5339
- return true;
5340
- }
5341
- asSimple() {
5342
- let result = "";
5343
- for (const segment of this._segments) if (segment.type === "property") {
5344
- if (result.length > 0) result += ".";
5345
- result += segment.name;
5346
- } else if (segment.type === "index") result += `[${segment.index}]`;
5347
- else if (segment.type === "items") result += "[*]";
5348
- return result;
5349
- }
5350
- asJsonPointer() {
5351
- if (this._segments.length === 0) return "";
5352
- let result = "";
5353
- for (const segment of this._segments) if (segment.type === "property") result += "/" + segment.name;
5354
- else if (segment.type === "index") result += "/" + segment.index;
5355
- else if (segment.type === "items") result += "/-";
5356
- return result;
5357
- }
5358
- segmentEquals(a, b) {
5359
- if (a.type !== b.type) return false;
5360
- if (a.type === "property" && b.type === "property") return a.name === b.name;
5361
- if (a.type === "index" && b.type === "index") return a.index === b.index;
5362
- return true;
5363
- }
5364
- };
5365
-
5366
- //#endregion
5367
- //#region src/value-model/tree/TreeIndex.ts
5368
- var TreeIndex = class {
5369
- nodesById = /* @__PURE__ */ new Map();
5370
- pathCache = /* @__PURE__ */ new Map();
5371
- constructor(root) {
5372
- this.root = root;
5373
- this.rebuild();
5374
- }
5375
- nodeById(id) {
5376
- const node = this.nodesById.get(id);
5377
- if (node) return node;
5378
- this.rebuild();
5379
- return this.nodesById.get(id);
5380
- }
5381
- pathOf(node) {
5382
- if (this.isInsideArray(node)) return this.computePath(node);
5383
- const cached = this.pathCache.get(node.id);
5384
- if (cached) return cached;
5385
- const path = this.computePath(node);
5386
- this.pathCache.set(node.id, path);
5387
- return path;
5388
- }
5389
- isInsideArray(node) {
5390
- let current = node.parent;
5391
- while (current) {
5392
- if (current.isArray()) return true;
5393
- current = current.parent;
5394
- }
5395
- return false;
5396
- }
5397
- rebuild() {
5398
- this.nodesById.clear();
5399
- this.pathCache.clear();
5400
- this.indexNode(this.root);
5401
- }
5402
- registerNode(node) {
5403
- this.indexNode(node);
5404
- }
5405
- invalidatePathsUnder(node) {
5406
- this.pathCache.delete(node.id);
5407
- this.invalidateChildPaths(node);
5408
- }
5409
- indexNode(node) {
5410
- this.nodesById.set(node.id, node);
5411
- if (node.isObject()) for (const child of node.children) this.indexNode(child);
5412
- else if (node.isArray()) for (const item of node.value) this.indexNode(item);
5413
- }
5414
- computePath(node) {
5415
- const segments = [];
5416
- let current = node;
5417
- while (current?.parent) {
5418
- const parent = current.parent;
5419
- if (parent.isObject()) segments.unshift({
5420
- type: "property",
5421
- name: current.name
5422
- });
5423
- else if (parent.isArray()) {
5424
- const index = parent.value.indexOf(current);
5425
- if (index >= 0) segments.unshift({
5426
- type: "index",
5427
- index
5428
- });
5429
- }
5430
- current = parent;
5431
- }
5432
- return Path.fromSegments(segments);
5433
- }
5434
- invalidateChildPaths(node) {
5435
- if (node.isObject()) for (const child of node.children) {
5436
- this.pathCache.delete(child.id);
5437
- this.invalidateChildPaths(child);
5438
- }
5439
- else if (node.isArray()) for (const item of node.value) {
5440
- this.pathCache.delete(item.id);
5441
- this.invalidateChildPaths(item);
5442
- }
5443
- }
5444
- };
5445
-
5446
- //#endregion
5447
- //#region src/value-model/tree/ChangeTracker.ts
5448
- var ChangeTracker = class {
5449
- _changes = [];
5450
- get changes() {
5451
- return this._changes;
5452
- }
5453
- get hasChanges() {
5454
- return this._changes.length > 0;
5455
- }
5456
- track(change) {
5457
- this._changes.push(change);
5458
- }
5459
- clear() {
5460
- this._changes = [];
5461
- }
5462
- toPatches() {
5463
- const patches = [];
5464
- for (const change of this._changes) {
5465
- const patch = this.changeToPatches(change);
5466
- patches.push(...patch);
5467
- }
5468
- return patches;
5469
- }
5470
- changeToPatches(change) {
5471
- const path = change.path.asJsonPointer();
5472
- switch (change.type) {
5473
- case "setValue": return [{
5474
- op: "replace",
5475
- path,
5476
- value: change.value
5477
- }];
5478
- case "addProperty": return [{
5479
- op: "add",
5480
- path,
5481
- value: change.value
5482
- }];
5483
- case "removeProperty": return [{
5484
- op: "remove",
5485
- path
5486
- }];
5487
- case "arrayPush": return [{
5488
- op: "add",
5489
- path: `${path}/-`,
5490
- value: change.value
5491
- }];
5492
- case "arrayInsert": return [{
5493
- op: "add",
5494
- path: `${path}/${change.index}`,
5495
- value: change.value
5496
- }];
5497
- case "arrayRemove": return [{
5498
- op: "remove",
5499
- path: `${path}/${change.index}`
5500
- }];
5501
- case "arrayMove": {
5502
- const fromIndex = change.fromIndex ?? 0;
5503
- const toIndex = change.toIndex ?? 0;
5504
- return [{
5505
- op: "move",
5506
- from: `${path}/${fromIndex}`,
5507
- path: `${path}/${toIndex}`
5508
- }];
5509
- }
5510
- case "arrayReplace": return [{
5511
- op: "replace",
5512
- path: `${path}/${change.index}`,
5513
- value: change.value
5514
- }];
5515
- case "arrayClear": return [{
5516
- op: "replace",
5517
- path,
5518
- value: []
5519
- }];
5520
- default: return [];
5521
- }
5522
- }
5523
- };
5524
-
5525
- //#endregion
5526
- //#region src/value-model/tree/ValueTree.ts
5527
- var ValueTree = class {
5528
- index;
5529
- changeTracker;
5530
- _formulaEngine = null;
5531
- constructor(_root) {
5532
- this._root = _root;
5533
- this.index = new TreeIndex(_root);
5534
- this.changeTracker = new ChangeTracker();
5535
- (0, mobx.makeObservable)(this, {
5536
- allErrors: mobx.computed,
5537
- allWarnings: mobx.computed,
5538
- allDiagnostics: mobx.computed,
5539
- isValid: mobx.computed,
5540
- hasDiagnostics: mobx.computed,
5541
- isDirty: mobx.computed,
5542
- commit: mobx.action,
5543
- revert: mobx.action
5544
- });
5545
- }
5546
- get root() {
5547
- return this._root;
5548
- }
5549
- nodeById(id) {
5550
- return this.index.nodeById(id);
5551
- }
5552
- get(path) {
5553
- return this.getByPath(Path.fromString(path));
5554
- }
5555
- getByPath(path) {
5556
- if (path.isEmpty()) return this._root;
5557
- let current = this._root;
5558
- for (const segment of path.segments()) {
5559
- if (!current) return;
5560
- current = this.resolveSegment(current, segment);
5561
- }
5562
- return current;
5563
- }
5564
- resolveSegment(node, segment) {
5565
- if (segment.type === "property" && node.isObject()) return node.child(segment.name);
5566
- if (segment.type === "index" && node.isArray()) return node.at(segment.index);
5567
- }
5568
- pathOf(nodeOrId) {
5569
- const node = typeof nodeOrId === "string" ? this.nodeById(nodeOrId) : nodeOrId;
5570
- if (!node) return Path.empty();
5571
- return this.index.pathOf(node);
5572
- }
5573
- get allErrors() {
5574
- return this._root.errors;
5575
- }
5576
- get allWarnings() {
5577
- return this._root.warnings;
5578
- }
5579
- get allDiagnostics() {
5580
- return [...this.allErrors, ...this.allWarnings];
5581
- }
5582
- get isValid() {
5583
- return this.allErrors.length === 0;
5584
- }
5585
- get hasDiagnostics() {
5586
- return this.allDiagnostics.length > 0;
5587
- }
5588
- get errorsByPath() {
5589
- const map = /* @__PURE__ */ new Map();
5590
- for (const error of this.allErrors) {
5591
- const list = map.get(error.path) ?? [];
5592
- list.push(error);
5593
- map.set(error.path, list);
5594
- }
5595
- return map;
5596
- }
5597
- getValue(path) {
5598
- return this.get(path)?.getPlainValue();
5599
- }
5600
- setValue(path, value) {
5601
- const parsedPath = Path.fromString(path);
5602
- const node = this.getByPath(parsedPath);
5603
- if (!node) throw new Error(`Path not found: ${path}`);
5604
- if (!node.isPrimitive()) throw new Error(`Cannot set value on non-primitive node: ${path}`);
5605
- const oldValue = node.value;
5606
- node.setValue(value);
5607
- this.changeTracker.track({
5608
- type: "setValue",
5609
- path: parsedPath,
5610
- value,
5611
- oldValue
5612
- });
5613
- }
5614
- getPlainValue() {
5615
- return this._root.getPlainValue();
5616
- }
5617
- get changes() {
5618
- return this.changeTracker.changes;
5619
- }
5620
- get hasChanges() {
5621
- return this.changeTracker.hasChanges;
5622
- }
5623
- clearChanges() {
5624
- this.changeTracker.clear();
5625
- }
5626
- getPatches() {
5627
- return this.changeTracker.toPatches();
5628
- }
5629
- trackChange(change) {
5630
- this.changeTracker.track(change);
5631
- }
5632
- rebuildIndex() {
5633
- this.index.rebuild();
5634
- }
5635
- invalidatePathsUnder(node) {
5636
- this.index.invalidatePathsUnder(node);
5637
- }
5638
- get isDirty() {
5639
- const root = this._root;
5640
- if ("isDirty" in root) return root.isDirty;
5641
- return false;
5642
- }
5643
- commit() {
5644
- const root = this._root;
5645
- if ("commit" in root && typeof root.commit === "function") root.commit();
5646
- this.changeTracker.clear();
5647
- }
5648
- revert() {
5649
- const root = this._root;
5650
- if ("revert" in root && typeof root.revert === "function") root.revert();
5651
- this.changeTracker.clear();
5652
- }
5653
- setFormulaEngine(engine) {
5654
- this._formulaEngine = engine;
5655
- }
5656
- get formulaEngine() {
5657
- return this._formulaEngine;
5658
- }
5659
- dispose() {
5660
- this._formulaEngine?.dispose();
5661
- this._formulaEngine = null;
5662
- }
5663
- };
5664
-
5665
- //#endregion
5666
- //#region src/value-model/formula/FormulaCollector.ts
5667
- const INDEX_REGEX = /^\[(-?\d+)\]/;
5668
- const PROP_REGEX = /^\.?([a-zA-Z_]\w*)/;
5669
- var FormulaCollector = class {
5670
- root = null;
5671
- collect(root) {
5672
- this.root = root;
5673
- const formulas = [];
5674
- this.traverse(root, {
5675
- parent: null,
5676
- arrayLevels: []
5677
- }, formulas);
5678
- return formulas;
5679
- }
5680
- traverse(node, context, formulas) {
5681
- if (node.isPrimitive()) this.collectPrimitive(node, context, formulas);
5682
- else if (node.isObject()) for (const child of node.children) this.traverse(child, {
5683
- ...context,
5684
- parent: node
5685
- }, formulas);
5686
- else if (node.isArray()) for (let i = 0; i < node.length; i++) {
5687
- const item = node.at(i);
5688
- if (item) this.traverse(item, {
5689
- ...context,
5690
- arrayLevels: [...context.arrayLevels, {
5691
- array: node,
5692
- index: i
5693
- }]
5694
- }, formulas);
5695
- }
5696
- }
5697
- collectPrimitive(node, context, formulas) {
5698
- const formula = node.formula;
5699
- if (!formula) return;
5700
- const rawDependencies = this.extractDependencies(formula.expression);
5701
- const dependencyNodes = this.resolveDependencies(rawDependencies, node, context);
5702
- formulas.push({
5703
- node,
5704
- expression: formula.expression,
5705
- parent: context.parent,
5706
- dependencyNodes,
5707
- arrayLevels: context.arrayLevels
5708
- });
5709
- }
5710
- extractDependencies(expression) {
5711
- try {
5712
- return (0, _revisium_formula.parseExpression)(expression).dependencies;
5713
- } catch {
5714
- return [];
5715
- }
5716
- }
5717
- resolveDependencies(rawDeps, formulaNode, context) {
5718
- const nodes = [];
5719
- for (const dep of rawDeps) {
5720
- const node = this.resolveOneDependency(dep, formulaNode, context);
5721
- if (node) this.collectPrimitiveNodes(node, nodes);
5722
- }
5723
- return nodes;
5724
- }
5725
- collectPrimitiveNodes(node, result) {
5726
- if (node.isPrimitive()) result.push(node);
5727
- else if (node.isArray()) for (let i = 0; i < node.length; i++) {
5728
- const item = node.at(i);
5729
- if (item) this.collectPrimitiveNodes(item, result);
5730
- }
5731
- else if (node.isObject()) for (const child of node.children) this.collectPrimitiveNodes(child, result);
5732
- }
5733
- resolveOneDependency(dep, _formulaNode, context) {
5734
- if (dep.startsWith("/")) return this.resolveFromRoot(dep.slice(1));
5735
- if (dep.startsWith("../")) return this.resolveRelative(dep, context);
5736
- if (context.parent) return this.resolveFromNode(context.parent, dep);
5737
- return this.resolveFromRoot(dep);
5738
- }
5739
- resolveFromRoot(pathStr) {
5740
- if (!this.root) return null;
5741
- return this.resolveFromNode(this.root, pathStr);
5742
- }
5743
- resolveFromNode(startNode, pathStr) {
5744
- const segments = this.parsePathSegments(pathStr);
5745
- let current = startNode;
5746
- for (const segment of segments) {
5747
- if (!current) return null;
5748
- if (segment.type === "property") if (current.isObject()) current = current.children.find((c) => c.name === segment.name) ?? null;
5749
- else return null;
5750
- else if (segment.type === "index") if (current.isArray()) current = current.at(segment.index) ?? null;
5751
- else return null;
5752
- }
5753
- return current;
5754
- }
5755
- resolveRelative(dep, context) {
5756
- let upLevels = 0;
5757
- let remaining = dep;
5758
- while (remaining.startsWith("../")) {
5759
- upLevels++;
5760
- remaining = remaining.slice(3);
5761
- }
5762
- let current = context.parent;
5763
- for (let i = 0; i < upLevels && current; i++) {
5764
- current = this.findParent(current);
5765
- if (current?.isArray()) current = this.findParent(current);
5766
- }
5767
- if (!current) return null;
5768
- if (remaining) return this.resolveFromNode(current, remaining);
5769
- return current;
5770
- }
5771
- findParent(node) {
5772
- if (!this.root || node === this.root) return null;
5773
- return this.findParentRecursive(this.root, node);
5774
- }
5775
- findParentRecursive(current, target) {
5776
- const children = this.getChildNodes(current);
5777
- for (const child of children) {
5778
- if (child === target) return current;
5779
- const found = this.findParentRecursive(child, target);
5780
- if (found) return found;
5781
- }
5782
- return null;
5783
- }
5784
- getChildNodes(node) {
5785
- if (node.isObject()) return [...node.children];
5786
- if (node.isArray()) {
5787
- const items = [];
5788
- for (let i = 0; i < node.length; i++) {
5789
- const item = node.at(i);
5790
- if (item) items.push(item);
5791
- }
5792
- return items;
5793
- }
5794
- return [];
5795
- }
5796
- parsePathSegments(pathStr) {
5797
- const segments = [];
5798
- let current = pathStr;
5799
- while (current.length > 0) {
5800
- const indexMatch = INDEX_REGEX.exec(current);
5801
- if (indexMatch?.[1]) {
5802
- segments.push({
5803
- type: "index",
5804
- index: Number.parseInt(indexMatch[1], 10)
5805
- });
5806
- current = current.slice(indexMatch[0].length);
5807
- continue;
5808
- }
5809
- const propMatch = PROP_REGEX.exec(current);
5810
- if (propMatch?.[1]) {
5811
- segments.push({
5812
- type: "property",
5813
- name: propMatch[1]
5814
- });
5815
- current = current.slice(propMatch[0].length);
5816
- continue;
5817
- }
5818
- break;
5819
- }
5820
- return segments;
5821
- }
5822
- };
5823
-
5824
- //#endregion
5825
- //#region src/value-model/formula/DependencyGraph.ts
5826
- var DependencyGraph = class {
5827
- buildDependencyMap(formulas) {
5828
- const map = /* @__PURE__ */ new Map();
5829
- for (const field of formulas) for (const depNode of field.dependencyNodes) {
5830
- let depSet = map.get(depNode);
5831
- if (!depSet) {
5832
- depSet = /* @__PURE__ */ new Set();
5833
- map.set(depNode, depSet);
5834
- }
5835
- depSet.add(field);
5836
- }
5837
- return map;
5838
- }
5839
- buildEvaluationOrder(formulas) {
5840
- const formulaNodes = new Set(formulas.map((f) => f.node));
5841
- const visited = /* @__PURE__ */ new Set();
5842
- const order = [];
5843
- const formulaByNode = /* @__PURE__ */ new Map();
5844
- for (const field of formulas) formulaByNode.set(field.node, field);
5845
- const visit = (field, stack) => {
5846
- if (visited.has(field.node)) return;
5847
- if (stack.has(field.node)) return;
5848
- stack.add(field.node);
5849
- for (const depNode of field.dependencyNodes) if (formulaNodes.has(depNode)) {
5850
- const depFormula = formulaByNode.get(depNode);
5851
- if (depFormula) visit(depFormula, stack);
5852
- }
5853
- stack.delete(field.node);
5854
- visited.add(field.node);
5855
- order.push(field);
5856
- };
5857
- for (const field of formulas) visit(field, /* @__PURE__ */ new Set());
5858
- return order;
5859
- }
5860
- getAffectedFormulas(changedNode, dependencyMap, evaluationOrder) {
5861
- const affected = /* @__PURE__ */ new Set();
5862
- const queue = [changedNode];
5863
- while (queue.length > 0) {
5864
- const current = queue.shift();
5865
- if (!current) continue;
5866
- const dependents = dependencyMap.get(current);
5867
- if (dependents) {
5868
- for (const field of dependents) if (!affected.has(field)) {
5869
- affected.add(field);
5870
- queue.push(field.node);
5871
- }
5872
- }
5873
- }
5874
- return evaluationOrder.filter((field) => affected.has(field));
5875
- }
5876
- };
5877
-
5878
- //#endregion
5879
- //#region src/value-model/formula/FormulaEvaluator.ts
5880
- var FormulaEvaluator = class {
5881
- constructor(tree, options = {}) {
5882
- this.tree = tree;
5883
- this.options = options;
5884
- }
5885
- evaluate(field) {
5886
- try {
5887
- const context = this.buildContext(field);
5888
- const result = (0, _revisium_formula.evaluateWithContext)(field.expression, context);
5889
- this.setNodeValue(field, result);
5890
- this.checkForWarnings(field, result);
5891
- } catch (error) {
5892
- this.handleError(field, error);
5893
- }
5894
- }
5895
- evaluateAll(fields) {
5896
- for (const field of fields) this.evaluate(field);
5897
- }
5898
- buildContext(field) {
5899
- const context = { rootData: this.tree.getPlainValue() };
5900
- if (field.parent) {
5901
- const itemData = this.getPlainObjectValue(field.parent);
5902
- if (itemData) context.itemData = itemData;
5903
- }
5904
- if (field.arrayLevels.length > 0) context.arrayContext = { levels: this.buildArrayLevels(field) };
5905
- return context;
5906
- }
5907
- buildArrayLevels(field) {
5908
- const levels = [];
5909
- for (let i = field.arrayLevels.length - 1; i >= 0; i--) {
5910
- const level = field.arrayLevels[i];
5911
- if (!level) continue;
5912
- const { array, index } = level;
5913
- levels.push({
5914
- index,
5915
- length: array.length,
5916
- prev: this.getPrevItemValue(array, index),
5917
- next: this.getNextItemValue(array, index)
5918
- });
5919
- }
5920
- return levels;
5921
- }
5922
- getPrevItemValue(array, index) {
5923
- if (index <= 0) return null;
5924
- const prevItem = array.at(index - 1);
5925
- return prevItem ? this.getPlainNodeValue(prevItem) : null;
5926
- }
5927
- getNextItemValue(array, index) {
5928
- if (index >= array.length - 1) return null;
5929
- const nextItem = array.at(index + 1);
5930
- return nextItem ? this.getPlainNodeValue(nextItem) : null;
5931
- }
5932
- getPlainObjectValue(node) {
5933
- const result = {};
5934
- for (const child of node.children) result[child.name] = this.getPlainNodeValue(child);
5935
- return result;
5936
- }
5937
- getPlainNodeValue(node) {
5938
- if (node.isPrimitive()) return node.value;
5939
- if (node.isObject()) return this.getPlainObjectValue(node);
5940
- if (node.isArray()) {
5941
- const result = [];
5942
- for (let i = 0; i < node.length; i++) {
5943
- const item = node.at(i);
5944
- if (item) result.push(this.getPlainNodeValue(item));
5945
- }
5946
- return result;
5947
- }
5948
- return null;
5949
- }
5950
- setNodeValue(field, result) {
5951
- const { node } = field;
5952
- const defaultValue = node.defaultValue;
5953
- if (result === null || result === void 0) {
5954
- node.setValue(defaultValue, { internal: true });
5955
- return;
5956
- }
5957
- if (typeof result === "number" && (Number.isNaN(result) || !Number.isFinite(result))) {
5958
- node.setValue(defaultValue, { internal: true });
5959
- return;
5960
- }
5961
- node.setValue(result, { internal: true });
5962
- }
5963
- checkForWarnings(field, result) {
5964
- const { node } = field;
5965
- if (typeof result === "number") {
5966
- if (Number.isNaN(result)) {
5967
- node.setFormulaWarning({
5968
- type: "nan",
5969
- message: "Formula result is NaN",
5970
- expression: field.expression,
5971
- computedValue: result
5972
- });
5973
- return;
5974
- }
5975
- if (!Number.isFinite(result)) {
5976
- node.setFormulaWarning({
5977
- type: "infinity",
5978
- message: "Formula result is Infinity",
5979
- expression: field.expression,
5980
- computedValue: result
5981
- });
5982
- return;
5983
- }
5984
- }
5985
- node.setFormulaWarning(null);
5986
- }
5987
- handleError(field, error) {
5988
- const { node } = field;
5989
- node.setValue(node.defaultValue, { internal: true });
5990
- node.setFormulaWarning({
5991
- type: "runtime-error",
5992
- message: error.message,
5993
- expression: field.expression,
5994
- computedValue: void 0
5995
- });
5996
- if (this.options.onError) this.options.onError(node, error);
5997
- }
5998
- };
5999
-
6000
- //#endregion
6001
- //#region src/value-model/formula/FormulaEngine.ts
6002
- var FormulaEngine = class {
6003
- collector;
6004
- graph;
6005
- evaluator;
6006
- formulas = [];
6007
- dependencyMap = /* @__PURE__ */ new Map();
6008
- evaluationOrder = [];
6009
- disposers = [];
6010
- constructor(tree, options = {}) {
6011
- this.tree = tree;
6012
- this.collector = new FormulaCollector();
6013
- this.graph = new DependencyGraph();
6014
- this.evaluator = new FormulaEvaluator(tree, options);
6015
- this.initialize();
6016
- }
6017
- reinitialize() {
6018
- this.disposeReactions();
6019
- this.initialize();
6020
- }
6021
- dispose() {
6022
- this.disposeReactions();
6023
- this.formulas = [];
6024
- this.dependencyMap = /* @__PURE__ */ new Map();
6025
- this.evaluationOrder = [];
6026
- }
6027
- getFormulas() {
6028
- return this.formulas;
6029
- }
6030
- getEvaluationOrder() {
6031
- return this.evaluationOrder;
6032
- }
6033
- initialize() {
6034
- this.formulas = this.collector.collect(this.tree.root);
6035
- this.dependencyMap = this.graph.buildDependencyMap(this.formulas);
6036
- this.evaluationOrder = this.graph.buildEvaluationOrder(this.formulas);
6037
- this.evaluateAll();
6038
- this.setupReactions();
6039
- }
6040
- evaluateAll() {
6041
- (0, mobx.runInAction)(() => {
6042
- for (const field of this.evaluationOrder) this.evaluator.evaluate(field);
6043
- });
6044
- }
6045
- setupReactions() {
6046
- const watchedNodes = /* @__PURE__ */ new Set();
6047
- for (const [depNode] of this.dependencyMap) {
6048
- if (watchedNodes.has(depNode)) continue;
6049
- watchedNodes.add(depNode);
6050
- const disposer = (0, mobx.reaction)(() => depNode.value, () => this.handleDependencyChange(depNode));
6051
- this.disposers.push(disposer);
6052
- }
6053
- this.setupArrayReactions(this.tree.root);
6054
- }
6055
- setupArrayReactions(node) {
6056
- if (node.isArray()) {
6057
- const disposer = (0, mobx.reaction)(() => node.length, () => this.handleStructureChange());
6058
- this.disposers.push(disposer);
6059
- for (const item of node.value) this.setupArrayReactions(item);
6060
- } else if (node.isObject()) for (const child of node.children) this.setupArrayReactions(child);
6061
- }
6062
- handleDependencyChange(changedNode) {
6063
- const affected = this.graph.getAffectedFormulas(changedNode, this.dependencyMap, this.evaluationOrder);
6064
- (0, mobx.runInAction)(() => {
6065
- for (const field of affected) this.evaluator.evaluate(field);
6066
- });
6067
- }
6068
- handleStructureChange() {
6069
- this.reinitialize();
6070
- }
6071
- disposeReactions() {
6072
- for (const disposer of this.disposers) disposer();
6073
- this.disposers = [];
6074
- }
6075
- };
6076
-
6077
- //#endregion
6078
- //#region src/value-model/factory.ts
6079
- function createValueModel(schema, initialValue, options) {
6080
- const nodeFactory = options?.nodeFactory ?? createNodeFactory();
6081
- const rootNode = nodeFactory.createTree(schema, initialValue);
6082
- propagateFactoryToArrays(rootNode, nodeFactory);
6083
- const tree = new ValueTree(rootNode);
6084
- if (options?.formulaEngine !== false) {
6085
- const engine = new FormulaEngine(tree, typeof options?.formulaEngine === "object" ? options.formulaEngine : {});
6086
- tree.setFormulaEngine(engine);
6087
- }
6088
- return tree;
6089
- }
6090
- function propagateFactoryToArrays(node, factory) {
6091
- if (node.isArray()) {
6092
- node.setNodeFactory(factory);
6093
- for (const item of node.value) propagateFactoryToArrays(item, factory);
6094
- } else if (node.isObject()) for (const child of node.children) propagateFactoryToArrays(child, factory);
6095
- }
6096
- function createEmptyValueModel(schema, options) {
6097
- return createValueModel(schema, void 0, options);
6098
- }
6099
-
6100
- //#endregion
6101
- exports.ArrayValueNode = ArrayValueNode;
6102
4616
  exports.BackButton = BackButton;
6103
- exports.BooleanValueNode = BooleanValueNode;
6104
4617
  exports.CloseButton = CloseButton;
6105
4618
  exports.ContentEditable = ContentEditable;
6106
4619
  exports.CopyButton = CopyButton;
6107
4620
  exports.CreateButton = CreateButton;
6108
4621
  exports.CreatingEditorVM = CreatingEditorVM;
6109
4622
  exports.CreatingSchemaEditor = CreatingSchemaEditor;
6110
- exports.FormulaEngine = FormulaEngine;
6111
4623
  exports.GrayButton = GrayButton;
6112
4624
  exports.JsonCard = JsonCard;
6113
4625
  Object.defineProperty(exports, 'JsonSchemaTypeName', {
@@ -6116,20 +4628,27 @@ Object.defineProperty(exports, 'JsonSchemaTypeName', {
6116
4628
  return _revisium_schema_toolkit.JsonSchemaTypeName;
6117
4629
  }
6118
4630
  });
6119
- exports.NumberValueNode = NumberValueNode;
6120
- exports.ObjectValueNode = ObjectValueNode;
6121
4631
  exports.SchemaEditorCore = SchemaEditorCore;
6122
4632
  exports.SchemaTypeIds = SchemaTypeIds;
6123
4633
  exports.SettingsButton = SettingsButton;
6124
- exports.StringValueNode = StringValueNode;
6125
4634
  exports.Tooltip = Tooltip;
6126
4635
  exports.UpdatingEditorVM = UpdatingEditorVM;
6127
4636
  exports.UpdatingSchemaEditor = UpdatingSchemaEditor;
6128
- exports.ValueTree = ValueTree;
6129
4637
  exports.ViewerSwitcher = ViewerSwitcher;
6130
4638
  exports.ViewerSwitcherMode = ViewerSwitcherMode;
6131
- exports.createEmptyValueModel = createEmptyValueModel;
6132
- exports.createValueModel = createValueModel;
4639
+ Object.defineProperty(exports, 'createRowModel', {
4640
+ enumerable: true,
4641
+ get: function () {
4642
+ return _revisium_schema_toolkit.createRowModel;
4643
+ }
4644
+ });
4645
+ Object.defineProperty(exports, 'createTableModel', {
4646
+ enumerable: true,
4647
+ get: function () {
4648
+ return _revisium_schema_toolkit.createTableModel;
4649
+ }
4650
+ });
4651
+ exports.ensureReactivityProvider = ensureReactivityProvider;
6133
4652
  exports.getLabelByRef = getLabelByRef;
6134
4653
  exports.typeMenuGroups = typeMenuGroups;
6135
4654
  exports.useContentEditable = useContentEditable;