tinybase 7.2.0-beta.2 → 7.2.0

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 (44) hide show
  1. package/@types/queries/index.d.ts +333 -4
  2. package/@types/queries/with-schemas/index.d.ts +359 -4
  3. package/@types/ui-react/index.d.ts +477 -8
  4. package/@types/ui-react/with-schemas/index.d.ts +519 -8
  5. package/agents.md +34 -0
  6. package/index.js +100 -18
  7. package/min/index.js +1 -1
  8. package/min/index.js.gz +0 -0
  9. package/min/omni/index.js +1 -1
  10. package/min/omni/index.js.gz +0 -0
  11. package/min/omni/with-schemas/index.js +1 -1
  12. package/min/omni/with-schemas/index.js.gz +0 -0
  13. package/min/queries/index.js +1 -1
  14. package/min/queries/index.js.gz +0 -0
  15. package/min/queries/with-schemas/index.js +1 -1
  16. package/min/queries/with-schemas/index.js.gz +0 -0
  17. package/min/ui-react/index.js +1 -1
  18. package/min/ui-react/index.js.gz +0 -0
  19. package/min/ui-react/with-schemas/index.js +1 -1
  20. package/min/ui-react/with-schemas/index.js.gz +0 -0
  21. package/min/ui-react-dom/index.js +1 -1
  22. package/min/ui-react-dom/index.js.gz +0 -0
  23. package/min/ui-react-dom/with-schemas/index.js +1 -1
  24. package/min/ui-react-dom/with-schemas/index.js.gz +0 -0
  25. package/min/ui-react-inspector/index.js +1 -1
  26. package/min/ui-react-inspector/index.js.gz +0 -0
  27. package/min/ui-react-inspector/with-schemas/index.js +1 -1
  28. package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
  29. package/min/with-schemas/index.js +1 -1
  30. package/min/with-schemas/index.js.gz +0 -0
  31. package/omni/index.js +173 -48
  32. package/omni/with-schemas/index.js +173 -48
  33. package/package.json +3 -3
  34. package/queries/index.js +120 -18
  35. package/queries/with-schemas/index.js +120 -18
  36. package/readme.md +13 -13
  37. package/releases.md +40 -40
  38. package/ui-react/index.js +98 -30
  39. package/ui-react/with-schemas/index.js +98 -30
  40. package/ui-react-dom/index.js +38 -15
  41. package/ui-react-dom/with-schemas/index.js +38 -15
  42. package/ui-react-inspector/index.js +40 -17
  43. package/ui-react-inspector/with-schemas/index.js +40 -17
  44. package/with-schemas/index.js +100 -18
package/queries/index.js CHANGED
@@ -28,8 +28,10 @@ const math = Math;
28
28
  const mathMax = math.max;
29
29
  const mathMin = math.min;
30
30
  const isFiniteNumber = isFinite;
31
+ const isNullish = (thing) => thing == null;
31
32
  const isUndefined = (thing) => thing === void 0;
32
33
  const isNull = (thing) => thing === null;
34
+ const ifNotNullish = getIfNotFunction(isNullish);
33
35
  const ifNotUndefined = getIfNotFunction(isUndefined);
34
36
  const isTypeStringOrBoolean = (type) => type == STRING || type == BOOLEAN;
35
37
  const isFunction = (thing) => getTypeOf(thing) == FUNCTION;
@@ -42,6 +44,10 @@ const arrayEvery = (array, cb) => array.every(cb);
42
44
  const arrayIsEqual = (array1, array2) =>
43
45
  size(array1) === size(array2) &&
44
46
  arrayEvery(array1, (value1, index) => array2[index] === value1);
47
+ const arrayOrValueEqual = (value1, value2) =>
48
+ isArray(value1) && isArray(value2)
49
+ ? arrayIsEqual(value1, value2)
50
+ : value1 === value2;
45
51
  const arrayForEach = (array, cb) => array.forEach(cb);
46
52
  const arrayMap = (array, cb) => array.map(cb);
