tinybase 7.0.0-beta.2 → 7.0.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.
- package/@types/common/index.d.ts +1 -1
- package/@types/mergeable-store/index.d.ts +1 -1
- package/@types/mergeable-store/with-schemas/index.d.ts +1 -1
- package/@types/persisters/persister-cr-sqlite-wasm/index.d.ts +4 -0
- package/@types/persisters/persister-cr-sqlite-wasm/with-schemas/index.d.ts +4 -0
- package/@types/persisters/persister-durable-object-sql-storage/index.d.ts +4 -0
- package/@types/persisters/persister-durable-object-sql-storage/with-schemas/index.d.ts +4 -0
- package/@types/persisters/persister-electric-sql/index.d.ts +4 -0
- package/@types/persisters/persister-electric-sql/with-schemas/index.d.ts +4 -0
- package/@types/persisters/persister-expo-sqlite/index.d.ts +4 -0
- package/@types/persisters/persister-expo-sqlite/with-schemas/index.d.ts +4 -0
- package/@types/persisters/persister-libsql/index.d.ts +4 -0
- package/@types/persisters/persister-libsql/with-schemas/index.d.ts +4 -0
- package/@types/persisters/persister-pglite/index.d.ts +5 -1
- package/@types/persisters/persister-pglite/with-schemas/index.d.ts +5 -1
- package/@types/persisters/persister-postgres/index.d.ts +4 -0
- package/@types/persisters/persister-postgres/with-schemas/index.d.ts +4 -0
- package/@types/persisters/persister-powersync/index.d.ts +4 -0
- package/@types/persisters/persister-powersync/with-schemas/index.d.ts +4 -0
- package/@types/persisters/persister-react-native-sqlite/index.d.ts +4 -0
- package/@types/persisters/persister-react-native-sqlite/with-schemas/index.d.ts +4 -0
- package/@types/persisters/persister-sqlite-bun/index.d.ts +4 -0
- package/@types/persisters/persister-sqlite-bun/with-schemas/index.d.ts +4 -0
- package/@types/persisters/persister-sqlite-wasm/index.d.ts +4 -0
- package/@types/persisters/persister-sqlite-wasm/with-schemas/index.d.ts +4 -0
- package/@types/persisters/persister-sqlite3/index.d.ts +4 -0
- package/@types/persisters/persister-sqlite3/with-schemas/index.d.ts +4 -0
- package/@types/queries/index.d.ts +1 -1
- package/@types/store/index.d.ts +21 -19
- package/@types/store/with-schemas/index.d.ts +15 -13
- package/agents.md +62 -0
- package/checkpoints/index.js +8 -6
- package/checkpoints/with-schemas/index.js +8 -6
- package/common/index.js +4 -3
- package/common/with-schemas/index.js +4 -3
- package/index.js +60 -30
- package/indexes/index.js +7 -5
- package/indexes/with-schemas/index.js +7 -5
- package/mergeable-store/index.js +51 -21
- package/mergeable-store/with-schemas/index.js +51 -21
- package/metrics/index.js +7 -5
- package/metrics/with-schemas/index.js +7 -5
- package/min/checkpoints/index.js +1 -1
- package/min/checkpoints/index.js.gz +0 -0
- package/min/checkpoints/with-schemas/index.js +1 -1
- package/min/checkpoints/with-schemas/index.js.gz +0 -0
- package/min/common/index.js +1 -1
- package/min/common/index.js.gz +0 -0
- package/min/common/with-schemas/index.js +1 -1
- package/min/common/with-schemas/index.js.gz +0 -0
- package/min/index.js +1 -1
- package/min/index.js.gz +0 -0
- package/min/indexes/index.js +1 -1
- package/min/indexes/index.js.gz +0 -0
- package/min/indexes/with-schemas/index.js +1 -1
- package/min/indexes/with-schemas/index.js.gz +0 -0
- package/min/mergeable-store/index.js +1 -1
- package/min/mergeable-store/index.js.gz +0 -0
- package/min/mergeable-store/with-schemas/index.js +1 -1
- package/min/mergeable-store/with-schemas/index.js.gz +0 -0
- package/min/metrics/index.js +1 -1
- package/min/metrics/index.js.gz +0 -0
- package/min/metrics/with-schemas/index.js +1 -1
- package/min/metrics/with-schemas/index.js.gz +0 -0
- package/min/omni/index.js +1 -1
- package/min/omni/index.js.gz +0 -0
- package/min/omni/with-schemas/index.js +1 -1
- package/min/omni/with-schemas/index.js.gz +0 -0
- package/min/persisters/index.js +1 -1
- package/min/persisters/index.js.gz +0 -0
- package/min/persisters/persister-automerge/index.js +1 -1
- package/min/persisters/persister-automerge/index.js.gz +0 -0
- package/min/persisters/persister-automerge/with-schemas/index.js +1 -1
- package/min/persisters/persister-automerge/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-browser/index.js +1 -1
- package/min/persisters/persister-browser/index.js.gz +0 -0
- package/min/persisters/persister-browser/with-schemas/index.js +1 -1
- package/min/persisters/persister-browser/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-cr-sqlite-wasm/index.js +1 -1
- package/min/persisters/persister-cr-sqlite-wasm/index.js.gz +0 -0
- package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +1 -1
- package/min/persisters/persister-cr-sqlite-wasm/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-durable-object-sql-storage/index.js +1 -1
- package/min/persisters/persister-durable-object-sql-storage/index.js.gz +0 -0
- package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js +1 -1
- package/min/persisters/persister-durable-object-sql-storage/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-durable-object-storage/index.js +1 -1
- package/min/persisters/persister-durable-object-storage/index.js.gz +0 -0
- package/min/persisters/persister-durable-object-storage/with-schemas/index.js +1 -1
- package/min/persisters/persister-durable-object-storage/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-electric-sql/index.js +1 -1
- package/min/persisters/persister-electric-sql/index.js.gz +0 -0
- package/min/persisters/persister-electric-sql/with-schemas/index.js +1 -1
- package/min/persisters/persister-electric-sql/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-expo-sqlite/index.js +1 -1
- package/min/persisters/persister-expo-sqlite/index.js.gz +0 -0
- package/min/persisters/persister-expo-sqlite/with-schemas/index.js +1 -1
- package/min/persisters/persister-expo-sqlite/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-file/index.js +1 -1
- package/min/persisters/persister-file/index.js.gz +0 -0
- package/min/persisters/persister-file/with-schemas/index.js +1 -1
- package/min/persisters/persister-file/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-indexed-db/index.js +1 -1
- package/min/persisters/persister-indexed-db/index.js.gz +0 -0
- package/min/persisters/persister-indexed-db/with-schemas/index.js +1 -1
- package/min/persisters/persister-indexed-db/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-libsql/index.js +1 -1
- package/min/persisters/persister-libsql/index.js.gz +0 -0
- package/min/persisters/persister-libsql/with-schemas/index.js +1 -1
- package/min/persisters/persister-libsql/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-partykit-client/index.js +1 -1
- package/min/persisters/persister-partykit-client/index.js.gz +0 -0
- package/min/persisters/persister-partykit-client/with-schemas/index.js +1 -1
- package/min/persisters/persister-partykit-client/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-partykit-server/index.js +1 -1
- package/min/persisters/persister-partykit-server/index.js.gz +0 -0
- package/min/persisters/persister-partykit-server/with-schemas/index.js +1 -1
- package/min/persisters/persister-partykit-server/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-pglite/index.js +1 -1
- package/min/persisters/persister-pglite/index.js.gz +0 -0
- package/min/persisters/persister-pglite/with-schemas/index.js +1 -1
- package/min/persisters/persister-pglite/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-postgres/index.js +1 -1
- package/min/persisters/persister-postgres/index.js.gz +0 -0
- package/min/persisters/persister-postgres/with-schemas/index.js +1 -1
- package/min/persisters/persister-postgres/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-powersync/index.js +1 -1
- package/min/persisters/persister-powersync/index.js.gz +0 -0
- package/min/persisters/persister-powersync/with-schemas/index.js +1 -1
- package/min/persisters/persister-powersync/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-react-native-mmkv/index.js +1 -1
- package/min/persisters/persister-react-native-mmkv/index.js.gz +0 -0
- package/min/persisters/persister-react-native-mmkv/with-schemas/index.js +1 -1
- package/min/persisters/persister-react-native-mmkv/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-react-native-sqlite/index.js +1 -1
- package/min/persisters/persister-react-native-sqlite/index.js.gz +0 -0
- package/min/persisters/persister-react-native-sqlite/with-schemas/index.js +1 -1
- package/min/persisters/persister-react-native-sqlite/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-remote/index.js +1 -1
- package/min/persisters/persister-remote/index.js.gz +0 -0
- package/min/persisters/persister-remote/with-schemas/index.js +1 -1
- package/min/persisters/persister-remote/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-sqlite-bun/index.js +1 -1
- package/min/persisters/persister-sqlite-bun/index.js.gz +0 -0
- package/min/persisters/persister-sqlite-bun/with-schemas/index.js +1 -1
- package/min/persisters/persister-sqlite-bun/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-sqlite-wasm/index.js +1 -1
- package/min/persisters/persister-sqlite-wasm/index.js.gz +0 -0
- package/min/persisters/persister-sqlite-wasm/with-schemas/index.js +1 -1
- package/min/persisters/persister-sqlite-wasm/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-sqlite3/index.js +1 -1
- package/min/persisters/persister-sqlite3/index.js.gz +0 -0
- package/min/persisters/persister-sqlite3/with-schemas/index.js +1 -1
- package/min/persisters/persister-sqlite3/with-schemas/index.js.gz +0 -0
- package/min/persisters/persister-yjs/index.js +1 -1
- package/min/persisters/persister-yjs/index.js.gz +0 -0
- package/min/persisters/persister-yjs/with-schemas/index.js +1 -1
- package/min/persisters/persister-yjs/with-schemas/index.js.gz +0 -0
- package/min/persisters/with-schemas/index.js +1 -1
- package/min/persisters/with-schemas/index.js.gz +0 -0
- package/min/queries/index.js +1 -1
- package/min/queries/index.js.gz +0 -0
- package/min/queries/with-schemas/index.js +1 -1
- package/min/queries/with-schemas/index.js.gz +0 -0
- package/min/relationships/index.js +1 -1
- package/min/relationships/index.js.gz +0 -0
- package/min/relationships/with-schemas/index.js +1 -1
- package/min/relationships/with-schemas/index.js.gz +0 -0
- package/min/store/index.js +1 -1
- package/min/store/index.js.gz +0 -0
- package/min/store/with-schemas/index.js +1 -1
- package/min/store/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/index.js +1 -1
- package/min/synchronizers/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-broadcast-channel/index.js +1 -1
- package/min/synchronizers/synchronizer-broadcast-channel/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-local/index.js +1 -1
- package/min/synchronizers/synchronizer-local/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-local/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-local/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-client/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-client/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-client/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server-durable-object/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server-durable-object/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server-simple/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server-simple/index.js.gz +0 -0
- package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +1 -1
- package/min/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js.gz +0 -0
- package/min/synchronizers/with-schemas/index.js +1 -1
- package/min/synchronizers/with-schemas/index.js.gz +0 -0
- package/min/ui-react/index.js +1 -1
- package/min/ui-react/index.js.gz +0 -0
- package/min/ui-react/with-schemas/index.js +1 -1
- package/min/ui-react/with-schemas/index.js.gz +0 -0
- package/min/ui-react-dom/index.js +1 -1
- package/min/ui-react-dom/index.js.gz +0 -0
- package/min/ui-react-dom/with-schemas/index.js +1 -1
- package/min/ui-react-dom/with-schemas/index.js.gz +0 -0
- package/min/ui-react-inspector/index.js +1 -1
- package/min/ui-react-inspector/index.js.gz +0 -0
- package/min/ui-react-inspector/with-schemas/index.js +1 -1
- package/min/ui-react-inspector/with-schemas/index.js.gz +0 -0
- package/min/with-schemas/index.js +1 -1
- package/min/with-schemas/index.js.gz +0 -0
- package/omni/index.js +78 -46
- package/omni/with-schemas/index.js +78 -46
- package/package.json +3 -3
- package/persisters/index.js +14 -10
- package/persisters/persister-automerge/index.js +12 -8
- package/persisters/persister-automerge/with-schemas/index.js +12 -8
- package/persisters/persister-browser/index.js +12 -8
- package/persisters/persister-browser/with-schemas/index.js +12 -8
- package/persisters/persister-cr-sqlite-wasm/index.js +14 -10
- package/persisters/persister-cr-sqlite-wasm/with-schemas/index.js +14 -10
- package/persisters/persister-durable-object-sql-storage/index.js +14 -10
- package/persisters/persister-durable-object-sql-storage/with-schemas/index.js +14 -10
- package/persisters/persister-durable-object-storage/index.js +12 -8
- package/persisters/persister-durable-object-storage/with-schemas/index.js +12 -8
- package/persisters/persister-electric-sql/index.js +14 -10
- package/persisters/persister-electric-sql/with-schemas/index.js +14 -10
- package/persisters/persister-expo-sqlite/index.js +14 -10
- package/persisters/persister-expo-sqlite/with-schemas/index.js +14 -10
- package/persisters/persister-file/index.js +12 -8
- package/persisters/persister-file/with-schemas/index.js +12 -8
- package/persisters/persister-indexed-db/index.js +12 -8
- package/persisters/persister-indexed-db/with-schemas/index.js +12 -8
- package/persisters/persister-libsql/index.js +14 -10
- package/persisters/persister-libsql/with-schemas/index.js +14 -10
- package/persisters/persister-partykit-client/index.js +12 -8
- package/persisters/persister-partykit-client/with-schemas/index.js +12 -8
- package/persisters/persister-partykit-server/index.js +4 -3
- package/persisters/persister-partykit-server/with-schemas/index.js +4 -3
- package/persisters/persister-pglite/index.js +13 -9
- package/persisters/persister-pglite/with-schemas/index.js +13 -9
- package/persisters/persister-postgres/index.js +13 -9
- package/persisters/persister-postgres/with-schemas/index.js +13 -9
- package/persisters/persister-powersync/index.js +14 -10
- package/persisters/persister-powersync/with-schemas/index.js +14 -10
- package/persisters/persister-react-native-mmkv/index.js +12 -8
- package/persisters/persister-react-native-mmkv/with-schemas/index.js +12 -8
- package/persisters/persister-react-native-sqlite/index.js +14 -10
- package/persisters/persister-react-native-sqlite/with-schemas/index.js +14 -10
- package/persisters/persister-remote/index.js +14 -10
- package/persisters/persister-remote/with-schemas/index.js +14 -10
- package/persisters/persister-sqlite-bun/index.js +14 -10
- package/persisters/persister-sqlite-bun/with-schemas/index.js +14 -10
- package/persisters/persister-sqlite-wasm/index.js +14 -10
- package/persisters/persister-sqlite-wasm/with-schemas/index.js +14 -10
- package/persisters/persister-sqlite3/index.js +14 -10
- package/persisters/persister-sqlite3/with-schemas/index.js +14 -10
- package/persisters/persister-yjs/index.js +18 -12
- package/persisters/persister-yjs/with-schemas/index.js +18 -12
- package/persisters/with-schemas/index.js +14 -10
- package/queries/index.js +17 -12
- package/queries/with-schemas/index.js +17 -12
- package/readme.md +2 -2
- package/relationships/index.js +7 -5
- package/relationships/with-schemas/index.js +7 -5
- package/releases.md +100 -12
- package/store/index.js +48 -18
- package/store/with-schemas/index.js +48 -18
- package/synchronizers/index.js +13 -9
- package/synchronizers/synchronizer-broadcast-channel/index.js +14 -10
- package/synchronizers/synchronizer-broadcast-channel/with-schemas/index.js +14 -10
- package/synchronizers/synchronizer-local/index.js +14 -10
- package/synchronizers/synchronizer-local/with-schemas/index.js +14 -10
- package/synchronizers/synchronizer-ws-client/index.js +13 -9
- package/synchronizers/synchronizer-ws-client/with-schemas/index.js +13 -9
- package/synchronizers/synchronizer-ws-server/index.js +13 -9
- package/synchronizers/synchronizer-ws-server/with-schemas/index.js +13 -9
- package/synchronizers/synchronizer-ws-server-durable-object/index.js +13 -9
- package/synchronizers/synchronizer-ws-server-durable-object/with-schemas/index.js +13 -9
- package/synchronizers/synchronizer-ws-server-simple/index.js +5 -4
- package/synchronizers/synchronizer-ws-server-simple/with-schemas/index.js +5 -4
- package/synchronizers/with-schemas/index.js +13 -9
- package/ui-react/index.js +9 -6
- package/ui-react/with-schemas/index.js +9 -6
- package/ui-react-dom/index.js +14 -7
- package/ui-react-dom/with-schemas/index.js +14 -7
- package/ui-react-inspector/index.js +53 -23
- package/ui-react-inspector/with-schemas/index.js +53 -23
- package/with-schemas/index.js +60 -30
|
@@ -5,9 +5,13 @@ const EMPTY_STRING = '';
|
|
|
5
5
|
const T = 't';
|
|
6
6
|
const V = 'v';
|
|
7
7
|
|
|
8
|
-
const
|
|
9
|
-
|
|
10
|
-
|
|
8
|
+
const getIfNotFunction = (predicate) => (value, then, otherwise) =>
|
|
9
|
+
predicate(value) ? otherwise?.() : then(value);
|
|
10
|
+
const isNullish = (thing) => thing == null;
|
|
11
|
+
const isUndefined = (thing) => thing === void 0;
|
|
12
|
+
const isNull = (thing) => thing === null;
|
|
13
|
+
const ifNotNullish = getIfNotFunction(isNullish);
|
|
14
|
+
const ifNotUndefined = getIfNotFunction(isUndefined);
|
|
11
15
|
const isArray = (thing) => Array.isArray(thing);
|
|
12
16
|
const size = (arrayOrString) => arrayOrString.length;
|
|
13
17
|
const test = (regex, subject) => regex.test(subject);
|
|
@@ -40,12 +44,12 @@ const object = Object;
|
|
|
40
44
|
const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
|
|
41
45
|
const objEntries = object.entries;
|
|
42
46
|
const isObject = (obj) =>
|
|
43
|
-
!
|
|
44
|
-
|
|
47
|
+
!isNullish(obj) &&
|
|
48
|
+
ifNotNullish(
|
|
45
49
|
getPrototypeOf(obj),
|
|
46
50
|
(objPrototype) =>
|
|
47
51
|
objPrototype == object.prototype ||
|
|
48
|
-
|
|
52
|
+
isNullish(getPrototypeOf(objPrototype)),
|
|
49
53
|
|
|
50
54
|
/* istanbul ignore next */
|
|
51
55
|
() => true,
|
|
@@ -72,7 +76,7 @@ const mapGet = (map, key) => map?.get(key);
|
|
|
72
76
|
const mapForEach = (map, cb) =>
|
|
73
77
|
collForEach(map, (value, key) => cb(key, value));
|
|
74
78
|
const mapSet = (map, key, value) =>
|
|
75
|
-
|
|
79
|
+
value === void 0 ? (collDel(map, key), map) : map?.set(key, value);
|
|
76
80
|
const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
|
|
77
81
|
if (!collHas(map, key)) {
|
|
78
82
|
mapSet(map, key, getDefaultValue());
|
|
@@ -183,7 +187,7 @@ const getListenerFunctions = (getThing) => {
|
|
|
183
187
|
const index = size(ids);
|
|
184
188
|
if (index == size(path)) {
|
|
185
189
|
listener(thing, ...ids, ...extraArgsGetter(ids));
|
|
186
|
-
} else if (
|
|
190
|
+
} else if (isNull(path[index])) {
|
|
187
191
|
arrayForEach(pathGetters[index]?.(...ids) ?? [], (id2) =>
|
|
188
192
|
callWithIds(...ids, id2),
|
|
189
193
|
);
|
|
@@ -459,7 +463,8 @@ const getChangesFromYDoc = (yContent, events) => {
|
|
|
459
463
|
mapForEach(
|
|
460
464
|
keys,
|
|
461
465
|
(cellId, {action}) =>
|
|
462
|
-
(row[cellId] =
|
|
466
|
+
(row[cellId] =
|
|
467
|
+
action == DELETE ? void 0 : yRow.get(cellId)),
|
|
463
468
|
);
|
|
464
469
|
},
|
|
465
470
|
() =>
|
|
@@ -467,7 +472,7 @@ const getChangesFromYDoc = (yContent, events) => {
|
|
|
467
472
|
keys,
|
|
468
473
|
(rowId, {action}) =>
|
|
469
474
|
(table[rowId] =
|
|
470
|
-
action == DELETE ?
|
|
475
|
+
action == DELETE ? void 0 : yTable.get(rowId)?.toJSON()),
|
|
471
476
|
),
|
|
472
477
|
);
|
|
473
478
|
},
|
|
@@ -476,13 +481,14 @@ const getChangesFromYDoc = (yContent, events) => {
|
|
|
476
481
|
keys,
|
|
477
482
|
(tableId, {action}) =>
|
|
478
483
|
(tables[tableId] =
|
|
479
|
-
action == DELETE ?
|
|
484
|
+
action == DELETE ? void 0 : yTables.get(tableId)?.toJSON()),
|
|
480
485
|
),
|
|
481
486
|
)
|
|
482
487
|
: mapForEach(
|
|
483
488
|
keys,
|
|
484
489
|
(valueId, {action}) =>
|
|
485
|
-
(values[valueId] =
|
|
490
|
+
(values[valueId] =
|
|
491
|
+
action == DELETE ? void 0 : yValues.get(valueId)),
|
|
486
492
|
),
|
|
487
493
|
);
|
|
488
494
|
return [tables, values, 1];
|
|
@@ -13,15 +13,19 @@ const strReplace = (str, searchValue, replaceValue) =>
|
|
|
13
13
|
str.replace(searchValue, replaceValue);
|
|
14
14
|
|
|
15
15
|
const promise = Promise;
|
|
16
|
+
const getIfNotFunction = (predicate) => (value, then, otherwise) =>
|
|
17
|
+
predicate(value) ? otherwise?.() : then(value);
|
|
16
18
|
const GLOBAL = globalThis;
|
|
17
19
|
const THOUSAND = 1e3;
|
|
18
20
|
const startInterval = (callback, sec, immediate) => {
|
|
19
21
|
return setInterval(callback, sec * THOUSAND);
|
|
20
22
|
};
|
|
21
23
|
const stopInterval = clearInterval;
|
|
22
|
-
const
|
|
23
|
-
const
|
|
24
|
-
|
|
24
|
+
const isNullish = (thing) => thing == null;
|
|
25
|
+
const isUndefined = (thing) => thing === void 0;
|
|
26
|
+
const isNull = (thing) => thing === null;
|
|
27
|
+
const ifNotNullish = getIfNotFunction(isNullish);
|
|
28
|
+
const ifNotUndefined = getIfNotFunction(isUndefined);
|
|
25
29
|
const isString = (thing) => getTypeOf(thing) == STRING;
|
|
26
30
|
const isArray = (thing) => Array.isArray(thing);
|
|
27
31
|
const slice = (arrayOrString, start, end) => arrayOrString.slice(start, end);
|
|
@@ -61,12 +65,12 @@ const object = Object;
|
|
|
61
65
|
const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
|
|
62
66
|
const objEntries = object.entries;
|
|
63
67
|
const isObject = (obj) =>
|
|
64
|
-
!
|
|
65
|
-
|
|
68
|
+
!isNullish(obj) &&
|
|
69
|
+
ifNotNullish(
|
|
66
70
|
getPrototypeOf(obj),
|
|
67
71
|
(objPrototype) =>
|
|
68
72
|
objPrototype == object.prototype ||
|
|
69
|
-
|
|
73
|
+
isNullish(getPrototypeOf(objPrototype)),
|
|
70
74
|
|
|
71
75
|
/* istanbul ignore next */
|
|
72
76
|
() => true,
|
|
@@ -95,7 +99,7 @@ const mapForEach = (map, cb) =>
|
|
|
95
99
|
const mapMap = (coll, cb) =>
|
|
96
100
|
arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
|
|
97
101
|
const mapSet = (map, key, value) =>
|
|
98
|
-
|
|
102
|
+
value === void 0 ? (collDel(map, key), map) : map?.set(key, value);
|
|
99
103
|
const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
|
|
100
104
|
if (!collHas(map, key)) {
|
|
101
105
|
mapSet(map, key, getDefaultValue());
|
|
@@ -206,7 +210,7 @@ const getListenerFunctions = (getThing) => {
|
|
|
206
210
|
const index = size(ids);
|
|
207
211
|
if (index == size(path)) {
|
|
208
212
|
listener(thing, ...ids, ...extraArgsGetter(ids));
|
|
209
|
-
} else if (
|
|
213
|
+
} else if (isNull(path[index])) {
|
|
210
214
|
arrayForEach(pathGetters[index]?.(...ids) ?? [], (id2) =>
|
|
211
215
|
callWithIds(...ids, id2),
|
|
212
216
|
);
|
|
@@ -579,7 +583,7 @@ const getDefaultedTabularConfigMap = (
|
|
|
579
583
|
0,
|
|
580
584
|
objSize(defaultObj),
|
|
581
585
|
);
|
|
582
|
-
if (!
|
|
586
|
+
if (!isNull(defaultedConfig[0]) && !exclude(id, defaultedConfig[0])) {
|
|
583
587
|
then(id, defaultedConfig[0]);
|
|
584
588
|
mapSet(configMap, id, defaultedConfig);
|
|
585
589
|
}
|
|
@@ -1306,7 +1310,7 @@ const createCustomSqlitePersister = (
|
|
|
1306
1310
|
` ${DATA_VERSION} d,${SCHEMA_VERSION} s,TOTAL_CHANGES() c FROM ${PRAGMA}${DATA_VERSION} JOIN ${PRAGMA}${SCHEMA_VERSION}`,
|
|
1307
1311
|
);
|
|
1308
1312
|
if (d != dataVersion || s != schemaVersion || c != totalChanges) {
|
|
1309
|
-
if (dataVersion
|
|
1313
|
+
if (!isNullish(dataVersion)) {
|
|
1310
1314
|
listener();
|
|
1311
1315
|
}
|
|
1312
1316
|
dataVersion = d;
|
package/queries/index.js
CHANGED
|
@@ -21,13 +21,15 @@ const SORTED_ROW_IDS = 'Sorted' + ROW + IDS;
|
|
|
21
21
|
const CELL = 'Cell';
|
|
22
22
|
const CELL_IDS = CELL + IDS;
|
|
23
23
|
|
|
24
|
+
const getIfNotFunction = (predicate) => (value, then, otherwise) =>
|
|
25
|
+
predicate(value) ? otherwise?.() : then(value);
|
|
24
26
|
const math = Math;
|
|
25
27
|
const mathMax = math.max;
|
|
26
28
|
const mathMin = math.min;
|
|
27
29
|
const isFiniteNumber = isFinite;
|
|
28
|
-
const isUndefined = (thing) => thing
|
|
29
|
-
const
|
|
30
|
-
|
|
30
|
+
const isUndefined = (thing) => thing === void 0;
|
|
31
|
+
const isNull = (thing) => thing === null;
|
|
32
|
+
const ifNotUndefined = getIfNotFunction(isUndefined);
|
|
31
33
|
const isTypeStringOrBoolean = (type) => type == STRING || type == BOOLEAN;
|
|
32
34
|
const isFunction = (thing) => getTypeOf(thing) == FUNCTION;
|
|
33
35
|
const isArray = (thing) => Array.isArray(thing);
|
|
@@ -69,7 +71,7 @@ const mapGet = (map, key) => map?.get(key);
|
|
|
69
71
|
const mapForEach = (map, cb) =>
|
|
70
72
|
collForEach(map, (value, key) => cb(key, value));
|
|
71
73
|
const mapSet = (map, key, value) =>
|
|
72
|
-
|
|
74
|
+
value === void 0 ? (collDel(map, key), map) : map?.set(key, value);
|
|
73
75
|
const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
|
|
74
76
|
if (!collHas(map, key)) {
|
|
75
77
|
mapSet(map, key, getDefaultValue());
|
|
@@ -170,6 +172,9 @@ const getAggregateValue = (
|
|
|
170
172
|
};
|
|
171
173
|
|
|
172
174
|
const getCellOrValueType = (cellOrValue) => {
|
|
175
|
+
if (isNull(cellOrValue)) {
|
|
176
|
+
return 'null';
|
|
177
|
+
}
|
|
173
178
|
const type = getTypeOf(cellOrValue);
|
|
174
179
|
return isTypeStringOrBoolean(type) ||
|
|
175
180
|
(type == NUMBER && isFiniteNumber(cellOrValue))
|
|
@@ -426,7 +431,7 @@ const createQueries = getCreateFunction((store) => {
|
|
|
426
431
|
setDefinition(queryId, tableId);
|
|
427
432
|
resetPreStores(queryId);
|
|
428
433
|
const selectEntries = [];
|
|
429
|
-
const joinEntries = [[
|
|
434
|
+
const joinEntries = [[void 0, [tableId, void 0, void 0, [], mapNew()]]];
|
|
430
435
|
const wheres = [];
|
|
431
436
|
const groupEntries = [];
|
|
432
437
|
const havings = [];
|
|
@@ -442,7 +447,7 @@ const createQueries = getCreateFunction((store) => {
|
|
|
442
447
|
};
|
|
443
448
|
const join = (joinedTableId, arg1, arg2) => {
|
|
444
449
|
const fromIntermediateJoinedTableId =
|
|
445
|
-
isUndefined(arg2) || isFunction(arg1) ?
|
|
450
|
+
isUndefined(arg2) || isFunction(arg1) ? void 0 : arg1;
|
|
446
451
|
const onArg = isUndefined(fromIntermediateJoinedTableId) ? arg1 : arg2;
|
|
447
452
|
const joinEntry = [
|
|
448
453
|
joinedTableId,
|
|
@@ -562,7 +567,7 @@ const createQueries = getCreateFunction((store) => {
|
|
|
562
567
|
groupRow[groupedCellId] = isUndefined(
|
|
563
568
|
getCellOrValueType(aggregateValue),
|
|
564
569
|
)
|
|
565
|
-
?
|
|
570
|
+
? void 0
|
|
566
571
|
: aggregateValue;
|
|
567
572
|
},
|
|
568
573
|
);
|
|
@@ -691,20 +696,20 @@ const createQueries = getCreateFunction((store) => {
|
|
|
691
696
|
const listenToTable = (rootRowId, tableId2, rowId, joinedTableIds2) => {
|
|
692
697
|
const getCell = (cellId) => store.getCell(tableId2, rowId, cellId);
|
|
693
698
|
arrayForEach(joinedTableIds2, (remoteAsTableId) => {
|
|
694
|
-
const [realJoinedTableId, , on, nextJoinedTableIds,
|
|
699
|
+
const [realJoinedTableId, , on, nextJoinedTableIds, remoteIdPairs] =
|
|
695
700
|
mapGet(joins, remoteAsTableId);
|
|
696
701
|
const remoteRowId = on?.(getCell, rootRowId);
|
|
697
702
|
const [previousRemoteRowId, previousRemoteListenerId] =
|
|
698
|
-
mapGet(
|
|
703
|
+
mapGet(remoteIdPairs, rootRowId) ?? [];
|
|
699
704
|
if (remoteRowId != previousRemoteRowId) {
|
|
700
705
|
if (!isUndefined(previousRemoteListenerId)) {
|
|
701
706
|
delStoreListeners(queryId, previousRemoteListenerId);
|
|
702
707
|
}
|
|
703
708
|
mapSet(
|
|
704
|
-
|
|
709
|
+
remoteIdPairs,
|
|
705
710
|
rootRowId,
|
|
706
711
|
isUndefined(remoteRowId)
|
|
707
|
-
?
|
|
712
|
+
? void 0
|
|
708
713
|
: [
|
|
709
714
|
remoteRowId,
|
|
710
715
|
...addStoreListeners(
|
|
@@ -725,7 +730,7 @@ const createQueries = getCreateFunction((store) => {
|
|
|
725
730
|
});
|
|
726
731
|
writeSelectRow(rootRowId);
|
|
727
732
|
};
|
|
728
|
-
const {3: joinedTableIds} = mapGet(joins,
|
|
733
|
+
const {3: joinedTableIds} = mapGet(joins, void 0);
|
|
729
734
|
selectJoinWhereStore.transaction(() =>
|
|
730
735
|
addStoreListeners(
|
|
731
736
|
queryId,
|
|
@@ -21,13 +21,15 @@ const SORTED_ROW_IDS = 'Sorted' + ROW + IDS;
|
|
|
21
21
|
const CELL = 'Cell';
|
|
22
22
|
const CELL_IDS = CELL + IDS;
|
|
23
23
|
|
|
24
|
+
const getIfNotFunction = (predicate) => (value, then, otherwise) =>
|
|
25
|
+
predicate(value) ? otherwise?.() : then(value);
|
|
24
26
|
const math = Math;
|
|
25
27
|
const mathMax = math.max;
|
|
26
28
|
const mathMin = math.min;
|
|
27
29
|
const isFiniteNumber = isFinite;
|
|
28
|
-
const isUndefined = (thing) => thing
|
|
29
|
-
const
|
|
30
|
-
|
|
30
|
+
const isUndefined = (thing) => thing === void 0;
|
|
31
|
+
const isNull = (thing) => thing === null;
|
|
32
|
+
const ifNotUndefined = getIfNotFunction(isUndefined);
|
|
31
33
|
const isTypeStringOrBoolean = (type) => type == STRING || type == BOOLEAN;
|
|
32
34
|
const isFunction = (thing) => getTypeOf(thing) == FUNCTION;
|
|
33
35
|
const isArray = (thing) => Array.isArray(thing);
|
|
@@ -69,7 +71,7 @@ const mapGet = (map, key) => map?.get(key);
|
|
|
69
71
|
const mapForEach = (map, cb) =>
|
|
70
72
|
collForEach(map, (value, key) => cb(key, value));
|
|
71
73
|
const mapSet = (map, key, value) =>
|
|
72
|
-
|
|
74
|
+
value === void 0 ? (collDel(map, key), map) : map?.set(key, value);
|
|
73
75
|
const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
|
|
74
76
|
if (!collHas(map, key)) {
|
|
75
77
|
mapSet(map, key, getDefaultValue());
|
|
@@ -170,6 +172,9 @@ const getAggregateValue = (
|
|
|
170
172
|
};
|
|
171
173
|
|
|
172
174
|
const getCellOrValueType = (cellOrValue) => {
|
|
175
|
+
if (isNull(cellOrValue)) {
|
|
176
|
+
return 'null';
|
|
177
|
+
}
|
|
173
178
|
const type = getTypeOf(cellOrValue);
|
|
174
179
|
return isTypeStringOrBoolean(type) ||
|
|
175
180
|
(type == NUMBER && isFiniteNumber(cellOrValue))
|
|
@@ -426,7 +431,7 @@ const createQueries = getCreateFunction((store) => {
|
|
|
426
431
|
setDefinition(queryId, tableId);
|
|
427
432
|
resetPreStores(queryId);
|
|
428
433
|
const selectEntries = [];
|
|
429
|
-
const joinEntries = [[
|
|
434
|
+
const joinEntries = [[void 0, [tableId, void 0, void 0, [], mapNew()]]];
|
|
430
435
|
const wheres = [];
|
|
431
436
|
const groupEntries = [];
|
|
432
437
|
const havings = [];
|
|
@@ -442,7 +447,7 @@ const createQueries = getCreateFunction((store) => {
|
|
|
442
447
|
};
|
|
443
448
|
const join = (joinedTableId, arg1, arg2) => {
|
|
444
449
|
const fromIntermediateJoinedTableId =
|
|
445
|
-
isUndefined(arg2) || isFunction(arg1) ?
|
|
450
|
+
isUndefined(arg2) || isFunction(arg1) ? void 0 : arg1;
|
|
446
451
|
const onArg = isUndefined(fromIntermediateJoinedTableId) ? arg1 : arg2;
|
|
447
452
|
const joinEntry = [
|
|
448
453
|
joinedTableId,
|
|
@@ -562,7 +567,7 @@ const createQueries = getCreateFunction((store) => {
|
|
|
562
567
|
groupRow[groupedCellId] = isUndefined(
|
|
563
568
|
getCellOrValueType(aggregateValue),
|
|
564
569
|
)
|
|
565
|
-
?
|
|
570
|
+
? void 0
|
|
566
571
|
: aggregateValue;
|
|
567
572
|
},
|
|
568
573
|
);
|
|
@@ -691,20 +696,20 @@ const createQueries = getCreateFunction((store) => {
|
|
|
691
696
|
const listenToTable = (rootRowId, tableId2, rowId, joinedTableIds2) => {
|
|
692
697
|
const getCell = (cellId) => store.getCell(tableId2, rowId, cellId);
|
|
693
698
|
arrayForEach(joinedTableIds2, (remoteAsTableId) => {
|
|
694
|
-
const [realJoinedTableId, , on, nextJoinedTableIds,
|
|
699
|
+
const [realJoinedTableId, , on, nextJoinedTableIds, remoteIdPairs] =
|
|
695
700
|
mapGet(joins, remoteAsTableId);
|
|
696
701
|
const remoteRowId = on?.(getCell, rootRowId);
|
|
697
702
|
const [previousRemoteRowId, previousRemoteListenerId] =
|
|
698
|
-
mapGet(
|
|
703
|
+
mapGet(remoteIdPairs, rootRowId) ?? [];
|
|
699
704
|
if (remoteRowId != previousRemoteRowId) {
|
|
700
705
|
if (!isUndefined(previousRemoteListenerId)) {
|
|
701
706
|
delStoreListeners(queryId, previousRemoteListenerId);
|
|
702
707
|
}
|
|
703
708
|
mapSet(
|
|
704
|
-
|
|
709
|
+
remoteIdPairs,
|
|
705
710
|
rootRowId,
|
|
706
711
|
isUndefined(remoteRowId)
|
|
707
|
-
?
|
|
712
|
+
? void 0
|
|
708
713
|
: [
|
|
709
714
|
remoteRowId,
|
|
710
715
|
...addStoreListeners(
|
|
@@ -725,7 +730,7 @@ const createQueries = getCreateFunction((store) => {
|
|
|
725
730
|
});
|
|
726
731
|
writeSelectRow(rootRowId);
|
|
727
732
|
};
|
|
728
|
-
const {3: joinedTableIds} = mapGet(joins,
|
|
733
|
+
const {3: joinedTableIds} = mapGet(joins, void 0);
|
|
729
734
|
selectJoinWhereStore.transaction(() =>
|
|
730
735
|
addStoreListeners(
|
|
731
736
|
queryId,
|
package/readme.md
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
<link rel="preload" as="image" href="https://beta.tinybase.org/react.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/indexeddb.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/browser.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/cloudflare.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/postgresql.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/pglite.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/sqlite.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/bun.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/expo.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/electric.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/turso.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/powersync.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/partykit.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/yjs.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/crsqlite.png"><link rel="preload" as="image" href="https://beta.tinybase.org/automerge.svg?asImg"><link rel="preload" as="image" href="https://img.shields.io/github/stars/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=GitHub&labelColor=%23d81b60&color=%23333"><link rel="preload" as="image" href="https://img.shields.io/badge/Bluesky-Follow-blue?style=for-the-badge&logo=bluesky&logoColor=%23fff&color=%23333&labelColor=%230285FF"><link rel="preload" as="image" href="https://img.shields.io/badge/%2F%20Twitter-Follow-blue?style=for-the-badge&logo=x&logoColor=%23fff&color=%23333&labelColor=%23000"><link rel="preload" as="image" href="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&logo=discord&logoColor=%23fff&label=Discord&labelColor=%233131e8&color=%23333"><link rel="preload" as="image" href="https://img.shields.io/github/discussions/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Ideas&labelColor=%23d81b60&color=%23333"><link rel="preload" as="image" href="https://img.shields.io/github/issues/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Issues&labelColor=%23d81b60&color=%23333"><link rel="preload" as="image" href="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&logo=Vitest&logoColor=%23fff&color=%23333&labelColor=%2387c305"><link rel="preload" as="image" href="https://img.shields.io/npm/v/tinybase?style=for-the-badge&logo=npm&logoColor=%23fff&labelColor=%23bd0005&color=%23333"><link rel="preload" as="image" href="https://beta.tinybase.org/ui-react-dom.webp"><link rel="preload" as="image" href="https://beta.tinybase.org/inspector.webp"><link rel="preload" as="image" href="https://github.com/cpojer.png?size=48"><link rel="preload" as="image" href="https://github.com/expo.png?size=48"><link rel="preload" as="image" href="https://github.com/beekeeb.png?size=48"><link rel="preload" as="image" href="https://github.com/cancelself.png?size=48"><link rel="preload" as="image" href="https://github.com/WonderPanda.png?size=48"><link rel="preload" as="image" href="https://github.com/arpitBhalla.png?size=48"><link rel="preload" as="image" href="https://github.com/behrends.png?size=48"><link rel="preload" as="image" href="https://github.com/betomoedano.png?size=48"><link rel="preload" as="image" href="https://github.com/brentvatne.png?size=48"><link rel="preload" as="image" href="https://github.com/byCedric.png?size=48"><link rel="preload" as="image" href="https://github.com/circadian-risk.png?size=48"><link rel="preload" as="image" href="https://github.com/cubecull.png?size=48"><link rel="preload" as="image" href="https://github.com/erwinkn.png?size=48"><link rel="preload" as="image" href="https://github.com/ezra-en.png?size=48"><link rel="preload" as="image" href="https://github.com/feychenie.png?size=48"><link rel="preload" as="image" href="https://github.com/flaming-codes.png?size=48"><link rel="preload" as="image" href="https://github.com/fostertheweb.png?size=48"><link rel="preload" as="image" href="https://github.com/Giulio987.png?size=48"><link rel="preload" as="image" href="https://github.com/hi-ogawa.png?size=48"><link rel="preload" as="image" href="https://github.com/itsdevcoffee.png?size=48"><link rel="preload" as="image" href="https://github.com/jbolda.png?size=48"><link rel="preload" as="image" href="https://github.com/Kayoo-asso.png?size=48"><link rel="preload" as="image" href="https://github.com/kotofurumiya.png?size=48"><link rel="preload" as="image" href="https://github.com/Kudo.png?size=48"><link rel="preload" as="image" href="https://github.com/learn-anything.png?size=48"><link rel="preload" as="image" href="https://github.com/lluc.png?size=48"><link rel="preload" as="image" href="https://github.com/marksteve.png?size=48"><link rel="preload" as="image" href="https://github.com/miking-the-viking.png?size=48"><link rel="preload" as="image" href="https://github.com/mjamesderocher.png?size=48"><link rel="preload" as="image" href="https://github.com/mouktardev.png?size=48"><link rel="preload" as="image" href="https://github.com/nickmessing.png?size=48"><link rel="preload" as="image" href="https://github.com/nikitavoloboev.png?size=48"><link rel="preload" as="image" href="https://github.com/nkzw-tech.png?size=48"><link rel="preload" as="image" href="https://github.com/palerdot.png?size=48"><link rel="preload" as="image" href="https://github.com/PorcoRosso85.png?size=48"><link rel="preload" as="image" href="https://github.com/primodiumxyz.png?size=48"><link rel="preload" as="image" href="https://github.com/shaneosullivan.png?size=48"><link rel="preload" as="image" href="https://github.com/sudo-self.png?size=48"><link rel="preload" as="image" href="https://github.com/SuperSonicHub1.png?size=48"><link rel="preload" as="image" href="https://github.com/threepointone.png?size=48"><link rel="preload" as="image" href="https://github.com/uptonking.png?size=48"><link rel="preload" as="image" href="https://github.com/ViktorZhurbin.png?size=48"><link rel="preload" as="image" href="https://github.com/wilkerlucio.png?size=48"><link rel="preload" as="image" href="https://synclets.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://tinywidgets.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://tinytick.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/youtube.webp"><section id="hero"><h2 id="a-reactive-data-store-sync-engine">A <em>reactive</em> data store & <span><em>sync</em> engine</span></h2></section><p><a href="https://beta.tinybase.org/guides/releases/#v6-7"><em>NEW!</em> v6.7 release</a></p><p><span id="one-with">"The one with OPFS!"</span></p><p><a class="start" href="https://beta.tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://beta.tinybase.org/demos/">Try the demos</a></p><p><a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/">Read the docs</a></p><hr><section><h2 id="it-s-reactive">It's <em>Reactive</em></h2><p>TinyBase lets you <a href="#register-granular-listeners">listen to changes</a> made to any part of your data. This means your app will be fast, since you only spend rendering cycles on things that change. The optional <a href="#call-hooks-to-bind-to-data">bindings to React</a> and <a href="#pre-built-reactive-components">pre-built components</a> let you easily build fully reactive UIs on top of TinyBase. You even get a built-in <a href="#set-checkpoints-for-an-undo-stack">undo stack</a>, and <a href="#an-inspector-for-your-data">developer tools</a>!</p></section><section><h2 id="it-s-database-like">It's <em>Database-Like</em></h2><p>Consumer app? Enterprise app? Or even a game? Model <a href="#start-with-a-simple-key-value-store">key-value data</a> and <a href="#level-up-to-use-tabular-data">tabular data</a> with optional typed <a href="#apply-schemas-to-tables-values">schematization</a>, whatever its data structures. There are built-in <a href="#create-indexes-for-fast-lookups">indexing</a>, <a href="#define-metrics-and-aggregations">metric aggregation</a>, and tabular <a href="#model-table-relationships">relationships</a> APIs - and a powerful <a href="#build-complex-queries-with-tinyql">query engine</a> to select, join, filter, and group data (reactively!) without SQL.</p></section><section><h2 id="it-synchronizes">It <em>Synchronizes</em></h2><p>TinyBase has <a href="#synchronize-between-devices">native CRDT</a> support, meaning that you can deterministically <a href="https://beta.tinybase.org/guides/synchronization/">synchronize</a> and merge data across multiple sources, clients, and servers. And although TinyBase is an in-memory data store, you can easily <a href="#persist-to-storage-databases-more">persist</a> your data to file, <a href="https://beta.tinybase.org/api/persister-browser">browser storage</a>, <a href="https://beta.tinybase.org/api/persister-indexed-db">IndexedDB</a>, <a href="https://beta.tinybase.org/guides/persistence/database-persistence/">SQLite or PostgreSQL databases</a>, and <a href="https://beta.tinybase.org/guides/persistence/third-party-crdt-persistence/">more</a>.</p></section><section><h2 id="it-s-built-for-a-local-first-world">It's Built For A <em>Local-First</em> World</h2><p>TinyBase works anywhere that JavaScript does, but it's especially great for local-first apps: where data is stored locally on the user's device and that can be run offline. It's tiny by name, tiny by nature: just <a href="#did-we-say-tiny">5.3kB - 11.7kB</a> and with no dependencies - yet <a href="#well-tested-and-documented">100% tested</a>, <a href="https://beta.tinybase.org/guides/the-basics/getting-started/">fully documented</a>, and of course, <a href="https://github.com/tinyplex/tinybase">open source</a>!</p></section><hr><section id="friends"><h2 id="tinybase-works-great-on-its-own-but-also-plays-well-with-friends">TinyBase works great on its own, but also plays well with friends.</h2><div><a href="https://beta.tinybase.org/guides/building-uis/getting-started-with-ui-react"><img src="https://beta.tinybase.org/react.svg?asImg" width="48"> React</a></div><div><a href="https://beta.tinybase.org/api/persister-indexed-db/functions/creation/createindexeddbpersister"><img src="https://beta.tinybase.org/indexeddb.svg?asImg" width="48"> IndexedDB</a></div><div><a href="https://beta.tinybase.org/api/persister-browser"><img src="https://beta.tinybase.org/browser.svg?asImg" width="48"> OPFS</a></div><div><a href="https://beta.tinybase.org/guides/integrations/cloudflare-durable-objects"><img src="https://beta.tinybase.org/cloudflare.svg?asImg" width="48"> Cloudflare</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/postgresql.svg?asImg" width="48"> PostgreSQL</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/pglite.svg?asImg" width="48"> PGlite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/sqlite.svg?asImg" width="48"> SQLite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/bun.svg?asImg" width="48"> Bun SQLite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/expo.svg?asImg" width="48"> Expo SQLite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/electric.svg?asImg" width="48"> ElectricSQL</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/turso.svg?asImg" width="48"> Turso</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/powersync.svg?asImg" width="48"> PowerSync</a></div><div><a href="https://beta.tinybase.org/api/persister-partykit-client"><img src="https://beta.tinybase.org/partykit.svg?asImg" width="48"> PartyKit</a></div><div><a href="https://beta.tinybase.org/api/persister-yjs/functions/creation/createyjspersister"><img src="https://beta.tinybase.org/yjs.svg?asImg" width="48"> YJS</a></div><div><a href="https://beta.tinybase.org/api/persister-cr-sqlite-wasm"><img src="https://beta.tinybase.org/crsqlite.png" width="48"> CR-SQLite</a></div><div><a href="https://beta.tinybase.org/api/persister-automerge"><img src="https://beta.tinybase.org/automerge.svg?asImg" width="48"> Automerge</a></div><p>(Baffled by all these logos? Check out our <a href="https://beta.tinybase.org/guides/the-basics/architectural-options">architectural options</a> guide to make sense of it all!)</p></section><hr><section id="follow"><a href="https://github.com/tinyplex/tinybase" target="_blank"><img src="https://img.shields.io/github/stars/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=GitHub&labelColor=%23d81b60&color=%23333"> </a><a href="https://bsky.app/profile/tinybase.bsky.social"><img src="https://img.shields.io/badge/Bluesky-Follow-blue?style=for-the-badge&logo=bluesky&logoColor=%23fff&color=%23333&labelColor=%230285FF"> </a><a href="https://x.com/tinybasejs" target="_blank"><img src="https://img.shields.io/badge/%2F%20Twitter-Follow-blue?style=for-the-badge&logo=x&logoColor=%23fff&color=%23333&labelColor=%23000"> </a><a href="https://discord.com/invite/mGz3mevwP8" target="_blank"><img src="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&logo=discord&logoColor=%23fff&label=Discord&labelColor=%233131e8&color=%23333"></a><br><a href="https://github.com/tinyplex/tinybase/discussions" target="_blank"><img src="https://img.shields.io/github/discussions/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Ideas&labelColor=%23d81b60&color=%23333"> </a><a href="https://github.com/tinyplex/tinybase/issues" target="_blank"><img src="https://img.shields.io/github/issues/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Issues&labelColor=%23d81b60&color=%23333"> </a><a href="#well-tested-and-documented"><img src="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&logo=Vitest&logoColor=%23fff&color=%23333&labelColor=%2387c305"> </a><a href="https://www.npmjs.com/package/tinybase/v/7.0.0-beta.2" target="_blank"><img src="https://img.shields.io/npm/v/tinybase?style=for-the-badge&logo=npm&logoColor=%23fff&labelColor=%23bd0005&color=%23333"></a></section><hr><section><h2 id="start-with-a-simple-key-value-store">Start with a simple key-value store.</h2><p>Creating a <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a> requires just a simple call to the <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/createstore/"><code>createStore</code></a> function. Once you have one, you can easily set <a href="https://beta.tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a> in it by unique <a href="https://beta.tinybase.org/api/common/type-aliases/identity/id/"><code>Id</code></a>. And of course you can easily get them back out again.</p><p>Read more about using keyed value data in <a href="https://beta.tinybase.org/guides/the-basics/">The Basics</a> guide.</p></section>
|
|
1
|
+
<link rel="preload" as="image" href="https://beta.tinybase.org/react.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/indexeddb.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/browser.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/cloudflare.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/postgresql.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/pglite.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/sqlite.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/bun.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/expo.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/electric.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/turso.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/powersync.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/partykit.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/yjs.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/crsqlite.png"><link rel="preload" as="image" href="https://beta.tinybase.org/automerge.svg?asImg"><link rel="preload" as="image" href="https://img.shields.io/github/stars/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=GitHub&labelColor=%23d81b60&color=%23333"><link rel="preload" as="image" href="https://img.shields.io/badge/Bluesky-Follow-blue?style=for-the-badge&logo=bluesky&logoColor=%23fff&color=%23333&labelColor=%230285FF"><link rel="preload" as="image" href="https://img.shields.io/badge/%2F%20Twitter-Follow-blue?style=for-the-badge&logo=x&logoColor=%23fff&color=%23333&labelColor=%23000"><link rel="preload" as="image" href="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&logo=discord&logoColor=%23fff&label=Discord&labelColor=%233131e8&color=%23333"><link rel="preload" as="image" href="https://img.shields.io/github/discussions/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Ideas&labelColor=%23d81b60&color=%23333"><link rel="preload" as="image" href="https://img.shields.io/github/issues/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Issues&labelColor=%23d81b60&color=%23333"><link rel="preload" as="image" href="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&logo=Vitest&logoColor=%23fff&color=%23333&labelColor=%2387c305"><link rel="preload" as="image" href="https://img.shields.io/npm/v/tinybase?style=for-the-badge&logo=npm&logoColor=%23fff&labelColor=%23bd0005&color=%23333"><link rel="preload" as="image" href="https://beta.tinybase.org/ui-react-dom.webp"><link rel="preload" as="image" href="https://beta.tinybase.org/inspector.webp"><link rel="preload" as="image" href="https://github.com/cpojer.png?size=48"><link rel="preload" as="image" href="https://github.com/expo.png?size=48"><link rel="preload" as="image" href="https://github.com/beekeeb.png?size=48"><link rel="preload" as="image" href="https://github.com/cancelself.png?size=48"><link rel="preload" as="image" href="https://github.com/WonderPanda.png?size=48"><link rel="preload" as="image" href="https://github.com/arpitBhalla.png?size=48"><link rel="preload" as="image" href="https://github.com/behrends.png?size=48"><link rel="preload" as="image" href="https://github.com/betomoedano.png?size=48"><link rel="preload" as="image" href="https://github.com/brentvatne.png?size=48"><link rel="preload" as="image" href="https://github.com/byCedric.png?size=48"><link rel="preload" as="image" href="https://github.com/circadian-risk.png?size=48"><link rel="preload" as="image" href="https://github.com/cubecull.png?size=48"><link rel="preload" as="image" href="https://github.com/erwinkn.png?size=48"><link rel="preload" as="image" href="https://github.com/ezra-en.png?size=48"><link rel="preload" as="image" href="https://github.com/feychenie.png?size=48"><link rel="preload" as="image" href="https://github.com/flaming-codes.png?size=48"><link rel="preload" as="image" href="https://github.com/fostertheweb.png?size=48"><link rel="preload" as="image" href="https://github.com/Giulio987.png?size=48"><link rel="preload" as="image" href="https://github.com/hi-ogawa.png?size=48"><link rel="preload" as="image" href="https://github.com/itsdevcoffee.png?size=48"><link rel="preload" as="image" href="https://github.com/jbolda.png?size=48"><link rel="preload" as="image" href="https://github.com/Kayoo-asso.png?size=48"><link rel="preload" as="image" href="https://github.com/kotofurumiya.png?size=48"><link rel="preload" as="image" href="https://github.com/Kudo.png?size=48"><link rel="preload" as="image" href="https://github.com/learn-anything.png?size=48"><link rel="preload" as="image" href="https://github.com/lluc.png?size=48"><link rel="preload" as="image" href="https://github.com/marksteve.png?size=48"><link rel="preload" as="image" href="https://github.com/miking-the-viking.png?size=48"><link rel="preload" as="image" href="https://github.com/mjamesderocher.png?size=48"><link rel="preload" as="image" href="https://github.com/mouktardev.png?size=48"><link rel="preload" as="image" href="https://github.com/nickmessing.png?size=48"><link rel="preload" as="image" href="https://github.com/nikitavoloboev.png?size=48"><link rel="preload" as="image" href="https://github.com/nkzw-tech.png?size=48"><link rel="preload" as="image" href="https://github.com/palerdot.png?size=48"><link rel="preload" as="image" href="https://github.com/PorcoRosso85.png?size=48"><link rel="preload" as="image" href="https://github.com/primodiumxyz.png?size=48"><link rel="preload" as="image" href="https://github.com/shaneosullivan.png?size=48"><link rel="preload" as="image" href="https://github.com/sudo-self.png?size=48"><link rel="preload" as="image" href="https://github.com/SuperSonicHub1.png?size=48"><link rel="preload" as="image" href="https://github.com/threepointone.png?size=48"><link rel="preload" as="image" href="https://github.com/uptonking.png?size=48"><link rel="preload" as="image" href="https://github.com/ViktorZhurbin.png?size=48"><link rel="preload" as="image" href="https://github.com/wilkerlucio.png?size=48"><link rel="preload" as="image" href="https://synclets.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://tinywidgets.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://tinytick.org/favicon.svg?asImg"><link rel="preload" as="image" href="https://beta.tinybase.org/youtube.webp"><section id="hero"><h2 id="a-reactive-data-store-sync-engine">A <em>reactive</em> data store & <span><em>sync</em> engine</span></h2></section><p><a href="https://beta.tinybase.org/guides/releases/#v7-0"><em>NEW!</em> v7.0 release</a></p><p><span id="one-with">"The one with <code>NULL</code>!"</span></p><p><a class="start" href="https://beta.tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://beta.tinybase.org/demos/">Try the demos</a></p><p><a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/">Read the docs</a></p><hr><section><h2 id="it-s-reactive">It's <em>Reactive</em></h2><p>TinyBase lets you <a href="#register-granular-listeners">listen to changes</a> made to any part of your data. This means your app will be fast, since you only spend rendering cycles on things that change. The optional <a href="#call-hooks-to-bind-to-data">bindings to React</a> and <a href="#pre-built-reactive-components">pre-built components</a> let you easily build fully reactive UIs on top of TinyBase. You even get a built-in <a href="#set-checkpoints-for-an-undo-stack">undo stack</a>, and <a href="#an-inspector-for-your-data">developer tools</a>!</p></section><section><h2 id="it-s-database-like">It's <em>Database-Like</em></h2><p>Consumer app? Enterprise app? Or even a game? Model <a href="#start-with-a-simple-key-value-store">key-value data</a> and <a href="#level-up-to-use-tabular-data">tabular data</a> with optional typed <a href="#apply-schemas-to-tables-values">schematization</a>, whatever its data structures. There are built-in <a href="#create-indexes-for-fast-lookups">indexing</a>, <a href="#define-metrics-and-aggregations">metric aggregation</a>, and tabular <a href="#model-table-relationships">relationships</a> APIs - and a powerful <a href="#build-complex-queries-with-tinyql">query engine</a> to select, join, filter, and group data (reactively!) without SQL.</p></section><section><h2 id="it-synchronizes">It <em>Synchronizes</em></h2><p>TinyBase has <a href="#synchronize-between-devices">native CRDT</a> support, meaning that you can deterministically <a href="https://beta.tinybase.org/guides/synchronization/">synchronize</a> and merge data across multiple sources, clients, and servers. And although TinyBase is an in-memory data store, you can easily <a href="#persist-to-storage-databases-more">persist</a> your data to file, <a href="https://beta.tinybase.org/api/persister-browser">browser storage</a>, <a href="https://beta.tinybase.org/api/persister-indexed-db">IndexedDB</a>, <a href="https://beta.tinybase.org/guides/persistence/database-persistence/">SQLite or PostgreSQL databases</a>, and <a href="https://beta.tinybase.org/guides/persistence/third-party-crdt-persistence/">more</a>.</p></section><section><h2 id="it-s-built-for-a-local-first-world">It's Built For A <em>Local-First</em> World</h2><p>TinyBase works anywhere that JavaScript does, but it's especially great for local-first apps: where data is stored locally on the user's device and that can be run offline. It's tiny by name, tiny by nature: just <a href="#did-we-say-tiny">5.4kB - 11.8kB</a> and with no dependencies - yet <a href="#well-tested-and-documented">100% tested</a>, <a href="https://beta.tinybase.org/guides/the-basics/getting-started/">fully documented</a>, and of course, <a href="https://github.com/tinyplex/tinybase">open source</a>!</p></section><hr><section id="friends"><h2 id="tinybase-works-great-on-its-own-but-also-plays-well-with-friends">TinyBase works great on its own, but also plays well with friends.</h2><div><a href="https://beta.tinybase.org/guides/building-uis/getting-started-with-ui-react"><img src="https://beta.tinybase.org/react.svg?asImg" width="48"> React</a></div><div><a href="https://beta.tinybase.org/api/persister-indexed-db/functions/creation/createindexeddbpersister"><img src="https://beta.tinybase.org/indexeddb.svg?asImg" width="48"> IndexedDB</a></div><div><a href="https://beta.tinybase.org/api/persister-browser"><img src="https://beta.tinybase.org/browser.svg?asImg" width="48"> OPFS</a></div><div><a href="https://beta.tinybase.org/guides/integrations/cloudflare-durable-objects"><img src="https://beta.tinybase.org/cloudflare.svg?asImg" width="48"> Cloudflare</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/postgresql.svg?asImg" width="48"> PostgreSQL</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/pglite.svg?asImg" width="48"> PGlite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/sqlite.svg?asImg" width="48"> SQLite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/bun.svg?asImg" width="48"> Bun SQLite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/expo.svg?asImg" width="48"> Expo SQLite</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/electric.svg?asImg" width="48"> ElectricSQL</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/turso.svg?asImg" width="48"> Turso</a></div><div><a href="https://beta.tinybase.org/guides/schemas-and-persistence/database-persistence"><img src="https://beta.tinybase.org/powersync.svg?asImg" width="48"> PowerSync</a></div><div><a href="https://beta.tinybase.org/api/persister-partykit-client"><img src="https://beta.tinybase.org/partykit.svg?asImg" width="48"> PartyKit</a></div><div><a href="https://beta.tinybase.org/api/persister-yjs/functions/creation/createyjspersister"><img src="https://beta.tinybase.org/yjs.svg?asImg" width="48"> YJS</a></div><div><a href="https://beta.tinybase.org/api/persister-cr-sqlite-wasm"><img src="https://beta.tinybase.org/crsqlite.png" width="48"> CR-SQLite</a></div><div><a href="https://beta.tinybase.org/api/persister-automerge"><img src="https://beta.tinybase.org/automerge.svg?asImg" width="48"> Automerge</a></div><p>(Baffled by all these logos? Check out our <a href="https://beta.tinybase.org/guides/the-basics/architectural-options">architectural options</a> guide to make sense of it all!)</p></section><hr><section id="follow"><a href="https://github.com/tinyplex/tinybase" target="_blank"><img src="https://img.shields.io/github/stars/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=GitHub&labelColor=%23d81b60&color=%23333"> </a><a href="https://bsky.app/profile/tinybase.bsky.social"><img src="https://img.shields.io/badge/Bluesky-Follow-blue?style=for-the-badge&logo=bluesky&logoColor=%23fff&color=%23333&labelColor=%230285FF"> </a><a href="https://x.com/tinybasejs" target="_blank"><img src="https://img.shields.io/badge/%2F%20Twitter-Follow-blue?style=for-the-badge&logo=x&logoColor=%23fff&color=%23333&labelColor=%23000"> </a><a href="https://discord.com/invite/mGz3mevwP8" target="_blank"><img src="https://img.shields.io/discord/1027918215323590676?style=for-the-badge&logo=discord&logoColor=%23fff&label=Discord&labelColor=%233131e8&color=%23333"></a><br><a href="https://github.com/tinyplex/tinybase/discussions" target="_blank"><img src="https://img.shields.io/github/discussions/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Ideas&labelColor=%23d81b60&color=%23333"> </a><a href="https://github.com/tinyplex/tinybase/issues" target="_blank"><img src="https://img.shields.io/github/issues/tinyplex/tinybase?style=for-the-badge&logo=GitHub&logoColor=%23fff&label=Issues&labelColor=%23d81b60&color=%23333"> </a><a href="#well-tested-and-documented"><img src="https://img.shields.io/badge/Tests-100%25-green?style=for-the-badge&logo=Vitest&logoColor=%23fff&color=%23333&labelColor=%2387c305"> </a><a href="https://www.npmjs.com/package/tinybase/v/7.0.0-beta.3" target="_blank"><img src="https://img.shields.io/npm/v/tinybase?style=for-the-badge&logo=npm&logoColor=%23fff&labelColor=%23bd0005&color=%23333"></a></section><hr><section><h2 id="start-with-a-simple-key-value-store">Start with a simple key-value store.</h2><p>Creating a <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/"><code>Store</code></a> requires just a simple call to the <a href="https://beta.tinybase.org/api/the-essentials/creating-stores/createstore/"><code>createStore</code></a> function. Once you have one, you can easily set <a href="https://beta.tinybase.org/api/store/type-aliases/store/values/"><code>Values</code></a> in it by unique <a href="https://beta.tinybase.org/api/common/type-aliases/identity/id/"><code>Id</code></a>. And of course you can easily get them back out again.</p><p>Read more about using keyed value data in <a href="https://beta.tinybase.org/guides/the-basics/">The Basics</a> guide.</p></section>
|
|
2
2
|
|
|
3
3
|
```js
|
|
4
4
|
import {createStore} from 'tinybase';
|
|
@@ -275,4 +275,4 @@ console.log(store.getCell('pets', 'felix', 'sold'));
|
|
|
275
275
|
// -> false
|
|
276
276
|
```
|
|
277
277
|
|
|
278
|
-
<section><h2 id="did-we-say-tiny">Did we say tiny?</h2><p>If you use the basic <a href="https://beta.tinybase.org/api/store/"><code>store</code></a> module alone, you'll only add a gzipped <em>5.3kB</em> to your app. Incrementally add the other modules as you need more functionality, or get it all for <em>11.7kB</em>.</p><p>The optional <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module is just <em>5.1kB</em>, the ui-react-dom components are another <em>3.6kB</em>, and everything is super fast. Life is easy when you have zero dependencies!</p><p>Read more about how TinyBase is structured and packaged in the <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/architecture/">Architecture</a> guide.</p></section><div class="table"><table class="fixed"><tbody><tr><th> </th><th>Minified .js.gz</th><th>Source .js</th></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/store/">tinybase/store</a> (minimal)</th><td>5.3kB</td><td>53.6kB</td></tr><tr><th class="right">tinybase (complete)</th><td>11.7kB</td><td>122.5kB</td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/ui-react/">ui-react</a></th><td>5.1kB</td><td>55.5kB</td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/ui-react-dom/">ui-react-dom</a></th><td>3.6kB</td><td>32.6kB</td></tr></tbody></table></div><section><h2 id="well-tested-and-documented">Well tested and documented.</h2><p>TinyBase has <em>100.0%</em> test coverage, including the code throughout the documentation - even on this page! The guides, demos, and API examples are designed to make it as easy as possible for you to get your TinyBase-powered app up and running.</p><p>Read more about how TinyBase is tested in the Unit <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/testing/">Testing</a> guide.</p></section><div class="table"><table class="fixed"><tbody><tr><th width="30%"> </th><th>Total</th><th>Tested</th><th>Coverage</th></tr><tr><th class="right">Lines</th><td>2,326</td><td>2,326</td><td>100.0%</td></tr><tr><th class="right">Statements</th><td>2,515</td><td>2,515</td><td>100.0%</td></tr><tr><th class="right">Functions</th><td>1,005</td><td>1,005</td><td>100.0%</td></tr><tr><th class="right">Branches</th><td>876</td><td>876</td><td>100.0%</td></tr><tr><th class="right">Tests</th><td colspan="3">7,143</td></tr><tr><th class="right">Assertions</th><td colspan="3">32,130</td></tr></tbody></table></div><hr><section id="sponsors"><h2 id="proud-to-be-sponsored-by">Proud to be sponsored by:</h2><a href="https://github.com/cpojer" target="_blank"><img src="https://github.com/cpojer.png?size=48" title="cpojer" width="48" height="48"></a><a href="https://github.com/expo" target="_blank"><img src="https://github.com/expo.png?size=48" title="expo" width="48" height="48"></a><a href="https://github.com/beekeeb" target="_blank"><img src="https://github.com/beekeeb.png?size=48" title="beekeeb" width="48" height="48"></a><a href="https://github.com/cancelself" target="_blank"><img src="https://github.com/cancelself.png?size=48" title="cancelself" width="48" height="48"></a><a href="https://github.com/WonderPanda" target="_blank"><img src="https://github.com/WonderPanda.png?size=48" title="WonderPanda" width="48" height="48"></a><a href="https://github.com/arpitBhalla" target="_blank"><img src="https://github.com/arpitBhalla.png?size=48" title="arpitBhalla" width="48" height="48"></a></section><section id="users"><h2 id="excited-to-be-used-by">Excited to be used by:</h2><a href="https://github.com/behrends" target="_blank"><img src="https://github.com/behrends.png?size=48" title="behrends" width="48" height="48"></a><a href="https://github.com/betomoedano" target="_blank"><img src="https://github.com/betomoedano.png?size=48" title="betomoedano" width="48" height="48"></a><a href="https://github.com/brentvatne" target="_blank"><img src="https://github.com/brentvatne.png?size=48" title="brentvatne" width="48" height="48"></a><a href="https://github.com/byCedric" target="_blank"><img src="https://github.com/byCedric.png?size=48" title="byCedric" width="48" height="48"></a><a href="https://github.com/circadian-risk" target="_blank"><img src="https://github.com/circadian-risk.png?size=48" title="circadian-risk" width="48" height="48"></a><a href="https://github.com/cpojer" target="_blank"><img src="https://github.com/cpojer.png?size=48" title="cpojer" width="48" height="48"></a><a href="https://github.com/cubecull" target="_blank"><img src="https://github.com/cubecull.png?size=48" title="cubecull" width="48" height="48"></a><a href="https://github.com/erwinkn" target="_blank"><img src="https://github.com/erwinkn.png?size=48" title="erwinkn" width="48" height="48"></a><a href="https://github.com/expo" target="_blank"><img src="https://github.com/expo.png?size=48" title="expo" width="48" height="48"></a><a href="https://github.com/ezra-en" target="_blank"><img src="https://github.com/ezra-en.png?size=48" title="ezra-en" width="48" height="48"></a><a href="https://github.com/feychenie" target="_blank"><img src="https://github.com/feychenie.png?size=48" title="feychenie" width="48" height="48"></a><a href="https://github.com/flaming-codes" target="_blank"><img src="https://github.com/flaming-codes.png?size=48" title="flaming-codes" width="48" height="48"></a><a href="https://github.com/fostertheweb" target="_blank"><img src="https://github.com/fostertheweb.png?size=48" title="fostertheweb" width="48" height="48"></a><a href="https://github.com/Giulio987" target="_blank"><img src="https://github.com/Giulio987.png?size=48" title="Giulio987" width="48" height="48"></a><a href="https://github.com/hi-ogawa" target="_blank"><img src="https://github.com/hi-ogawa.png?size=48" title="hi-ogawa" width="48" height="48"></a><a href="https://github.com/itsdevcoffee" target="_blank"><img src="https://github.com/itsdevcoffee.png?size=48" title="itsdevcoffee" width="48" height="48"></a><a href="https://github.com/jbolda" target="_blank"><img src="https://github.com/jbolda.png?size=48" title="jbolda" width="48" height="48"></a><a href="https://github.com/Kayoo-asso" target="_blank"><img src="https://github.com/Kayoo-asso.png?size=48" title="Kayoo-asso" width="48" height="48"></a><a href="https://github.com/kotofurumiya" target="_blank"><img src="https://github.com/kotofurumiya.png?size=48" title="kotofurumiya" width="48" height="48"></a><a href="https://github.com/Kudo" target="_blank"><img src="https://github.com/Kudo.png?size=48" title="Kudo" width="48" height="48"></a><a href="https://github.com/learn-anything" target="_blank"><img src="https://github.com/learn-anything.png?size=48" title="learn-anything" width="48" height="48"></a><a href="https://github.com/lluc" target="_blank"><img src="https://github.com/lluc.png?size=48" title="lluc" width="48" height="48"></a><a href="https://github.com/marksteve" target="_blank"><img src="https://github.com/marksteve.png?size=48" title="marksteve" width="48" height="48"></a><a href="https://github.com/miking-the-viking" target="_blank"><img src="https://github.com/miking-the-viking.png?size=48" title="miking-the-viking" width="48" height="48"></a><a href="https://github.com/mjamesderocher" target="_blank"><img src="https://github.com/mjamesderocher.png?size=48" title="mjamesderocher" width="48" height="48"></a><a href="https://github.com/mouktardev" target="_blank"><img src="https://github.com/mouktardev.png?size=48" title="mouktardev" width="48" height="48"></a><a href="https://github.com/nickmessing" target="_blank"><img src="https://github.com/nickmessing.png?size=48" title="nickmessing" width="48" height="48"></a><a href="https://github.com/nikitavoloboev" target="_blank"><img src="https://github.com/nikitavoloboev.png?size=48" title="nikitavoloboev" width="48" height="48"></a><a href="https://github.com/nkzw-tech" target="_blank"><img src="https://github.com/nkzw-tech.png?size=48" title="nkzw-tech" width="48" height="48"></a><a href="https://github.com/palerdot" target="_blank"><img src="https://github.com/palerdot.png?size=48" title="palerdot" width="48" height="48"></a><a href="https://github.com/PorcoRosso85" target="_blank"><img src="https://github.com/PorcoRosso85.png?size=48" title="PorcoRosso85" width="48" height="48"></a><a href="https://github.com/primodiumxyz" target="_blank"><img src="https://github.com/primodiumxyz.png?size=48" title="primodiumxyz" width="48" height="48"></a><a href="https://github.com/shaneosullivan" target="_blank"><img src="https://github.com/shaneosullivan.png?size=48" title="shaneosullivan" width="48" height="48"></a><a href="https://github.com/sudo-self" target="_blank"><img src="https://github.com/sudo-self.png?size=48" title="sudo-self" width="48" height="48"></a><a href="https://github.com/SuperSonicHub1" target="_blank"><img src="https://github.com/SuperSonicHub1.png?size=48" title="SuperSonicHub1" width="48" height="48"></a><a href="https://github.com/threepointone" target="_blank"><img src="https://github.com/threepointone.png?size=48" title="threepointone" width="48" height="48"></a><a href="https://github.com/uptonking" target="_blank"><img src="https://github.com/uptonking.png?size=48" title="uptonking" width="48" height="48"></a><a href="https://github.com/ViktorZhurbin" target="_blank"><img src="https://github.com/ViktorZhurbin.png?size=48" title="ViktorZhurbin" width="48" height="48"></a><a href="https://github.com/wilkerlucio" target="_blank"><img src="https://github.com/wilkerlucio.png?size=48" title="wilkerlucio" width="48" height="48"></a><a href="https://github.com/WonderPanda" target="_blank"><img src="https://github.com/WonderPanda.png?size=48" title="WonderPanda" width="48" height="48"></a></section><hr><p><a class="start" href="https://beta.tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://beta.tinybase.org/demos/">Try the demos</a></p><p><a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/">Read the docs</a></p><hr><section id="family"><h2 id="meet-the-family">Meet the family</h2><p>TinyBase is part of a group of small libraries designed to help make rich client and local-first apps easier to build. Check out the others!</p><p><a href="https://synclets.org" target="_blank"><img src="https://synclets.org/favicon.svg?asImg" width="48"><br><b>Synclets</b></a><br>An open, storage-agnostic, sync engine development kit.</p><p><a href="https://tinywidgets.org" target="_blank"><img src="https://tinywidgets.org/favicon.svg?asImg" width="48"><br><b>TinyWidgets</b></a><br>A collection of tiny, reusable, UI components.</p><p><a href="https://tinytick.org" target="_blank"><img src="https://tinytick.org/favicon.svg?asImg" width="48"><br><b>TinyTick</b></a><br>A tiny but very useful task orchestrator.</p></section><hr><section id="about"><h2 id="about">About</h2><p>Modern apps deserve better. Why trade reactive user experiences to be able to use relational data? Or sacrifice features for bundle size? And why does the cloud do all the work <a href="https://localfirstweb.dev/" target="_blank">anyway</a>?</p><p>Building TinyBase was originally an interesting exercise for <a rel="me" href="https://tripleodeon.com">me</a> in API design, minification, and documentation. But now it has taken on a life of its own, and has grown beyond my wildest expectations.</p><p>It could not have been built without these great <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/credits/#giants">projects</a> and <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/credits/#and-friends">friends</a>, and I hope you enjoy using it as much as I do building it!</p></section><section id="story"><h2 id="the-story">The story</h2><a href="https://youtu.be/hXL7OkW-Prk?t=1232" target="_blank"><img src="https://beta.tinybase.org/youtube.webp"></a></section>
|
|
278
|
+
<section><h2 id="did-we-say-tiny">Did we say tiny?</h2><p>If you use the basic <a href="https://beta.tinybase.org/api/store/"><code>store</code></a> module alone, you'll only add a gzipped <em>5.4kB</em> to your app. Incrementally add the other modules as you need more functionality, or get it all for <em>11.8kB</em>.</p><p>The optional <a href="https://beta.tinybase.org/api/ui-react/"><code>ui-react</code></a> module is just <em>5.2kB</em>, the ui-react-dom components are another <em>3.7kB</em>, and everything is super fast. Life is easy when you have zero dependencies!</p><p>Read more about how TinyBase is structured and packaged in the <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/architecture/">Architecture</a> guide.</p></section><div class="table"><table class="fixed"><tbody><tr><th> </th><th>Minified .js.gz</th><th>Source .js</th></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/store/">tinybase/store</a> (minimal)</th><td>5.4kB</td><td>54.6kB</td></tr><tr><th class="right">tinybase (complete)</th><td>11.8kB</td><td>123.4kB</td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/ui-react/">ui-react</a></th><td>5.2kB</td><td>55.6kB</td></tr><tr><th class="right"><a href="https://beta.tinybase.org/api/ui-react-dom/">ui-react-dom</a></th><td>3.7kB</td><td>32.8kB</td></tr></tbody></table></div><section><h2 id="well-tested-and-documented">Well tested and documented.</h2><p>TinyBase has <em>100.0%</em> test coverage, including the code throughout the documentation - even on this page! The guides, demos, and API examples are designed to make it as easy as possible for you to get your TinyBase-powered app up and running.</p><p>Read more about how TinyBase is tested in the Unit <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/testing/">Testing</a> guide.</p></section><div class="table"><table class="fixed"><tbody><tr><th width="30%"> </th><th>Total</th><th>Tested</th><th>Coverage</th></tr><tr><th class="right">Lines</th><td>2,342</td><td>2,342</td><td>100.0%</td></tr><tr><th class="right">Statements</th><td>2,533</td><td>2,533</td><td>100.0%</td></tr><tr><th class="right">Functions</th><td>1,010</td><td>1,010</td><td>100.0%</td></tr><tr><th class="right">Branches</th><td>894</td><td>892</td><td>99.8%</td></tr><tr><th class="right">Tests</th><td colspan="3">7,101</td></tr><tr><th class="right">Assertions</th><td colspan="3">31,961</td></tr></tbody></table></div><hr><section id="sponsors"><h2 id="proud-to-be-sponsored-by">Proud to be sponsored by:</h2><a href="https://github.com/cpojer" target="_blank"><img src="https://github.com/cpojer.png?size=48" title="cpojer" width="48" height="48"></a><a href="https://github.com/expo" target="_blank"><img src="https://github.com/expo.png?size=48" title="expo" width="48" height="48"></a><a href="https://github.com/beekeeb" target="_blank"><img src="https://github.com/beekeeb.png?size=48" title="beekeeb" width="48" height="48"></a><a href="https://github.com/cancelself" target="_blank"><img src="https://github.com/cancelself.png?size=48" title="cancelself" width="48" height="48"></a><a href="https://github.com/WonderPanda" target="_blank"><img src="https://github.com/WonderPanda.png?size=48" title="WonderPanda" width="48" height="48"></a><a href="https://github.com/arpitBhalla" target="_blank"><img src="https://github.com/arpitBhalla.png?size=48" title="arpitBhalla" width="48" height="48"></a></section><section id="users"><h2 id="excited-to-be-used-by">Excited to be used by:</h2><a href="https://github.com/behrends" target="_blank"><img src="https://github.com/behrends.png?size=48" title="behrends" width="48" height="48"></a><a href="https://github.com/betomoedano" target="_blank"><img src="https://github.com/betomoedano.png?size=48" title="betomoedano" width="48" height="48"></a><a href="https://github.com/brentvatne" target="_blank"><img src="https://github.com/brentvatne.png?size=48" title="brentvatne" width="48" height="48"></a><a href="https://github.com/byCedric" target="_blank"><img src="https://github.com/byCedric.png?size=48" title="byCedric" width="48" height="48"></a><a href="https://github.com/circadian-risk" target="_blank"><img src="https://github.com/circadian-risk.png?size=48" title="circadian-risk" width="48" height="48"></a><a href="https://github.com/cpojer" target="_blank"><img src="https://github.com/cpojer.png?size=48" title="cpojer" width="48" height="48"></a><a href="https://github.com/cubecull" target="_blank"><img src="https://github.com/cubecull.png?size=48" title="cubecull" width="48" height="48"></a><a href="https://github.com/erwinkn" target="_blank"><img src="https://github.com/erwinkn.png?size=48" title="erwinkn" width="48" height="48"></a><a href="https://github.com/expo" target="_blank"><img src="https://github.com/expo.png?size=48" title="expo" width="48" height="48"></a><a href="https://github.com/ezra-en" target="_blank"><img src="https://github.com/ezra-en.png?size=48" title="ezra-en" width="48" height="48"></a><a href="https://github.com/feychenie" target="_blank"><img src="https://github.com/feychenie.png?size=48" title="feychenie" width="48" height="48"></a><a href="https://github.com/flaming-codes" target="_blank"><img src="https://github.com/flaming-codes.png?size=48" title="flaming-codes" width="48" height="48"></a><a href="https://github.com/fostertheweb" target="_blank"><img src="https://github.com/fostertheweb.png?size=48" title="fostertheweb" width="48" height="48"></a><a href="https://github.com/Giulio987" target="_blank"><img src="https://github.com/Giulio987.png?size=48" title="Giulio987" width="48" height="48"></a><a href="https://github.com/hi-ogawa" target="_blank"><img src="https://github.com/hi-ogawa.png?size=48" title="hi-ogawa" width="48" height="48"></a><a href="https://github.com/itsdevcoffee" target="_blank"><img src="https://github.com/itsdevcoffee.png?size=48" title="itsdevcoffee" width="48" height="48"></a><a href="https://github.com/jbolda" target="_blank"><img src="https://github.com/jbolda.png?size=48" title="jbolda" width="48" height="48"></a><a href="https://github.com/Kayoo-asso" target="_blank"><img src="https://github.com/Kayoo-asso.png?size=48" title="Kayoo-asso" width="48" height="48"></a><a href="https://github.com/kotofurumiya" target="_blank"><img src="https://github.com/kotofurumiya.png?size=48" title="kotofurumiya" width="48" height="48"></a><a href="https://github.com/Kudo" target="_blank"><img src="https://github.com/Kudo.png?size=48" title="Kudo" width="48" height="48"></a><a href="https://github.com/learn-anything" target="_blank"><img src="https://github.com/learn-anything.png?size=48" title="learn-anything" width="48" height="48"></a><a href="https://github.com/lluc" target="_blank"><img src="https://github.com/lluc.png?size=48" title="lluc" width="48" height="48"></a><a href="https://github.com/marksteve" target="_blank"><img src="https://github.com/marksteve.png?size=48" title="marksteve" width="48" height="48"></a><a href="https://github.com/miking-the-viking" target="_blank"><img src="https://github.com/miking-the-viking.png?size=48" title="miking-the-viking" width="48" height="48"></a><a href="https://github.com/mjamesderocher" target="_blank"><img src="https://github.com/mjamesderocher.png?size=48" title="mjamesderocher" width="48" height="48"></a><a href="https://github.com/mouktardev" target="_blank"><img src="https://github.com/mouktardev.png?size=48" title="mouktardev" width="48" height="48"></a><a href="https://github.com/nickmessing" target="_blank"><img src="https://github.com/nickmessing.png?size=48" title="nickmessing" width="48" height="48"></a><a href="https://github.com/nikitavoloboev" target="_blank"><img src="https://github.com/nikitavoloboev.png?size=48" title="nikitavoloboev" width="48" height="48"></a><a href="https://github.com/nkzw-tech" target="_blank"><img src="https://github.com/nkzw-tech.png?size=48" title="nkzw-tech" width="48" height="48"></a><a href="https://github.com/palerdot" target="_blank"><img src="https://github.com/palerdot.png?size=48" title="palerdot" width="48" height="48"></a><a href="https://github.com/PorcoRosso85" target="_blank"><img src="https://github.com/PorcoRosso85.png?size=48" title="PorcoRosso85" width="48" height="48"></a><a href="https://github.com/primodiumxyz" target="_blank"><img src="https://github.com/primodiumxyz.png?size=48" title="primodiumxyz" width="48" height="48"></a><a href="https://github.com/shaneosullivan" target="_blank"><img src="https://github.com/shaneosullivan.png?size=48" title="shaneosullivan" width="48" height="48"></a><a href="https://github.com/sudo-self" target="_blank"><img src="https://github.com/sudo-self.png?size=48" title="sudo-self" width="48" height="48"></a><a href="https://github.com/SuperSonicHub1" target="_blank"><img src="https://github.com/SuperSonicHub1.png?size=48" title="SuperSonicHub1" width="48" height="48"></a><a href="https://github.com/threepointone" target="_blank"><img src="https://github.com/threepointone.png?size=48" title="threepointone" width="48" height="48"></a><a href="https://github.com/uptonking" target="_blank"><img src="https://github.com/uptonking.png?size=48" title="uptonking" width="48" height="48"></a><a href="https://github.com/ViktorZhurbin" target="_blank"><img src="https://github.com/ViktorZhurbin.png?size=48" title="ViktorZhurbin" width="48" height="48"></a><a href="https://github.com/wilkerlucio" target="_blank"><img src="https://github.com/wilkerlucio.png?size=48" title="wilkerlucio" width="48" height="48"></a><a href="https://github.com/WonderPanda" target="_blank"><img src="https://github.com/WonderPanda.png?size=48" title="WonderPanda" width="48" height="48"></a></section><hr><p><a class="start" href="https://beta.tinybase.org/guides/the-basics/getting-started/">Get started</a></p><p><a href="https://beta.tinybase.org/demos/">Try the demos</a></p><p><a href="https://beta.tinybase.org/api/the-essentials/creating-stores/store/">Read the docs</a></p><hr><section id="family"><h2 id="meet-the-family">Meet the family</h2><p>TinyBase is part of a group of small libraries designed to help make rich client and local-first apps easier to build. Check out the others!</p><p><a href="https://synclets.org" target="_blank"><img src="https://synclets.org/favicon.svg?asImg" width="48"><br><b>Synclets</b></a><br>An open, storage-agnostic, sync engine development kit.</p><p><a href="https://tinywidgets.org" target="_blank"><img src="https://tinywidgets.org/favicon.svg?asImg" width="48"><br><b>TinyWidgets</b></a><br>A collection of tiny, reusable, UI components.</p><p><a href="https://tinytick.org" target="_blank"><img src="https://tinytick.org/favicon.svg?asImg" width="48"><br><b>TinyTick</b></a><br>A tiny but very useful task orchestrator.</p></section><hr><section id="about"><h2 id="about">About</h2><p>Modern apps deserve better. Why trade reactive user experiences to be able to use relational data? Or sacrifice features for bundle size? And why does the cloud do all the work <a href="https://localfirstweb.dev/" target="_blank">anyway</a>?</p><p>Building TinyBase was originally an interesting exercise for <a rel="me" href="https://tripleodeon.com">me</a> in API design, minification, and documentation. But now it has taken on a life of its own, and has grown beyond my wildest expectations.</p><p>It could not have been built without these great <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/credits/#giants">projects</a> and <a href="https://beta.tinybase.org/guides/how-tinybase-is-built/credits/#and-friends">friends</a>, and I hope you enjoy using it as much as I do building it!</p></section><section id="story"><h2 id="the-story">The story</h2><a href="https://youtu.be/hXL7OkW-Prk?t=1232" target="_blank"><img src="https://beta.tinybase.org/youtube.webp"></a></section>
|
package/relationships/index.js
CHANGED
|
@@ -2,9 +2,11 @@ const getTypeOf = (thing) => typeof thing;
|
|
|
2
2
|
const EMPTY_STRING = '';
|
|
3
3
|
const STRING = getTypeOf(EMPTY_STRING);
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
const getIfNotFunction = (predicate) => (value, then, otherwise) =>
|
|
6
|
+
predicate(value) ? otherwise?.() : then(value);
|
|
7
|
+
const isUndefined = (thing) => thing === void 0;
|
|
8
|
+
const isNull = (thing) => thing === null;
|
|
9
|
+
const ifNotUndefined = getIfNotFunction(isUndefined);
|
|
8
10
|
const isString = (thing) => getTypeOf(thing) == STRING;
|
|
9
11
|
const isArray = (thing) => Array.isArray(thing);
|
|
10
12
|
const size = (arrayOrString) => arrayOrString.length;
|
|
@@ -41,7 +43,7 @@ const mapGet = (map, key) => map?.get(key);
|
|
|
41
43
|
const mapForEach = (map, cb) =>
|
|
42
44
|
collForEach(map, (value, key) => cb(key, value));
|
|
43
45
|
const mapSet = (map, key, value) =>
|
|
44
|
-
|
|
46
|
+
value === void 0 ? (collDel(map, key), map) : map?.set(key, value);
|
|
45
47
|
const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
|
|
46
48
|
if (!collHas(map, key)) {
|
|
47
49
|
mapSet(map, key, getDefaultValue());
|
|
@@ -323,7 +325,7 @@ const getListenerFunctions = (getThing) => {
|
|
|
323
325
|
const index = size(ids);
|
|
324
326
|
if (index == size(path)) {
|
|
325
327
|
listener(thing, ...ids, ...extraArgsGetter(ids));
|
|
326
|
-
} else if (
|
|
328
|
+
} else if (isNull(path[index])) {
|
|
327
329
|
arrayForEach(pathGetters[index]?.(...ids) ?? [], (id2) =>
|
|
328
330
|
callWithIds(...ids, id2),
|
|
329
331
|
);
|
|
@@ -2,9 +2,11 @@ const getTypeOf = (thing) => typeof thing;
|
|
|
2
2
|
const EMPTY_STRING = '';
|
|
3
3
|
const STRING = getTypeOf(EMPTY_STRING);
|
|
4
4
|
|
|
5
|
-
const
|
|
6
|
-
|
|
7
|
-
|
|
5
|
+
const getIfNotFunction = (predicate) => (value, then, otherwise) =>
|
|
6
|
+
predicate(value) ? otherwise?.() : then(value);
|
|
7
|
+
const isUndefined = (thing) => thing === void 0;
|
|
8
|
+
const isNull = (thing) => thing === null;
|
|
9
|
+
const ifNotUndefined = getIfNotFunction(isUndefined);
|
|
8
10
|
const isString = (thing) => getTypeOf(thing) == STRING;
|
|
9
11
|
const isArray = (thing) => Array.isArray(thing);
|
|
10
12
|
const size = (arrayOrString) => arrayOrString.length;
|
|
@@ -41,7 +43,7 @@ const mapGet = (map, key) => map?.get(key);
|
|
|
41
43
|
const mapForEach = (map, cb) =>
|
|
42
44
|
collForEach(map, (value, key) => cb(key, value));
|
|
43
45
|
const mapSet = (map, key, value) =>
|
|
44
|
-
|
|
46
|
+
value === void 0 ? (collDel(map, key), map) : map?.set(key, value);
|
|
45
47
|
const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
|
|
46
48
|
if (!collHas(map, key)) {
|
|
47
49
|
mapSet(map, key, getDefaultValue());
|
|
@@ -323,7 +325,7 @@ const getListenerFunctions = (getThing) => {
|
|
|
323
325
|
const index = size(ids);
|
|
324
326
|
if (index == size(path)) {
|
|
325
327
|
listener(thing, ...ids, ...extraArgsGetter(ids));
|
|
326
|
-
} else if (
|
|
328
|
+
} else if (isNull(path[index])) {
|
|
327
329
|
arrayForEach(pathGetters[index]?.(...ids) ?? [], (id2) =>
|
|
328
330
|
callWithIds(...ids, id2),
|
|
329
331
|
);
|