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