tinybase 9.1.0-beta.1 → 9.1.0-beta.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.
Files changed (80) hide show
  1. package/@types/_internal/store/with-schemas/index.d.ts +133 -2
  2. package/@types/indexes/index.d.ts +97 -0
  3. package/@types/indexes/with-schemas/index.d.ts +137 -0
  4. package/@types/store/index.d.ts +96 -18
  5. package/@types/store/with-schemas/index.d.ts +107 -44
  6. package/@types/ui-react/index.d.ts +42 -0
  7. package/@types/ui-react/with-schemas/index.d.ts +101 -32
  8. package/@types/ui-solid/index.d.ts +42 -0
  9. package/@types/ui-solid/with-schemas/index.d.ts +101 -32
  10. package/@types/ui-svelte/index.d.ts +34 -0
  11. package/@types/ui-svelte/with-schemas/index.d.ts +34 -0
  12. package/index.js +121 -32
  13. package/indexes/index.js +39 -0
  14. package/indexes/with-schemas/index.js +39 -0
  15. package/mergeable-store/index.js +82 -32
  16. package/mergeable-store/with-schemas/index.js +82 -32
  17. package/min/index.js +1 -1
  18. package/min/index.js.gz +0 -0
  19. package/min/indexes/index.js +1 -1
  20. package/min/indexes/index.js.gz +0 -0
  21. package/min/indexes/with-schemas/index.js +1 -1
  22. package/min/indexes/with-schemas/index.js.gz +0 -0
  23. package/min/mergeable-store/index.js +1 -1
  24. package/min/mergeable-store/index.js.gz +0 -0
  25. package/min/mergeable-store/with-schemas/index.js +1 -1
  26. package/min/mergeable-store/with-schemas/index.js.gz +0 -0
  27. package/min/omni/index.js +1 -1
  28. package/min/omni/index.js.gz +0 -0
  29. package/min/omni/with-schemas/index.js +1 -1
  30. package/min/omni/with-schemas/index.js.gz +0 -0
  31. package/min/store/index.js +1 -1
  32. package/min/store/index.js.gz +0 -0
  33. package/min/store/with-schemas/index.js +1 -1
  34. package/min/store/with-schemas/index.js.gz +0 -0
  35. package/min/ui-react/index.js +1 -1
  36. package/min/ui-react/index.js.gz +0 -0
  37. package/min/ui-react/with-schemas/index.js +1 -1
  38. package/min/ui-react/with-schemas/index.js.gz +0 -0
  39. package/min/ui-react-inspector/index.js +1 -1
  40. package/min/ui-react-inspector/index.js.gz +0 -0
  41. package/min/ui-react-inspector/with-schemas/index.js +1 -1
  42. package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
  43. package/min/ui-solid/index.js +1 -1
  44. package/min/ui-solid/index.js.gz +0 -0
  45. package/min/ui-solid/with-schemas/index.js +1 -1
  46. package/min/ui-solid/with-schemas/index.js.gz +0 -0
  47. package/min/ui-solid-inspector/index.js +1 -1
  48. package/min/ui-solid-inspector/index.js.gz +0 -0
  49. package/min/ui-solid-inspector/with-schemas/index.js +1 -1
  50. package/min/ui-solid-inspector/with-schemas/index.js.gz +0 -0
  51. package/min/ui-svelte/index.js +1 -1
  52. package/min/ui-svelte/index.js.gz +0 -0
  53. package/min/ui-svelte/with-schemas/index.js +1 -1
  54. package/min/ui-svelte/with-schemas/index.js.gz +0 -0
  55. package/min/ui-svelte-inspector/index.js +1 -1
  56. package/min/ui-svelte-inspector/index.js.gz +0 -0
  57. package/min/ui-svelte-inspector/with-schemas/index.js +1 -1
  58. package/min/ui-svelte-inspector/with-schemas/index.js.gz +0 -0
  59. package/min/with-schemas/index.js +1 -1
  60. package/min/with-schemas/index.js.gz +0 -0
  61. package/omni/index.js +121 -32
  62. package/omni/with-schemas/index.js +121 -32
  63. package/package.json +2 -2
  64. package/readme.md +14 -14
  65. package/releases.md +101 -60
  66. package/store/index.js +82 -32
  67. package/store/with-schemas/index.js +82 -32
  68. package/ui-react/index.js +16 -0
  69. package/ui-react/with-schemas/index.js +16 -0
  70. package/ui-react-inspector/index.js +82 -32
  71. package/ui-react-inspector/with-schemas/index.js +82 -32
  72. package/ui-solid/index.js +16 -0
  73. package/ui-solid/with-schemas/index.js +16 -0
  74. package/ui-solid-inspector/index.js +82 -32
  75. package/ui-solid-inspector/with-schemas/index.js +82 -32
  76. package/ui-svelte/index.js +18 -0
  77. package/ui-svelte/with-schemas/index.js +18 -0
  78. package/ui-svelte-inspector/index.js +82 -32
  79. package/ui-svelte-inspector/with-schemas/index.js +82 -32
  80. package/with-schemas/index.js +121 -32
