jedison 1.4.1 → 1.4.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.
@@ -1,8 +1,29 @@
1
1
  function clone(thing) {
2
- if (typeof thing === "undefined") {
3
- return void 0;
2
+ if (thing === null || typeof thing !== "object") {
3
+ return thing;
4
+ }
5
+ if (Array.isArray(thing)) {
6
+ const len = thing.length;
7
+ const arr = new Array(len);
8
+ for (let i = 0; i < len; i++) {
9
+ const item = thing[i];
10
+ arr[i] = item === null || typeof item !== "object" ? item : clone(item);
11
+ }
12
+ return arr;
13
+ }
14
+ const keys = Object.keys(thing);
15
+ const obj = {};
16
+ for (let i = 0, len = keys.length; i < len; i++) {
17
+ const key = keys[i];
18
+ const val = thing[key];
19
+ const cloned = val === null || typeof val !== "object" ? val : clone(val);
20
+ if (key === "__proto__") {
21
+ Object.defineProperty(obj, key, { value: cloned, writable: true, enumerable: true, configurable: true });
22
+ } else {
23
+ obj[key] = cloned;
24
+ }
4
25
  }
5
- return JSON.parse(JSON.stringify(thing));
26
+ return obj;
6
27
  }
7
28
  function escapeRegExp(string) {
8
29
  return string.replace(/[.*+?^${}()|[\]\\]/g, "\\$&");
@@ -24,11 +45,29 @@ function sortObject(obj) {
24
45
  }
25
46
  function equal(a, b) {
26
47
  if (a === b) return true;
27
- if (isObject(a) && isObject(b)) {
28
- a = sortObject(a);
29
- b = sortObject(b);
48
+ if (a === null || b === null || typeof a !== "object" || typeof b !== "object") {
49
+ return false;
50
+ }
51
+ const aIsArray = Array.isArray(a);
52
+ const bIsArray = Array.isArray(b);
53
+ if (aIsArray !== bIsArray) return false;
54
+ if (aIsArray) {
55
+ const len = a.length;
56
+ if (len !== b.length) return false;
57
+ for (let i = 0; i < len; i++) {
58
+ if (!equal(a[i], b[i])) return false;
59
+ }
60
+ return true;
61
+ }
62
+ const keysA = Object.keys(a);
63
+ const keysB = Object.keys(b);
64
+ if (keysA.length !== keysB.length) return false;
65
+ for (let i = 0, len = keysA.length; i < len; i++) {
66
+ const key = keysA[i];
67
+ if (!Object.prototype.hasOwnProperty.call(b, key)) return false;
68
+ if (!equal(a[key], b[key])) return false;
30
69
  }
31
- return JSON.stringify(a) === JSON.stringify(b);
70
+ return true;
32
71
  }
33
72
  function different(a, b) {
34
73
  return !equal(a, b);
@@ -472,9 +511,7 @@ function allOf(context) {
472
511
  const allOf2 = getSchemaAllOf(context.schema);
473
512
  if (isSet(allOf2)) {
474
513
  allOf2.forEach((schema) => {
475
- const subSchemaEditor = new Jedison({ refParser: context.validator.refParser, schema, data: context.value, rootName: context.key });
476
- const subSchemaErrors = subSchemaEditor.getErrors();
477
- subSchemaEditor.destroy();
514
+ const subSchemaErrors = context.validator.getErrors(context.value, schema, context.key, context.path);
478
515
  subSchemaErrors.forEach((error) => {
479
516
  error.path = context.path;
480
517
  });
@@ -510,14 +547,13 @@ function anyOf(context) {
510
547
  const anyOf2 = getSchemaAnyOf(context.schema);
511
548
  if (isSet(anyOf2)) {
512
549
  let valid = false;
513
- anyOf2.forEach((schema) => {
514
- const anyOfEditor = new Jedison({ refParser: context.validator.refParser, schema, data: context.value });
515
- const anyOfErrors = anyOfEditor.getErrors();
516
- anyOfEditor.destroy();
550
+ for (const schema of anyOf2) {
551
+ const anyOfErrors = context.validator.getErrors(context.value, schema, context.key, context.path);
517
552
  if (anyOfErrors.length === 0) {
518
553
  valid = true;
554
+ break;
519
555
  }
520
- });
556
+ }
521
557
  if (!valid) {
522
558
  errors.push({
523
559
  type: "error",
@@ -639,13 +675,7 @@ function items(context) {
639
675
  } else if (isObject(items2)) {
640
676
  context.value.slice(prefixItemsSchemasCount).forEach((itemValue, i) => {
641
677
  const index2 = prefixItemsSchemasCount + i;
642
- const tmpEditor = new Jedison({
643
- refParser: context.validator.refParser,
644
- schema: items2,
645
- data: itemValue
646
- });
647
- const tmpErrors = tmpEditor.getErrors();
648
- tmpEditor.destroy();
678
+ const tmpErrors = context.validator.getErrors(itemValue, items2, index2, context.path + "/" + index2);
649
679
  if (tmpErrors.length > 0) {
650
680
  errors.push({
651
681
  type: "error",
@@ -812,9 +842,7 @@ function not(context) {
812
842
  const errors = [];
813
843
  const not2 = getSchemaNot(context.schema);
814
844
  if (isSet(not2)) {
815
- const notEditor = new Jedison({ refParser: context.validator.refParser, schema: not2, data: context.value });
816
- const notErrors = notEditor.getErrors();
817
- notEditor.destroy();
845
+ const notErrors = context.validator.getErrors(context.value, not2, context.key, context.path);
818
846
  const invalid = notErrors.length === 0;
819
847
  if (invalid) {
820
848
  errors.push({
@@ -835,9 +863,7 @@ function oneOf(context) {
835
863
  if (isSet(oneOf2)) {
836
864
  let counter = 0;
837
865
  oneOf2.forEach((schema) => {
838
- const oneOfEditor = new Jedison({ refParser: context.validator.refParser, schema, data: context.value });
839
- const oneOfErrors = oneOfEditor.getErrors();
840
- oneOfEditor.destroy();
866
+ const oneOfErrors = context.validator.getErrors(context.value, schema, context.key, context.path);
841
867
  if (oneOfErrors.length === 0) {
842
868
  counter++;
843
869
  }
@@ -887,12 +913,7 @@ function patternProperties(context) {
887
913
  const regexp = new RegExp(pattern2);
888
914
  if (regexp.test(propertyName)) {
889
915
  const schema = patternProperties2[pattern2];
890
- const editor = new Jedison({
891
- refParser: context.validator.refParser,
892
- schema,
893
- data: context.value[propertyName]
894
- });
895
- const editorErrors = editor.getErrors().map((error) => {
916
+ const editorErrors = context.validator.getErrors(context.value[propertyName], schema, propertyName, context.path + "/" + propertyName).map((error) => {
896
917
  return {
897
918
  type: "error",
898
919
  path: context.path + "/" + propertyName,
@@ -901,7 +922,6 @@ function patternProperties(context) {
901
922
  };
902
923
  });
903
924
  errors = [...errors, ...editorErrors];
904
- editor.destroy();
905
925
  }
906
926
  });
907
927
  });
@@ -1085,19 +1105,13 @@ function additionalProperties(context) {
1085
1105
  ]
1086
1106
  });
1087
1107
  } else if (isObject(additionalProperties2)) {
1088
- const editor = new Jedison({
1089
- refParser: context.validator.refParser,
1090
- schema: additionalProperties2,
1091
- data: context.value[property]
1092
- });
1093
- const additionalPropertyErrors = editor.getErrors().map((error) => ({
1108
+ const additionalPropertyErrors = context.validator.getErrors(context.value[property], additionalProperties2, property, context.path + "/" + property).map((error) => ({
1094
1109
  type: "error",
1095
1110
  path: `${context.path}.${property}`,
1096
1111
  constraint: "additionalProperties",
1097
1112
  messages: error.messages
1098
1113
  }));
1099
1114
  errors.push(...additionalPropertyErrors);
1100
- editor.destroy();
1101
1115
  }
1102
1116
  }
1103
1117
  });
@@ -1159,13 +1173,11 @@ function contains(context) {
1159
1173
  const maxContains = getSchemaMaxContains(context.schema);
1160
1174
  if (isArray(context.value) && isSet(contains2)) {
1161
1175
  let counter = 0;
1162
- context.value.forEach((item) => {
1163
- const containsEditor = new Jedison({ refParser: context.validator.refParser, schema: contains2, data: item });
1164
- const containsErrors = containsEditor.getErrors();
1176
+ context.value.forEach((item, index2) => {
1177
+ const containsErrors = context.validator.getErrors(item, contains2, index2, context.path + "/" + index2);
1165
1178
  if (containsErrors.length === 0) {
1166
1179
  counter++;
1167
1180
  }
1168
- containsEditor.destroy();
1169
1181
  });
1170
1182
  const containsInvalid = counter === 0;
1171
1183
  if (isSet(minContains)) {
@@ -1248,9 +1260,7 @@ function dependentSchemas(context) {
1248
1260
  Object.keys(dependentSchemas2).forEach((key) => {
1249
1261
  if (isSet(context.value[key])) {
1250
1262
  const dependentSchema = dependentSchemas2[key];
1251
- const tmpEditor = new Jedison({ refParser: context.validator.refParser, schema: dependentSchema, data: context.value });
1252
- const tmpErrors = tmpEditor.getErrors();
1253
- tmpEditor.destroy();
1263
+ const tmpErrors = context.validator.getErrors(context.value, dependentSchema, context.key, context.path);
1254
1264
  errors = [...errors, ...tmpErrors];
1255
1265
  }
1256
1266
  });
@@ -1258,43 +1268,26 @@ function dependentSchemas(context) {
1258
1268
  return errors;
1259
1269
  }
1260
1270
  function ifThenElse(context) {
1261
- const errors = [];
1262
1271
  const schemaIf = getSchemaIf(context.schema);
1263
1272
  const schemaThen = getSchemaThen(context.schema);
1264
1273
  const schemaElse = getSchemaElse(context.schema);
1265
1274
  if (isSet(schemaIf)) {
1266
1275
  if (notSet(schemaThen) && notSet(schemaElse)) {
1267
- return errors;
1268
- }
1269
- const ifEditor = new Jedison({ refParser: context.validator.refParser, schema: schemaIf, data: context.value });
1270
- const ifErrors = ifEditor.getErrors();
1271
- ifEditor.destroy();
1272
- let thenErrors = [];
1273
- let elseErrors = [];
1274
- if (isSet(schemaThen)) {
1275
- const thenEditor = new Jedison({ refParser: context.validator.refParser, schema: schemaThen, data: context.value });
1276
- thenErrors = thenEditor.getErrors();
1277
- thenEditor.destroy();
1278
- }
1279
- if (isSet(schemaElse)) {
1280
- const elseEditor = new Jedison({ refParser: context.validator.refParser, schema: schemaElse, data: context.value });
1281
- elseErrors = elseEditor.getErrors();
1282
- elseEditor.destroy();
1276
+ return [];
1283
1277
  }
1284
1278
  if (schemaIf === true) {
1285
- return thenErrors;
1279
+ return isSet(schemaThen) ? context.validator.getErrors(context.value, schemaThen, context.key, context.path) : [];
1286
1280
  }
1287
1281
  if (schemaIf === false) {
1288
- return elseErrors;
1282
+ return isSet(schemaElse) ? context.validator.getErrors(context.value, schemaElse, context.key, context.path) : [];
1289
1283
  }
1284
+ const ifErrors = context.validator.getErrors(context.value, schemaIf, context.key, context.path);
1290
1285
  if (ifErrors.length === 0) {
1291
- return thenErrors;
1292
- }
1293
- if (ifErrors.length > 0) {
1294
- return elseErrors;
1286
+ return isSet(schemaThen) ? context.validator.getErrors(context.value, schemaThen, context.key, context.path) : [];
1295
1287
  }
1288
+ return isSet(schemaElse) ? context.validator.getErrors(context.value, schemaElse, context.key, context.path) : [];
1296
1289
  }
1297
- return errors;
1290
+ return [];
1298
1291
  }
1299
1292
  function prefixItems(context) {
1300
1293
  const errors = [];
@@ -1303,9 +1296,7 @@ function prefixItems(context) {
1303
1296
  prefixItems2.forEach((itemSchema, index2) => {
1304
1297
  const itemValue = context.value[index2];
1305
1298
  if (isSet(itemValue)) {
1306
- const tmpEditor = new Jedison({ refParser: context.validator.refParser, schema: itemSchema, data: itemValue });
1307
- const tmpErrors = tmpEditor.getErrors();
1308
- tmpEditor.destroy();
1299
+ const tmpErrors = context.validator.getErrors(itemValue, itemSchema, index2, context.path + "/" + index2);
1309
1300
  if (tmpErrors.length > 0) {
1310
1301
  errors.push({
1311
1302
  type: "error",
@@ -1437,12 +1428,7 @@ function unevaluatedProperties(context) {
1437
1428
  });
1438
1429
  }
1439
1430
  if (!definedInPatternProperty && isObject(unevaluatedProperties2) && !hasOwn(properties2, property)) {
1440
- const editor = new Jedison({
1441
- refParser: context.validator.refParser,
1442
- schema: unevaluatedProperties2,
1443
- data: context.value[property]
1444
- });
1445
- const unevaluatedPropertiesErrors = editor.getErrors().map((error) => {
1431
+ const unevaluatedPropertiesErrors = context.validator.getErrors(context.value[property], unevaluatedProperties2, property, context.path + "/" + property).map((error) => {
1446
1432
  return {
1447
1433
  type: "error",
1448
1434
  path: property,
@@ -1451,7 +1437,6 @@ function unevaluatedProperties(context) {
1451
1437
  };
1452
1438
  });
1453
1439
  errors = [...errors, ...unevaluatedPropertiesErrors];
1454
- editor.destroy();
1455
1440
  }
1456
1441
  });
1457
1442
  }
@@ -1497,12 +1482,7 @@ function propertyNames(context) {
1497
1482
  const schemaPropertyNames = getSchemaPropertyNames(context.schema);
1498
1483
  if (isObject(context.value) && isSet(schemaPropertyNames)) {
1499
1484
  Object.keys(context.value).forEach((propertyName) => {
1500
- const editor = new Jedison({
1501
- refParser: context.validator.refParser,
1502
- schema: schemaPropertyNames,
1503
- data: propertyName
1504
- });
1505
- const invalid = editor.getErrors().length > 0;
1485
+ const invalid = context.validator.getErrors(propertyName, schemaPropertyNames, propertyName, context.path).length > 0;
1506
1486
  if (invalid) {
1507
1487
  errors.push({
1508
1488
  type: "error",
@@ -1572,24 +1552,26 @@ class Validator {
1572
1552
  */
1573
1553
  getErrors(value, schema, key, path) {
1574
1554
  let schemaErrors = [];
1575
- const schemaClone = clone(schema);
1576
- if (isBoolean(schemaClone) && schemaClone === true) {
1555
+ if (isBoolean(schema) && schema === true) {
1577
1556
  return schemaErrors;
1578
1557
  }
1579
- if (isBoolean(schemaClone) && schemaClone === false) {
1558
+ if (isBoolean(schema) && schema === false) {
1580
1559
  return [{
1581
1560
  type: "error",
1582
1561
  messages: ["invalid"],
1583
1562
  path
1584
1563
  }];
1585
1564
  }
1565
+ if (this.refParser && isObject(schema) && hasOwn(schema, "$ref")) {
1566
+ schema = this.refParser.expand(schema);
1567
+ }
1586
1568
  const allConstraints = { ...this.draft, ...this.constraints };
1587
1569
  for (const [constraintName, constraint] of Object.entries(allConstraints)) {
1588
- if (hasOwn(schemaClone, constraintName)) {
1570
+ if (hasOwn(schema, constraintName)) {
1589
1571
  const context = {
1590
1572
  validator: this,
1591
1573
  value,
1592
- schema: schemaClone,
1574
+ schema,
1593
1575
  key,
1594
1576
  path,
1595
1577
  translator: this.translator
@@ -1628,7 +1610,7 @@ class Validator {
1628
1610
  }
1629
1611
  class EventEmitter {
1630
1612
  constructor() {
1631
- this.listeners = [];
1613
+ this.listeners = /* @__PURE__ */ new Map();
1632
1614
  }
1633
1615
  /**
1634
1616
  * Adds a named event listener
@@ -1637,10 +1619,15 @@ class EventEmitter {
1637
1619
  * @param {function} callback - A callback functions that will be executed when this event is emitted
1638
1620
  */
1639
1621
  on(name, callback) {
1640
- this.listeners.push({ name, callback });
1622
+ let callbacks = this.listeners.get(name);
1623
+ if (!callbacks) {
1624
+ callbacks = [];
1625
+ this.listeners.set(name, callbacks);
1626
+ }
1627
+ callbacks.push(callback);
1641
1628
  }
1642
1629
  off(name) {
1643
- this.listeners = this.listeners.filter((listener) => listener.name !== name);
1630
+ this.listeners.delete(name);
1644
1631
  }
1645
1632
  /**
1646
1633
  * Triggers the callback function of a named event listener
@@ -1649,14 +1636,16 @@ class EventEmitter {
1649
1636
  * @param {...*} args - Arguments to be passed to the callback function
1650
1637
  */
1651
1638
  emit(name, ...args) {
1652
- const listeners = this.listeners.filter((listener) => listener.name === name);
1653
- listeners.forEach((listener) => {
1654
- try {
1655
- listener.callback(...args);
1656
- } catch (error) {
1657
- console.error(`Error in listener callback for event "${name}":`, error);
1639
+ const callbacks = this.listeners.get(name);
1640
+ if (callbacks) {
1641
+ for (const listener of callbacks) {
1642
+ try {
1643
+ listener(...args);
1644
+ } catch (error) {
1645
+ console.error(`Error in listener callback for event "${name}":`, error);
1646
+ }
1658
1647
  }
1659
- });
1648
+ }
1660
1649
  }
1661
1650
  /**
1662
1651
  * Deletes all properties of the class
@@ -1680,6 +1669,8 @@ class Instance extends EventEmitter {
1680
1669
  this.children = [];
1681
1670
  this.ui = null;
1682
1671
  this.isDirty = false;
1672
+ this.cachedErrors = null;
1673
+ this.cachedErrorsValue = void 0;
1683
1674
  this.watched = {};
1684
1675
  this.key = this.path.split(this.jedison.pathSeparator).pop();
1685
1676
  this.arrayTemplateData = config.arrayTemplateData || {};
@@ -1764,7 +1755,7 @@ class Instance extends EventEmitter {
1764
1755
  const enforceEnum = schemaEnforceEnum ?? this.jedison.options.enforceEnum;
1765
1756
  const finalEnforceEnum = isSet(schemaEnforceEnum) ? enforceEnum : enforceEnumDefault;
1766
1757
  const schemaEnum = getSchemaEnum(this.schema);
1767
- if (isSet(schemaEnum) && !schemaEnum.includes(this.getValue()) && isSet(schemaEnum[0]) && finalEnforceEnum) {
1758
+ if (isSet(schemaEnum) && !schemaEnum.includes(this.getValueRaw()) && isSet(schemaEnum[0]) && finalEnforceEnum) {
1768
1759
  this.setValue(schemaEnum[0], false);
1769
1760
  }
1770
1761
  if (notSet(this.value)) {
@@ -1829,13 +1820,19 @@ class Instance extends EventEmitter {
1829
1820
  getValue() {
1830
1821
  return clone(this.value);
1831
1822
  }
1823
+ /**
1824
+ * Returns the value of the instance without cloning (internal read-only use)
1825
+ */
1826
+ getValueRaw() {
1827
+ return this.value;
1828
+ }
1832
1829
  /**
1833
1830
  * Returns the data that will replace placeholders in titles, descriptions (e.g. "{{ i1 }} {{ value.title }}")
1834
1831
  */
1835
1832
  getTemplateData(template) {
1836
1833
  const templateData = {
1837
1834
  ...this.arrayTemplateData,
1838
- value: this.getValue(),
1835
+ value: this.getValueRaw(),
1839
1836
  settings: this.jedison.options.settings
1840
1837
  };
1841
1838
  if (typeof this.value === "string") {
@@ -1889,6 +1886,7 @@ class Instance extends EventEmitter {
1889
1886
  }
1890
1887
  this.value = newValue;
1891
1888
  this.isDirty = true;
1889
+ this.cachedErrors = null;
1892
1890
  this.emit("set-value", newValue, initiator);
1893
1891
  this.emit("change", initiator);
1894
1892
  this.jedison.emit("instance-change", this, initiator);
@@ -1909,8 +1907,15 @@ class Instance extends EventEmitter {
1909
1907
  if (!this.isActive) {
1910
1908
  return [];
1911
1909
  }
1912
- const errors = this.jedison.validator.getErrors(this.getValue(), this.originalSchema, this.getKey(), this.path);
1913
- return removeDuplicatesFromArray(errors);
1910
+ if (this.cachedErrorsValue === this.value && this.cachedErrors !== null) {
1911
+ return this.cachedErrors;
1912
+ }
1913
+ const errors = removeDuplicatesFromArray(
1914
+ this.jedison.validator.getErrors(this.getValueRaw(), this.originalSchema, this.getKey(), this.path)
1915
+ );
1916
+ this.cachedErrorsValue = this.value;
1917
+ this.cachedErrors = errors;
1918
+ return errors;
1914
1919
  }
1915
1920
  /**
1916
1921
  * Returns true if any leaf descendant is showing validation errors.
@@ -2379,7 +2384,7 @@ class InstanceIfThenElse extends Instance {
2379
2384
  this.on("set-value", (value, initiator) => {
2380
2385
  this.changeValue(value, initiator);
2381
2386
  });
2382
- const ifValue = this.instanceWithoutIf.getValue();
2387
+ const ifValue = this.instanceWithoutIf.getValueRaw();
2383
2388
  this.changeValue(ifValue);
2384
2389
  }
2385
2390
  changeValue(value, initiator = "api") {
@@ -2415,7 +2420,7 @@ class InstanceIfThenElse extends Instance {
2415
2420
  }
2416
2421
  instance.setValue(instanceValue, false, initiator);
2417
2422
  instance.on("notifyParent", (initiator2) => {
2418
- const value2 = instance.getValue();
2423
+ const value2 = instance.getValueRaw();
2419
2424
  this.changeValue(value2, initiator2);
2420
2425
  this.emit("notifyParent", initiator2);
2421
2426
  this.emit("change", initiator2);
@@ -2424,7 +2429,7 @@ class InstanceIfThenElse extends Instance {
2424
2429
  if (initiator === "api" && this.hasNullableFields(this.activeInstance)) {
2425
2430
  this.activeInstance.setValue(value, false, "secondary");
2426
2431
  }
2427
- this.value = this.activeInstance.getValue();
2432
+ this.value = this.activeInstance.getValueRaw();
2428
2433
  }
2429
2434
  getWithoutIfValueFromValue(value) {
2430
2435
  let withoutIf = this.instanceWithoutIf.getValue();
@@ -2483,23 +2488,15 @@ class InstanceIfThenElse extends Instance {
2483
2488
  */
2484
2489
  getFittestIndex(value) {
2485
2490
  let fittestIndex = this.index;
2491
+ const key = this.getKey();
2486
2492
  this.ifThenElseSchemas.forEach((schema, index2) => {
2487
2493
  if (schema.if === true) {
2488
2494
  fittestIndex = 0;
2489
2495
  } else if (schema.if === false) {
2490
2496
  fittestIndex = 1;
2491
2497
  } else {
2492
- const testSchema = clone(schema.if);
2493
- if (isSet(this.schema.type)) {
2494
- testSchema.type = this.schema.type;
2495
- }
2496
- const ifValidator = new Jedison({
2497
- schema: testSchema,
2498
- data: value,
2499
- refParser: this.jedison.refParser
2500
- });
2501
- const ifErrors = ifValidator.getErrors();
2502
- ifValidator.destroy();
2498
+ const testSchema = isSet(this.schema.type) ? { ...schema.if, type: this.schema.type } : schema.if;
2499
+ const ifErrors = this.jedison.validator.getErrors(value, testSchema, key, this.path);
2503
2500
  if (ifErrors.length === 0 && schema.then) {
2504
2501
  fittestIndex = index2;
2505
2502
  }
@@ -2610,7 +2607,7 @@ class InstanceMultiple extends Instance {
2610
2607
  instance.unregister();
2611
2608
  instance.off("notifyParent");
2612
2609
  instance.on("notifyParent", (initiator) => {
2613
- this.value = this.activeInstance.getValue();
2610
+ this.value = this.activeInstance.getValueRaw();
2614
2611
  this.emit("notifyParent", initiator);
2615
2612
  this.emit("change", initiator);
2616
2613
  });
@@ -2626,10 +2623,10 @@ class InstanceMultiple extends Instance {
2626
2623
  if (isSet(value)) {
2627
2624
  this.activeInstance.setValue(value, false, initiator);
2628
2625
  }
2629
- this.setValue(this.activeInstance.getValue(), true, initiator);
2626
+ this.setValue(this.activeInstance.getValueRaw(), true, initiator);
2630
2627
  }
2631
2628
  onSetValue() {
2632
- if (different(this.activeInstance.getValue(), this.value)) {
2629
+ if (different(this.activeInstance.getValueRaw(), this.value)) {
2633
2630
  const fittestIndex = this.getFittestIndex(this.value);
2634
2631
  this.switchInstance(fittestIndex, this.value);
2635
2632
  }
@@ -2642,9 +2639,8 @@ class InstanceMultiple extends Instance {
2642
2639
  let championErrors;
2643
2640
  for (let index2 = 0; index2 < this.instances.length; index2++) {
2644
2641
  const instance = this.instances[index2];
2645
- const tmpEditor = new Jedison({ refParser: this.jedison.refParser, schema: instance.schema, data: value });
2646
- const instanceErrors = tmpEditor.getErrors();
2647
- tmpEditor.destroy();
2642
+ const testValue = isSet(value) ? value : instance.getValueRaw();
2643
+ const instanceErrors = this.jedison.validator.getErrors(testValue, instance.schema, this.getKey(), this.path);
2648
2644
  if (instanceErrors.length === 0) {
2649
2645
  fittestIndex = index2;
2650
2646
  break;
@@ -2672,6 +2668,8 @@ class InstanceObject extends Instance {
2672
2668
  prepare() {
2673
2669
  this.properties = {};
2674
2670
  this.requiredProperties = /* @__PURE__ */ new Set();
2671
+ this.schemaPatternProperties = getSchemaPatternProperties(this.schema);
2672
+ this.schemaAdditionalProperties = getSchemaAdditionalProperties(this.schema);
2675
2673
  const schemaProperties = getSchemaProperties(this.schema);
2676
2674
  const schemaRequired = getSchemaRequired(this.schema);
2677
2675
  if (isSet(schemaProperties)) {
@@ -2683,16 +2681,17 @@ class InstanceObject extends Instance {
2683
2681
  const optionsDeactivateNonRequired = this.jedison.options.deactivateNonRequired;
2684
2682
  const deactivateNonRequired = getSchemaXOption(this.schema, "deactivateNonRequired");
2685
2683
  const schemaDeactivateNonRequired = getSchemaXOption(schema, "deactivateNonRequired");
2686
- if (!this.isRequired(key) && isSet(optionsDeactivateNonRequired) && optionsDeactivateNonRequired === true) {
2684
+ const isReq = this.isRequired(key);
2685
+ if (!isReq && isSet(optionsDeactivateNonRequired) && optionsDeactivateNonRequired === true) {
2687
2686
  musstCreateChild = false;
2688
2687
  }
2689
- if (!this.isRequired(key) && isSet(deactivateNonRequired) && deactivateNonRequired === true) {
2688
+ if (!isReq && isSet(deactivateNonRequired) && deactivateNonRequired === true) {
2690
2689
  musstCreateChild = false;
2691
2690
  }
2692
- if (!this.isRequired(key) && isSet(schemaDeactivateNonRequired) && schemaDeactivateNonRequired === true) {
2691
+ if (!isReq && isSet(schemaDeactivateNonRequired) && schemaDeactivateNonRequired === true) {
2693
2692
  musstCreateChild = false;
2694
2693
  }
2695
- if (!this.isRequired(key) && isRecursive) {
2694
+ if (!isReq && isRecursive) {
2696
2695
  musstCreateChild = false;
2697
2696
  }
2698
2697
  if (musstCreateChild) {
@@ -2719,11 +2718,12 @@ class InstanceObject extends Instance {
2719
2718
  removeNotListedPropertiesFromValue(value) {
2720
2719
  const schemaEnforceAdditionalProperties = getSchemaXOption(this.schema, "enforceAdditionalProperties");
2721
2720
  const enforceAdditionalProperties = isSet(schemaEnforceAdditionalProperties) ? schemaEnforceAdditionalProperties : this.jedison.options.enforceAdditionalProperties;
2722
- const schemaAdditionalProperties = getSchemaAdditionalProperties(this.schema);
2723
- const schemaPatternProperties = getSchemaPatternProperties(this.schema) || {};
2721
+ const schemaAdditionalProperties = this.schemaAdditionalProperties;
2722
+ const schemaPatternProperties = this.schemaPatternProperties || {};
2724
2723
  if (this.jedison.isEditor && enforceAdditionalProperties && isSet(schemaAdditionalProperties) && schemaAdditionalProperties === false) {
2724
+ const compiledPatterns = Object.keys(schemaPatternProperties).map((p) => new RegExp(p));
2725
2725
  Object.keys(value).forEach((propertyName) => {
2726
- const matchesPattern = Object.keys(schemaPatternProperties).some((pattern2) => new RegExp(pattern2).test(propertyName));
2726
+ const matchesPattern = compiledPatterns.some((re) => re.test(propertyName));
2727
2727
  if (!hasOwn(this.properties, propertyName) && !matchesPattern) {
2728
2728
  console.warn("deleting", propertyName);
2729
2729
  delete value[propertyName];
@@ -2803,18 +2803,18 @@ class InstanceObject extends Instance {
2803
2803
  }
2804
2804
  getPropertySchema(propertyName) {
2805
2805
  let schema;
2806
- const schemaAdditionalProperties = getSchemaAdditionalProperties(this.schema);
2806
+ const schemaAdditionalProperties = this.schemaAdditionalProperties;
2807
2807
  const schemaProperties = getSchemaProperties(this.schema);
2808
- const schemaPatternProperties = getSchemaPatternProperties(this.schema);
2808
+ const schemaPatternProperties = this.schemaPatternProperties;
2809
2809
  if (isSet(schemaProperties) && hasOwn(schemaProperties, propertyName)) {
2810
2810
  schema = schemaProperties[propertyName];
2811
2811
  } else if (isSet(schemaPatternProperties)) {
2812
- Object.keys(schemaPatternProperties).forEach((pattern2) => {
2813
- const regexp = new RegExp(pattern2);
2814
- if (regexp.test(propertyName)) {
2812
+ for (const pattern2 of Object.keys(schemaPatternProperties)) {
2813
+ if (new RegExp(pattern2).test(propertyName)) {
2815
2814
  schema = schemaPatternProperties[pattern2];
2815
+ break;
2816
2816
  }
2817
- });
2817
+ }
2818
2818
  }
2819
2819
  if (notSet(schema) && isSet(schemaAdditionalProperties)) {
2820
2820
  schema = schemaAdditionalProperties;
@@ -2831,11 +2831,11 @@ class InstanceObject extends Instance {
2831
2831
  const propertyName = child.getKey();
2832
2832
  if (propertyName === "__proto__") {
2833
2833
  Object.defineProperty(value, propertyName, {
2834
- value: child.getValue(),
2834
+ value: child.getValueRaw(),
2835
2835
  enumerable: true
2836
2836
  });
2837
2837
  } else {
2838
- value[propertyName] = child.getValue();
2838
+ value[propertyName] = child.getValueRaw();
2839
2839
  }
2840
2840
  }
2841
2841
  });
@@ -2876,15 +2876,19 @@ class InstanceObject extends Instance {
2876
2876
  if (!isObject(value)) {
2877
2877
  return;
2878
2878
  }
2879
+ const childMap = /* @__PURE__ */ new Map();
2880
+ for (const child of this.children) {
2881
+ childMap.set(child.getKey(), child);
2882
+ }
2879
2883
  Object.keys(value).forEach((propertyName) => {
2880
- const child = this.getChild(propertyName);
2884
+ const child = childMap.get(propertyName);
2881
2885
  if (child) {
2882
2886
  child.activate();
2883
- const oldValue = child.getValue();
2884
- const newValue = value[child.getKey()];
2887
+ const oldValue = child.getValueRaw();
2888
+ const newValue = value[propertyName];
2885
2889
  if (different(oldValue, newValue)) {
2886
2890
  const finalValue = child.setValue(newValue, false, initiator);
2887
- value[child.getKey()] = finalValue;
2891
+ value[propertyName] = finalValue;
2888
2892
  }
2889
2893
  } else {
2890
2894
  const schema = this.getPropertySchema(propertyName);
@@ -2895,7 +2899,7 @@ class InstanceObject extends Instance {
2895
2899
  const instance = this.children[i];
2896
2900
  const propertyName = instance.getKey();
2897
2901
  if (notSet(value[propertyName])) {
2898
- if (this.getChild(propertyName)) {
2902
+ if (childMap.has(propertyName)) {
2899
2903
  instance.deactivate();
2900
2904
  } else {
2901
2905
  this.deleteChild(propertyName);
@@ -2908,6 +2912,8 @@ class InstanceObject extends Instance {
2908
2912
  }
2909
2913
  class InstanceArray extends Instance {
2910
2914
  prepare() {
2915
+ this.schemaItems = getSchemaItems(this.schema);
2916
+ this.schemaPrefixItems = getSchemaPrefixItems(this.schema);
2911
2917
  const schemaMinItems = getSchemaMinItems(this.schema);
2912
2918
  const schemaEnforceMinItems = getSchemaXOption(this.schema, "enforceMinItems");
2913
2919
  const enforceMinItems = isSet(schemaEnforceMinItems) ? schemaEnforceMinItems : this.jedison.options.enforceMinItems;
@@ -2927,8 +2933,8 @@ class InstanceArray extends Instance {
2927
2933
  createItemInstance(index2) {
2928
2934
  let schema;
2929
2935
  const itemsCount = this.children.length;
2930
- const schemaItems = getSchemaItems(this.schema);
2931
- const schemaPrefixItems = getSchemaPrefixItems(this.schema);
2936
+ const schemaItems = this.schemaItems;
2937
+ const schemaPrefixItems = this.schemaPrefixItems;
2932
2938
  schema = isSet(schemaItems) ? schemaItems : {};
2933
2939
  const hasPrefixItemsSchema = isSet(schemaPrefixItems) && isSet(schemaPrefixItems[itemsCount]);
2934
2940
  if (hasPrefixItemsSchema) {
@@ -2952,10 +2958,11 @@ class InstanceArray extends Instance {
2952
2958
  }
2953
2959
  }
2954
2960
  move(fromIndex, toIndex, initiator) {
2955
- const value = clone(this.getValue());
2956
- if (!isArray(value)) {
2961
+ const raw = this.getValueRaw();
2962
+ if (!isArray(raw)) {
2957
2963
  return;
2958
2964
  }
2965
+ const value = clone(raw);
2959
2966
  const item = value[fromIndex];
2960
2967
  value.splice(fromIndex, 1);
2961
2968
  value.splice(toIndex, 0, item);
@@ -2965,11 +2972,9 @@ class InstanceArray extends Instance {
2965
2972
  }
2966
2973
  addItem(initiator) {
2967
2974
  const tempEditor = this.createItemInstance();
2968
- let value = clone(this.getValue());
2969
- if (!isArray(value)) {
2970
- value = [];
2971
- }
2972
- value.push(tempEditor.getValue());
2975
+ const raw = this.getValueRaw();
2976
+ const value = isArray(raw) ? clone(raw) : [];
2977
+ value.push(tempEditor.getValueRaw());
2973
2978
  tempEditor.destroy();
2974
2979
  this.setValue(value, true, initiator);
2975
2980
  const instance = this.children[this.children.length - 1];
@@ -2977,10 +2982,11 @@ class InstanceArray extends Instance {
2977
2982
  this.jedison.emit("item-add", initiator, instance);
2978
2983
  }
2979
2984
  deleteItem(itemIndex, initiator) {
2980
- const currentValue = clone(this.getValue());
2981
- if (!isArray(currentValue)) {
2985
+ const raw = this.getValueRaw();
2986
+ if (!isArray(raw)) {
2982
2987
  return;
2983
2988
  }
2989
+ const currentValue = clone(raw);
2984
2990
  const newValue = currentValue.filter((item, index2) => index2 !== itemIndex);
2985
2991
  this.setValue(newValue, true, initiator);
2986
2992
  this.emit("item-delete", initiator);
@@ -2989,7 +2995,7 @@ class InstanceArray extends Instance {
2989
2995
  onChildChange(initiator) {
2990
2996
  const value = [];
2991
2997
  this.children.forEach((child) => {
2992
- value.push(child.getValue());
2998
+ value.push(child.getValueRaw());
2993
2999
  });
2994
3000
  this.value = value;
2995
3001
  this.jedison.emit("instance-change", this, initiator);
@@ -2997,18 +3003,28 @@ class InstanceArray extends Instance {
2997
3003
  this.emit("notifyParent", initiator);
2998
3004
  }
2999
3005
  refreshChildren() {
3000
- this.children = [];
3001
- const value = this.getValue();
3006
+ const value = this.getValueRaw();
3002
3007
  if (!isArray(value)) {
3008
+ this.children = [];
3003
3009
  return;
3004
3010
  }
3005
3011
  const correctedValues = [];
3006
- value.forEach((itemValue, index2) => {
3007
- const child = this.createItemInstance(index2);
3008
- this.children.push(child);
3009
- const finalValue = child.setValue(itemValue, false);
3010
- correctedValues.push(finalValue);
3011
- });
3012
+ for (let index2 = 0; index2 < value.length; index2++) {
3013
+ if (index2 < this.children.length) {
3014
+ const child = this.children[index2];
3015
+ const finalValue = child.setValue(value[index2], false);
3016
+ correctedValues.push(finalValue);
3017
+ } else {
3018
+ const child = this.createItemInstance(index2);
3019
+ this.children.push(child);
3020
+ const finalValue = child.setValue(value[index2], false);
3021
+ correctedValues.push(finalValue);
3022
+ }
3023
+ }
3024
+ while (this.children.length > value.length) {
3025
+ const child = this.children.pop();
3026
+ child.destroy();
3027
+ }
3012
3028
  this.value = correctedValues;
3013
3029
  }
3014
3030
  }
@@ -3726,6 +3742,7 @@ class EditorObject extends Editor {
3726
3742
  } = this.theme.getPropertiesGroup();
3727
3743
  this.control.propertiesActivators.appendChild(defaultGroupContainer);
3728
3744
  const propertiesGroups = {};
3745
+ const currentValue = this.instance.getValue();
3729
3746
  properties2.forEach((property) => {
3730
3747
  const isRequired = this.instance.isRequired(property);
3731
3748
  const ariaLive = this.control.ariaLive;
@@ -3773,7 +3790,7 @@ class EditorObject extends Editor {
3773
3790
  defaultGroup.appendChild(checkboxControl.container);
3774
3791
  }
3775
3792
  checkbox.disabled = this.disabled || isRequired;
3776
- checkbox.checked = hasOwn(this.instance.getValue(), property);
3793
+ checkbox.checked = hasOwn(currentValue, property);
3777
3794
  });
3778
3795
  }
3779
3796
  }
@@ -5659,12 +5676,11 @@ class Jedison extends EventEmitter {
5659
5676
  });
5660
5677
  }
5661
5678
  this.on("instance-change", (instance) => {
5662
- for (const [path, callbacks] of Object.entries(this.watched)) {
5663
- if (instance.path === path) {
5664
- callbacks.forEach((callback) => {
5665
- callback();
5666
- });
5667
- }
5679
+ const callbacks = this.watched[instance.path];
5680
+ if (callbacks) {
5681
+ callbacks.forEach((callback) => {
5682
+ callback();
5683
+ });
5668
5684
  }
5669
5685
  });
5670
5686
  if (this.hiddenInput) {