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