47
53
  const arraySum = (array) => arrayReduce(array, (i, j) => i + j, 0);
@@ -49,7 +55,11 @@ const arrayIsEmpty = (array) => size(array) == 0;
49
55
  const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
50
56
  const arrayPush = (array, ...values) => array.push(...values);
51
57
 
58
+ const collSizeN = (collSizer) => (coll) =>
59
+ arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
52
60
  const collSize = (coll) => coll?.size ?? 0;
61
+ const collSize2 = collSizeN(collSize);
62
+ const collSize3 = collSizeN(collSize2);
53
63
  const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
54
64
  const collIsEmpty = (coll) => isUndefined(coll) || collSize(coll) == 0;
55
65
  const collValues = (coll) => [...(coll?.values() ?? [])];
@@ -58,14 +68,49 @@ const collForEach = (coll, cb) => coll?.forEach(cb);
58
68
  const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
59
69
 
60
70
  const object = Object;
71
+ const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
61
72
  const objEntries = object.entries;
73
+ const isObject = (obj) =>
74
+ !isNullish(obj) &&
75
+ ifNotNullish(
76
+ getPrototypeOf(obj),
77
+ (objPrototype) =>
78
+ objPrototype == object.prototype ||
79
+ isNullish(getPrototypeOf(objPrototype)),
80
+
81
+ /* istanbul ignore next */
82
+ () => true,
83
+ );
84
+ const objIds = object.keys;
62
85
  const objFreeze = object.freeze;
63
86
  const objNew = (entries = []) => object.fromEntries(entries);
87
+ const objGet = (obj, id) => ifNotUndefined(obj, (obj2) => obj2[id]);
64
88
  const objToMap = (obj) => new Map(objEntries(obj));
65
89
  const objToArray = (obj, cb) =>
66
90
  arrayMap(objEntries(obj), ([id, value]) => cb(value, id));
67
91
  const objMap = (obj, cb) =>
68
92
  objNew(objToArray(obj, (value, id) => [id, cb(value, id)]));
93
+ const objSize = (obj) => size(objIds(obj));
94
+
95
+ /* istanbul ignore next */
96
+ const objIsEqual = (
97
+ obj1,
98
+ obj2,
99
+ isEqual = (value1, value2) => value1 === value2,
100
+ ) => {
101
+ const entries1 = objEntries(obj1);
102
+ return (
103
+ size(entries1) === objSize(obj2) &&
104
+ arrayEvery(entries1, ([index, value1]) =>
105
+ isObject(value1)
106
+ ? /* istanbul ignore next */
107
+ isObject(obj2[index])
108
+ ? objIsEqual(obj2[index], value1)
109
+ : false
110
+ : isEqual(value1, obj2[index]),
111
+ )
112
+ );
113
+ };
69
114
 
70
115
  const mapNew = (entries) => new Map(entries);
71
116
  const mapKeys = (map) => [...(map?.keys() ?? [])];
