tinybase 5.0.0-beta.3 → 5.0.0-beta.5
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/lib/checkpoints.js +1 -1
- package/lib/checkpoints.js.gz +0 -0
- package/lib/cjs/checkpoints.cjs +1 -1
- package/lib/cjs/checkpoints.cjs.gz +0 -0
- package/lib/cjs/indexes.cjs +1 -1
- package/lib/cjs/indexes.cjs.gz +0 -0
- package/lib/cjs/mergeable-store.cjs +1 -1
- package/lib/cjs/mergeable-store.cjs.gz +0 -0
- package/lib/cjs/metrics.cjs +1 -1
- package/lib/cjs/metrics.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-automerge.cjs +1 -1
- package/lib/cjs/persisters/persister-automerge.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-browser.cjs +1 -1
- package/lib/cjs/persisters/persister-browser.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-cr-sqlite-wasm.cjs +1 -1
- package/lib/cjs/persisters/persister-cr-sqlite-wasm.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-electric-sql.cjs +1 -1
- package/lib/cjs/persisters/persister-electric-sql.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-expo-sqlite-next.cjs +1 -1
- package/lib/cjs/persisters/persister-expo-sqlite-next.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-expo-sqlite.cjs +1 -1
- package/lib/cjs/persisters/persister-expo-sqlite.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-file.cjs +1 -1
- package/lib/cjs/persisters/persister-file.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-indexed-db.cjs +1 -1
- package/lib/cjs/persisters/persister-indexed-db.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-libsql.cjs +1 -0
- package/lib/cjs/persisters/persister-libsql.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-partykit-client.cjs +1 -1
- package/lib/cjs/persisters/persister-partykit-client.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-remote.cjs +1 -1
- package/lib/cjs/persisters/persister-remote.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-sqlite-wasm.cjs +1 -1
- package/lib/cjs/persisters/persister-sqlite-wasm.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-sqlite3.cjs +1 -1
- package/lib/cjs/persisters/persister-sqlite3.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-yjs.cjs +1 -1
- package/lib/cjs/persisters/persister-yjs.cjs.gz +0 -0
- package/lib/cjs/persisters.cjs +1 -1
- package/lib/cjs/persisters.cjs.gz +0 -0
- package/lib/cjs/queries.cjs +1 -1
- package/lib/cjs/queries.cjs.gz +0 -0
- package/lib/cjs/relationships.cjs +1 -1
- package/lib/cjs/relationships.cjs.gz +0 -0
- package/lib/cjs/store.cjs +1 -1
- package/lib/cjs/store.cjs.gz +0 -0
- package/lib/cjs/tinybase.cjs +1 -1
- package/lib/cjs/tinybase.cjs.gz +0 -0
- package/lib/cjs/tools.cjs +1 -1
- package/lib/cjs/tools.cjs.gz +0 -0
- package/lib/cjs/ui-react-dom-debug.cjs +1 -1
- package/lib/cjs/ui-react-dom-debug.cjs.gz +0 -0
- package/lib/cjs-es6/checkpoints.cjs +1 -1
- package/lib/cjs-es6/checkpoints.cjs.gz +0 -0
- package/lib/cjs-es6/indexes.cjs +1 -1
- package/lib/cjs-es6/indexes.cjs.gz +0 -0
- package/lib/cjs-es6/mergeable-store.cjs +1 -1
- package/lib/cjs-es6/mergeable-store.cjs.gz +0 -0
- package/lib/cjs-es6/metrics.cjs +1 -1
- package/lib/cjs-es6/metrics.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-automerge.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-automerge.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-browser.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-browser.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-cr-sqlite-wasm.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-cr-sqlite-wasm.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-electric-sql.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-electric-sql.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-expo-sqlite-next.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-expo-sqlite-next.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-expo-sqlite.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-expo-sqlite.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-file.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-file.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-indexed-db.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-indexed-db.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-libsql.cjs +1 -0
- package/lib/cjs-es6/persisters/persister-libsql.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-partykit-client.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-partykit-client.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-remote.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-remote.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-sqlite-wasm.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-sqlite-wasm.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-sqlite3.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-sqlite3.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-yjs.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-yjs.cjs.gz +0 -0
- package/lib/cjs-es6/persisters.cjs +1 -1
- package/lib/cjs-es6/persisters.cjs.gz +0 -0
- package/lib/cjs-es6/queries.cjs +1 -1
- package/lib/cjs-es6/queries.cjs.gz +0 -0
- package/lib/cjs-es6/relationships.cjs +1 -1
- package/lib/cjs-es6/relationships.cjs.gz +0 -0
- package/lib/cjs-es6/store.cjs +1 -1
- package/lib/cjs-es6/store.cjs.gz +0 -0
- package/lib/cjs-es6/tinybase.cjs +1 -1
- package/lib/cjs-es6/tinybase.cjs.gz +0 -0
- package/lib/cjs-es6/tools.cjs +1 -1
- package/lib/cjs-es6/tools.cjs.gz +0 -0
- package/lib/cjs-es6/ui-react-dom-debug.cjs +1 -1
- package/lib/cjs-es6/ui-react-dom-debug.cjs.gz +0 -0
- package/lib/debug/checkpoints.js +3 -1
- package/lib/debug/indexes.js +3 -1
- package/lib/debug/mergeable-store.js +247 -139
- package/lib/debug/metrics.js +3 -1
- package/lib/debug/persisters/persister-automerge.js +36 -12
- package/lib/debug/persisters/persister-browser.js +37 -13
- package/lib/debug/persisters/persister-cr-sqlite-wasm.js +36 -12
- package/lib/debug/persisters/persister-electric-sql.js +36 -12
- package/lib/debug/persisters/persister-expo-sqlite-next.js +36 -12
- package/lib/debug/persisters/persister-expo-sqlite.js +36 -12
- package/lib/debug/persisters/persister-file.js +37 -13
- package/lib/debug/persisters/persister-indexed-db.js +36 -12
- package/lib/debug/persisters/persister-libsql.js +898 -0
- package/lib/debug/persisters/persister-partykit-client.js +36 -12
- package/lib/debug/persisters/persister-remote.js +36 -12
- package/lib/debug/persisters/persister-sqlite-wasm.js +36 -12
- package/lib/debug/persisters/persister-sqlite3.js +36 -12
- package/lib/debug/persisters/persister-yjs.js +36 -12
- package/lib/debug/persisters.js +36 -12
- package/lib/debug/queries.js +7 -4
- package/lib/debug/relationships.js +3 -1
- package/lib/debug/store.js +21 -22
- package/lib/debug/tinybase.js +279 -150
- package/lib/debug/tools.js +7 -4
- package/lib/debug/ui-react-dom.js +55 -34
- package/lib/es6/checkpoints.js +1 -1
- package/lib/es6/checkpoints.js.gz +0 -0
- package/lib/es6/indexes.js +1 -1
- package/lib/es6/indexes.js.gz +0 -0
- package/lib/es6/mergeable-store.js +1 -1
- package/lib/es6/mergeable-store.js.gz +0 -0
- package/lib/es6/metrics.js +1 -1
- package/lib/es6/metrics.js.gz +0 -0
- package/lib/es6/persisters/persister-automerge.js +1 -1
- package/lib/es6/persisters/persister-automerge.js.gz +0 -0
- package/lib/es6/persisters/persister-browser.js +1 -1
- package/lib/es6/persisters/persister-browser.js.gz +0 -0
- package/lib/es6/persisters/persister-cr-sqlite-wasm.js +1 -1
- package/lib/es6/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
- package/lib/es6/persisters/persister-electric-sql.js +1 -1
- package/lib/es6/persisters/persister-electric-sql.js.gz +0 -0
- package/lib/es6/persisters/persister-expo-sqlite-next.js +1 -1
- package/lib/es6/persisters/persister-expo-sqlite-next.js.gz +0 -0
- package/lib/es6/persisters/persister-expo-sqlite.js +1 -1
- package/lib/es6/persisters/persister-expo-sqlite.js.gz +0 -0
- package/lib/es6/persisters/persister-file.js +1 -1
- package/lib/es6/persisters/persister-file.js.gz +0 -0
- package/lib/es6/persisters/persister-indexed-db.js +1 -1
- package/lib/es6/persisters/persister-indexed-db.js.gz +0 -0
- package/lib/es6/persisters/persister-libsql.js +1 -0
- package/lib/es6/persisters/persister-libsql.js.gz +0 -0
- package/lib/es6/persisters/persister-partykit-client.js +1 -1
- package/lib/es6/persisters/persister-partykit-client.js.gz +0 -0
- package/lib/es6/persisters/persister-remote.js +1 -1
- package/lib/es6/persisters/persister-remote.js.gz +0 -0
- package/lib/es6/persisters/persister-sqlite-wasm.js +1 -1
- package/lib/es6/persisters/persister-sqlite-wasm.js.gz +0 -0
- package/lib/es6/persisters/persister-sqlite3.js +1 -1
- package/lib/es6/persisters/persister-sqlite3.js.gz +0 -0
- package/lib/es6/persisters/persister-yjs.js +1 -1
- package/lib/es6/persisters/persister-yjs.js.gz +0 -0
- package/lib/es6/persisters.js +1 -1
- package/lib/es6/persisters.js.gz +0 -0
- package/lib/es6/queries.js +1 -1
- package/lib/es6/queries.js.gz +0 -0
- package/lib/es6/relationships.js +1 -1
- package/lib/es6/relationships.js.gz +0 -0
- package/lib/es6/store.js +1 -1
- package/lib/es6/store.js.gz +0 -0
- package/lib/es6/tinybase.js +1 -1
- package/lib/es6/tinybase.js.gz +0 -0
- package/lib/es6/tools.js +1 -1
- package/lib/es6/tools.js.gz +0 -0
- package/lib/es6/ui-react-dom-debug.js +1 -1
- package/lib/es6/ui-react-dom-debug.js.gz +0 -0
- package/lib/indexes.js +1 -1
- package/lib/indexes.js.gz +0 -0
- package/lib/mergeable-store.js +1 -1
- package/lib/mergeable-store.js.gz +0 -0
- package/lib/metrics.js +1 -1
- package/lib/metrics.js.gz +0 -0
- package/lib/persisters/persister-automerge.js +1 -1
- package/lib/persisters/persister-automerge.js.gz +0 -0
- package/lib/persisters/persister-browser.js +1 -1
- package/lib/persisters/persister-browser.js.gz +0 -0
- package/lib/persisters/persister-cr-sqlite-wasm.js +1 -1
- package/lib/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
- package/lib/persisters/persister-electric-sql.js +1 -1
- package/lib/persisters/persister-electric-sql.js.gz +0 -0
- package/lib/persisters/persister-expo-sqlite-next.js +1 -1
- package/lib/persisters/persister-expo-sqlite-next.js.gz +0 -0
- package/lib/persisters/persister-expo-sqlite.js +1 -1
- package/lib/persisters/persister-expo-sqlite.js.gz +0 -0
- package/lib/persisters/persister-file.js +1 -1
- package/lib/persisters/persister-file.js.gz +0 -0
- package/lib/persisters/persister-indexed-db.js +1 -1
- package/lib/persisters/persister-indexed-db.js.gz +0 -0
- package/lib/persisters/persister-libsql.js +1 -0
- package/lib/persisters/persister-libsql.js.gz +0 -0
- package/lib/persisters/persister-partykit-client.js +1 -1
- package/lib/persisters/persister-partykit-client.js.gz +0 -0
- package/lib/persisters/persister-remote.js +1 -1
- package/lib/persisters/persister-remote.js.gz +0 -0
- package/lib/persisters/persister-sqlite-wasm.js +1 -1
- package/lib/persisters/persister-sqlite-wasm.js.gz +0 -0
- package/lib/persisters/persister-sqlite3.js +1 -1
- package/lib/persisters/persister-sqlite3.js.gz +0 -0
- package/lib/persisters/persister-yjs.js +1 -1
- package/lib/persisters/persister-yjs.js.gz +0 -0
- package/lib/persisters.js +1 -1
- package/lib/persisters.js.gz +0 -0
- package/lib/queries.js +1 -1
- package/lib/queries.js.gz +0 -0
- package/lib/relationships.js +1 -1
- package/lib/relationships.js.gz +0 -0
- package/lib/store.js +1 -1
- package/lib/store.js.gz +0 -0
- package/lib/tinybase.js +1 -1
- package/lib/tinybase.js.gz +0 -0
- package/lib/tools.js +1 -1
- package/lib/tools.js.gz +0 -0
- package/lib/types/mergeable-store.d.ts +78 -11
- package/lib/types/persisters/persister-browser.d.ts +2 -2
- package/lib/types/persisters/persister-file.d.ts +1 -1
- package/lib/types/persisters/persister-libsql.d.ts +139 -0
- package/lib/types/persisters.d.ts +19 -7
- package/lib/types/with-schemas/mergeable-store.d.ts +314 -31
- package/lib/types/with-schemas/persisters/persister-browser.d.ts +2 -2
- package/lib/types/with-schemas/persisters/persister-file.d.ts +1 -1
- package/lib/types/with-schemas/persisters/persister-libsql.d.ts +152 -0
- package/lib/types/with-schemas/persisters.d.ts +14 -6
- package/lib/types/with-schemas/store.d.ts +37 -87
- package/lib/umd/checkpoints.js +1 -1
- package/lib/umd/checkpoints.js.gz +0 -0
- package/lib/umd/indexes.js +1 -1
- package/lib/umd/indexes.js.gz +0 -0
- package/lib/umd/mergeable-store.js +1 -1
- package/lib/umd/mergeable-store.js.gz +0 -0
- package/lib/umd/metrics.js +1 -1
- package/lib/umd/metrics.js.gz +0 -0
- package/lib/umd/persisters/persister-automerge.js +1 -1
- package/lib/umd/persisters/persister-automerge.js.gz +0 -0
- package/lib/umd/persisters/persister-browser.js +1 -1
- package/lib/umd/persisters/persister-browser.js.gz +0 -0
- package/lib/umd/persisters/persister-cr-sqlite-wasm.js +1 -1
- package/lib/umd/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
- package/lib/umd/persisters/persister-electric-sql.js +1 -1
- package/lib/umd/persisters/persister-electric-sql.js.gz +0 -0
- package/lib/umd/persisters/persister-expo-sqlite-next.js +1 -1
- package/lib/umd/persisters/persister-expo-sqlite-next.js.gz +0 -0
- package/lib/umd/persisters/persister-expo-sqlite.js +1 -1
- package/lib/umd/persisters/persister-expo-sqlite.js.gz +0 -0
- package/lib/umd/persisters/persister-file.js +1 -1
- package/lib/umd/persisters/persister-file.js.gz +0 -0
- package/lib/umd/persisters/persister-indexed-db.js +1 -1
- package/lib/umd/persisters/persister-indexed-db.js.gz +0 -0
- package/lib/umd/persisters/persister-libsql.js +1 -0
- package/lib/umd/persisters/persister-libsql.js.gz +0 -0
- package/lib/umd/persisters/persister-partykit-client.js +1 -1
- package/lib/umd/persisters/persister-partykit-client.js.gz +0 -0
- package/lib/umd/persisters/persister-remote.js +1 -1
- package/lib/umd/persisters/persister-remote.js.gz +0 -0
- package/lib/umd/persisters/persister-sqlite-wasm.js +1 -1
- package/lib/umd/persisters/persister-sqlite-wasm.js.gz +0 -0
- package/lib/umd/persisters/persister-sqlite3.js +1 -1
- package/lib/umd/persisters/persister-sqlite3.js.gz +0 -0
- package/lib/umd/persisters/persister-yjs.js +1 -1
- package/lib/umd/persisters/persister-yjs.js.gz +0 -0
- package/lib/umd/persisters.js +1 -1
- package/lib/umd/persisters.js.gz +0 -0
- package/lib/umd/queries.js +1 -1
- package/lib/umd/queries.js.gz +0 -0
- package/lib/umd/relationships.js +1 -1
- package/lib/umd/relationships.js.gz +0 -0
- package/lib/umd/store.js +1 -1
- package/lib/umd/store.js.gz +0 -0
- package/lib/umd/tinybase.js +1 -1
- package/lib/umd/tinybase.js.gz +0 -0
- package/lib/umd/tools.js +1 -1
- package/lib/umd/tools.js.gz +0 -0
- package/lib/umd/ui-react-dom-debug.js +1 -1
- package/lib/umd/ui-react-dom-debug.js.gz +0 -0
- package/lib/umd-es6/checkpoints.js +1 -1
- package/lib/umd-es6/checkpoints.js.gz +0 -0
- package/lib/umd-es6/indexes.js +1 -1
- package/lib/umd-es6/indexes.js.gz +0 -0
- package/lib/umd-es6/mergeable-store.js +1 -1
- package/lib/umd-es6/mergeable-store.js.gz +0 -0
- package/lib/umd-es6/metrics.js +1 -1
- package/lib/umd-es6/metrics.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-automerge.js +1 -1
- package/lib/umd-es6/persisters/persister-automerge.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-browser.js +1 -1
- package/lib/umd-es6/persisters/persister-browser.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-cr-sqlite-wasm.js +1 -1
- package/lib/umd-es6/persisters/persister-cr-sqlite-wasm.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-electric-sql.js +1 -1
- package/lib/umd-es6/persisters/persister-electric-sql.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-expo-sqlite-next.js +1 -1
- package/lib/umd-es6/persisters/persister-expo-sqlite-next.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-expo-sqlite.js +1 -1
- package/lib/umd-es6/persisters/persister-expo-sqlite.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-file.js +1 -1
- package/lib/umd-es6/persisters/persister-file.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-indexed-db.js +1 -1
- package/lib/umd-es6/persisters/persister-indexed-db.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-libsql.js +1 -0
- package/lib/umd-es6/persisters/persister-libsql.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-partykit-client.js +1 -1
- package/lib/umd-es6/persisters/persister-partykit-client.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-remote.js +1 -1
- package/lib/umd-es6/persisters/persister-remote.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-sqlite-wasm.js +1 -1
- package/lib/umd-es6/persisters/persister-sqlite-wasm.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-sqlite3.js +1 -1
- package/lib/umd-es6/persisters/persister-sqlite3.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-yjs.js +1 -1
- package/lib/umd-es6/persisters/persister-yjs.js.gz +0 -0
- package/lib/umd-es6/persisters.js +1 -1
- package/lib/umd-es6/persisters.js.gz +0 -0
- package/lib/umd-es6/queries.js +1 -1
- package/lib/umd-es6/queries.js.gz +0 -0
- package/lib/umd-es6/relationships.js +1 -1
- package/lib/umd-es6/relationships.js.gz +0 -0
- package/lib/umd-es6/store.js +1 -1
- package/lib/umd-es6/store.js.gz +0 -0
- package/lib/umd-es6/tinybase.js +1 -1
- package/lib/umd-es6/tinybase.js.gz +0 -0
- package/lib/umd-es6/tools.js +1 -1
- package/lib/umd-es6/tools.js.gz +0 -0
- package/lib/umd-es6/ui-react-dom-debug.js +1 -1
- package/lib/umd-es6/ui-react-dom-debug.js.gz +0 -0
- package/package.json +35 -30
- package/readme.md +2 -2
package/lib/debug/tinybase.js
CHANGED
|
@@ -31,8 +31,7 @@ const VALUE_IDS = VALUE + IDS;
|
|
|
31
31
|
const id = (key) => EMPTY_STRING + key;
|
|
32
32
|
const strStartsWith = (str, prefix) => str.startsWith(prefix);
|
|
33
33
|
const strEndsWith = (str, suffix) => str.endsWith(suffix);
|
|
34
|
-
const
|
|
35
|
-
const strCharCodeAt = (str, position = 0) => str.charCodeAt(position);
|
|
34
|
+
const strCharCodeAt = (str, position) => str.charCodeAt(position);
|
|
36
35
|
|
|
37
36
|
const mathMax = Math.max;
|
|
38
37
|
const mathMin = Math.min;
|
|
@@ -100,6 +99,12 @@ const objToArray = (obj, cb) =>
|
|
|
100
99
|
arrayMap(objEntries(obj), ([id, value]) => cb(value, id));
|
|
101
100
|
const objSize = (obj) => size(objIds(obj));
|
|
102
101
|
const objIsEmpty = (obj) => isObject(obj) && objSize(obj) == 0;
|
|
102
|
+
const objEnsure = (obj, id, getDefaultValue) => {
|
|
103
|
+
if (!objHas(obj, id)) {
|
|
104
|
+
obj[id] = getDefaultValue();
|
|
105
|
+
}
|
|
106
|
+
return obj[id];
|
|
107
|
+
};
|
|
103
108
|
|
|
104
109
|
const collSizeN = (collSizer) => (coll) =>
|
|
105
110
|
arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
|
|
@@ -123,9 +128,11 @@ const mapMap = (coll, cb) =>
|
|
|
123
128
|
arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
|
|
124
129
|
const mapSet = (map, key, value) =>
|
|
125
130
|
isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
|
|
126
|
-
const mapEnsure = (map, key, getDefaultValue) => {
|
|
131
|
+
const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
|
|
127
132
|
if (!collHas(map, key)) {
|
|
128
133
|
mapSet(map, key, getDefaultValue());
|
|
134
|
+
} else {
|
|
135
|
+
hadExistingValue?.(mapGet(map, key));
|
|
129
136
|
}
|
|
130
137
|
return mapGet(map, key);
|
|
131
138
|
};
|
|
@@ -183,9 +190,10 @@ const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
|
|
|
183
190
|
},
|
|
184
191
|
);
|
|
185
192
|
|
|
186
|
-
const getCellOrValueType = (
|
|
187
|
-
const type = getTypeOf(
|
|
188
|
-
return isTypeStringOrBoolean(type) ||
|
|
193
|
+
const getCellOrValueType = (cellOrValue) => {
|
|
194
|
+
const type = getTypeOf(cellOrValue);
|
|
195
|
+
return isTypeStringOrBoolean(type) ||
|
|
196
|
+
(type == NUMBER && isFiniteNumber(cellOrValue))
|
|
189
197
|
? type
|
|
190
198
|
: void 0;
|
|
191
199
|
};
|
|
@@ -1085,6 +1093,23 @@ const createMetrics = getCreateFunction((store) => {
|
|
|
1085
1093
|
|
|
1086
1094
|
const scheduleRunning = mapNew();
|
|
1087
1095
|
const scheduleActions = mapNew();
|
|
1096
|
+
const isMergeable = (contentOrChanges) => isString(contentOrChanges?.[0]);
|
|
1097
|
+
const getStoreFunctions = (supportsMergeableStore, store) =>
|
|
1098
|
+
!supportsMergeableStore || isUndefined(store.getMergeableContent)
|
|
1099
|
+
? [
|
|
1100
|
+
0,
|
|
1101
|
+
store.getContent,
|
|
1102
|
+
store.getTransactionChanges,
|
|
1103
|
+
([changedTables, changedValues]) =>
|
|
1104
|
+
!objIsEmpty(changedTables) || !objIsEmpty(changedValues),
|
|
1105
|
+
]
|
|
1106
|
+
: [
|
|
1107
|
+
1,
|
|
1108
|
+
store.getMergeableContent,
|
|
1109
|
+
store.getTransactionMergeableChanges,
|
|
1110
|
+
([, [[, changedTables], [, changedValues]]]) =>
|
|
1111
|
+
!objIsEmpty(changedTables) || !objIsEmpty(changedValues),
|
|
1112
|
+
];
|
|
1088
1113
|
const createCustomPersister = (
|
|
1089
1114
|
store,
|
|
1090
1115
|
getPersisted,
|
|
@@ -1105,10 +1130,8 @@ const createCustomPersister = (
|
|
|
1105
1130
|
let listeningHandle;
|
|
1106
1131
|
mapEnsure(scheduleRunning, scheduleId, () => 0);
|
|
1107
1132
|
mapEnsure(scheduleActions, scheduleId, () => []);
|
|
1108
|
-
const getContent =
|
|
1109
|
-
(supportsMergeableStore
|
|
1110
|
-
store.getContent;
|
|
1111
|
-
const getChanges = store.getTransactionChanges;
|
|
1133
|
+
const [isMergeableStore, getContent, getChanges, hasChanges] =
|
|
1134
|
+
getStoreFunctions(supportsMergeableStore, store);
|
|
1112
1135
|
const run = async () => {
|
|
1113
1136
|
/* istanbul ignore else */
|
|
1114
1137
|
if (!mapGet(scheduleRunning, scheduleId)) {
|
|
@@ -1145,8 +1168,8 @@ const createCustomPersister = (
|
|
|
1145
1168
|
await loadLock(async () => {
|
|
1146
1169
|
try {
|
|
1147
1170
|
const content = await getPersisted();
|
|
1148
|
-
(
|
|
1149
|
-
? store.
|
|
1171
|
+
(isMergeableStore && isMergeable(content)
|
|
1172
|
+
? store.setMergeableContent
|
|
1150
1173
|
: store.setContent)(content);
|
|
1151
1174
|
} catch {
|
|
1152
1175
|
store.setContent([initialTables, initialValues]);
|
|
@@ -1160,11 +1183,18 @@ const createCustomPersister = (
|
|
|
1160
1183
|
async (getContent2, getChanges2) => {
|
|
1161
1184
|
if (getChanges2) {
|
|
1162
1185
|
const changes = getChanges2();
|
|
1163
|
-
await loadLock(async () =>
|
|
1186
|
+
await loadLock(async () =>
|
|
1187
|
+
(isMergeableStore && isMergeable(changes)
|
|
1188
|
+
? store.applyMergeableChanges
|
|
1189
|
+
: store.applyChanges)(changes),
|
|
1190
|
+
);
|
|
1164
1191
|
} else {
|
|
1165
1192
|
await loadLock(async () => {
|
|
1166
1193
|
try {
|
|
1167
|
-
|
|
1194
|
+
const content = getContent2?.() ?? (await getPersisted());
|
|
1195
|
+
(isMergeableStore && isMergeable(content)
|
|
1196
|
+
? store.setMergeableContent
|
|
1197
|
+
: store.setContent)(content);
|
|
1168
1198
|
} catch (error) {
|
|
1169
1199
|
onIgnoredError?.(error);
|
|
1170
1200
|
}
|
|
@@ -1204,9 +1234,9 @@ const createCustomPersister = (
|
|
|
1204
1234
|
startAutoSave: async () => {
|
|
1205
1235
|
await persister.stopAutoSave().save();
|
|
1206
1236
|
listenerId = store.addDidFinishTransactionListener(() => {
|
|
1207
|
-
const
|
|
1208
|
-
if (
|
|
1209
|
-
persister.save(() =>
|
|
1237
|
+
const changes = getChanges();
|
|
1238
|
+
if (hasChanges(changes)) {
|
|
1239
|
+
persister.save(() => changes);
|
|
1210
1240
|
}
|
|
1211
1241
|
});
|
|
1212
1242
|
return persister;
|
|
@@ -1879,34 +1909,36 @@ const createRelationships = getCreateFunction((store) => {
|
|
|
1879
1909
|
return objFreeze(relationships);
|
|
1880
1910
|
});
|
|
1881
1911
|
|
|
1882
|
-
const
|
|
1883
|
-
const
|
|
1884
|
-
|
|
1885
|
-
|
|
1886
|
-
|
|
1887
|
-
|
|
1888
|
-
|
|
1889
|
-
|
|
1890
|
-
|
|
1891
|
-
|
|
1892
|
-
|
|
1893
|
-
|
|
1894
|
-
|
|
1895
|
-
|
|
1896
|
-
const
|
|
1897
|
-
|
|
1898
|
-
|
|
1912
|
+
const textEncoder = new globalThis.TextEncoder();
|
|
1913
|
+
const getHash = (value) => {
|
|
1914
|
+
let hash = 2166136261;
|
|
1915
|
+
arrayForEach(textEncoder.encode(value), (char) => {
|
|
1916
|
+
hash ^= char;
|
|
1917
|
+
hash +=
|
|
1918
|
+
(hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
|
|
1919
|
+
});
|
|
1920
|
+
return hash >>> 0;
|
|
1921
|
+
};
|
|
1922
|
+
|
|
1923
|
+
const cloneHashStamp = ([time, value, hash]) => [time, value, hash];
|
|
1924
|
+
const stampNew = (time, thing) => [time, thing];
|
|
1925
|
+
const hashIdAndHash = (id, hash) => getHash(id + ':' + hash);
|
|
1926
|
+
const updateHashStamp = (hashStamp, hash, time) => {
|
|
1927
|
+
hashStamp[2] = hash >>> 0;
|
|
1928
|
+
if (time > hashStamp[0]) {
|
|
1929
|
+
hashStamp[0] = time;
|
|
1899
1930
|
}
|
|
1900
|
-
merge(newThing, thingStamp[1], changes);
|
|
1901
1931
|
};
|
|
1902
|
-
const
|
|
1903
|
-
|
|
1904
|
-
|
|
1905
|
-
|
|
1906
|
-
|
|
1907
|
-
|
|
1908
|
-
|
|
1909
|
-
|
|
1932
|
+
const stampNewObj = (time) => stampNew(time, objNew());
|
|
1933
|
+
const hashStampNewMap = (time = EMPTY_STRING) => [time, mapNew(), 0];
|
|
1934
|
+
const hashStampNewThing = () => [EMPTY_STRING, void 0, 0];
|
|
1935
|
+
const hashStampMap = ([time, value, hash], mapper) => [
|
|
1936
|
+
time,
|
|
1937
|
+
mapper(value, time),
|
|
1938
|
+
hash,
|
|
1939
|
+
];
|
|
1940
|
+
const hashStampMapToObj = (hashStamp, mapper = cloneHashStamp) =>
|
|
1941
|
+
hashStampMap(hashStamp, (map) => mapToObj(map, mapper));
|
|
1910
1942
|
|
|
1911
1943
|
const pairNew = (value) => [value, value];
|
|
1912
1944
|
const pairCollSize2 = (pair, func = collSize2) => func(pair[0]) + func(pair[1]);
|
|
@@ -1941,12 +1973,10 @@ const idsChanged = (changedIds, id2, addedOrRemoved) =>
|
|
|
1941
1973
|
const createStore = () => {
|
|
1942
1974
|
let hasTablesSchema;
|
|
1943
1975
|
let hasValuesSchema;
|
|
1944
|
-
let cellsTouched = false;
|
|
1945
|
-
let valuesTouched = false;
|
|
1946
1976
|
let hadTables = false;
|
|
1947
1977
|
let hadValues = false;
|
|
1948
1978
|
let transactions = 0;
|
|
1949
|
-
let
|
|
1979
|
+
let internalListeners = [];
|
|
1950
1980
|
const changedTableIds = mapNew();
|
|
1951
1981
|
const changedTableCellIds = mapNew();
|
|
1952
1982
|
const changedRowCount = mapNew();
|
|
@@ -2906,8 +2936,8 @@ const createStore = () => {
|
|
|
2906
2936
|
),
|
|
2907
2937
|
];
|
|
2908
2938
|
const getTransactionLog = () => [
|
|
2909
|
-
|
|
2910
|
-
|
|
2939
|
+
!collIsEmpty(changedCells),
|
|
2940
|
+
!collIsEmpty(changedValues),
|
|
2911
2941
|
mapToObj3(changedCells, pairClone, pairIsEqual),
|
|
2912
2942
|
mapToObj3(invalidCells),
|
|
2913
2943
|
mapToObj(changedValues, pairClone, pairIsEqual),
|
|
@@ -2921,15 +2951,13 @@ const createStore = () => {
|
|
|
2921
2951
|
if (transactions > 0) {
|
|
2922
2952
|
transactions--;
|
|
2923
2953
|
if (transactions == 0) {
|
|
2924
|
-
cellsTouched = !collIsEmpty(changedCells);
|
|
2925
|
-
valuesTouched = !collIsEmpty(changedValues);
|
|
2926
2954
|
transactions = 1;
|
|
2927
2955
|
callInvalidCellListeners(1);
|
|
2928
|
-
if (
|
|
2956
|
+
if (!collIsEmpty(changedCells)) {
|
|
2929
2957
|
callTabularListenersForChanges(1);
|
|
2930
2958
|
}
|
|
2931
2959
|
callInvalidValueListeners(1);
|
|
2932
|
-
if (
|
|
2960
|
+
if (!collIsEmpty(changedValues)) {
|
|
2933
2961
|
callValuesListenersForChanges(1);
|
|
2934
2962
|
}
|
|
2935
2963
|
if (doRollback?.(store)) {
|
|
@@ -2940,25 +2968,26 @@ const createStore = () => {
|
|
|
2940
2968
|
),
|
|
2941
2969
|
),
|
|
2942
2970
|
);
|
|
2971
|
+
collClear(changedCells);
|
|
2943
2972
|
collForEach(changedValues, ([oldValue], valueId) =>
|
|
2944
2973
|
setOrDelValue(store, valueId, oldValue),
|
|
2945
2974
|
);
|
|
2946
|
-
|
|
2975
|
+
collClear(changedValues);
|
|
2947
2976
|
}
|
|
2948
2977
|
callListeners(finishTransactionListeners[0], void 0);
|
|
2949
2978
|
transactions = -1;
|
|
2950
2979
|
callInvalidCellListeners(0);
|
|
2951
|
-
if (
|
|
2980
|
+
if (!collIsEmpty(changedCells)) {
|
|
2952
2981
|
callTabularListenersForChanges(0);
|
|
2953
2982
|
}
|
|
2954
2983
|
callInvalidValueListeners(0);
|
|
2955
|
-
if (
|
|
2984
|
+
if (!collIsEmpty(changedValues)) {
|
|
2956
2985
|
callValuesListenersForChanges(0);
|
|
2957
2986
|
}
|
|
2958
|
-
|
|
2987
|
+
internalListeners[0]?.(store);
|
|
2959
2988
|
callListeners(finishTransactionListeners[1], void 0);
|
|
2989
|
+
internalListeners[1]?.(store);
|
|
2960
2990
|
transactions = 0;
|
|
2961
|
-
cellsTouched = valuesTouched = false;
|
|
2962
2991
|
hadTables = hasTables();
|
|
2963
2992
|
hadValues = hasValues();
|
|
2964
2993
|
arrayForEach(
|
|
@@ -3083,9 +3112,8 @@ const createStore = () => {
|
|
|
3083
3112
|
collSize2(startTransactionListeners) +
|
|
3084
3113
|
pairCollSize2(finishTransactionListeners),
|
|
3085
3114
|
});
|
|
3086
|
-
const
|
|
3087
|
-
|
|
3088
|
-
};
|
|
3115
|
+
const setInternalListeners = (preFinishTransaction, postFinishTransaction) =>
|
|
3116
|
+
(internalListeners = [preFinishTransaction, postFinishTransaction]);
|
|
3089
3117
|
const store = {
|
|
3090
3118
|
getContent,
|
|
3091
3119
|
getTables,
|
|
@@ -3163,7 +3191,7 @@ const createStore = () => {
|
|
|
3163
3191
|
createStore,
|
|
3164
3192
|
addListener,
|
|
3165
3193
|
callListeners,
|
|
3166
|
-
|
|
3194
|
+
setInternalListeners,
|
|
3167
3195
|
};
|
|
3168
3196
|
objToArray(
|
|
3169
3197
|
{
|
|
@@ -3247,12 +3275,6 @@ const SHIFT12 = 2 ** 12;
|
|
|
3247
3275
|
const SHIFT6 = 2 ** 6;
|
|
3248
3276
|
const toB64 = (num) => String.fromCharCode(48 + (num & MASK6));
|
|
3249
3277
|
const fromB64 = (str, pos) => strCharCodeAt(str, pos) - 48;
|
|
3250
|
-
const hash = (value) =>
|
|
3251
|
-
arrayReduce(
|
|
3252
|
-
strSplit(value),
|
|
3253
|
-
(hash2, char) => ((hash2 << 5) + hash2) ^ strCharCodeAt(char),
|
|
3254
|
-
5381,
|
|
3255
|
-
) >>> 0;
|
|
3256
3278
|
const encodeHlc = (logicalTime42, counter24, clientHash30) =>
|
|
3257
3279
|
toB64(logicalTime42 / SHIFT36) +
|
|
3258
3280
|
toB64(logicalTime42 / SHIFT30) +
|
|
@@ -3290,23 +3312,23 @@ const decodeHlc = (hlc16) => [
|
|
|
3290
3312
|
];
|
|
3291
3313
|
const getHlcFunctions = (uniqueId) => {
|
|
3292
3314
|
let logicalTime = 0;
|
|
3293
|
-
let
|
|
3294
|
-
const uniqueIdHash =
|
|
3315
|
+
let lastCounter = -1;
|
|
3316
|
+
const uniqueIdHash = getHash(uniqueId);
|
|
3295
3317
|
const getHlc = () => {
|
|
3296
3318
|
seenHlc();
|
|
3297
|
-
return encodeHlc(logicalTime, ++
|
|
3319
|
+
return encodeHlc(logicalTime, ++lastCounter, uniqueIdHash);
|
|
3298
3320
|
};
|
|
3299
3321
|
const seenHlc = (hlc) => {
|
|
3300
3322
|
const previousLogicalTime = logicalTime;
|
|
3301
3323
|
const [remoteLogicalTime, remoteCounter] = isUndefined(hlc)
|
|
3302
3324
|
? [0, 0]
|
|
3303
3325
|
: decodeHlc(hlc);
|
|
3304
|
-
logicalTime =
|
|
3305
|
-
|
|
3326
|
+
logicalTime = mathMax(previousLogicalTime, remoteLogicalTime, Date.now());
|
|
3327
|
+
lastCounter =
|
|
3306
3328
|
logicalTime == previousLogicalTime
|
|
3307
3329
|
? logicalTime == remoteLogicalTime
|
|
3308
|
-
?
|
|
3309
|
-
:
|
|
3330
|
+
? mathMax(lastCounter, remoteCounter)
|
|
3331
|
+
: lastCounter
|
|
3310
3332
|
: logicalTime == remoteLogicalTime
|
|
3311
3333
|
? remoteCounter
|
|
3312
3334
|
: -1;
|
|
@@ -3332,10 +3354,16 @@ const LISTENER_ARGS = {
|
|
|
3332
3354
|
InvalidCell: 3,
|
|
3333
3355
|
InvalidValue: 1,
|
|
3334
3356
|
};
|
|
3335
|
-
const
|
|
3357
|
+
const newContentHsm = (time = EMPTY_STRING) => [
|
|
3358
|
+
time,
|
|
3359
|
+
[hashStampNewMap(time), hashStampNewMap(time)],
|
|
3360
|
+
0,
|
|
3361
|
+
];
|
|
3336
3362
|
const createMergeableStore = (id) => {
|
|
3337
3363
|
let listening = 1;
|
|
3338
|
-
let
|
|
3364
|
+
let contentHsm = newContentHsm();
|
|
3365
|
+
let transactionTime;
|
|
3366
|
+
let transactionMergeableChanges;
|
|
3339
3367
|
const [getHlc, seenHlc] = getHlcFunctions(id);
|
|
3340
3368
|
const store = createStore();
|
|
3341
3369
|
const disableListening = (actions) => {
|
|
@@ -3344,105 +3372,206 @@ const createMergeableStore = (id) => {
|
|
|
3344
3372
|
actions();
|
|
3345
3373
|
listening = wasListening;
|
|
3346
3374
|
};
|
|
3347
|
-
const
|
|
3348
|
-
|
|
3349
|
-
|
|
3350
|
-
|
|
3351
|
-
|
|
3352
|
-
|
|
3353
|
-
|
|
3354
|
-
|
|
3355
|
-
|
|
3356
|
-
|
|
3357
|
-
|
|
3358
|
-
|
|
3359
|
-
|
|
3360
|
-
|
|
3361
|
-
|
|
3362
|
-
|
|
3363
|
-
|
|
3364
|
-
|
|
3365
|
-
|
|
3375
|
+
const mergeContentOrChanges = (contentOrChanges, hasHashes = 0) => {
|
|
3376
|
+
const tablesChanges = {};
|
|
3377
|
+
const valuesChanges = {};
|
|
3378
|
+
const [
|
|
3379
|
+
contentOrChangesTime,
|
|
3380
|
+
[[tablesTime, tablesObj, incomingTablesHash], values],
|
|
3381
|
+
incomingContentOrChangesHash,
|
|
3382
|
+
] = contentOrChanges;
|
|
3383
|
+
const [, [tablesHsm, valuesHsm]] = contentHsm;
|
|
3384
|
+
const [oldTablesTime, tableHsms, oldTablesHash] = tablesHsm;
|
|
3385
|
+
if (tablesTime) {
|
|
3386
|
+
let tablesHash = hasHashes
|
|
3387
|
+
? incomingTablesHash
|
|
3388
|
+
: oldTablesHash ^
|
|
3389
|
+
(tablesTime > oldTablesTime
|
|
3390
|
+
? (oldTablesTime ? getHash(oldTablesTime) : 0) ^ getHash(tablesTime)
|
|
3391
|
+
: 0);
|
|
3392
|
+
objForEach(
|
|
3393
|
+
tablesObj,
|
|
3394
|
+
([tableTime, rowsObj, incomingTableHash], tableId) => {
|
|
3395
|
+
const tableHsm = mapEnsure(tableHsms, tableId, hashStampNewMap);
|
|
3396
|
+
const [oldTableTime, rowHsms, oldTableHash] = tableHsm;
|
|
3397
|
+
let tableHash = hasHashes
|
|
3398
|
+
? incomingTableHash
|
|
3399
|
+
: oldTableHash ^
|
|
3400
|
+
(tableTime > oldTableTime
|
|
3401
|
+
? (oldTableTime ? getHash(oldTableTime) : 0) ^
|
|
3402
|
+
getHash(tableTime)
|
|
3403
|
+
: 0);
|
|
3404
|
+
objForEach(rowsObj, (row, rowId) => {
|
|
3405
|
+
const [oldRowHash, rowHash] = mergeCellsOrValues(
|
|
3406
|
+
row,
|
|
3407
|
+
mapEnsure(rowHsms, rowId, hashStampNewMap),
|
|
3408
|
+
objEnsure(
|
|
3409
|
+
objEnsure(tablesChanges, tableId, objNew),
|
|
3410
|
+
rowId,
|
|
3411
|
+
objNew,
|
|
3412
|
+
),
|
|
3413
|
+
hasHashes,
|
|
3366
3414
|
);
|
|
3415
|
+
tableHash ^= hasHashes
|
|
3416
|
+
? 0
|
|
3417
|
+
: (oldRowHash ? hashIdAndHash(rowId, oldRowHash) : 0) ^
|
|
3418
|
+
hashIdAndHash(rowId, rowHash);
|
|
3367
3419
|
});
|
|
3368
|
-
|
|
3369
|
-
|
|
3370
|
-
|
|
3371
|
-
|
|
3372
|
-
|
|
3373
|
-
|
|
3374
|
-
|
|
3375
|
-
|
|
3420
|
+
updateHashStamp(tableHsm, tableHash, tableTime);
|
|
3421
|
+
tablesHash ^= hasHashes
|
|
3422
|
+
? 0
|
|
3423
|
+
: (oldTableHash ? hashIdAndHash(tableId, oldTableHash) : 0) ^
|
|
3424
|
+
hashIdAndHash(tableId, tableHsm[2]);
|
|
3425
|
+
},
|
|
3426
|
+
);
|
|
3427
|
+
updateHashStamp(tablesHsm, tablesHash, tablesTime);
|
|
3376
3428
|
}
|
|
3429
|
+
mergeCellsOrValues(values, valuesHsm, valuesChanges, hasHashes);
|
|
3430
|
+
updateHashStamp(
|
|
3431
|
+
contentHsm,
|
|
3432
|
+
hasHashes ? incomingContentOrChangesHash : tablesHsm[2] ^ valuesHsm[2],
|
|
3433
|
+
contentOrChangesTime,
|
|
3434
|
+
);
|
|
3435
|
+
return [tablesChanges, valuesChanges];
|
|
3377
3436
|
};
|
|
3378
|
-
const
|
|
3379
|
-
const
|
|
3380
|
-
const
|
|
3381
|
-
|
|
3382
|
-
|
|
3437
|
+
const mergeCellsOrValues = (things, thingsHsm, thingsChanges, hasHashes) => {
|
|
3438
|
+
const [thingsTime, thingsObj, incomingThingsHash] = things;
|
|
3439
|
+
const [oldThingsTime, thingHsms, oldThingsHash] = thingsHsm;
|
|
3440
|
+
if (thingsTime) {
|
|
3441
|
+
let thingsHash = hasHashes
|
|
3442
|
+
? incomingThingsHash
|
|
3443
|
+
: oldThingsHash ^
|
|
3444
|
+
(thingsTime > oldThingsTime
|
|
3445
|
+
? (oldThingsTime ? getHash(oldThingsTime) : 0) ^ getHash(thingsTime)
|
|
3446
|
+
: 0);
|
|
3447
|
+
objForEach(
|
|
3448
|
+
thingsObj,
|
|
3449
|
+
([thingTime, thing, incomingThingHash], thingId) => {
|
|
3450
|
+
const thingHsm = mapEnsure(thingHsms, thingId, hashStampNewThing);
|
|
3451
|
+
const [oldThingTime, , oldThingHash] = thingHsm;
|
|
3452
|
+
if (thingTime > oldThingTime) {
|
|
3453
|
+
updateHashStamp(
|
|
3454
|
+
thingHsm,
|
|
3455
|
+
hasHashes
|
|
3456
|
+
? incomingThingHash
|
|
3457
|
+
: getHash(jsonString(thing ?? null) + ':' + thingTime),
|
|
3458
|
+
thingTime,
|
|
3459
|
+
);
|
|
3460
|
+
thingHsm[1] = thing;
|
|
3461
|
+
thingsChanges[thingId] = thing;
|
|
3462
|
+
thingsHash ^= hasHashes
|
|
3463
|
+
? 0
|
|
3464
|
+
: hashIdAndHash(thingId, oldThingHash) ^
|
|
3465
|
+
hashIdAndHash(thingId, thingHsm[2]);
|
|
3466
|
+
}
|
|
3467
|
+
},
|
|
3468
|
+
);
|
|
3469
|
+
updateHashStamp(thingsHsm, thingsHash, thingsTime);
|
|
3470
|
+
}
|
|
3471
|
+
return [oldThingsHash, thingsHsm[2]];
|
|
3383
3472
|
};
|
|
3473
|
+
const preFinishTransaction = () => {
|
|
3474
|
+
if (listening) {
|
|
3475
|
+
transactionMergeableChanges = getTransactionMergeableChanges();
|
|
3476
|
+
mergeContentOrChanges(transactionMergeableChanges);
|
|
3477
|
+
}
|
|
3478
|
+
};
|
|
3479
|
+
const postFinishTransaction = () =>
|
|
3480
|
+
(transactionTime = transactionMergeableChanges = void 0);
|
|
3384
3481
|
const getMergeableContent = () =>
|
|
3385
|
-
|
|
3386
|
-
|
|
3387
|
-
|
|
3388
|
-
mapStampMapToObj(cellsStamp, pairClone),
|
|
3389
|
-
),
|
|
3482
|
+
hashStampMap(contentHsm, ([tables, values]) => [
|
|
3483
|
+
hashStampMapToObj(tables, (table) =>
|
|
3484
|
+
hashStampMapToObj(table, (row) => hashStampMapToObj(row)),
|
|
3390
3485
|
),
|
|
3391
|
-
|
|
3486
|
+
hashStampMapToObj(values),
|
|
3392
3487
|
]);
|
|
3393
3488
|
const setMergeableContent = (mergeableContent) => {
|
|
3394
3489
|
disableListening(() =>
|
|
3395
3490
|
store.transaction(() => {
|
|
3396
3491
|
store.delTables().delValues();
|
|
3397
|
-
|
|
3492
|
+
contentHsm = newContentHsm();
|
|
3398
3493
|
}),
|
|
3399
3494
|
);
|
|
3400
|
-
|
|
3495
|
+
seenHlc(mergeableContent[0]);
|
|
3496
|
+
disableListening(() =>
|
|
3497
|
+
store.applyChanges(mergeContentOrChanges(mergeableContent, 1)),
|
|
3498
|
+
);
|
|
3401
3499
|
return mergeableStore;
|
|
3402
3500
|
};
|
|
3403
|
-
const
|
|
3404
|
-
|
|
3405
|
-
|
|
3406
|
-
|
|
3407
|
-
|
|
3408
|
-
|
|
3409
|
-
|
|
3410
|
-
(
|
|
3411
|
-
|
|
3412
|
-
|
|
3413
|
-
|
|
3414
|
-
|
|
3415
|
-
|
|
3416
|
-
|
|
3417
|
-
|
|
3418
|
-
|
|
3419
|
-
(
|
|
3420
|
-
|
|
3421
|
-
|
|
3422
|
-
|
|
3423
|
-
|
|
3424
|
-
|
|
3425
|
-
|
|
3426
|
-
|
|
3427
|
-
|
|
3428
|
-
|
|
3429
|
-
|
|
3430
|
-
|
|
3431
|
-
|
|
3432
|
-
|
|
3433
|
-
|
|
3434
|
-
|
|
3501
|
+
const getTransactionMergeableChanges = () => {
|
|
3502
|
+
if (isUndefined(transactionMergeableChanges)) {
|
|
3503
|
+
const [, , changedCells, , changedValues] = store.getTransactionLog();
|
|
3504
|
+
const time =
|
|
3505
|
+
!objIsEmpty(changedCells) || !objIsEmpty(changedValues)
|
|
3506
|
+
? transactionTime ?? (transactionTime = getHlc())
|
|
3507
|
+
: EMPTY_STRING;
|
|
3508
|
+
const mergeableChanges = stampNew(time, [
|
|
3509
|
+
stampNewObj(objIsEmpty(changedCells) ? EMPTY_STRING : time),
|
|
3510
|
+
stampNewObj(objIsEmpty(changedValues) ? EMPTY_STRING : time),
|
|
3511
|
+
]);
|
|
3512
|
+
const [[, tablesObj], [, valuesObj]] = mergeableChanges[1];
|
|
3513
|
+
objToArray(changedCells, (changedTable, tableId) => {
|
|
3514
|
+
const [, rowsObj] = (tablesObj[tableId] = stampNewObj(time));
|
|
3515
|
+
objToArray(changedTable, (changedRow, rowId) => {
|
|
3516
|
+
const [, cellsObj] = (rowsObj[rowId] = stampNewObj(time));
|
|
3517
|
+
objToArray(
|
|
3518
|
+
changedRow,
|
|
3519
|
+
([, newCell], cellId) =>
|
|
3520
|
+
(cellsObj[cellId] = stampNew(time, newCell)),
|
|
3521
|
+
);
|
|
3522
|
+
});
|
|
3523
|
+
});
|
|
3524
|
+
objToArray(
|
|
3525
|
+
changedValues,
|
|
3526
|
+
([, newValue], valueId) =>
|
|
3527
|
+
(valuesObj[valueId] = stampNew(time, newValue)),
|
|
3528
|
+
);
|
|
3529
|
+
return mergeableChanges;
|
|
3530
|
+
}
|
|
3531
|
+
return transactionMergeableChanges;
|
|
3532
|
+
};
|
|
3533
|
+
const applyMergeableChanges = (mergeableChanges) => {
|
|
3534
|
+
seenHlc(mergeableChanges[0]);
|
|
3535
|
+
disableListening(() =>
|
|
3536
|
+
store.applyChanges(mergeContentOrChanges(mergeableChanges)),
|
|
3435
3537
|
);
|
|
3436
|
-
disableListening(() => store.applyChanges(changes));
|
|
3437
3538
|
return mergeableStore;
|
|
3438
3539
|
};
|
|
3540
|
+
const merge = (mergeableStore2) => {
|
|
3541
|
+
const mergeableChanges = getMergeableContent();
|
|
3542
|
+
const mergeableChanges2 = mergeableStore2.getMergeableContent();
|
|
3543
|
+
mergeableStore2.applyMergeableChanges(mergeableChanges);
|
|
3544
|
+
return applyMergeableChanges(mergeableChanges2);
|
|
3545
|
+
};
|
|
3546
|
+
const getContentHash = () => contentHsm[2];
|
|
3547
|
+
const getTablesHash = () => contentHsm[1][0][2];
|
|
3548
|
+
const getTableHash = (tableId) =>
|
|
3549
|
+
mapGet(contentHsm[1][0][1], tableId)?.[2] ?? 0;
|
|
3550
|
+
const getRowHash = (tableId, rowId) =>
|
|
3551
|
+
mapGet(mapGet(contentHsm[1][0][1], tableId)?.[1], rowId)?.[2] ?? 0;
|
|
3552
|
+
const getCellHash = (tableId, rowId, cellId) =>
|
|
3553
|
+
mapGet(
|
|
3554
|
+
mapGet(mapGet(contentHsm[1][0][1], tableId)?.[1], rowId)?.[1],
|
|
3555
|
+
cellId,
|
|
3556
|
+
)?.[2] ?? 0;
|
|
3557
|
+
const getValuesHash = () => contentHsm[1][1][2];
|
|
3558
|
+
const getValueHash = (valueId) =>
|
|
3559
|
+
mapGet(contentHsm[1][1][1], valueId)?.[2] ?? 0;
|
|
3439
3560
|
const mergeableStore = {
|
|
3440
3561
|
getMergeableContent,
|
|
3441
3562
|
setMergeableContent,
|
|
3563
|
+
getTransactionMergeableChanges,
|
|
3442
3564
|
applyMergeableChanges,
|
|
3443
3565
|
merge,
|
|
3566
|
+
getContentHash,
|
|
3567
|
+
getTablesHash,
|
|
3568
|
+
getTableHash,
|
|
3569
|
+
getRowHash,
|
|
3570
|
+
getCellHash,
|
|
3571
|
+
getValuesHash,
|
|
3572
|
+
getValueHash,
|
|
3444
3573
|
};
|
|
3445
|
-
store.
|
|
3574
|
+
store.setInternalListeners(preFinishTransaction, postFinishTransaction);
|
|
3446
3575
|
objToArray(
|
|
3447
3576
|
store,
|
|
3448
3577
|
(method, name) =>
|
package/lib/debug/tools.js
CHANGED
|
@@ -36,9 +36,10 @@ const slice = (arrayOrString, start, end) => arrayOrString.slice(start, end);
|
|
|
36
36
|
const size = (arrayOrString) => arrayOrString.length;
|
|
37
37
|
const promiseAll = async (promises) => promise.all(promises);
|
|
38
38
|
|
|
39
|
-
const getCellOrValueType = (
|
|
40
|
-
const type = getTypeOf(
|
|
41
|
-
return isTypeStringOrBoolean(type) ||
|
|
39
|
+
const getCellOrValueType = (cellOrValue) => {
|
|
40
|
+
const type = getTypeOf(cellOrValue);
|
|
41
|
+
return isTypeStringOrBoolean(type) ||
|
|
42
|
+
(type == NUMBER && isFiniteNumber(cellOrValue))
|
|
42
43
|
? type
|
|
43
44
|
: void 0;
|
|
44
45
|
};
|
|
@@ -87,9 +88,11 @@ const mapMap = (coll, cb) =>
|
|
|
87
88
|
arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
|
|
88
89
|
const mapSet = (map, key, value) =>
|
|
89
90
|
isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
|
|
90
|
-
const mapEnsure = (map, key, getDefaultValue) => {
|
|
91
|
+
const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
|
|
91
92
|
if (!collHas(map, key)) {
|
|
92
93
|
mapSet(map, key, getDefaultValue());
|
|
94
|
+
} else {
|
|
95
|
+
hadExistingValue?.(mapGet(map, key));
|
|
93
96
|
}
|
|
94
97
|
return mapGet(map, key);
|
|
95
98
|
};
|