package/indexes/index.js CHANGED
@@ -339,7 +339,9 @@ const getListenerFunctions = (getThing) => {
339
339
  };
340
340
 
341
341
  const createIndexes = getCreateFunction((store) => {
342
+ const hasIndexListeners = mapNew();
342
343
  const sliceIdsListeners = mapNew();
344
+ const hasSliceListeners = mapNew();
343
345
  const sliceRowIdsListeners = mapNew();
344
346
  const [addListener, callListeners, delListenerImpl] = getListenerFunctions(
345
347
  () => indexes,
@@ -378,6 +380,7 @@ const createIndexes = getCreateFunction((store) => {
378
380
  sliceIdSorter,
379
381
  rowIdSorter = defaultSorter,
380
382
  ) => {
383
+ const hadIndex = hasIndex(indexId);
381
384
  const sliceIdArraySorter = isUndefined(sliceIdSorter)
382
385
  ? void 0
383
386
  : ([id1], [id2]) => sliceIdSorter(id1, id2);
@@ -394,8 +397,14 @@ const createIndexes = getCreateFunction((store) => {
394
397
  ) => {
395
398
  let sliceIdsChanged = 0;
396
399
  const changedSlices = setNew();
400
+ const hadSlices = mapNew();
397
401
  const unsortedSlices = setNew();
398
402
  const index = getIndex(indexId);
403
+ const setHadSlice = (sliceId) => {
404
+ if (!collHas(hadSlices, sliceId)) {
405
+ mapSet(hadSlices, sliceId, collHas(index, sliceId));
406
+ }
407
+ };
399
408
  collForEach(
400
409
  changedSliceIds,
401
410
  ([oldSliceIdOrIds, newSliceIdOrIds], rowId) => {
@@ -407,6 +416,7 @@ const createIndexes = getCreateFunction((store) => {
407
416
  : 0,
408
417
  );
409
418
  collForEach(oldSliceIds, (oldSliceId) => {
419
+ setHadSlice(oldSliceId);
410
420
  setAdd(changedSlices, oldSliceId);
411
421
  ifNotUndefined(mapGet(index, oldSliceId), (oldSlice) => {
412
422
  collDel(oldSlice, rowId);
@@ -417,6 +427,7 @@ const createIndexes = getCreateFunction((store) => {
417
427
  });
418
428
  });
419
429
  collForEach(newSliceIds, (newSliceId) => {
430
+ setHadSlice(newSliceId);
420
431
  setAdd(changedSlices, newSliceId);
421
432
  if (!collHas(index, newSliceId)) {
422
433
  mapSet(index, newSliceId, setNew());
@@ -478,6 +489,12 @@ const createIndexes = getCreateFunction((store) => {
478
489
  if (sliceIdsChanged) {
479
490
  callListeners(sliceIdsListeners, [indexId]);
480
491
  }
492
+ mapForEach(hadSlices, (sliceId, hadSlice) => {
493
+ const hasSliceNow = collHas(index, sliceId);
494
+ if (hadSlice != hasSliceNow) {
495
+ callListeners(hasSliceListeners, [indexId, sliceId], hasSliceNow);
496
+ }
497
+ });
481
498
  collForEach(changedSlices, (sliceId) =>
482
499
  callListeners(sliceRowIdsListeners, [indexId, sliceId]),
483
500
  );
@@ -485,6 +502,9 @@ const createIndexes = getCreateFunction((store) => {
485
502
  getRowCellFunction(getSliceIdOrIds),
486
503
  ifNotUndefined(getSortKey, getRowCellFunction),
487
504
  );
505
+ if (!hadIndex) {
506
+ callListeners(hasIndexListeners, [indexId], true);
507
+ }
488
508
  return indexes;
489
509
  };
490
510
  const forEachIndex = (indexCallback) =>
@@ -508,7 +528,20 @@ const createIndexes = getCreateFunction((store) => {
508
528
  );
509
529
  };
510
530
  const delIndexDefinition = (indexId) => {
531
+ const index = getIndex(indexId);
532
+ const hadIndex = hasIndex(indexId);
533
+ const sliceIds = hadIndex ? mapKeys(index) : [];
511
534
  delDefinition(indexId);
535
+ if (hadIndex) {
536
+ callListeners(hasIndexListeners, [indexId], false);
537
+ if (sliceIds.length > 0) {
538
+ callListeners(sliceIdsListeners, [indexId]);
539
+ arrayForEach(sliceIds, (sliceId) => {
540
+ callListeners(hasSliceListeners, [indexId, sliceId], false);
541
+ callListeners(sliceRowIdsListeners, [indexId, sliceId]);
542
+ });
543
+ }
544
+ }
512
545
  return indexes;
513
546
  };
514
547
  const getSliceIds = (indexId) => mapKeys(getIndex(indexId));
@@ -516,6 +549,10 @@ const createIndexes = getCreateFunction((store) => {
516
549
  collValues(mapGet(getIndex(indexId), sliceId));
517
550
  const addSliceIdsListener = (indexId, listener) =>
518
551
  addListener(listener, sliceIdsListeners, [indexId]);
552
+ const addHasIndexListener = (indexId, listener) =>
553
+ addListener(listener, hasIndexListeners, [indexId]);
554
+ const addHasSliceListener = (indexId, sliceId, listener) =>
555
+ addListener(listener, hasSliceListeners, [indexId, sliceId]);
519
556
  const addSliceRowIdsListener = (indexId, sliceId, listener) =>
520
557
  addListener(listener, sliceRowIdsListeners, [indexId, sliceId]);
521
558
  const delListener = (listenerId) => {
@@ -539,7 +576,9 @@ const createIndexes = getCreateFunction((store) => {
539
576
  getSliceIds,
540
577
  getSliceRowIds,
541
578
  addIndexIdsListener,
579
+ addHasIndexListener,
542
580
  addSliceIdsListener,
581
+ addHasSliceListener,
543
582
  addSliceRowIdsListener,
544
583
  delListener,
545
584
  destroy,
@@ -339,7 +339,9 @@ const getListenerFunctions = (getThing) => {
339
339
  };
340
340
 
341
341
  const createIndexes = getCreateFunction((store) => {
342
+ const hasIndexListeners = mapNew();
342
343
  const sliceIdsListeners = mapNew();
344
+ const hasSliceListeners = mapNew();
343
345
  const sliceRowIdsListeners = mapNew();
344
346
  const [addListener, callListeners, delListenerImpl] = getListenerFunctions(
345
347
  () => indexes,
@@ -378,6 +380,7 @@ const createIndexes = getCreateFunction((store) => {
378
380
  sliceIdSorter,
379
381
  rowIdSorter = defaultSorter,
380
382
  ) => {
383
+ const hadIndex = hasIndex(indexId);
381
384
  const sliceIdArraySorter = isUndefined(sliceIdSorter)
382
385
  ? void 0
383
386
  : ([id1], [id2]) => sliceIdSorter(id1, id2);
@@ -394,8 +397,14 @@ const createIndexes = getCreateFunction((store) => {
394
397
  ) => {
395
398
  let sliceIdsChanged = 0;
396
399
  const changedSlices = setNew();
400
+ const hadSlices = mapNew();
397
401
  const unsortedSlices = setNew();
398
402
  const index = getIndex(indexId);
403
+ const setHadSlice = (sliceId) => {
404
+ if (!collHas(hadSlices, sliceId)) {
405
+ mapSet(hadSlices, sliceId, collHas(index, sliceId));
406
+ }
407
+ };
399
408
  collForEach(
400
409
  changedSliceIds,
401
410
  ([oldSliceIdOrIds, newSliceIdOrIds], rowId) => {
@@ -407,6 +416,7 @@ const createIndexes = getCreateFunction((store) => {
407
416
  : 0,
408
417
  );
409
418
  collForEach(oldSliceIds, (oldSliceId) => {
419
+ setHadSlice(oldSliceId);
410
420
  setAdd(changedSlices, oldSliceId);
411
421
  ifNotUndefined(mapGet(index, oldSliceId), (oldSlice) => {
412
422
  collDel(oldSlice, rowId);
@@ -417,6 +427,7 @@ const createIndexes = getCreateFunction((store) => {
417
427
  });
418
428
  });
419
429
  collForEach(newSliceIds, (newSliceId) => {
430
+ setHadSlice(newSliceId);
420
431
  setAdd(changedSlices, newSliceId);
421
432
  if (!collHas(index, newSliceId)) {
422
433
  mapSet(index, newSliceId, setNew());
@@ -478,6 +489,12 @@ const createIndexes = getCreateFunction((store) => {
478
489
  if (sliceIdsChanged) {
479
490
  callListeners(sliceIdsListeners, [indexId]);
480
491
  }
492
+ mapForEach(hadSlices, (sliceId, hadSlice) => {
493
+ const hasSliceNow = collHas(index, sliceId);
494
+ if (hadSlice != hasSliceNow) {
495
+ callListeners(hasSliceListeners, [indexId, sliceId], hasSliceNow);
496
+ }
497
+ });
481
498
  collForEach(changedSlices, (sliceId) =>
482
499
  callListeners(sliceRowIdsListeners, [indexId, sliceId]),
483
500
  );
@@ -485,6 +502,9 @@ const createIndexes = getCreateFunction((store) => {
485
502
  getRowCellFunction(getSliceIdOrIds),
486
503
  ifNotUndefined(getSortKey, getRowCellFunction),
487
504
  );
505
+ if (!hadIndex) {
506
+ callListeners(hasIndexListeners, [indexId], true);
507
+ }
488
508
  return indexes;
489
509
  };
490
510
  const forEachIndex = (indexCallback) =>
@@ -508,7 +528,20 @@ const createIndexes = getCreateFunction((store) => {
508
528
  );
509
529
  };
510
530
  const delIndexDefinition = (indexId) => {
531
+ const index = getIndex(indexId);
532
+ const hadIndex = hasIndex(indexId);
533
+ const sliceIds = hadIndex ? mapKeys(index) : [];
511
534
  delDefinition(indexId);
535
+ if (hadIndex) {
536
+ callListeners(hasIndexListeners, [indexId], false);
537
+ if (sliceIds.length > 0) {
538
+ callListeners(sliceIdsListeners, [indexId]);
539
+ arrayForEach(sliceIds, (sliceId) => {
540
+ callListeners(hasSliceListeners, [indexId, sliceId], false);
541
+ callListeners(sliceRowIdsListeners, [indexId, sliceId]);
542
+ });
543
+ }
544
+ }
512
545
  return indexes;
513
546
  };
514
547
  const getSliceIds = (indexId) => mapKeys(getIndex(indexId));
@@ -516,6 +549,10 @@ const createIndexes = getCreateFunction((store) => {
516
549
  collValues(mapGet(getIndex(indexId), sliceId));
517
550
  const addSliceIdsListener = (indexId, listener) =>
518
551
  addListener(listener, sliceIdsListeners, [indexId]);
552
+ const addHasIndexListener = (indexId, listener) =>
553
+ addListener(listener, hasIndexListeners, [indexId]);
554
+ const addHasSliceListener = (indexId, sliceId, listener) =>
555
+ addListener(listener, hasSliceListeners, [indexId, sliceId]);
519
556
  const addSliceRowIdsListener = (indexId, sliceId, listener) =>
520
557
  addListener(listener, sliceRowIdsListeners, [indexId, sliceId]);
521
558
  const delListener = (listenerId) => {
@@ -539,7 +576,9 @@ const createIndexes = getCreateFunction((store) => {
539
576
  getSliceIds,
540
577
  getSliceRowIds,
541
578
  addIndexIdsListener,
579
+ addHasIndexListener,
542
580
  addSliceIdsListener,
581
+ addHasSliceListener,
543
582
  addSliceRowIdsListener,
544
583
  delListener,
545
584
  destroy,
@@ -28,6 +28,7 @@ const VALUE = 'Value';
28
28
  const VALUES = VALUE + 's';
29
29
  const VALUE_IDS = VALUE + IDS;
30
30
  const TRANSACTION = 'Transaction';
31
+ const REQUIRED = 'required';
31
32
  const JSON_PREFIX = '\uFFFD';
32
33
  const id = (key) => EMPTY_STRING + key;
33
34
  const strStartsWith = (str, prefix) => str.startsWith(prefix);
@@ -568,6 +569,7 @@ const createStore = () => {
568
569
  const valuesSchemaMap = mapNew();
569
570
  const valuesDefaulted = mapNew();
570
571
  const valuesNonDefaulted = setNew();
572
+ const valuesRequiredNonDefaulted = setNew();
571
573
  const tablePoolFunctions = mapNew();
572
574
  const tableCellIds = mapNew();
573
575
  const tablesMap = mapNew();
@@ -620,7 +622,7 @@ const createStore = () => {
620
622
  const validateCellOrValueSchema = (schema) => {
621
623
  if (
622
624
  !objValidate(schema, (_child, id2) =>
623
- arrayHas([TYPE, DEFAULT, ALLOW_NULL], id2),
625
+ arrayHas([TYPE, DEFAULT, ALLOW_NULL, REQUIRED], id2),
624
626
  )
625
627
  ) {
626
628
  return false;
@@ -655,20 +657,32 @@ const createStore = () => {
655
657
  (row, rowId) => validateRow(tableId, rowId, row),
656
658
  () => cellInvalid(tableId),
657
659
  );
658
- const validateRow = (tableId, rowId, row, skipDefaults) =>
659
- objValidate(
660
- skipDefaults ? row : addDefaultsToRow(row, tableId, rowId),
661
- (cell, cellId) =>
662
- ifNotUndefined(
663
- getValidatedCell(tableId, rowId, cellId, cell),
664
- (validCell) => {
665
- row[cellId] = validCell;
666
- return true;
667
- },
668
- () => false,
669
- ),
670
- () => cellInvalid(tableId, rowId),
660
+ const validateRow = (tableId, rowId, row, skipDefaults) => {
661
+ const rowWithDefaults = skipDefaults
662
+ ? row
663
+ : addDefaultsToRow(row, tableId, rowId);
664
+ return (
665
+ objValidate(
666
+ rowWithDefaults,
667
+ (cell, cellId) =>
668
+ ifNotUndefined(
669
+ getValidatedCell(tableId, rowId, cellId, cell),
670
+ (validCell) => {
671
+ row[cellId] = validCell;
672
+ return true;
673
+ },
674
+ () => false,
675
+ ),
676
+ () => cellInvalid(tableId, rowId),
677
+ ) &&
678
+ (skipDefaults
679
+ ? true
680
+ : arrayEvery(
681
+ collValues(mapGet(tablesSchemaRowCache, tableId)?.[2]),
682
+ (cellId) => objHas(rowWithDefaults, cellId),
683
+ ))
671
684
  );
685
+ };
672
686
  const getValidatedCell = (tableId, rowId, cellId, cell) =>
673
687
  hasTablesSchema
674
688
  ? ifNotUndefined(
@@ -694,20 +708,31 @@ const createStore = () => {
694
708
  : isUndefined(getCellOrValueType(cell))
695
709
  ? cellInvalid(tableId, rowId, cellId, cell)
696
710
  : encodeIfJson(cell);
697
- const validateValues = (values, skipDefaults) =>
698
- objValidate(
699
- skipDefaults ? values : addDefaultsToValues(values),
700
- (value, valueId) =>
701
- ifNotUndefined(
702
- getValidatedValue(valueId, value),
703
- (validValue) => {
704
- values[valueId] = validValue;
705
- return true;
706
- },
707
- () => false,
708
- ),
709
- () => valueInvalid(),
711
+ const validateValues = (values, skipDefaults) => {
712
+ const valuesWithDefaults = skipDefaults
713
+ ? values
714
+ : addDefaultsToValues(values);
715
+ return (
716
+ objValidate(
717
+ valuesWithDefaults,
718
+ (value, valueId) =>
719
+ ifNotUndefined(
720
+ getValidatedValue(valueId, value),
721
+ (validValue) => {
722
+ values[valueId] = validValue;
723
+ return true;
724
+ },
725
+ () => false,
726
+ ),
727
+ () => valueInvalid(),
728
+ ) &&
729
+ (skipDefaults
730
+ ? true
731
+ : arrayEvery(collValues(valuesRequiredNonDefaulted), (valueId) =>
732
+ objHas(valuesWithDefaults, valueId),
733
+ ))
710
734
  );
735
+ };
711
736
  const getValidatedValue = (valueId, value) =>
712
737
  hasValuesSchema
713
738
  ? ifNotUndefined(
@@ -778,6 +803,7 @@ const createStore = () => {
778
803
  (_tablesSchema, tableId, tableSchema) => {
779
804
  const rowDefaulted = mapNew();
780
805
  const rowNonDefaulted = setNew();
806
+ const rowRequiredNonDefaulted = setNew();
781
807
  mapMatch(
782
808
  mapEnsure(tablesSchemaMap, tableId, mapNew),
783
809
  tableSchema,
@@ -785,12 +811,23 @@ const createStore = () => {
785
811
  mapSet(tableSchemaMap, cellId, cellSchema);
786
812
  ifNotUndefined(
787
813
  cellSchema[DEFAULT],
788
- (def) => mapSet(rowDefaulted, cellId, def),
789
- () => setAdd(rowNonDefaulted, cellId),
814
+ (defaultCell) => {
815
+ mapSet(rowDefaulted, cellId, defaultCell);
816
+ },
817
+ () => {
818
+ setAdd(rowNonDefaulted, cellId);
819
+ if (cellSchema[REQUIRED] === true) {
820
+ setAdd(rowRequiredNonDefaulted, cellId);
821
+ }
822
+ },
790
823
  );
791
824
  },
792
825
  );
793
- mapSet(tablesSchemaRowCache, tableId, [rowDefaulted, rowNonDefaulted]);
826
+ mapSet(tablesSchemaRowCache, tableId, [
827
+ rowDefaulted,
828
+ rowNonDefaulted,
829
+ rowRequiredNonDefaulted,
830
+ ]);
794
831
  },
795
832
  (_tablesSchema, tableId) => {
796
833
  mapSet(tablesSchemaMap, tableId);
@@ -805,14 +842,27 @@ const createStore = () => {
805
842
  mapSet(valuesSchemaMap, valueId, valueSchema);
806
843
  ifNotUndefined(
807
844
  valueSchema[DEFAULT],
808
- (def) => mapSet(valuesDefaulted, valueId, def),
809
- () => setAdd(valuesNonDefaulted, valueId),
845
+ (defaultValue) => {
846
+ mapSet(valuesDefaulted, valueId, defaultValue);
847
+ collDel(valuesNonDefaulted, valueId);
848
+ collDel(valuesRequiredNonDefaulted, valueId);
849
+ },
850
+ () => {
851
+ mapSet(valuesDefaulted, valueId);
852
+ setAdd(valuesNonDefaulted, valueId);
853
+ if (valueSchema[REQUIRED] === true) {
854
+ setAdd(valuesRequiredNonDefaulted, valueId);
855
+ } else {
856
+ collDel(valuesRequiredNonDefaulted, valueId);
857
+ }
858
+ },
810
859
  );
811
860
  },
812
861
  (_valuesSchema, valueId) => {
813
862
  mapSet(valuesSchemaMap, valueId);
814
863
  mapSet(valuesDefaulted, valueId);
815
864
  collDel(valuesNonDefaulted, valueId);
865
+ collDel(valuesRequiredNonDefaulted, valueId);
816
866
  },
817
867
  );
818
868
  const setOrDelTables = (tables) =>
@@ -28,6 +28,7 @@ const VALUE = 'Value';
28
28
  const VALUES = VALUE + 's';
29
29
  const VALUE_IDS = VALUE + IDS;
30
30
  const TRANSACTION = 'Transaction';
31
+ const REQUIRED = 'required';
31
32
  const JSON_PREFIX = '\uFFFD';
32
33
  const id = (key) => EMPTY_STRING + key;
33
34
  const strStartsWith = (str, prefix) => str.startsWith(prefix);
@@ -568,6 +569,7 @@ const createStore = () => {
568
569
  const valuesSchemaMap = mapNew();
569
570
  const valuesDefaulted = mapNew();
570
571
  const valuesNonDefaulted = setNew();
572
+ const valuesRequiredNonDefaulted = setNew();
571
573
  const tablePoolFunctions = mapNew();
572
574
  const tableCellIds = mapNew();
573
575
  const tablesMap = mapNew();
@@ -620,7 +622,7 @@ const createStore = () => {
620
622
  const validateCellOrValueSchema = (schema) => {
621
623
  if (
622
624
  !objValidate(schema, (_child, id2) =>
623
- arrayHas([TYPE, DEFAULT, ALLOW_NULL], id2),
625
+ arrayHas([TYPE, DEFAULT, ALLOW_NULL, REQUIRED], id2),
624
626
  )
625
627
  ) {
626
628
  return false;
@@ -655,20 +657,32 @@ const createStore = () => {
655
657
  (row, rowId) => validateRow(tableId, rowId, row),
656
658
  () => cellInvalid(tableId),
657
659
  );
658
- const validateRow = (tableId, rowId, row, skipDefaults) =>
659
- objValidate(
660
- skipDefaults ? row : addDefaultsToRow(row, tableId, rowId),
661
- (cell, cellId) =>
662
- ifNotUndefined(
663
- getValidatedCell(tableId, rowId, cellId, cell),
664
- (validCell) => {
665
- row[cellId] = validCell;
666
- return true;
667
- },
668
- () => false,
669
- ),
670
- () => cellInvalid(tableId, rowId),
660
+ const validateRow = (tableId, rowId, row, skipDefaults) => {
661
+ const rowWithDefaults = skipDefaults
662
+ ? row
663
+ : addDefaultsToRow(row, tableId, rowId);
664
+ return (
665
+ objValidate(
666
+ rowWithDefaults,
667
+ (cell, cellId) =>
668
+ ifNotUndefined(
669
+ getValidatedCell(tableId, rowId, cellId, cell),
670
+ (validCell) => {
671
+ row[cellId] = validCell;
672
+ return true;
673
+ },
674
+ () => false,
675
+ ),
676
+ () => cellInvalid(tableId, rowId),
677
+ ) &&
678
+ (skipDefaults
679
+ ? true
680
+ : arrayEvery(
681
+ collValues(mapGet(tablesSchemaRowCache, tableId)?.[2]),
682
+ (cellId) => objHas(rowWithDefaults, cellId),
683
+ ))
671
684
  );
685
+ };
672
686
  const getValidatedCell = (tableId, rowId, cellId, cell) =>
673
687
  hasTablesSchema
674
688
  ? ifNotUndefined(
@@ -694,20 +708,31 @@ const createStore = () => {
694
708
  : isUndefined(getCellOrValueType(cell))
695
709
  ? cellInvalid(tableId, rowId, cellId, cell)
696
710
  : encodeIfJson(cell);
697
- const validateValues = (values, skipDefaults) =>
698
- objValidate(
699
- skipDefaults ? values : addDefaultsToValues(values),
700
- (value, valueId) =>
701
- ifNotUndefined(
702
- getValidatedValue(valueId, value),
703
- (validValue) => {
704
- values[valueId] = validValue;
705
- return true;
706
- },
707
- () => false,
708
- ),
709
- () => valueInvalid(),
711
+ const validateValues = (values, skipDefaults) => {
712
+ const valuesWithDefaults = skipDefaults
713
+ ? values
714
+ : addDefaultsToValues(values);
715
+ return (
716
+ objValidate(
717
+ valuesWithDefaults,
718
+ (value, valueId) =>
719
+ ifNotUndefined(
720
+ getValidatedValue(valueId, value),
721
+ (validValue) => {
722
+ values[valueId] = validValue;
723
+ return true;
724
+ },
725
+ () => false,
726
+ ),
727
+ () => valueInvalid(),
728
+ ) &&
729
+ (skipDefaults
730
+ ? true
731
+ : arrayEvery(collValues(valuesRequiredNonDefaulted), (valueId) =>
732
+ objHas(valuesWithDefaults, valueId),
733
+ ))
710
734
  );
735
+ };
711
736
  const getValidatedValue = (valueId, value) =>
712
737
  hasValuesSchema
713
738
  ? ifNotUndefined(
@@ -778,6 +803,7 @@ const createStore = () => {
778
803
  (_tablesSchema, tableId, tableSchema) => {
779
804
  const rowDefaulted = mapNew();
780
805
  const rowNonDefaulted = setNew();
806
+ const rowRequiredNonDefaulted = setNew();
781
807
  mapMatch(
782
808
  mapEnsure(tablesSchemaMap, tableId, mapNew),
783
809
  tableSchema,
@@ -785,12 +811,23 @@ const createStore = () => {
785
811
  mapSet(tableSchemaMap, cellId, cellSchema);
786
812
  ifNotUndefined(
787
813
  cellSchema[DEFAULT],
788
- (def) => mapSet(rowDefaulted, cellId, def),
789
- () => setAdd(rowNonDefaulted, cellId),
814
+ (defaultCell) => {
815
+ mapSet(rowDefaulted, cellId, defaultCell);
816
+ },
817
+ () => {
818
+ setAdd(rowNonDefaulted, cellId);
819
+ if (cellSchema[REQUIRED] === true) {
820
+ setAdd(rowRequiredNonDefaulted, cellId);
821
+ }
822
+ },
790
823
  );
791
824
  },
792
825
  );
793
- mapSet(tablesSchemaRowCache, tableId, [rowDefaulted, rowNonDefaulted]);
826
+ mapSet(tablesSchemaRowCache, tableId, [
827
+ rowDefaulted,
828
+ rowNonDefaulted,
829
+ rowRequiredNonDefaulted,
830
+ ]);
794
831
  },
795
832
  (_tablesSchema, tableId) => {
796
833
  mapSet(tablesSchemaMap, tableId);
@@ -805,14 +842,27 @@ const createStore = () => {
805
842
  mapSet(valuesSchemaMap, valueId, valueSchema);
806
843
  ifNotUndefined(
807
844
  valueSchema[DEFAULT],
808
- (def) => mapSet(valuesDefaulted, valueId, def),
809
- () => setAdd(valuesNonDefaulted, valueId),
845
+ (defaultValue) => {
846
+ mapSet(valuesDefaulted, valueId, defaultValue);
847
+ collDel(valuesNonDefaulted, valueId);
848
+ collDel(valuesRequiredNonDefaulted, valueId);
849
+ },
850
+ () => {
851
+ mapSet(valuesDefaulted, valueId);
852
+ setAdd(valuesNonDefaulted, valueId);
853
+ if (valueSchema[REQUIRED] === true) {
854
+ setAdd(valuesRequiredNonDefaulted, valueId);
855
+ } else {
856
+ collDel(valuesRequiredNonDefaulted, valueId);
857
+ }
858
+ },
810
859
  );
811
860
  },
812
861
  (_valuesSchema, valueId) => {
813
862
  mapSet(valuesSchemaMap, valueId);
814
863
  mapSet(valuesDefaulted, valueId);
815
864
  collDel(valuesNonDefaulted, valueId);
865
+ collDel(valuesRequiredNonDefaulted, valueId);
816
866
  },
817
867
  );
818
868
  const setOrDelTables = (tables) =>