@@ -380,6 +425,8 @@ const createQueries = getCreateFunction((store) => {
380
425
  const preStore = createStore();
381
426
  const resultStore = createStore();
382
427
  const preStoreListenerIds = mapNew();
428
+ const paramValuesListeners = mapNew();
429
+ const paramValueListeners = mapNew();
383
430
  const {
384
431
  addListener,
385
432
  callListeners,
@@ -402,7 +449,7 @@ const createQueries = getCreateFunction((store) => {
402
449
  delStoreListeners,
403
450
  ] = getDefinableFunctions(
404
451
  store,
405
- () => [() => {}, mapNew()],
452
+ () => [],
406
453
  getUndefined,
407
454
  addListener,
408
455
  callListeners,
@@ -442,8 +489,10 @@ const createQueries = getCreateFunction((store) => {
442
489
  ),
443
490
  );
444
491
  const setQueryDefinition = (queryId, tableId, build, paramValues = {}) => {
492
+ const oldParamValues = getParamValues(queryId);
445
493
  setDefinition(queryId, tableId);
446
494
  setQueryArgs(queryId, [build, objToMap(paramValues)]);
495
+ callParamListeners(queryId, oldParamValues, paramValues);
447
496
  resetPreStores(queryId);
448
497
  const [, paramsMap] = getQueryArgs(queryId);
449
498
  const selectEntries = [];
@@ -772,31 +821,76 @@ const createQueries = getCreateFunction((store) => {
772
821
  );
773
822
  return queries;
774
823
  };
824
+ const callParamListeners = (queryId, oldParamValues, newParamValues) => {
825
+ const allParamIds = setNew([
826
+ ...objIds(oldParamValues),
827
+ ...objIds(newParamValues),
828
+ ]);
829
+ let changed = 0;
830
+ collForEach(allParamIds, (paramId) => {
831
+ const newParamValue = objGet(newParamValues, paramId);
832
+ if (!arrayOrValueEqual(objGet(oldParamValues, paramId), newParamValue)) {
833
+ changed = 1;
834
+ callListeners(paramValueListeners, [queryId, paramId], newParamValue);
835
+ }
836
+ });
837
+ if (changed) {
838
+ callListeners(paramValuesListeners, [queryId], newParamValues);
839
+ }
840
+ };
775
841
  const delQueryDefinition = (queryId) => {
842
+ const oldParamValues = getParamValues(queryId);
776
843
  resetPreStores(queryId);
777
844
  delDefinition(queryId);
845
+ callParamListeners(queryId, oldParamValues, {});
778
846
  return queries;
779
847
  };
780
- const setParamValues = (queryId, paramValues) => {
781
- ifNotUndefined(getQueryArgs(queryId), (definition) =>
782
- resultStore.transaction(() =>
783
- setQueryDefinition(
784
- queryId,
785
- getTableId(queryId),
786
- definition[0],
787
- paramValues,
788
- ),
789
- ),
790
- );
848
+ const setParamValues = (queryId, paramValues, force = 0) => {
849
+ ifNotUndefined(getQueryArgs(queryId), ([definition, oldParamValues]) => {
850
+ if (
851
+ force ||
852
+ !objIsEqual(mapToObj(oldParamValues), paramValues, arrayOrValueEqual)
853
+ ) {
854
+ resultStore.transaction(() =>
855
+ setQueryDefinition(
856
+ queryId,
857
+ getTableId(queryId),
858
+ definition,
859
+ paramValues,
860
+ ),
861
+ );
862
+ }
863
+ });
791
864
  return queries;
792
865
  };
793
- const setParamValue = (queryId, paramId, value) =>
794
- setParamValues(queryId, {
795
- ...mapToObj(getQueryArgs(queryId)?.[1]),
796
- [paramId]: value,
797
- });
866
+ const setParamValue = (queryId, paramId, value) => {
867
+ if (!arrayOrValueEqual(getParamValue(queryId, paramId), value)) {
868
+ setParamValues(
869
+ queryId,
870
+ {...getParamValues(queryId), [paramId]: value},
871
+ 1,
872
+ );
873
+ }
874
+ return queries;
875
+ };
876
+ const getParamValues = (queryId) => mapToObj(getQueryArgs(queryId)?.[1]);
877
+ const getParamValue = (queryId, paramId) =>
878
+ mapGet(getQueryArgs(queryId)?.[1], paramId);
798
879
  const addQueryIdsListener = (listener) =>
799
880
  addQueryIdsListenerImpl(() => listener(queries));
881
+ const addParamValuesListener = (queryId, listener) =>
882
+ addListener(
883
+ (_, queryId2, paramValues) => listener(queries, queryId2, paramValues),
884
+ paramValuesListeners,
885
+ [queryId],
886
+ );
887
+ const addParamValueListener = (queryId, paramId, listener) =>
888
+ addListener(
889
+ (_, queryId2, paramId2, paramValue) =>
890
+ listener(queries, queryId2, paramId2, paramValue),
891
+ paramValueListeners,
892
+ [queryId, paramId],
893
+ );
800
894
  const delListener = (listenerId) => {
801
895
  delListenerImpl(listenerId);
802
896
  return queries;
@@ -808,11 +902,17 @@ const createQueries = getCreateFunction((store) => {
808
902
  transaction: _3,
809
903
  ...stats
810
904
  } = resultStore.getListenerStats();
811
- return stats;
905
+ return {
906
+ ...stats,
907
+ paramValues: collSize2(paramValuesListeners),
908
+ paramValue: collSize3(paramValueListeners),
909
+ };
812
910
  };
813
911
  const queries = {
814
912
  setQueryDefinition,
815
913
  delQueryDefinition,
914
+ getParamValues,
915
+ getParamValue,
816
916
  setParamValues,
817
917
  setParamValue,
818
918
  getStore,
@@ -821,6 +921,8 @@ const createQueries = getCreateFunction((store) => {
821
921
  hasQuery,
822
922
  getTableId,
823
923
  addQueryIdsListener,
924
+ addParamValuesListener,
925
+ addParamValueListener,
824
926
  delListener,
825
927
  destroy,
826
928
  getListenerStats,
@@ -28,8 +28,10 @@ const math = Math;
28
28
  const mathMax = math.max;
29
29
  const mathMin = math.min;
30
30
  const isFiniteNumber = isFinite;
31
+ const isNullish = (thing) => thing == null;
31
32
  const isUndefined = (thing) => thing === void 0;
32
33
  const isNull = (thing) => thing === null;
34
+ const ifNotNullish = getIfNotFunction(isNullish);
33
35
  const ifNotUndefined = getIfNotFunction(isUndefined);
34
36
  const isTypeStringOrBoolean = (type) => type == STRING || type == BOOLEAN;
35
37
  const isFunction = (thing) => getTypeOf(thing) == FUNCTION;
@@ -42,6 +44,10 @@ const arrayEvery = (array, cb) => array.every(cb);
42
44
  const arrayIsEqual = (array1, array2) =>
43
45
  size(array1) === size(array2) &&
44
46
  arrayEvery(array1, (value1, index) => array2[index] === value1);
47
+ const arrayOrValueEqual = (value1, value2) =>
48
+ isArray(value1) && isArray(value2)
49
+ ? arrayIsEqual(value1, value2)
50
+ : value1 === value2;
45
51
  const arrayForEach = (array, cb) => array.forEach(cb);
46
52
  const arrayMap = (array, cb) => array.map(cb);
47
53
  const arraySum = (array) => arrayReduce(array, (i, j) => i + j, 0);
@@ -49,7 +55,11 @@ const arrayIsEmpty = (array) => size(array) == 0;
49
55
  const arrayReduce = (array, cb, initial) => array.reduce(cb, initial);
50
56
  const arrayPush = (array, ...values) => array.push(...values);
51
57
 
58
+ const collSizeN = (collSizer) => (coll) =>
59
+ arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
52
60
  const collSize = (coll) => coll?.size ?? 0;
61
+ const collSize2 = collSizeN(collSize);
62
+ const collSize3 = collSizeN(collSize2);
53
63
  const collHas = (coll, keyOrValue) => coll?.has(keyOrValue) ?? false;
54
64
  const collIsEmpty = (coll) => isUndefined(coll) || collSize(coll) == 0;
55
65
  const collValues = (coll) => [...(coll?.values() ?? [])];
@@ -58,14 +68,49 @@ const collForEach = (coll, cb) => coll?.forEach(cb);
58
68
  const collDel = (coll, keyOrValue) => coll?.delete(keyOrValue);
59
69
 
60
70
  const object = Object;
71
+ const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
61
72
  const objEntries = object.entries;
73
+ const isObject = (obj) =>
74
+ !isNullish(obj) &&
75
+ ifNotNullish(
76
+ getPrototypeOf(obj),
77
+ (objPrototype) =>
78
+ objPrototype == object.prototype ||
79
+ isNullish(getPrototypeOf(objPrototype)),
80
+
81
+ /* istanbul ignore next */
82
+ () => true,
83
+ );
84
+ const objIds = object.keys;
62
85
  const objFreeze = object.freeze;
63
86
  const objNew = (entries = []) => object.fromEntries(entries);
87
+ const objGet = (obj, id) => ifNotUndefined(obj, (obj2) => obj2[id]);
64
88
  const objToMap = (obj) => new Map(objEntries(obj));
65
89
  const objToArray = (obj, cb) =>
66
90
  arrayMap(objEntries(obj), ([id, value]) => cb(value, id));
67
91
  const objMap = (obj, cb) =>
68
92
  objNew(objToArray(obj, (value, id) => [id, cb(value, id)]));
93
+ const objSize = (obj) => size(objIds(obj));
94
+
95
+ /* istanbul ignore next */
96
+ const objIsEqual = (
97
+ obj1,
98
+ obj2,
99
+ isEqual = (value1, value2) => value1 === value2,
100
+ ) => {
101
+ const entries1 = objEntries(obj1);
102
+ return (
103
+ size(entries1) === objSize(obj2) &&
104
+ arrayEvery(entries1, ([index, value1]) =>
105
+ isObject(value1)
106
+ ? /* istanbul ignore next */
107
+ isObject(obj2[index])
108
+ ? objIsEqual(obj2[index], value1)
109
+ : false
110
+ : isEqual(value1, obj2[index]),
111
+ )
112
+ );
113
+ };
69
114
 
70
115
  const mapNew = (entries) => new Map(entries);
71
116
  const mapKeys = (map) => [...(map?.keys() ?? [])];
@@ -380,6 +425,8 @@ const createQueries = getCreateFunction((store) => {
380
425
  const preStore = createStore();
381
426
  const resultStore = createStore();
382
427
  const preStoreListenerIds = mapNew();
428
+ const paramValuesListeners = mapNew();
429
+ const paramValueListeners = mapNew();
383
430
  const {
384
431
  addListener,
385
432
  callListeners,
@@ -402,7 +449,7 @@ const createQueries = getCreateFunction((store) => {
402
449
  delStoreListeners,
403
450
  ] = getDefinableFunctions(
404
451
  store,
405
- () => [() => {}, mapNew()],
452
+ () => [],
406
453
  getUndefined,
407
454
  addListener,
408
455
  callListeners,
@@ -442,8 +489,10 @@ const createQueries = getCreateFunction((store) => {
442
489
  ),
443
490
  );
444
491
  const setQueryDefinition = (queryId, tableId, build, paramValues = {}) => {
492
+ const oldParamValues = getParamValues(queryId);
445
493
  setDefinition(queryId, tableId);
446
494
  setQueryArgs(queryId, [build, objToMap(paramValues)]);
495
+ callParamListeners(queryId, oldParamValues, paramValues);
447
496
  resetPreStores(queryId);
448
497
  const [, paramsMap] = getQueryArgs(queryId);
449
498
  const selectEntries = [];
@@ -772,31 +821,76 @@ const createQueries = getCreateFunction((store) => {
772
821
  );
773
822
  return queries;
774
823
  };
824
+ const callParamListeners = (queryId, oldParamValues, newParamValues) => {
825
+ const allParamIds = setNew([
826
+ ...objIds(oldParamValues),
827
+ ...objIds(newParamValues),
828
+ ]);
829
+ let changed = 0;
830
+ collForEach(allParamIds, (paramId) => {
831
+ const newParamValue = objGet(newParamValues, paramId);
832
+ if (!arrayOrValueEqual(objGet(oldParamValues, paramId), newParamValue)) {
833
+ changed = 1;
834
+ callListeners(paramValueListeners, [queryId, paramId], newParamValue);
835
+ }
836
+ });
837
+ if (changed) {
838
+ callListeners(paramValuesListeners, [queryId], newParamValues);
839
+ }
840
+ };
775
841
  const delQueryDefinition = (queryId) => {
842
+ const oldParamValues = getParamValues(queryId);
776
843
  resetPreStores(queryId);
777
844
  delDefinition(queryId);
845
+ callParamListeners(queryId, oldParamValues, {});
778
846
  return queries;
779
847
  };
780
- const setParamValues = (queryId, paramValues) => {
781
- ifNotUndefined(getQueryArgs(queryId), (definition) =>
782
- resultStore.transaction(() =>
783
- setQueryDefinition(
784
- queryId,
785
- getTableId(queryId),
786
- definition[0],
787
- paramValues,
788
- ),
789
- ),
790
- );
848
+ const setParamValues = (queryId, paramValues, force = 0) => {
849
+ ifNotUndefined(getQueryArgs(queryId), ([definition, oldParamValues]) => {
850
+ if (
851
+ force ||
852
+ !objIsEqual(mapToObj(oldParamValues), paramValues, arrayOrValueEqual)
853
+ ) {
854
+ resultStore.transaction(() =>
855
+ setQueryDefinition(
856
+ queryId,
857
+ getTableId(queryId),
858
+ definition,
859
+ paramValues,
860
+ ),
861
+ );
862
+ }
863
+ });
791
864
  return queries;
792
865
  };
793
- const setParamValue = (queryId, paramId, value) =>
794
- setParamValues(queryId, {
795
- ...mapToObj(getQueryArgs(queryId)?.[1]),
796
- [paramId]: value,
797
- });
866
+ const setParamValue = (queryId, paramId, value) => {
867
+ if (!arrayOrValueEqual(getParamValue(queryId, paramId), value)) {
868
+ setParamValues(
869
+ queryId,
870
+ {...getParamValues(queryId), [paramId]: value},
871
+ 1,
872
+ );
873
+ }
874
+ return queries;
875
+ };
876
+ const getParamValues = (queryId) => mapToObj(getQueryArgs(queryId)?.[1]);
877
+ const getParamValue = (queryId, paramId) =>
878
+ mapGet(getQueryArgs(queryId)?.[1], paramId);
798
879
  const addQueryIdsListener = (listener) =>
799
880
  addQueryIdsListenerImpl(() => listener(queries));
881
+ const addParamValuesListener = (queryId, listener) =>
882
+ addListener(
883
+ (_, queryId2, paramValues) => listener(queries, queryId2, paramValues),
884
+ paramValuesListeners,
885
+ [queryId],
886
+ );
887
+ const addParamValueListener = (queryId, paramId, listener) =>
888
+ addListener(
889
+ (_, queryId2, paramId2, paramValue) =>
890
+ listener(queries, queryId2, paramId2, paramValue),
891
+ paramValueListeners,
892
+ [queryId, paramId],
893
+ );
800
894
  const delListener = (listenerId) => {
801
895
  delListenerImpl(listenerId);
802
896
  return queries;
@@ -808,11 +902,17 @@ const createQueries = getCreateFunction((store) => {
808
902
  transaction: _3,
809
903
  ...stats
810
904
  } = resultStore.getListenerStats();
811
- return stats;
905
+ return {
906
+ ...stats,
907
+ paramValues: collSize2(paramValuesListeners),
908
+ paramValue: collSize3(paramValueListeners),
909
+ };
812
910
  };
813
911
  const queries = {
814
912
  setQueryDefinition,
815
913
  delQueryDefinition,
914
+ getParamValues,
915
+ getParamValue,
816
916
  setParamValues,
817
917
  setParamValue,
818
918
  getStore,
@@ -821,6 +921,8 @@ const createQueries = getCreateFunction((store) => {
821
921
  hasQuery,
822
922
  getTableId,
823
923
  addQueryIdsListener,
924
+ addParamValuesListener,
925
+ addParamValueListener,
824
926
  delListener,
825
927
  destroy,
826
928
  getListenerStats,