tinybase 5.0.0-beta.1 → 5.0.0-beta.10
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 -0
- 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-partykit-server.cjs +1 -1
- package/lib/cjs/persisters/persister-partykit-server.cjs.gz +0 -0
- package/lib/cjs/persisters/persister-powersync.cjs +1 -0
- package/lib/cjs/persisters/persister-powersync.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/synchronizers/synchronizer-local.cjs +1 -0
- package/lib/cjs/synchronizers/synchronizer-local.cjs.gz +0 -0
- package/lib/cjs/synchronizers/synchronizer-ws-client.cjs +1 -0
- package/lib/cjs/synchronizers/synchronizer-ws-client.cjs.gz +0 -0
- package/lib/cjs/synchronizers/synchronizer-ws-server.cjs +1 -0
- package/lib/cjs/synchronizers/synchronizer-ws-server.cjs.gz +0 -0
- package/lib/cjs/synchronizers.cjs +1 -0
- package/lib/cjs/synchronizers.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/ui-react-dom.cjs +1 -1
- package/lib/cjs/ui-react-dom.cjs.gz +0 -0
- package/lib/cjs/ui-react.cjs +1 -1
- package/lib/cjs/ui-react.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 -0
- 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-partykit-server.cjs +1 -1
- package/lib/cjs-es6/persisters/persister-partykit-server.cjs.gz +0 -0
- package/lib/cjs-es6/persisters/persister-powersync.cjs +1 -0
- package/lib/cjs-es6/persisters/persister-powersync.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/synchronizers/synchronizer-local.cjs +1 -0
- package/lib/cjs-es6/synchronizers/synchronizer-local.cjs.gz +0 -0
- package/lib/cjs-es6/synchronizers/synchronizer-ws-client.cjs +1 -0
- package/lib/cjs-es6/synchronizers/synchronizer-ws-client.cjs.gz +0 -0
- package/lib/cjs-es6/synchronizers/synchronizer-ws-server.cjs +1 -0
- package/lib/cjs-es6/synchronizers/synchronizer-ws-server.cjs.gz +0 -0
- package/lib/cjs-es6/synchronizers.cjs +1 -0
- package/lib/cjs-es6/synchronizers.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/cjs-es6/ui-react-dom.cjs +1 -1
- package/lib/cjs-es6/ui-react-dom.cjs.gz +0 -0
- package/lib/cjs-es6/ui-react.cjs +1 -1
- package/lib/cjs-es6/ui-react.cjs.gz +0 -0
- package/lib/debug/checkpoints.js +3 -1
- package/lib/debug/indexes.js +3 -1
- package/lib/debug/mergeable-store.js +2230 -0
- package/lib/debug/metrics.js +3 -1
- package/lib/debug/persisters/persister-automerge.js +110 -86
- package/lib/debug/persisters/persister-browser.js +94 -57
- package/lib/debug/persisters/persister-cr-sqlite-wasm.js +168 -106
- package/lib/debug/persisters/persister-electric-sql.js +168 -106
- package/lib/debug/persisters/persister-expo-sqlite-next.js +168 -106
- package/lib/debug/persisters/persister-expo-sqlite.js +168 -106
- package/lib/debug/persisters/persister-file.js +93 -57
- package/lib/debug/persisters/persister-indexed-db.js +90 -56
- package/lib/debug/persisters/persister-libsql.js +913 -0
- package/lib/debug/persisters/persister-partykit-client.js +89 -59
- package/lib/debug/persisters/persister-partykit-server.js +17 -25
- package/lib/debug/persisters/persister-powersync.js +928 -0
- package/lib/debug/persisters/persister-remote.js +85 -53
- package/lib/debug/persisters/persister-sqlite-wasm.js +168 -106
- package/lib/debug/persisters/persister-sqlite3.js +168 -106
- package/lib/debug/persisters/persister-yjs.js +108 -83
- package/lib/debug/persisters.js +81 -50
- package/lib/debug/queries.js +9 -6
- package/lib/debug/relationships.js +3 -1
- package/lib/debug/store.js +147 -126
- package/lib/debug/synchronizers/synchronizer-local.js +559 -0
- package/lib/debug/synchronizers/synchronizer-ws-client.js +586 -0
- package/lib/debug/synchronizers/synchronizer-ws-server.js +96 -0
- package/lib/debug/synchronizers.js +519 -0
- package/lib/debug/tinybase.js +1027 -174
- package/lib/debug/tools.js +22 -21
- package/lib/debug/ui-react-dom.js +275 -213
- package/lib/debug/ui-react.js +55 -6
- 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 -0
- 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-partykit-server.js +1 -1
- package/lib/es6/persisters/persister-partykit-server.js.gz +0 -0
- package/lib/es6/persisters/persister-powersync.js +1 -0
- package/lib/es6/persisters/persister-powersync.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/synchronizers/synchronizer-local.js +1 -0
- package/lib/es6/synchronizers/synchronizer-local.js.gz +0 -0
- package/lib/es6/synchronizers/synchronizer-ws-client.js +1 -0
- package/lib/es6/synchronizers/synchronizer-ws-client.js.gz +0 -0
- package/lib/es6/synchronizers/synchronizer-ws-server.js +1 -0
- package/lib/es6/synchronizers/synchronizer-ws-server.js.gz +0 -0
- package/lib/es6/synchronizers.js +1 -0
- package/lib/es6/synchronizers.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/es6/ui-react-dom.js +1 -1
- package/lib/es6/ui-react-dom.js.gz +0 -0
- package/lib/es6/ui-react.js +1 -1
- package/lib/es6/ui-react.js.gz +0 -0
- package/lib/indexes.js +1 -1
- package/lib/indexes.js.gz +0 -0
- package/lib/mergeable-store.js +1 -0
- 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-partykit-server.js +1 -1
- package/lib/persisters/persister-partykit-server.js.gz +0 -0
- package/lib/persisters/persister-powersync.js +1 -0
- package/lib/persisters/persister-powersync.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/synchronizers/synchronizer-local.js +1 -0
- package/lib/synchronizers/synchronizer-local.js.gz +0 -0
- package/lib/synchronizers/synchronizer-ws-client.js +1 -0
- package/lib/synchronizers/synchronizer-ws-client.js.gz +0 -0
- package/lib/synchronizers/synchronizer-ws-server.js +1 -0
- package/lib/synchronizers/synchronizer-ws-server.js.gz +0 -0
- package/lib/synchronizers.js +1 -0
- package/lib/synchronizers.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/checkpoints.d.ts +2 -2
- package/lib/types/indexes.d.ts +2 -2
- package/lib/types/mergeable-store.d.ts +214 -0
- package/lib/types/metrics.d.ts +2 -2
- package/lib/types/persisters/persister-automerge.d.ts +11 -7
- package/lib/types/persisters/persister-browser.d.ts +13 -4
- package/lib/types/persisters/persister-cr-sqlite-wasm.d.ts +4 -0
- package/lib/types/persisters/persister-electric-sql.d.ts +4 -0
- package/lib/types/persisters/persister-expo-sqlite-next.d.ts +4 -0
- package/lib/types/persisters/persister-expo-sqlite.d.ts +4 -0
- package/lib/types/persisters/persister-file.d.ts +7 -2
- package/lib/types/persisters/persister-indexed-db.d.ts +4 -0
- package/lib/types/persisters/persister-libsql.d.ts +142 -0
- package/lib/types/persisters/persister-partykit-client.d.ts +4 -0
- package/lib/types/persisters/persister-partykit-server.d.ts +12 -8
- package/lib/types/persisters/persister-powersync.d.ts +157 -0
- package/lib/types/persisters/persister-remote.d.ts +4 -0
- package/lib/types/persisters/persister-sqlite-wasm.d.ts +4 -0
- package/lib/types/persisters/persister-sqlite3.d.ts +4 -0
- package/lib/types/persisters/persister-yjs.d.ts +6 -2
- package/lib/types/persisters.d.ts +125 -48
- package/lib/types/queries.d.ts +2 -2
- package/lib/types/relationships.d.ts +2 -2
- package/lib/types/store.d.ts +275 -187
- package/lib/types/synchronizers/synchronizer-local.d.ts +27 -0
- package/lib/types/synchronizers/synchronizer-ws-client.d.ts +35 -0
- package/lib/types/synchronizers/synchronizer-ws-server.d.ts +36 -0
- package/lib/types/synchronizers.d.ts +132 -0
- package/lib/types/tinybase.d.ts +10 -8
- package/lib/types/tools.d.ts +4 -4
- package/lib/types/ui-react.d.ts +160 -9
- package/lib/types/with-schemas/checkpoints.d.ts +2 -2
- package/lib/types/with-schemas/indexes.d.ts +2 -2
- package/lib/types/with-schemas/internal/store.d.ts +4 -0
- package/lib/types/with-schemas/mergeable-store.d.ts +492 -0
- package/lib/types/with-schemas/metrics.d.ts +2 -2
- package/lib/types/with-schemas/persisters/persister-automerge.d.ts +12 -8
- package/lib/types/with-schemas/persisters/persister-browser.d.ts +17 -8
- package/lib/types/with-schemas/persisters/persister-cr-sqlite-wasm.d.ts +5 -1
- package/lib/types/with-schemas/persisters/persister-electric-sql.d.ts +5 -1
- package/lib/types/with-schemas/persisters/persister-expo-sqlite-next.d.ts +5 -1
- package/lib/types/with-schemas/persisters/persister-expo-sqlite.d.ts +5 -1
- package/lib/types/with-schemas/persisters/persister-file.d.ts +9 -4
- package/lib/types/with-schemas/persisters/persister-indexed-db.d.ts +5 -1
- package/lib/types/with-schemas/persisters/persister-libsql.d.ts +155 -0
- package/lib/types/with-schemas/persisters/persister-partykit-client.d.ts +5 -1
- package/lib/types/with-schemas/persisters/persister-partykit-server.d.ts +15 -11
- package/lib/types/with-schemas/persisters/persister-powersync.d.ts +170 -0
- package/lib/types/with-schemas/persisters/persister-remote.d.ts +5 -1
- package/lib/types/with-schemas/persisters/persister-sqlite-wasm.d.ts +5 -1
- package/lib/types/with-schemas/persisters/persister-sqlite3.d.ts +5 -1
- package/lib/types/with-schemas/persisters/persister-yjs.d.ts +7 -3
- package/lib/types/with-schemas/persisters.d.ts +161 -101
- package/lib/types/with-schemas/queries.d.ts +3 -3
- package/lib/types/with-schemas/relationships.d.ts +2 -2
- package/lib/types/with-schemas/store.d.ts +483 -345
- package/lib/types/with-schemas/synchronizers/synchronizer-local.d.ts +29 -0
- package/lib/types/with-schemas/synchronizers/synchronizer-ws-client.d.ts +41 -0
- package/lib/types/with-schemas/synchronizers/synchronizer-ws-server.d.ts +36 -0
- package/lib/types/with-schemas/synchronizers.d.ts +146 -0
- package/lib/types/with-schemas/tinybase.d.ts +9 -8
- package/lib/types/with-schemas/tools.d.ts +4 -4
- package/lib/types/with-schemas/ui-react.d.ts +177 -9
- package/lib/ui-react-dom.js +1 -1
- package/lib/ui-react-dom.js.gz +0 -0
- package/lib/ui-react.js +1 -1
- package/lib/ui-react.js.gz +0 -0
- 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 -0
- 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-partykit-server.js +1 -1
- package/lib/umd/persisters/persister-partykit-server.js.gz +0 -0
- package/lib/umd/persisters/persister-powersync.js +1 -0
- package/lib/umd/persisters/persister-powersync.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/synchronizers/synchronizer-local.js +1 -0
- package/lib/umd/synchronizers/synchronizer-local.js.gz +0 -0
- package/lib/umd/synchronizers/synchronizer-ws-client.js +1 -0
- package/lib/umd/synchronizers/synchronizer-ws-client.js.gz +0 -0
- package/lib/umd/synchronizers/synchronizer-ws-server.js +1 -0
- package/lib/umd/synchronizers/synchronizer-ws-server.js.gz +0 -0
- package/lib/umd/synchronizers.js +1 -0
- package/lib/umd/synchronizers.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/ui-react-dom.js +1 -1
- package/lib/umd/ui-react-dom.js.gz +0 -0
- package/lib/umd/ui-react.js +1 -1
- package/lib/umd/ui-react.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 -0
- 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-partykit-server.js +1 -1
- package/lib/umd-es6/persisters/persister-partykit-server.js.gz +0 -0
- package/lib/umd-es6/persisters/persister-powersync.js +1 -0
- package/lib/umd-es6/persisters/persister-powersync.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/synchronizers/synchronizer-local.js +1 -0
- package/lib/umd-es6/synchronizers/synchronizer-local.js.gz +0 -0
- package/lib/umd-es6/synchronizers/synchronizer-ws-client.js +1 -0
- package/lib/umd-es6/synchronizers/synchronizer-ws-client.js.gz +0 -0
- package/lib/umd-es6/synchronizers/synchronizer-ws-server.js +1 -0
- package/lib/umd-es6/synchronizers/synchronizer-ws-server.js.gz +0 -0
- package/lib/umd-es6/synchronizers.js +1 -0
- package/lib/umd-es6/synchronizers.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/lib/umd-es6/ui-react-dom.js +1 -1
- package/lib/umd-es6/ui-react-dom.js.gz +0 -0
- package/lib/umd-es6/ui-react.js +1 -1
- package/lib/umd-es6/ui-react.js.gz +0 -0
- package/package.json +65 -45
- package/readme.md +2 -2
package/lib/debug/tinybase.js
CHANGED
|
@@ -29,7 +29,11 @@ const VALUE = 'Value';
|
|
|
29
29
|
const VALUES = VALUE + 's';
|
|
30
30
|
const VALUE_IDS = VALUE + IDS;
|
|
31
31
|
const id = (key) => EMPTY_STRING + key;
|
|
32
|
+
const strStartsWith = (str, prefix) => str.startsWith(prefix);
|
|
33
|
+
const strEndsWith = (str, suffix) => str.endsWith(suffix);
|
|
34
|
+
const strCharCodeAt = (str, position) => str.charCodeAt(position);
|
|
32
35
|
|
|
36
|
+
const promise = Promise;
|
|
33
37
|
const mathMax = Math.max;
|
|
34
38
|
const mathMin = Math.min;
|
|
35
39
|
const isFiniteNumber = isFinite;
|
|
@@ -45,6 +49,7 @@ const slice = (arrayOrString, start, end) => arrayOrString.slice(start, end);
|
|
|
45
49
|
const size = (arrayOrString) => arrayOrString.length;
|
|
46
50
|
const test = (regex, subject) => regex.test(subject);
|
|
47
51
|
const getUndefined = () => void 0;
|
|
52
|
+
const promiseNew = (resolver) => new promise(resolver);
|
|
48
53
|
|
|
49
54
|
const arrayHas = (array, value) => array.includes(value);
|
|
50
55
|
const arrayEvery = (array, cb) => array.every(cb);
|
|
@@ -71,9 +76,7 @@ const arrayShift = (array) => array.shift();
|
|
|
71
76
|
const object = Object;
|
|
72
77
|
const getPrototypeOf = (obj) => object.getPrototypeOf(obj);
|
|
73
78
|
const objEntries = object.entries;
|
|
74
|
-
const objIds = object.keys;
|
|
75
79
|
const objFrozen = object.isFrozen;
|
|
76
|
-
const objFreeze = object.freeze;
|
|
77
80
|
const isObject = (obj) =>
|
|
78
81
|
!isUndefined(obj) &&
|
|
79
82
|
ifNotUndefined(
|
|
@@ -84,16 +87,43 @@ const isObject = (obj) =>
|
|
|
84
87
|
/* istanbul ignore next */
|
|
85
88
|
() => true,
|
|
86
89
|
);
|
|
87
|
-
const
|
|
88
|
-
const
|
|
90
|
+
const objIds = object.keys;
|
|
91
|
+
const objFreeze = object.freeze;
|
|
92
|
+
const objNew = (entries = []) => object.fromEntries(entries);
|
|
93
|
+
const objHas = (obj, id) => id in obj;
|
|
89
94
|
const objDel = (obj, id) => {
|
|
90
95
|
delete obj[id];
|
|
91
96
|
return obj;
|
|
92
97
|
};
|
|
93
|
-
const
|
|
98
|
+
const objForEach = (obj, cb) =>
|
|
99
|
+
arrayForEach(objEntries(obj), ([id, value]) => cb(value, id));
|
|
100
|
+
const objToArray = (obj, cb) =>
|
|
94
101
|
arrayMap(objEntries(obj), ([id, value]) => cb(value, id));
|
|
95
102
|
const objSize = (obj) => size(objIds(obj));
|
|
96
103
|
const objIsEmpty = (obj) => isObject(obj) && objSize(obj) == 0;
|
|
104
|
+
const objEnsure = (obj, id, getDefaultValue) => {
|
|
105
|
+
if (!objHas(obj, id)) {
|
|
106
|
+
obj[id] = getDefaultValue();
|
|
107
|
+
}
|
|
108
|
+
return obj[id];
|
|
109
|
+
};
|
|
110
|
+
const objValidate = (obj, validateChild, onInvalidObj, emptyIsValid = 0) => {
|
|
111
|
+
if (
|
|
112
|
+
isUndefined(obj) ||
|
|
113
|
+
!isObject(obj) ||
|
|
114
|
+
(!emptyIsValid && objIsEmpty(obj)) ||
|
|
115
|
+
objFrozen(obj)
|
|
116
|
+
) {
|
|
117
|
+
onInvalidObj?.();
|
|
118
|
+
return false;
|
|
119
|
+
}
|
|
120
|
+
objToArray(obj, (child, id) => {
|
|
121
|
+
if (!validateChild(child, id)) {
|
|
122
|
+
objDel(obj, id);
|
|
123
|
+
}
|
|
124
|
+
});
|
|
125
|
+
return emptyIsValid ? true : !objIsEmpty(obj);
|
|
126
|
+
};
|
|
97
127
|
|
|
98
128
|
const collSizeN = (collSizer) => (coll) =>
|
|
99
129
|
arrayReduce(collValues(coll), (total, coll2) => total + collSizer(coll2), 0);
|
|
@@ -117,35 +147,41 @@ const mapMap = (coll, cb) =>
|
|
|
117
147
|
arrayMap([...(coll?.entries() ?? [])], ([key, value]) => cb(value, key));
|
|
118
148
|
const mapSet = (map, key, value) =>
|
|
119
149
|
isUndefined(value) ? (collDel(map, key), map) : map?.set(key, value);
|
|
120
|
-
const mapEnsure = (map, key, getDefaultValue) => {
|
|
150
|
+
const mapEnsure = (map, key, getDefaultValue, hadExistingValue) => {
|
|
121
151
|
if (!collHas(map, key)) {
|
|
122
152
|
mapSet(map, key, getDefaultValue());
|
|
153
|
+
} else {
|
|
154
|
+
hadExistingValue?.(mapGet(map, key));
|
|
123
155
|
}
|
|
124
156
|
return mapGet(map, key);
|
|
125
157
|
};
|
|
126
158
|
const mapMatch = (map, obj, set, del = mapSet) => {
|
|
127
|
-
|
|
159
|
+
objToArray(obj, (value, id) => set(map, id, value));
|
|
128
160
|
mapForEach(map, (id) => (objHas(obj, id) ? 0 : del(map, id)));
|
|
129
161
|
return map;
|
|
130
162
|
};
|
|
131
|
-
const mapToObj = (map,
|
|
163
|
+
const mapToObj = (map, valueMapper, excludeMapValue, excludeObjValue) => {
|
|
132
164
|
const obj = {};
|
|
133
|
-
collForEach(map, (
|
|
134
|
-
|
|
135
|
-
|
|
165
|
+
collForEach(map, (mapValue, id) => {
|
|
166
|
+
if (!excludeMapValue?.(mapValue, id)) {
|
|
167
|
+
const objValue = valueMapper ? valueMapper(mapValue, id) : mapValue;
|
|
168
|
+
excludeObjValue?.(objValue) ? 0 : (obj[id] = objValue);
|
|
169
|
+
}
|
|
136
170
|
});
|
|
137
171
|
return obj;
|
|
138
172
|
};
|
|
139
|
-
const mapToObj2 = (map,
|
|
173
|
+
const mapToObj2 = (map, valueMapper, excludeMapValue) =>
|
|
140
174
|
mapToObj(
|
|
141
175
|
map,
|
|
142
|
-
(childMap) => mapToObj(childMap,
|
|
176
|
+
(childMap) => mapToObj(childMap, valueMapper, excludeMapValue),
|
|
177
|
+
collIsEmpty,
|
|
143
178
|
objIsEmpty,
|
|
144
179
|
);
|
|
145
|
-
const mapToObj3 = (map,
|
|
180
|
+
const mapToObj3 = (map, valueMapper, excludeMapValue) =>
|
|
146
181
|
mapToObj(
|
|
147
182
|
map,
|
|
148
|
-
(childMap) => mapToObj2(childMap,
|
|
183
|
+
(childMap) => mapToObj2(childMap, valueMapper, excludeMapValue),
|
|
184
|
+
collIsEmpty,
|
|
149
185
|
objIsEmpty,
|
|
150
186
|
);
|
|
151
187
|
const mapClone = (map, mapValue) => {
|
|
@@ -177,12 +213,15 @@ const visitTree = (node, path, ensureLeaf, pruneLeaf, p = 0) =>
|
|
|
177
213
|
},
|
|
178
214
|
);
|
|
179
215
|
|
|
180
|
-
const getCellOrValueType = (
|
|
181
|
-
const type = getTypeOf(
|
|
182
|
-
return isTypeStringOrBoolean(type) ||
|
|
216
|
+
const getCellOrValueType = (cellOrValue) => {
|
|
217
|
+
const type = getTypeOf(cellOrValue);
|
|
218
|
+
return isTypeStringOrBoolean(type) ||
|
|
219
|
+
(type == NUMBER && isFiniteNumber(cellOrValue))
|
|
183
220
|
? type
|
|
184
221
|
: void 0;
|
|
185
222
|
};
|
|
223
|
+
const isCellOrValueOrNullOrUndefined = (cellOrValue) =>
|
|
224
|
+
isUndefined(cellOrValue) || !isUndefined(getCellOrValueType(cellOrValue));
|
|
186
225
|
const setOrDelCell = (store, tableId, rowId, cellId, cell) =>
|
|
187
226
|
isUndefined(cell)
|
|
188
227
|
? store.delCell(tableId, rowId, cellId, true)
|
|
@@ -1079,6 +1118,24 @@ const createMetrics = getCreateFunction((store) => {
|
|
|
1079
1118
|
|
|
1080
1119
|
const scheduleRunning = mapNew();
|
|
1081
1120
|
const scheduleActions = mapNew();
|
|
1121
|
+
const getStoreFunctions = (supportsMergeableStore, store) =>
|
|
1122
|
+
!supportsMergeableStore || isUndefined(store.getMergeableContent)
|
|
1123
|
+
? [
|
|
1124
|
+
0,
|
|
1125
|
+
store.getContent,
|
|
1126
|
+
store.getTransactionChanges,
|
|
1127
|
+
([changedTables, changedValues]) =>
|
|
1128
|
+
!objIsEmpty(changedTables) || !objIsEmpty(changedValues),
|
|
1129
|
+
store.setContent,
|
|
1130
|
+
]
|
|
1131
|
+
: [
|
|
1132
|
+
1,
|
|
1133
|
+
store.getMergeableContent,
|
|
1134
|
+
store.getTransactionMergeableChanges,
|
|
1135
|
+
([[changedTables], [changedValues]]) =>
|
|
1136
|
+
!objIsEmpty(changedTables) || !objIsEmpty(changedValues),
|
|
1137
|
+
store.setDefaultContent,
|
|
1138
|
+
];
|
|
1082
1139
|
const createCustomPersister = (
|
|
1083
1140
|
store,
|
|
1084
1141
|
getPersisted,
|
|
@@ -1086,18 +1143,25 @@ const createCustomPersister = (
|
|
|
1086
1143
|
addPersisterListener,
|
|
1087
1144
|
delPersisterListener,
|
|
1088
1145
|
onIgnoredError,
|
|
1089
|
-
|
|
1146
|
+
supportsMergeableStore,
|
|
1147
|
+
extra = {},
|
|
1090
1148
|
scheduleId = [],
|
|
1091
1149
|
) => {
|
|
1092
|
-
let listenerId;
|
|
1093
1150
|
let loadSave = 0;
|
|
1094
1151
|
let loads = 0;
|
|
1095
1152
|
let saves = 0;
|
|
1096
|
-
let listening = 0;
|
|
1097
1153
|
let action;
|
|
1098
|
-
let
|
|
1154
|
+
let autoLoadHandle;
|
|
1155
|
+
let autoSaveListenerId;
|
|
1099
1156
|
mapEnsure(scheduleRunning, scheduleId, () => 0);
|
|
1100
1157
|
mapEnsure(scheduleActions, scheduleId, () => []);
|
|
1158
|
+
const [
|
|
1159
|
+
isMergeableStore,
|
|
1160
|
+
getContent,
|
|
1161
|
+
getChanges,
|
|
1162
|
+
hasChanges,
|
|
1163
|
+
setDefaultContent,
|
|
1164
|
+
] = getStoreFunctions(supportsMergeableStore, store);
|
|
1101
1165
|
const run = async () => {
|
|
1102
1166
|
/* istanbul ignore else */
|
|
1103
1167
|
if (!mapGet(scheduleRunning, scheduleId)) {
|
|
@@ -1129,48 +1193,54 @@ const createCustomPersister = (
|
|
|
1129
1193
|
}
|
|
1130
1194
|
return persister;
|
|
1131
1195
|
};
|
|
1196
|
+
const setContentOrChanges = (contentOrChanges) => {
|
|
1197
|
+
(isMergeableStore && isArray(contentOrChanges?.[0])
|
|
1198
|
+
? contentOrChanges?.[2] === 1
|
|
1199
|
+
? store.applyMergeableChanges
|
|
1200
|
+
: store.setMergeableContent
|
|
1201
|
+
: contentOrChanges?.[2] === 1
|
|
1202
|
+
? store.applyChanges
|
|
1203
|
+
: store.setContent)(contentOrChanges);
|
|
1204
|
+
};
|
|
1132
1205
|
const persister = {
|
|
1133
|
-
load: async (
|
|
1206
|
+
load: async (initialContent) =>
|
|
1134
1207
|
await loadLock(async () => {
|
|
1135
1208
|
try {
|
|
1136
|
-
|
|
1137
|
-
} catch {
|
|
1138
|
-
|
|
1209
|
+
setContentOrChanges(await getPersisted());
|
|
1210
|
+
} catch (error) {
|
|
1211
|
+
onIgnoredError?.(error);
|
|
1212
|
+
if (initialContent) {
|
|
1213
|
+
setDefaultContent(initialContent);
|
|
1214
|
+
}
|
|
1139
1215
|
}
|
|
1140
1216
|
}),
|
|
1141
|
-
startAutoLoad: async (
|
|
1142
|
-
persister.stopAutoLoad();
|
|
1143
|
-
|
|
1144
|
-
|
|
1145
|
-
|
|
1146
|
-
|
|
1147
|
-
|
|
1148
|
-
|
|
1149
|
-
|
|
1150
|
-
|
|
1151
|
-
)
|
|
1152
|
-
|
|
1153
|
-
|
|
1154
|
-
|
|
1155
|
-
store.setContent(getContent?.() ?? (await getPersisted()));
|
|
1156
|
-
} catch (error) {
|
|
1157
|
-
onIgnoredError?.(error);
|
|
1158
|
-
}
|
|
1159
|
-
});
|
|
1160
|
-
}
|
|
1217
|
+
startAutoLoad: async (initialContent) => {
|
|
1218
|
+
await persister.stopAutoLoad().load(initialContent);
|
|
1219
|
+
autoLoadHandle = addPersisterListener(
|
|
1220
|
+
async (getContent2, getChanges2) => {
|
|
1221
|
+
const changes = getChanges2?.();
|
|
1222
|
+
await loadLock(async () => {
|
|
1223
|
+
try {
|
|
1224
|
+
setContentOrChanges(
|
|
1225
|
+
changes ?? getContent2?.() ?? (await getPersisted()),
|
|
1226
|
+
);
|
|
1227
|
+
} catch (error) {
|
|
1228
|
+
onIgnoredError?.(error);
|
|
1229
|
+
}
|
|
1230
|
+
});
|
|
1161
1231
|
},
|
|
1162
1232
|
);
|
|
1163
1233
|
return persister;
|
|
1164
1234
|
},
|
|
1165
1235
|
stopAutoLoad: () => {
|
|
1166
|
-
if (
|
|
1167
|
-
delPersisterListener(
|
|
1168
|
-
|
|
1169
|
-
listening = 0;
|
|
1236
|
+
if (autoLoadHandle) {
|
|
1237
|
+
delPersisterListener(autoLoadHandle);
|
|
1238
|
+
autoLoadHandle = void 0;
|
|
1170
1239
|
}
|
|
1171
1240
|
return persister;
|
|
1172
1241
|
},
|
|
1173
|
-
|
|
1242
|
+
isAutoLoading: () => !isUndefined(autoLoadHandle),
|
|
1243
|
+
save: async (getChanges2) => {
|
|
1174
1244
|
/* istanbul ignore else */
|
|
1175
1245
|
if (loadSave != 1) {
|
|
1176
1246
|
loadSave = 2;
|
|
@@ -1179,7 +1249,7 @@ const createCustomPersister = (
|
|
|
1179
1249
|
}
|
|
1180
1250
|
await persister.schedule(async () => {
|
|
1181
1251
|
try {
|
|
1182
|
-
await setPersisted(
|
|
1252
|
+
await setPersisted(getContent, getChanges2);
|
|
1183
1253
|
} catch (error) {
|
|
1184
1254
|
/* istanbul ignore next */
|
|
1185
1255
|
onIgnoredError?.(error);
|
|
@@ -1191,21 +1261,20 @@ const createCustomPersister = (
|
|
|
1191
1261
|
},
|
|
1192
1262
|
startAutoSave: async () => {
|
|
1193
1263
|
await persister.stopAutoSave().save();
|
|
1194
|
-
|
|
1195
|
-
|
|
1196
|
-
|
|
1197
|
-
|
|
1198
|
-
|
|
1199
|
-
|
|
1200
|
-
},
|
|
1201
|
-
);
|
|
1264
|
+
autoSaveListenerId = store.addDidFinishTransactionListener(() => {
|
|
1265
|
+
const changes = getChanges();
|
|
1266
|
+
if (hasChanges(changes)) {
|
|
1267
|
+
persister.save(() => changes);
|
|
1268
|
+
}
|
|
1269
|
+
});
|
|
1202
1270
|
return persister;
|
|
1203
1271
|
},
|
|
1204
1272
|
stopAutoSave: () => {
|
|
1205
|
-
ifNotUndefined(
|
|
1206
|
-
|
|
1273
|
+
ifNotUndefined(autoSaveListenerId, store.delListener);
|
|
1274
|
+
autoSaveListenerId = void 0;
|
|
1207
1275
|
return persister;
|
|
1208
1276
|
},
|
|
1277
|
+
isAutoSaving: () => !isUndefined(autoSaveListenerId),
|
|
1209
1278
|
schedule: async (...actions) => {
|
|
1210
1279
|
arrayPush(mapGet(scheduleActions, scheduleId), ...actions);
|
|
1211
1280
|
await run();
|
|
@@ -1214,13 +1283,325 @@ const createCustomPersister = (
|
|
|
1214
1283
|
getStore: () => store,
|
|
1215
1284
|
destroy: () => persister.stopAutoLoad().stopAutoSave(),
|
|
1216
1285
|
getStats: () => ({loads, saves}),
|
|
1286
|
+
...extra,
|
|
1217
1287
|
};
|
|
1218
|
-
if (getThing) {
|
|
1219
|
-
persister[getThing] = () => thing;
|
|
1220
|
-
}
|
|
1221
1288
|
return objFreeze(persister);
|
|
1222
1289
|
};
|
|
1223
1290
|
|
|
1291
|
+
const textEncoder = new globalThis.TextEncoder();
|
|
1292
|
+
const getHash = (value) => {
|
|
1293
|
+
let hash = 2166136261;
|
|
1294
|
+
arrayForEach(textEncoder.encode(value), (char) => {
|
|
1295
|
+
hash ^= char;
|
|
1296
|
+
hash +=
|
|
1297
|
+
(hash << 1) + (hash << 4) + (hash << 7) + (hash << 8) + (hash << 24);
|
|
1298
|
+
});
|
|
1299
|
+
return hash >>> 0;
|
|
1300
|
+
};
|
|
1301
|
+
|
|
1302
|
+
const stampCloneWithHash = ([value, time, hash]) => [value, time, hash];
|
|
1303
|
+
const stampCloneWithoutHash = ([value, time]) => newStamp(value, time);
|
|
1304
|
+
const newStamp = (value, time) => (time ? [value, time] : [value]);
|
|
1305
|
+
const getStampHash = (stamp) => stamp[2];
|
|
1306
|
+
const hashIdAndHash = (id, hash) => getHash(id + ':' + hash);
|
|
1307
|
+
const replaceTimeHash = (oldTime, newTime) =>
|
|
1308
|
+
newTime > oldTime ? (oldTime ? getHash(oldTime) : 0) ^ getHash(newTime) : 0;
|
|
1309
|
+
const getLatestTime = (time1, time2) =>
|
|
1310
|
+
((time1 ?? '') > (time2 ?? '') ? time1 : time2) ?? '';
|
|
1311
|
+
const stampUpdate = (stamp, hash, time) => {
|
|
1312
|
+
stamp[2] = hash >>> 0;
|
|
1313
|
+
if (time > stamp[1]) {
|
|
1314
|
+
stamp[1] = time;
|
|
1315
|
+
}
|
|
1316
|
+
};
|
|
1317
|
+
const stampNewObj = (time = EMPTY_STRING) => newStamp(objNew(), time);
|
|
1318
|
+
const stampNewMap = (time = EMPTY_STRING) => [mapNew(), time, 0];
|
|
1319
|
+
const stampMapToObjWithHash = (
|
|
1320
|
+
[map, time, hash],
|
|
1321
|
+
mapper = stampCloneWithHash,
|
|
1322
|
+
) => [mapToObj(map, mapper), time, hash];
|
|
1323
|
+
const stampMapToObjWithoutHash = (
|
|
1324
|
+
[map, time],
|
|
1325
|
+
mapper = stampCloneWithoutHash,
|
|
1326
|
+
) => newStamp(mapToObj(map, mapper), time);
|
|
1327
|
+
const stampValidate = (stamp, validateThing) =>
|
|
1328
|
+
isArray(stamp) &&
|
|
1329
|
+
size(stamp) == 3 &&
|
|
1330
|
+
isString(stamp[1]) &&
|
|
1331
|
+
getTypeOf(stamp[2]) == NUMBER &&
|
|
1332
|
+
isFiniteNumber(stamp[2]) &&
|
|
1333
|
+
validateThing(stamp[0]);
|
|
1334
|
+
|
|
1335
|
+
const MASK6 = 63;
|
|
1336
|
+
const SHIFT36 = 2 ** 36;
|
|
1337
|
+
const SHIFT30 = 2 ** 30;
|
|
1338
|
+
const SHIFT24 = 2 ** 24;
|
|
1339
|
+
const SHIFT18 = 2 ** 18;
|
|
1340
|
+
const SHIFT12 = 2 ** 12;
|
|
1341
|
+
const SHIFT6 = 2 ** 6;
|
|
1342
|
+
const toB64 = (num) => String.fromCharCode(48 + (num & MASK6));
|
|
1343
|
+
const fromB64 = (str, pos) => strCharCodeAt(str, pos) - 48;
|
|
1344
|
+
const encodeHlc = (logicalTime42, counter24, clientHash30) =>
|
|
1345
|
+
toB64(logicalTime42 / SHIFT36) +
|
|
1346
|
+
toB64(logicalTime42 / SHIFT30) +
|
|
1347
|
+
toB64(logicalTime42 / SHIFT24) +
|
|
1348
|
+
toB64(logicalTime42 / SHIFT18) +
|
|
1349
|
+
toB64(logicalTime42 / SHIFT12) +
|
|
1350
|
+
toB64(logicalTime42 / SHIFT6) +
|
|
1351
|
+
toB64(logicalTime42) +
|
|
1352
|
+
toB64(counter24 / SHIFT18) +
|
|
1353
|
+
toB64(counter24 / SHIFT12) +
|
|
1354
|
+
toB64(counter24 / SHIFT6) +
|
|
1355
|
+
toB64(counter24) +
|
|
1356
|
+
toB64(clientHash30 / SHIFT24) +
|
|
1357
|
+
toB64(clientHash30 / SHIFT18) +
|
|
1358
|
+
toB64(clientHash30 / SHIFT12) +
|
|
1359
|
+
toB64(clientHash30 / SHIFT6) +
|
|
1360
|
+
toB64(clientHash30);
|
|
1361
|
+
const decodeHlc = (hlc16) => [
|
|
1362
|
+
fromB64(hlc16, 0) * SHIFT36 +
|
|
1363
|
+
fromB64(hlc16, 1) * SHIFT30 +
|
|
1364
|
+
fromB64(hlc16, 2) * SHIFT24 +
|
|
1365
|
+
fromB64(hlc16, 3) * SHIFT18 +
|
|
1366
|
+
fromB64(hlc16, 4) * SHIFT12 +
|
|
1367
|
+
fromB64(hlc16, 5) * SHIFT6 +
|
|
1368
|
+
fromB64(hlc16, 6),
|
|
1369
|
+
fromB64(hlc16, 7) * SHIFT18 +
|
|
1370
|
+
fromB64(hlc16, 8) * SHIFT12 +
|
|
1371
|
+
fromB64(hlc16, 9) * SHIFT6 +
|
|
1372
|
+
fromB64(hlc16, 10),
|
|
1373
|
+
fromB64(hlc16, 11) * SHIFT24 +
|
|
1374
|
+
fromB64(hlc16, 12) * SHIFT18 +
|
|
1375
|
+
fromB64(hlc16, 13) * SHIFT12 +
|
|
1376
|
+
fromB64(hlc16, 14) * SHIFT6 +
|
|
1377
|
+
fromB64(hlc16, 15),
|
|
1378
|
+
];
|
|
1379
|
+
const getHlcFunctions = (uniqueId) => {
|
|
1380
|
+
let logicalTime = 0;
|
|
1381
|
+
let lastCounter = -1;
|
|
1382
|
+
const uniqueIdHash = getHash(uniqueId);
|
|
1383
|
+
const getHlc = () => {
|
|
1384
|
+
seenHlc();
|
|
1385
|
+
return encodeHlc(logicalTime, ++lastCounter, uniqueIdHash);
|
|
1386
|
+
};
|
|
1387
|
+
const seenHlc = (hlc) => {
|
|
1388
|
+
const previousLogicalTime = logicalTime;
|
|
1389
|
+
const [remoteLogicalTime, remoteCounter] =
|
|
1390
|
+
isUndefined(hlc) || hlc == '' ? [0, 0] : decodeHlc(hlc);
|
|
1391
|
+
logicalTime = mathMax(
|
|
1392
|
+
previousLogicalTime,
|
|
1393
|
+
remoteLogicalTime,
|
|
1394
|
+
globalThis.HLC_TIME ?? Date.now(),
|
|
1395
|
+
);
|
|
1396
|
+
lastCounter =
|
|
1397
|
+
logicalTime == previousLogicalTime
|
|
1398
|
+
? logicalTime == remoteLogicalTime
|
|
1399
|
+
? mathMax(lastCounter, remoteCounter)
|
|
1400
|
+
: lastCounter
|
|
1401
|
+
: logicalTime == remoteLogicalTime
|
|
1402
|
+
? remoteCounter
|
|
1403
|
+
: -1;
|
|
1404
|
+
};
|
|
1405
|
+
return [getHlc, seenHlc];
|
|
1406
|
+
};
|
|
1407
|
+
|
|
1408
|
+
const RESPONSE = 0;
|
|
1409
|
+
const GET_CONTENT_HASHES = 1;
|
|
1410
|
+
const CONTENT_HASHES = 2;
|
|
1411
|
+
const CONTENT_DIFF = 3;
|
|
1412
|
+
const GET_TABLE_DIFF = 4;
|
|
1413
|
+
const GET_ROW_DIFF = 5;
|
|
1414
|
+
const GET_CELL_DIFF = 6;
|
|
1415
|
+
const GET_VALUE_DIFF = 7;
|
|
1416
|
+
const createCustomSynchronizer = (
|
|
1417
|
+
store,
|
|
1418
|
+
send,
|
|
1419
|
+
onReceive,
|
|
1420
|
+
destroyImpl,
|
|
1421
|
+
requestTimeoutSeconds,
|
|
1422
|
+
onIgnoredError,
|
|
1423
|
+
extra = {},
|
|
1424
|
+
) => {
|
|
1425
|
+
let persisterListener;
|
|
1426
|
+
let sends = 0;
|
|
1427
|
+
let receives = 0;
|
|
1428
|
+
const [getHlc] = getHlcFunctions(store.getId());
|
|
1429
|
+
const pendingRequests = mapNew();
|
|
1430
|
+
onReceive((fromClientId, requestId, messageType, messageBody) => {
|
|
1431
|
+
{
|
|
1432
|
+
receives++;
|
|
1433
|
+
}
|
|
1434
|
+
if (messageType == RESPONSE) {
|
|
1435
|
+
ifNotUndefined(
|
|
1436
|
+
mapGet(pendingRequests, requestId),
|
|
1437
|
+
([toClientId, handleResponse]) =>
|
|
1438
|
+
isUndefined(toClientId) || toClientId == fromClientId
|
|
1439
|
+
? handleResponse(messageBody, fromClientId)
|
|
1440
|
+
: /* istanbul ignore next */
|
|
1441
|
+
0,
|
|
1442
|
+
);
|
|
1443
|
+
} else if (messageType == CONTENT_HASHES && persister.isAutoLoading()) {
|
|
1444
|
+
getChangesFromOtherStore(fromClientId, messageBody).then((changes) => {
|
|
1445
|
+
persisterListener?.(void 0, () => changes);
|
|
1446
|
+
});
|
|
1447
|
+
} else if (messageType == CONTENT_DIFF && persister.isAutoLoading()) {
|
|
1448
|
+
persisterListener?.(void 0, () => messageBody);
|
|
1449
|
+
} else {
|
|
1450
|
+
ifNotUndefined(
|
|
1451
|
+
messageType == GET_CONTENT_HASHES && persister.isAutoSaving()
|
|
1452
|
+
? store.getMergeableContentHashes()
|
|
1453
|
+
: messageType == GET_TABLE_DIFF
|
|
1454
|
+
? store.getMergeableTableDiff(messageBody)
|
|
1455
|
+
: messageType == GET_ROW_DIFF
|
|
1456
|
+
? store.getMergeableRowDiff(messageBody)
|
|
1457
|
+
: messageType == GET_CELL_DIFF
|
|
1458
|
+
? store.getMergeableCellDiff(messageBody)
|
|
1459
|
+
: messageType == GET_VALUE_DIFF
|
|
1460
|
+
? store.getMergeableValueDiff(messageBody)
|
|
1461
|
+
: void 0,
|
|
1462
|
+
(response) => {
|
|
1463
|
+
{
|
|
1464
|
+
sends++;
|
|
1465
|
+
}
|
|
1466
|
+
send(fromClientId, requestId, RESPONSE, response);
|
|
1467
|
+
},
|
|
1468
|
+
);
|
|
1469
|
+
}
|
|
1470
|
+
});
|
|
1471
|
+
const request = async (toClientId, messageType, messageBody = EMPTY_STRING) =>
|
|
1472
|
+
promiseNew((resolve, reject) => {
|
|
1473
|
+
const requestId = getHlc();
|
|
1474
|
+
const timeout = setTimeout(() => {
|
|
1475
|
+
collDel(pendingRequests, requestId);
|
|
1476
|
+
reject(
|
|
1477
|
+
`No response from ${toClientId ?? 'anyone'} to '${messageType}'`,
|
|
1478
|
+
);
|
|
1479
|
+
}, requestTimeoutSeconds * 1e3);
|
|
1480
|
+
mapSet(pendingRequests, requestId, [
|
|
1481
|
+
toClientId,
|
|
1482
|
+
(response, fromClientId) => {
|
|
1483
|
+
clearTimeout(timeout);
|
|
1484
|
+
collDel(pendingRequests, requestId);
|
|
1485
|
+
resolve([response, fromClientId]);
|
|
1486
|
+
},
|
|
1487
|
+
]);
|
|
1488
|
+
{
|
|
1489
|
+
sends++;
|
|
1490
|
+
}
|
|
1491
|
+
send(toClientId, requestId, messageType, messageBody);
|
|
1492
|
+
});
|
|
1493
|
+
const mergeTablesStamps = (tablesStamp, [tableStamps2, tablesTime2]) => {
|
|
1494
|
+
objForEach(tableStamps2, ([rowStamps2, tableTime2], tableId) => {
|
|
1495
|
+
const tableStamp = objEnsure(tablesStamp[0], tableId, stampNewObj);
|
|
1496
|
+
objForEach(rowStamps2, ([cellStamps2, rowTime2], rowId) => {
|
|
1497
|
+
const rowStamp = objEnsure(tableStamp[0], rowId, stampNewObj);
|
|
1498
|
+
objForEach(
|
|
1499
|
+
cellStamps2,
|
|
1500
|
+
([cell2, cellTime2], cellId) =>
|
|
1501
|
+
(rowStamp[0][cellId] = newStamp(cell2, cellTime2)),
|
|
1502
|
+
);
|
|
1503
|
+
rowStamp[1] = getLatestTime(rowStamp[1], rowTime2);
|
|
1504
|
+
});
|
|
1505
|
+
tableStamp[1] = getLatestTime(tableStamp[1], tableTime2);
|
|
1506
|
+
});
|
|
1507
|
+
tablesStamp[1] = getLatestTime(tablesStamp[1], tablesTime2);
|
|
1508
|
+
};
|
|
1509
|
+
const getChangesFromOtherStore = async (
|
|
1510
|
+
otherClientId = null,
|
|
1511
|
+
otherContentHashes,
|
|
1512
|
+
) => {
|
|
1513
|
+
if (isUndefined(otherContentHashes)) {
|
|
1514
|
+
[otherContentHashes, otherClientId] = await request(
|
|
1515
|
+
otherClientId,
|
|
1516
|
+
GET_CONTENT_HASHES,
|
|
1517
|
+
);
|
|
1518
|
+
}
|
|
1519
|
+
const [otherTablesHash, otherValuesHash] = otherContentHashes;
|
|
1520
|
+
const [tablesHash, valuesHash] = store.getMergeableContentHashes();
|
|
1521
|
+
let tablesChanges = stampNewObj();
|
|
1522
|
+
if (tablesHash != otherTablesHash) {
|
|
1523
|
+
const [newTables, differentTableHashes] = (
|
|
1524
|
+
await request(
|
|
1525
|
+
otherClientId,
|
|
1526
|
+
GET_TABLE_DIFF,
|
|
1527
|
+
store.getMergeableTableHashes(),
|
|
1528
|
+
)
|
|
1529
|
+
)[0];
|
|
1530
|
+
tablesChanges = newTables;
|
|
1531
|
+
if (!objIsEmpty(differentTableHashes)) {
|
|
1532
|
+
const [newRows, differentRowHashes] = (
|
|
1533
|
+
await request(
|
|
1534
|
+
otherClientId,
|
|
1535
|
+
GET_ROW_DIFF,
|
|
1536
|
+
store.getMergeableRowHashes(differentTableHashes),
|
|
1537
|
+
)
|
|
1538
|
+
)[0];
|
|
1539
|
+
mergeTablesStamps(tablesChanges, newRows);
|
|
1540
|
+
if (!objIsEmpty(differentRowHashes)) {
|
|
1541
|
+
const newCells = (
|
|
1542
|
+
await request(
|
|
1543
|
+
otherClientId,
|
|
1544
|
+
GET_CELL_DIFF,
|
|
1545
|
+
store.getMergeableCellHashes(differentRowHashes),
|
|
1546
|
+
)
|
|
1547
|
+
)[0];
|
|
1548
|
+
mergeTablesStamps(tablesChanges, newCells);
|
|
1549
|
+
}
|
|
1550
|
+
}
|
|
1551
|
+
}
|
|
1552
|
+
return [
|
|
1553
|
+
tablesChanges,
|
|
1554
|
+
valuesHash == otherValuesHash
|
|
1555
|
+
? stampNewObj()
|
|
1556
|
+
: (
|
|
1557
|
+
await request(
|
|
1558
|
+
otherClientId,
|
|
1559
|
+
GET_VALUE_DIFF,
|
|
1560
|
+
store.getMergeableValuesHashes(),
|
|
1561
|
+
)
|
|
1562
|
+
)[0],
|
|
1563
|
+
1,
|
|
1564
|
+
];
|
|
1565
|
+
};
|
|
1566
|
+
const getPersisted = async () => {
|
|
1567
|
+
const changes = await getChangesFromOtherStore();
|
|
1568
|
+
return !objIsEmpty(changes[0][0]) || !objIsEmpty(changes[1][0])
|
|
1569
|
+
? changes
|
|
1570
|
+
: void 0;
|
|
1571
|
+
};
|
|
1572
|
+
const setPersisted = async (getContent, getChanges) => {
|
|
1573
|
+
{
|
|
1574
|
+
sends++;
|
|
1575
|
+
}
|
|
1576
|
+
if (getChanges) {
|
|
1577
|
+
send(null, null, CONTENT_DIFF, getChanges());
|
|
1578
|
+
} else {
|
|
1579
|
+
send(null, null, CONTENT_HASHES, store.getMergeableContentHashes());
|
|
1580
|
+
}
|
|
1581
|
+
};
|
|
1582
|
+
const addPersisterListener = (listener) => (persisterListener = listener);
|
|
1583
|
+
const delPersisterListener = () => (persisterListener = void 0);
|
|
1584
|
+
const startSync = async (initialContent) =>
|
|
1585
|
+
await (await persister.startAutoLoad(initialContent)).startAutoSave();
|
|
1586
|
+
const stopSync = () => persister.stopAutoLoad().stopAutoSave();
|
|
1587
|
+
const destroy = () => {
|
|
1588
|
+
destroyImpl();
|
|
1589
|
+
return persister.stopSync();
|
|
1590
|
+
};
|
|
1591
|
+
const getSynchronizerStats = () => ({sends, receives});
|
|
1592
|
+
const persister = createCustomPersister(
|
|
1593
|
+
store,
|
|
1594
|
+
getPersisted,
|
|
1595
|
+
setPersisted,
|
|
1596
|
+
addPersisterListener,
|
|
1597
|
+
delPersisterListener,
|
|
1598
|
+
onIgnoredError,
|
|
1599
|
+
true,
|
|
1600
|
+
{startSync, stopSync, destroy, getSynchronizerStats, ...extra},
|
|
1601
|
+
);
|
|
1602
|
+
return persister;
|
|
1603
|
+
};
|
|
1604
|
+
|
|
1224
1605
|
const createQueries = getCreateFunction((store) => {
|
|
1225
1606
|
const createStore = store.createStore;
|
|
1226
1607
|
const preStore = createStore();
|
|
@@ -1648,7 +2029,7 @@ const createQueries = getCreateFunction((store) => {
|
|
|
1648
2029
|
destroy,
|
|
1649
2030
|
getListenerStats,
|
|
1650
2031
|
};
|
|
1651
|
-
|
|
2032
|
+
objToArray(
|
|
1652
2033
|
{
|
|
1653
2034
|
[TABLE]: [1, 1],
|
|
1654
2035
|
[TABLE + CELL_IDS]: [0, 1],
|
|
@@ -1875,24 +2256,12 @@ const pairNewMap = () => [mapNew(), mapNew()];
|
|
|
1875
2256
|
const pairClone = (array) => [...array];
|
|
1876
2257
|
const pairIsEqual = ([entry1, entry2]) => entry1 === entry2;
|
|
1877
2258
|
|
|
1878
|
-
const
|
|
2259
|
+
const jsonStringWithMap = (obj) =>
|
|
1879
2260
|
JSON.stringify(obj, (_key, value) =>
|
|
1880
2261
|
isInstanceOf(value, Map) ? object.fromEntries([...value]) : value,
|
|
1881
2262
|
);
|
|
1882
2263
|
const jsonParse = JSON.parse;
|
|
1883
2264
|
|
|
1884
|
-
const validate = (obj, validateChild, onInvalidObj) => {
|
|
1885
|
-
if (isUndefined(obj) || !isObject(obj) || objIsEmpty(obj) || objFrozen(obj)) {
|
|
1886
|
-
onInvalidObj?.();
|
|
1887
|
-
return false;
|
|
1888
|
-
}
|
|
1889
|
-
objMap(obj, (child, id2) => {
|
|
1890
|
-
if (!validateChild(child, id2)) {
|
|
1891
|
-
objDel(obj, id2);
|
|
1892
|
-
}
|
|
1893
|
-
});
|
|
1894
|
-
return !objIsEmpty(obj);
|
|
1895
|
-
};
|
|
1896
2265
|
const idsChanged = (changedIds, id2, addedOrRemoved) =>
|
|
1897
2266
|
mapSet(
|
|
1898
2267
|
changedIds,
|
|
@@ -1902,11 +2271,10 @@ const idsChanged = (changedIds, id2, addedOrRemoved) =>
|
|
|
1902
2271
|
const createStore = () => {
|
|
1903
2272
|
let hasTablesSchema;
|
|
1904
2273
|
let hasValuesSchema;
|
|
1905
|
-
let cellsTouched = false;
|
|
1906
|
-
let valuesTouched = false;
|
|
1907
2274
|
let hadTables = false;
|
|
1908
2275
|
let hadValues = false;
|
|
1909
2276
|
let transactions = 0;
|
|
2277
|
+
let internalListeners = [];
|
|
1910
2278
|
const changedTableIds = mapNew();
|
|
1911
2279
|
const changedTableCellIds = mapNew();
|
|
1912
2280
|
const changedRowCount = mapNew();
|
|
@@ -1953,13 +2321,13 @@ const createStore = () => {
|
|
|
1953
2321
|
const [addListener, callListeners, delListenerImpl, callListenerImpl] =
|
|
1954
2322
|
getListenerFunctions(() => store);
|
|
1955
2323
|
const validateTablesSchema = (tableSchema) =>
|
|
1956
|
-
|
|
1957
|
-
|
|
2324
|
+
objValidate(tableSchema, (tableSchema2) =>
|
|
2325
|
+
objValidate(tableSchema2, validateCellOrValueSchema),
|
|
1958
2326
|
);
|
|
1959
2327
|
const validateValuesSchema = (valuesSchema) =>
|
|
1960
|
-
|
|
2328
|
+
objValidate(valuesSchema, validateCellOrValueSchema);
|
|
1961
2329
|
const validateCellOrValueSchema = (schema) => {
|
|
1962
|
-
if (!
|
|
2330
|
+
if (!objValidate(schema, (_child, id2) => arrayHas([TYPE, DEFAULT], id2))) {
|
|
1963
2331
|
return false;
|
|
1964
2332
|
}
|
|
1965
2333
|
const type = schema[TYPE];
|
|
@@ -1972,18 +2340,18 @@ const createStore = () => {
|
|
|
1972
2340
|
return true;
|
|
1973
2341
|
};
|
|
1974
2342
|
const validateTables = (tables) =>
|
|
1975
|
-
|
|
2343
|
+
objValidate(tables, validateTable, cellInvalid);
|
|
1976
2344
|
const validateTable = (table, tableId) =>
|
|
1977
2345
|
(!hasTablesSchema ||
|
|
1978
2346
|
collHas(tablesSchemaMap, tableId) ||
|
|
1979
2347
|
cellInvalid(tableId)) &&
|
|
1980
|
-
|
|
2348
|
+
objValidate(
|
|
1981
2349
|
table,
|
|
1982
2350
|
(row, rowId) => validateRow(tableId, rowId, row),
|
|
1983
2351
|
() => cellInvalid(tableId),
|
|
1984
2352
|
);
|
|
1985
2353
|
const validateRow = (tableId, rowId, row, skipDefaults) =>
|
|
1986
|
-
|
|
2354
|
+
objValidate(
|
|
1987
2355
|
skipDefaults ? row : addDefaultsToRow(row, tableId, rowId),
|
|
1988
2356
|
(cell, cellId) =>
|
|
1989
2357
|
ifNotUndefined(
|
|
@@ -2010,7 +2378,7 @@ const createStore = () => {
|
|
|
2010
2378
|
? cellInvalid(tableId, rowId, cellId, cell)
|
|
2011
2379
|
: cell;
|
|
2012
2380
|
const validateValues = (values, skipDefaults) =>
|
|
2013
|
-
|
|
2381
|
+
objValidate(
|
|
2014
2382
|
skipDefaults ? values : addDefaultsToValues(values),
|
|
2015
2383
|
(value, valueId) =>
|
|
2016
2384
|
ifNotUndefined(
|
|
@@ -2273,16 +2641,20 @@ const createStore = () => {
|
|
|
2273
2641
|
addedOrRemoved,
|
|
2274
2642
|
);
|
|
2275
2643
|
};
|
|
2276
|
-
const cellChanged = (tableId, rowId, cellId, oldCell, newCell) =>
|
|
2277
|
-
|
|
2644
|
+
const cellChanged = (tableId, rowId, cellId, oldCell, newCell) => {
|
|
2645
|
+
mapEnsure(
|
|
2278
2646
|
mapEnsure(mapEnsure(changedCells, tableId, mapNew), rowId, mapNew),
|
|
2279
2647
|
cellId,
|
|
2280
2648
|
() => [oldCell, 0],
|
|
2281
|
-
)[1] = newCell
|
|
2649
|
+
)[1] = newCell;
|
|
2650
|
+
internalListeners[3]?.(tableId, rowId, cellId, newCell);
|
|
2651
|
+
};
|
|
2282
2652
|
const valueIdsChanged = (valueId, addedOrRemoved) =>
|
|
2283
2653
|
idsChanged(changedValueIds, valueId, addedOrRemoved);
|
|
2284
|
-
const valueChanged = (valueId, oldValue, newValue) =>
|
|
2285
|
-
|
|
2654
|
+
const valueChanged = (valueId, oldValue, newValue) => {
|
|
2655
|
+
mapEnsure(changedValues, valueId, () => [oldValue, 0])[1] = newValue;
|
|
2656
|
+
internalListeners[4]?.(valueId, newValue);
|
|
2657
|
+
};
|
|
2286
2658
|
const cellInvalid = (tableId, rowId, cellId, invalidCell, defaultedCell) => {
|
|
2287
2659
|
arrayPush(
|
|
2288
2660
|
mapEnsure(
|
|
@@ -2548,44 +2920,6 @@ const createStore = () => {
|
|
|
2548
2920
|
transaction(() => actions(...arrayMap(args, id)));
|
|
2549
2921
|
return store;
|
|
2550
2922
|
};
|
|
2551
|
-
const getTransactionChanges = () => [
|
|
2552
|
-
mapToObj(
|
|
2553
|
-
changedCells,
|
|
2554
|
-
(table, tableId) =>
|
|
2555
|
-
mapGet(changedTableIds, tableId) === -1
|
|
2556
|
-
? null
|
|
2557
|
-
: mapToObj(
|
|
2558
|
-
table,
|
|
2559
|
-
(row, rowId) =>
|
|
2560
|
-
mapGet(mapGet(changedRowIds, tableId), rowId) === -1
|
|
2561
|
-
? null
|
|
2562
|
-
: mapToObj(
|
|
2563
|
-
row,
|
|
2564
|
-
([, newCell]) => newCell ?? null,
|
|
2565
|
-
(_, changedCell) => pairIsEqual(changedCell),
|
|
2566
|
-
),
|
|
2567
|
-
objIsEmpty,
|
|
2568
|
-
),
|
|
2569
|
-
objIsEmpty,
|
|
2570
|
-
),
|
|
2571
|
-
mapToObj(
|
|
2572
|
-
changedValues,
|
|
2573
|
-
([, newValue]) => newValue ?? null,
|
|
2574
|
-
(_, changedValue) => pairIsEqual(changedValue),
|
|
2575
|
-
),
|
|
2576
|
-
];
|
|
2577
|
-
const getTransactionLog = () => ({
|
|
2578
|
-
cellsTouched,
|
|
2579
|
-
valuesTouched,
|
|
2580
|
-
changedCells: mapToObj3(changedCells, pairClone, pairIsEqual),
|
|
2581
|
-
invalidCells: mapToObj3(invalidCells),
|
|
2582
|
-
changedValues: mapToObj(changedValues, pairClone, pairIsEqual),
|
|
2583
|
-
invalidValues: mapToObj(invalidValues),
|
|
2584
|
-
changedTableIds: mapToObj(changedTableIds),
|
|
2585
|
-
changedRowIds: mapToObj2(changedRowIds),
|
|
2586
|
-
changedCellIds: mapToObj3(changedCellIds),
|
|
2587
|
-
changedValueIds: mapToObj(changedValueIds),
|
|
2588
|
-
});
|
|
2589
2923
|
const getContent = () => [getTables(), getValues()];
|
|
2590
2924
|
const getTables = () => mapToObj3(tablesMap);
|
|
2591
2925
|
const getTableIds = () => mapKeys(tablesMap);
|
|
@@ -2629,12 +2963,13 @@ const createStore = () => {
|
|
|
2629
2963
|
collHas(mapGet(mapGet(tablesMap, id(tableId)), id(rowId)), id(cellId));
|
|
2630
2964
|
const hasValues = () => !collIsEmpty(valuesMap);
|
|
2631
2965
|
const hasValue = (valueId) => collHas(valuesMap, id(valueId));
|
|
2632
|
-
const getTablesJson = () =>
|
|
2633
|
-
const getValuesJson = () =>
|
|
2634
|
-
const getJson = () =>
|
|
2635
|
-
const getTablesSchemaJson = () =>
|
|
2636
|
-
const getValuesSchemaJson = () =>
|
|
2637
|
-
const getSchemaJson = () =>
|
|
2966
|
+
const getTablesJson = () => jsonStringWithMap(tablesMap);
|
|
2967
|
+
const getValuesJson = () => jsonStringWithMap(valuesMap);
|
|
2968
|
+
const getJson = () => jsonStringWithMap([tablesMap, valuesMap]);
|
|
2969
|
+
const getTablesSchemaJson = () => jsonStringWithMap(tablesSchemaMap);
|
|
2970
|
+
const getValuesSchemaJson = () => jsonStringWithMap(valuesSchemaMap);
|
|
2971
|
+
const getSchemaJson = () =>
|
|
2972
|
+
jsonStringWithMap([tablesSchemaMap, valuesSchemaMap]);
|
|
2638
2973
|
const setContent = ([tables, values]) =>
|
|
2639
2974
|
fluentTransaction(() => {
|
|
2640
2975
|
(objIsEmpty(tables) ? delTables : setTables)(tables);
|
|
@@ -2678,7 +3013,7 @@ const createStore = () => {
|
|
|
2678
3013
|
(tableId2, rowId2) => {
|
|
2679
3014
|
if (validateRow(tableId2, rowId2, partialRow, 1)) {
|
|
2680
3015
|
const table = getOrCreateTable(tableId2);
|
|
2681
|
-
|
|
3016
|
+
objToArray(partialRow, (cell, cellId) =>
|
|
2682
3017
|
setCellIntoDefaultRow(tableId2, table, rowId2, cellId, cell),
|
|
2683
3018
|
);
|
|
2684
3019
|
}
|
|
@@ -2716,7 +3051,7 @@ const createStore = () => {
|
|
|
2716
3051
|
const setPartialValues = (partialValues) =>
|
|
2717
3052
|
fluentTransaction(() =>
|
|
2718
3053
|
validateValues(partialValues, 1)
|
|
2719
|
-
?
|
|
3054
|
+
? objToArray(partialValues, (value, valueId) =>
|
|
2720
3055
|
setValidValue(valueId, value),
|
|
2721
3056
|
)
|
|
2722
3057
|
: 0,
|
|
@@ -2733,20 +3068,20 @@ const createStore = () => {
|
|
|
2733
3068
|
),
|
|
2734
3069
|
valueId,
|
|
2735
3070
|
);
|
|
2736
|
-
const
|
|
3071
|
+
const applyChanges = (changes) =>
|
|
2737
3072
|
fluentTransaction(() => {
|
|
2738
|
-
|
|
3073
|
+
objToArray(changes[0], (table, tableId) =>
|
|
2739
3074
|
isUndefined(table)
|
|
2740
3075
|
? delTable(tableId)
|
|
2741
|
-
:
|
|
3076
|
+
: objToArray(table, (row, rowId) =>
|
|
2742
3077
|
isUndefined(row)
|
|
2743
3078
|
? delRow(tableId, rowId)
|
|
2744
|
-
:
|
|
3079
|
+
: objToArray(row, (cell, cellId) =>
|
|
2745
3080
|
setOrDelCell(store, tableId, rowId, cellId, cell),
|
|
2746
3081
|
),
|
|
2747
3082
|
),
|
|
2748
3083
|
);
|
|
2749
|
-
|
|
3084
|
+
objToArray(changes[1], (value, valueId) =>
|
|
2750
3085
|
setOrDelValue(store, valueId, value),
|
|
2751
3086
|
);
|
|
2752
3087
|
});
|
|
@@ -2873,31 +3208,66 @@ const createStore = () => {
|
|
|
2873
3208
|
transactions++;
|
|
2874
3209
|
}
|
|
2875
3210
|
if (transactions == 1) {
|
|
2876
|
-
|
|
2877
|
-
|
|
2878
|
-
void 0,
|
|
2879
|
-
getTransactionChanges,
|
|
2880
|
-
getTransactionLog,
|
|
2881
|
-
);
|
|
3211
|
+
internalListeners[0]?.();
|
|
3212
|
+
callListeners(startTransactionListeners, void 0);
|
|
2882
3213
|
}
|
|
2883
3214
|
return store;
|
|
2884
3215
|
};
|
|
3216
|
+
const getTransactionChanges = () => [
|
|
3217
|
+
mapToObj(
|
|
3218
|
+
changedCells,
|
|
3219
|
+
(table, tableId) =>
|
|
3220
|
+
mapGet(changedTableIds, tableId) === -1
|
|
3221
|
+
? void 0
|
|
3222
|
+
: mapToObj(
|
|
3223
|
+
table,
|
|
3224
|
+
(row, rowId) =>
|
|
3225
|
+
mapGet(mapGet(changedRowIds, tableId), rowId) === -1
|
|
3226
|
+
? void 0
|
|
3227
|
+
: mapToObj(
|
|
3228
|
+
row,
|
|
3229
|
+
([, newCell]) => newCell,
|
|
3230
|
+
(changedCell) => pairIsEqual(changedCell),
|
|
3231
|
+
),
|
|
3232
|
+
collIsEmpty,
|
|
3233
|
+
objIsEmpty,
|
|
3234
|
+
),
|
|
3235
|
+
collIsEmpty,
|
|
3236
|
+
objIsEmpty,
|
|
3237
|
+
),
|
|
3238
|
+
mapToObj(
|
|
3239
|
+
changedValues,
|
|
3240
|
+
([, newValue]) => newValue,
|
|
3241
|
+
(changedValue) => pairIsEqual(changedValue),
|
|
3242
|
+
),
|
|
3243
|
+
1,
|
|
3244
|
+
];
|
|
3245
|
+
const getTransactionLog = () => [
|
|
3246
|
+
!collIsEmpty(changedCells),
|
|
3247
|
+
!collIsEmpty(changedValues),
|
|
3248
|
+
mapToObj3(changedCells, pairClone, pairIsEqual),
|
|
3249
|
+
mapToObj3(invalidCells),
|
|
3250
|
+
mapToObj(changedValues, pairClone, pairIsEqual),
|
|
3251
|
+
mapToObj(invalidValues),
|
|
3252
|
+
mapToObj(changedTableIds),
|
|
3253
|
+
mapToObj2(changedRowIds),
|
|
3254
|
+
mapToObj3(changedCellIds),
|
|
3255
|
+
mapToObj(changedValueIds),
|
|
3256
|
+
];
|
|
2885
3257
|
const finishTransaction = (doRollback) => {
|
|
2886
3258
|
if (transactions > 0) {
|
|
2887
3259
|
transactions--;
|
|
2888
3260
|
if (transactions == 0) {
|
|
2889
|
-
cellsTouched = !collIsEmpty(changedCells);
|
|
2890
|
-
valuesTouched = !collIsEmpty(changedValues);
|
|
2891
3261
|
transactions = 1;
|
|
2892
3262
|
callInvalidCellListeners(1);
|
|
2893
|
-
if (
|
|
3263
|
+
if (!collIsEmpty(changedCells)) {
|
|
2894
3264
|
callTabularListenersForChanges(1);
|
|
2895
3265
|
}
|
|
2896
3266
|
callInvalidValueListeners(1);
|
|
2897
|
-
if (
|
|
3267
|
+
if (!collIsEmpty(changedValues)) {
|
|
2898
3268
|
callValuesListenersForChanges(1);
|
|
2899
3269
|
}
|
|
2900
|
-
if (doRollback?.(
|
|
3270
|
+
if (doRollback?.(store)) {
|
|
2901
3271
|
collForEach(changedCells, (table, tableId) =>
|
|
2902
3272
|
collForEach(table, (row, rowId) =>
|
|
2903
3273
|
collForEach(row, ([oldCell], cellId) =>
|
|
@@ -2905,34 +3275,26 @@ const createStore = () => {
|
|
|
2905
3275
|
),
|
|
2906
3276
|
),
|
|
2907
3277
|
);
|
|
3278
|
+
collClear(changedCells);
|
|
2908
3279
|
collForEach(changedValues, ([oldValue], valueId) =>
|
|
2909
3280
|
setOrDelValue(store, valueId, oldValue),
|
|
2910
3281
|
);
|
|
2911
|
-
|
|
3282
|
+
collClear(changedValues);
|
|
2912
3283
|
}
|
|
2913
|
-
callListeners(
|
|
2914
|
-
finishTransactionListeners[0],
|
|
2915
|
-
void 0,
|
|
2916
|
-
getTransactionChanges,
|
|
2917
|
-
getTransactionLog,
|
|
2918
|
-
);
|
|
3284
|
+
callListeners(finishTransactionListeners[0], void 0);
|
|
2919
3285
|
transactions = -1;
|
|
2920
3286
|
callInvalidCellListeners(0);
|
|
2921
|
-
if (
|
|
3287
|
+
if (!collIsEmpty(changedCells)) {
|
|
2922
3288
|
callTabularListenersForChanges(0);
|
|
2923
3289
|
}
|
|
2924
3290
|
callInvalidValueListeners(0);
|
|
2925
|
-
if (
|
|
3291
|
+
if (!collIsEmpty(changedValues)) {
|
|
2926
3292
|
callValuesListenersForChanges(0);
|
|
2927
3293
|
}
|
|
2928
|
-
|
|
2929
|
-
|
|
2930
|
-
|
|
2931
|
-
getTransactionChanges,
|
|
2932
|
-
getTransactionLog,
|
|
2933
|
-
);
|
|
3294
|
+
internalListeners[1]?.();
|
|
3295
|
+
callListeners(finishTransactionListeners[1], void 0);
|
|
3296
|
+
internalListeners[2]?.();
|
|
2934
3297
|
transactions = 0;
|
|
2935
|
-
cellsTouched = valuesTouched = false;
|
|
2936
3298
|
hadTables = hasTables();
|
|
2937
3299
|
hadValues = hasValues();
|
|
2938
3300
|
arrayForEach(
|
|
@@ -3057,6 +3419,20 @@ const createStore = () => {
|
|
|
3057
3419
|
collSize2(startTransactionListeners) +
|
|
3058
3420
|
pairCollSize2(finishTransactionListeners),
|
|
3059
3421
|
});
|
|
3422
|
+
const setInternalListeners = (
|
|
3423
|
+
preStartTransaction,
|
|
3424
|
+
preFinishTransaction,
|
|
3425
|
+
postFinishTransaction,
|
|
3426
|
+
cellChanged2,
|
|
3427
|
+
valueChanged2,
|
|
3428
|
+
) =>
|
|
3429
|
+
(internalListeners = [
|
|
3430
|
+
preStartTransaction,
|
|
3431
|
+
preFinishTransaction,
|
|
3432
|
+
postFinishTransaction,
|
|
3433
|
+
cellChanged2,
|
|
3434
|
+
valueChanged2,
|
|
3435
|
+
]);
|
|
3060
3436
|
const store = {
|
|
3061
3437
|
getContent,
|
|
3062
3438
|
getTables,
|
|
@@ -3097,7 +3473,7 @@ const createStore = () => {
|
|
|
3097
3473
|
setValues,
|
|
3098
3474
|
setPartialValues,
|
|
3099
3475
|
setValue,
|
|
3100
|
-
|
|
3476
|
+
applyChanges,
|
|
3101
3477
|
setTablesJson,
|
|
3102
3478
|
setValuesJson,
|
|
3103
3479
|
setJson,
|
|
@@ -3115,6 +3491,8 @@ const createStore = () => {
|
|
|
3115
3491
|
delSchema,
|
|
3116
3492
|
transaction,
|
|
3117
3493
|
startTransaction,
|
|
3494
|
+
getTransactionChanges,
|
|
3495
|
+
getTransactionLog,
|
|
3118
3496
|
finishTransaction,
|
|
3119
3497
|
forEachTable,
|
|
3120
3498
|
forEachTableCell,
|
|
@@ -3132,8 +3510,9 @@ const createStore = () => {
|
|
|
3132
3510
|
createStore,
|
|
3133
3511
|
addListener,
|
|
3134
3512
|
callListeners,
|
|
3513
|
+
setInternalListeners,
|
|
3135
3514
|
};
|
|
3136
|
-
|
|
3515
|
+
objToArray(
|
|
3137
3516
|
{
|
|
3138
3517
|
[HAS + TABLES]: [0, hasTablesListeners, [], () => [hasTables()]],
|
|
3139
3518
|
[TABLES]: [0, tablesListeners],
|
|
@@ -3206,10 +3585,484 @@ const createStore = () => {
|
|
|
3206
3585
|
return objFreeze(store);
|
|
3207
3586
|
};
|
|
3208
3587
|
|
|
3588
|
+
const LISTENER_ARGS = {
|
|
3589
|
+
HasTable: 1,
|
|
3590
|
+
Table: 1,
|
|
3591
|
+
TableCellIds: 1,
|
|
3592
|
+
HasTableCell: 2,
|
|
3593
|
+
RowCount: 1,
|
|
3594
|
+
RowIds: 1,
|
|
3595
|
+
SortedRowIds: 5,
|
|
3596
|
+
HasRow: 2,
|
|
3597
|
+
Row: 2,
|
|
3598
|
+
CellIds: 2,
|
|
3599
|
+
HasCell: 3,
|
|
3600
|
+
Cell: 3,
|
|
3601
|
+
HasValue: 1,
|
|
3602
|
+
Value: 1,
|
|
3603
|
+
InvalidCell: 3,
|
|
3604
|
+
InvalidValue: 1,
|
|
3605
|
+
};
|
|
3606
|
+
const newContentStampMap = (time = EMPTY_STRING) => [
|
|
3607
|
+
stampNewMap(time),
|
|
3608
|
+
stampNewMap(time),
|
|
3609
|
+
];
|
|
3610
|
+
const validateMergeableContent = (mergeableContent) =>
|
|
3611
|
+
isArray(mergeableContent) &&
|
|
3612
|
+
size(mergeableContent) == 2 &&
|
|
3613
|
+
stampValidate(mergeableContent[0], (tableStamps) =>
|
|
3614
|
+
objValidate(
|
|
3615
|
+
tableStamps,
|
|
3616
|
+
(tableStamp) =>
|
|
3617
|
+
stampValidate(tableStamp, (rowStamps) =>
|
|
3618
|
+
objValidate(
|
|
3619
|
+
rowStamps,
|
|
3620
|
+
(rowStamp) =>
|
|
3621
|
+
stampValidate(rowStamp, (cellStamps) =>
|
|
3622
|
+
objValidate(
|
|
3623
|
+
cellStamps,
|
|
3624
|
+
(cellStamp) =>
|
|
3625
|
+
stampValidate(cellStamp, isCellOrValueOrNullOrUndefined),
|
|
3626
|
+
void 0,
|
|
3627
|
+
1,
|
|
3628
|
+
),
|
|
3629
|
+
),
|
|
3630
|
+
void 0,
|
|
3631
|
+
1,
|
|
3632
|
+
),
|
|
3633
|
+
),
|
|
3634
|
+
void 0,
|
|
3635
|
+
1,
|
|
3636
|
+
),
|
|
3637
|
+
) &&
|
|
3638
|
+
stampValidate(mergeableContent[1], (values) =>
|
|
3639
|
+
objValidate(
|
|
3640
|
+
values,
|
|
3641
|
+
(value) => stampValidate(value, isCellOrValueOrNullOrUndefined),
|
|
3642
|
+
void 0,
|
|
3643
|
+
1,
|
|
3644
|
+
),
|
|
3645
|
+
);
|
|
3646
|
+
const createMergeableStore = (id) => {
|
|
3647
|
+
let listeningToRawStoreChanges = 1;
|
|
3648
|
+
let contentStampMap = newContentStampMap();
|
|
3649
|
+
let defaultingContent = 0;
|
|
3650
|
+
const touchedCells = mapNew();
|
|
3651
|
+
const touchedValues = setNew();
|
|
3652
|
+
const [getHlc, seenHlc] = getHlcFunctions(id);
|
|
3653
|
+
const store = createStore();
|
|
3654
|
+
const disableListeningToRawStoreChanges = (actions) => {
|
|
3655
|
+
const wasListening = listeningToRawStoreChanges;
|
|
3656
|
+
listeningToRawStoreChanges = 0;
|
|
3657
|
+
actions();
|
|
3658
|
+
listeningToRawStoreChanges = wasListening;
|
|
3659
|
+
return mergeableStore;
|
|
3660
|
+
};
|
|
3661
|
+
const mergeContentOrChanges = (contentOrChanges, isContent = 0) => {
|
|
3662
|
+
const tablesChanges = {};
|
|
3663
|
+
const valuesChanges = {};
|
|
3664
|
+
const [
|
|
3665
|
+
[tablesObj, incomingTablesTime = EMPTY_STRING, incomingTablesHash = 0],
|
|
3666
|
+
values,
|
|
3667
|
+
] = contentOrChanges;
|
|
3668
|
+
const [tablesStampMap, valuesStampMap] = contentStampMap;
|
|
3669
|
+
const [tableStampMaps, oldTablesTime, oldTablesHash] = tablesStampMap;
|
|
3670
|
+
let tablesHash = isContent ? incomingTablesHash : oldTablesHash;
|
|
3671
|
+
let tablesTime = incomingTablesTime;
|
|
3672
|
+
objForEach(
|
|
3673
|
+
tablesObj,
|
|
3674
|
+
(
|
|
3675
|
+
[rowsObj, incomingTableTime = EMPTY_STRING, incomingTableHash = 0],
|
|
3676
|
+
tableId,
|
|
3677
|
+
) => {
|
|
3678
|
+
const tableStampMap = mapEnsure(tableStampMaps, tableId, stampNewMap);
|
|
3679
|
+
const [rowStampMaps, oldTableTime, oldTableHash] = tableStampMap;
|
|
3680
|
+
let tableHash = isContent ? incomingTableHash : oldTableHash;
|
|
3681
|
+
let tableTime = incomingTableTime;
|
|
3682
|
+
objForEach(rowsObj, (row, rowId) => {
|
|
3683
|
+
const [rowTime, oldRowHash, rowHash] = mergeCellsOrValues(
|
|
3684
|
+
row,
|
|
3685
|
+
mapEnsure(rowStampMaps, rowId, stampNewMap),
|
|
3686
|
+
objEnsure(objEnsure(tablesChanges, tableId, objNew), rowId, objNew),
|
|
3687
|
+
isContent,
|
|
3688
|
+
);
|
|
3689
|
+
tableHash ^= isContent
|
|
3690
|
+
? 0
|
|
3691
|
+
: (oldRowHash ? hashIdAndHash(rowId, oldRowHash) : 0) ^
|
|
3692
|
+
hashIdAndHash(rowId, rowHash);
|
|
3693
|
+
tableTime = getLatestTime(tableTime, rowTime);
|
|
3694
|
+
});
|
|
3695
|
+
tableHash ^= isContent
|
|
3696
|
+
? 0
|
|
3697
|
+
: replaceTimeHash(oldTableTime, incomingTableTime);
|
|
3698
|
+
stampUpdate(tableStampMap, tableHash, incomingTableTime);
|
|
3699
|
+
tablesHash ^= isContent
|
|
3700
|
+
? 0
|
|
3701
|
+
: (oldTableHash ? hashIdAndHash(tableId, oldTableHash) : 0) ^
|
|
3702
|
+
hashIdAndHash(tableId, tableStampMap[2]);
|
|
3703
|
+
tablesTime = getLatestTime(tablesTime, tableTime);
|
|
3704
|
+
},
|
|
3705
|
+
);
|
|
3706
|
+
tablesHash ^= isContent
|
|
3707
|
+
? 0
|
|
3708
|
+
: replaceTimeHash(oldTablesTime, incomingTablesTime);
|
|
3709
|
+
stampUpdate(tablesStampMap, tablesHash, incomingTablesTime);
|
|
3710
|
+
const [valuesTime] = mergeCellsOrValues(
|
|
3711
|
+
values,
|
|
3712
|
+
valuesStampMap,
|
|
3713
|
+
valuesChanges,
|
|
3714
|
+
isContent,
|
|
3715
|
+
);
|
|
3716
|
+
seenHlc(getLatestTime(tablesTime, valuesTime));
|
|
3717
|
+
return [tablesChanges, valuesChanges, 1];
|
|
3718
|
+
};
|
|
3719
|
+
const mergeCellsOrValues = (
|
|
3720
|
+
things,
|
|
3721
|
+
thingsStampMap,
|
|
3722
|
+
thingsChanges,
|
|
3723
|
+
isContent,
|
|
3724
|
+
) => {
|
|
3725
|
+
const [
|
|
3726
|
+
thingsObj,
|
|
3727
|
+
incomingThingsTime = EMPTY_STRING,
|
|
3728
|
+
incomingThingsHash = 0,
|
|
3729
|
+
] = things;
|
|
3730
|
+
const [thingStampMaps, oldThingsTime, oldThingsHash] = thingsStampMap;
|
|
3731
|
+
let thingsTime = incomingThingsTime;
|
|
3732
|
+
let thingsHash = isContent ? incomingThingsHash : oldThingsHash;
|
|
3733
|
+
objForEach(
|
|
3734
|
+
thingsObj,
|
|
3735
|
+
([thing, thingTime, incomingThingHash = 0], thingId) => {
|
|
3736
|
+
const thingStampMap = mapEnsure(thingStampMaps, thingId, () => [
|
|
3737
|
+
void 0,
|
|
3738
|
+
EMPTY_STRING,
|
|
3739
|
+
0,
|
|
3740
|
+
]);
|
|
3741
|
+
const [, oldThingTime, oldThingHash] = thingStampMap;
|
|
3742
|
+
if (!oldThingTime || thingTime > oldThingTime) {
|
|
3743
|
+
stampUpdate(
|
|
3744
|
+
thingStampMap,
|
|
3745
|
+
isContent
|
|
3746
|
+
? incomingThingHash
|
|
3747
|
+
: getHash(jsonStringWithMap(thing ?? null) + ':' + thingTime),
|
|
3748
|
+
thingTime,
|
|
3749
|
+
);
|
|
3750
|
+
thingStampMap[0] = thing;
|
|
3751
|
+
thingsChanges[thingId] = thing;
|
|
3752
|
+
thingsHash ^= isContent
|
|
3753
|
+
? 0
|
|
3754
|
+
: hashIdAndHash(thingId, oldThingHash) ^
|
|
3755
|
+
hashIdAndHash(thingId, thingStampMap[2]);
|
|
3756
|
+
thingsTime = getLatestTime(thingsTime, thingTime);
|
|
3757
|
+
}
|
|
3758
|
+
},
|
|
3759
|
+
);
|
|
3760
|
+
thingsHash ^= isContent
|
|
3761
|
+
? 0
|
|
3762
|
+
: replaceTimeHash(oldThingsTime, incomingThingsTime);
|
|
3763
|
+
stampUpdate(thingsStampMap, thingsHash, incomingThingsTime);
|
|
3764
|
+
return [thingsTime, oldThingsHash, thingsStampMap[2]];
|
|
3765
|
+
};
|
|
3766
|
+
const preStartTransaction = () => {};
|
|
3767
|
+
const preFinishTransaction = () => {};
|
|
3768
|
+
const postFinishTransaction = () => {
|
|
3769
|
+
collClear(touchedCells);
|
|
3770
|
+
collClear(touchedValues);
|
|
3771
|
+
};
|
|
3772
|
+
const cellChanged = (tableId, rowId, cellId, newCell) => {
|
|
3773
|
+
setAdd(
|
|
3774
|
+
mapEnsure(mapEnsure(touchedCells, tableId, mapNew), rowId, setNew),
|
|
3775
|
+
cellId,
|
|
3776
|
+
);
|
|
3777
|
+
if (listeningToRawStoreChanges) {
|
|
3778
|
+
mergeContentOrChanges([
|
|
3779
|
+
[
|
|
3780
|
+
{
|
|
3781
|
+
[tableId]: [
|
|
3782
|
+
{
|
|
3783
|
+
[rowId]: [
|
|
3784
|
+
{
|
|
3785
|
+
[cellId]: [
|
|
3786
|
+
newCell,
|
|
3787
|
+
defaultingContent ? EMPTY_STRING : getHlc(),
|
|
3788
|
+
],
|
|
3789
|
+
},
|
|
3790
|
+
],
|
|
3791
|
+
},
|
|
3792
|
+
],
|
|
3793
|
+
},
|
|
3794
|
+
],
|
|
3795
|
+
[{}],
|
|
3796
|
+
1,
|
|
3797
|
+
]);
|
|
3798
|
+
}
|
|
3799
|
+
};
|
|
3800
|
+
const valueChanged = (valueId, newValue) => {
|
|
3801
|
+
setAdd(touchedValues, valueId);
|
|
3802
|
+
if (listeningToRawStoreChanges) {
|
|
3803
|
+
mergeContentOrChanges([
|
|
3804
|
+
[{}],
|
|
3805
|
+
[{[valueId]: [newValue, defaultingContent ? EMPTY_STRING : getHlc()]}],
|
|
3806
|
+
1,
|
|
3807
|
+
]);
|
|
3808
|
+
}
|
|
3809
|
+
};
|
|
3810
|
+
const getId = () => id;
|
|
3811
|
+
const getMergeableContent = () => [
|
|
3812
|
+
stampMapToObjWithHash(contentStampMap[0], (tableStampMap) =>
|
|
3813
|
+
stampMapToObjWithHash(tableStampMap, (rowStampMap) =>
|
|
3814
|
+
stampMapToObjWithHash(rowStampMap),
|
|
3815
|
+
),
|
|
3816
|
+
),
|
|
3817
|
+
stampMapToObjWithHash(contentStampMap[1]),
|
|
3818
|
+
];
|
|
3819
|
+
const getMergeableContentHashes = () => [
|
|
3820
|
+
contentStampMap[0][2],
|
|
3821
|
+
contentStampMap[1][2],
|
|
3822
|
+
];
|
|
3823
|
+
const getMergeableTableHashes = () =>
|
|
3824
|
+
mapToObj(contentStampMap[0][0], getStampHash);
|
|
3825
|
+
const getMergeableTableDiff = (otherTableHashes) => {
|
|
3826
|
+
const newTables = stampNewObj(contentStampMap[0][1]);
|
|
3827
|
+
const differentTableHashes = {};
|
|
3828
|
+
mapForEach(
|
|
3829
|
+
contentStampMap[0][0],
|
|
3830
|
+
(tableId, [tableStampMap, tableTime, hash]) =>
|
|
3831
|
+
objHas(otherTableHashes, tableId)
|
|
3832
|
+
? hash != otherTableHashes[tableId]
|
|
3833
|
+
? (differentTableHashes[tableId] = hash)
|
|
3834
|
+
: 0
|
|
3835
|
+
: (newTables[0][tableId] = stampMapToObjWithoutHash(
|
|
3836
|
+
[tableStampMap, tableTime],
|
|
3837
|
+
(rowStampMap) => stampMapToObjWithoutHash(rowStampMap),
|
|
3838
|
+
)),
|
|
3839
|
+
);
|
|
3840
|
+
return [newTables, differentTableHashes];
|
|
3841
|
+
};
|
|
3842
|
+
const getMergeableRowHashes = (otherTableHashes) => {
|
|
3843
|
+
const rowHashes = {};
|
|
3844
|
+
objForEach(otherTableHashes, (otherTableHash, tableId) =>
|
|
3845
|
+
ifNotUndefined(
|
|
3846
|
+
mapGet(contentStampMap[0][0], tableId),
|
|
3847
|
+
([rowStampMaps, , tableHash]) =>
|
|
3848
|
+
tableHash != otherTableHash
|
|
3849
|
+
? mapForEach(
|
|
3850
|
+
rowStampMaps,
|
|
3851
|
+
(rowId, [, , rowHash]) =>
|
|
3852
|
+
(objEnsure(rowHashes, tableId, objNew)[rowId] = rowHash),
|
|
3853
|
+
)
|
|
3854
|
+
: 0,
|
|
3855
|
+
),
|
|
3856
|
+
);
|
|
3857
|
+
return rowHashes;
|
|
3858
|
+
};
|
|
3859
|
+
const getMergeableRowDiff = (otherTableRowHashes) => {
|
|
3860
|
+
const newRows = stampNewObj(contentStampMap[0][1]);
|
|
3861
|
+
const differentRowHashes = {};
|
|
3862
|
+
objForEach(otherTableRowHashes, (otherRowHashes, tableId) =>
|
|
3863
|
+
mapForEach(
|
|
3864
|
+
mapGet(contentStampMap[0][0], tableId)?.[0],
|
|
3865
|
+
(rowId, [rowStampMap, rowTime, hash]) =>
|
|
3866
|
+
objHas(otherRowHashes, rowId)
|
|
3867
|
+
? hash !== otherRowHashes[rowId]
|
|
3868
|
+
? (objEnsure(differentRowHashes, tableId, objNew)[rowId] = hash)
|
|
3869
|
+
: 0
|
|
3870
|
+
: (objEnsure(newRows[0], tableId, stampNewObj)[0][rowId] =
|
|
3871
|
+
stampMapToObjWithoutHash([rowStampMap, rowTime])),
|
|
3872
|
+
),
|
|
3873
|
+
);
|
|
3874
|
+
return [newRows, differentRowHashes];
|
|
3875
|
+
};
|
|
3876
|
+
const getMergeableCellHashes = (otherTableRowHashes) => {
|
|
3877
|
+
const cellHashes = {};
|
|
3878
|
+
objForEach(otherTableRowHashes, (otherRowHashes, tableId) =>
|
|
3879
|
+
ifNotUndefined(mapGet(contentStampMap[0][0], tableId), ([rowStampMaps]) =>
|
|
3880
|
+
objForEach(otherRowHashes, (otherRowHash, rowId) =>
|
|
3881
|
+
ifNotUndefined(
|
|
3882
|
+
mapGet(rowStampMaps, rowId),
|
|
3883
|
+
([cellStampMaps, , rowHash]) =>
|
|
3884
|
+
rowHash !== otherRowHash
|
|
3885
|
+
? mapForEach(
|
|
3886
|
+
cellStampMaps,
|
|
3887
|
+
(cellId, [, , cellHash]) =>
|
|
3888
|
+
(objEnsure(
|
|
3889
|
+
objEnsure(cellHashes, tableId, objNew),
|
|
3890
|
+
rowId,
|
|
3891
|
+
objNew,
|
|
3892
|
+
)[cellId] = cellHash),
|
|
3893
|
+
)
|
|
3894
|
+
: 0,
|
|
3895
|
+
),
|
|
3896
|
+
),
|
|
3897
|
+
),
|
|
3898
|
+
);
|
|
3899
|
+
return cellHashes;
|
|
3900
|
+
};
|
|
3901
|
+
const getMergeableCellDiff = (otherTableRowCellHashes) => {
|
|
3902
|
+
const [[tableStampMaps, tablesTime]] = contentStampMap;
|
|
3903
|
+
const tablesObj = {};
|
|
3904
|
+
objForEach(otherTableRowCellHashes, (otherRowCellHashes, tableId) =>
|
|
3905
|
+
objForEach(otherRowCellHashes, (otherCellHashes, rowId) =>
|
|
3906
|
+
ifNotUndefined(
|
|
3907
|
+
mapGet(tableStampMaps, tableId),
|
|
3908
|
+
([rowStampMaps, tableTime]) =>
|
|
3909
|
+
ifNotUndefined(
|
|
3910
|
+
mapGet(rowStampMaps, rowId),
|
|
3911
|
+
([cellStampMaps, rowTime]) =>
|
|
3912
|
+
mapForEach(cellStampMaps, (cellId, [cell, cellTime, hash]) =>
|
|
3913
|
+
hash !== otherCellHashes[cellId]
|
|
3914
|
+
? (objEnsure(
|
|
3915
|
+
objEnsure(tablesObj, tableId, () =>
|
|
3916
|
+
stampNewObj(tableTime),
|
|
3917
|
+
)[0],
|
|
3918
|
+
rowId,
|
|
3919
|
+
() => stampNewObj(rowTime),
|
|
3920
|
+
)[0][cellId] = [cell, cellTime])
|
|
3921
|
+
: 0,
|
|
3922
|
+
),
|
|
3923
|
+
),
|
|
3924
|
+
),
|
|
3925
|
+
),
|
|
3926
|
+
);
|
|
3927
|
+
return newStamp(tablesObj, tablesTime);
|
|
3928
|
+
};
|
|
3929
|
+
const getMergeableValuesHashes = () =>
|
|
3930
|
+
mapToObj(contentStampMap[1][0], getStampHash);
|
|
3931
|
+
const getMergeableValueDiff = (relativeTo) => {
|
|
3932
|
+
const [, [valueStampMaps, valuesTime]] = contentStampMap;
|
|
3933
|
+
const values = mapToObj(
|
|
3934
|
+
valueStampMaps,
|
|
3935
|
+
stampCloneWithoutHash,
|
|
3936
|
+
([, , hash], valueId) => hash == relativeTo?.[valueId],
|
|
3937
|
+
);
|
|
3938
|
+
return newStamp(values, valuesTime);
|
|
3939
|
+
};
|
|
3940
|
+
const setMergeableContent = (mergeableContent) =>
|
|
3941
|
+
disableListeningToRawStoreChanges(() =>
|
|
3942
|
+
validateMergeableContent(mergeableContent)
|
|
3943
|
+
? store.transaction(() => {
|
|
3944
|
+
store.delTables().delValues();
|
|
3945
|
+
contentStampMap = newContentStampMap();
|
|
3946
|
+
store.applyChanges(mergeContentOrChanges(mergeableContent, 1));
|
|
3947
|
+
})
|
|
3948
|
+
: 0,
|
|
3949
|
+
);
|
|
3950
|
+
const setDefaultContent = (content) => {
|
|
3951
|
+
store.transaction(() => {
|
|
3952
|
+
defaultingContent = 1;
|
|
3953
|
+
store.setContent(content);
|
|
3954
|
+
defaultingContent = 0;
|
|
3955
|
+
});
|
|
3956
|
+
return mergeableStore;
|
|
3957
|
+
};
|
|
3958
|
+
const getTransactionMergeableChanges = () => {
|
|
3959
|
+
const [[tableStampMaps, tablesTime], [valueStampMaps, valuesTime]] =
|
|
3960
|
+
contentStampMap;
|
|
3961
|
+
const tablesObj = {};
|
|
3962
|
+
collForEach(touchedCells, (touchedTable, tableId) =>
|
|
3963
|
+
ifNotUndefined(
|
|
3964
|
+
mapGet(tableStampMaps, tableId),
|
|
3965
|
+
([rowStampMaps, tableTime]) => {
|
|
3966
|
+
const tableObj = {};
|
|
3967
|
+
collForEach(touchedTable, (touchedRow, rowId) =>
|
|
3968
|
+
ifNotUndefined(
|
|
3969
|
+
mapGet(rowStampMaps, rowId),
|
|
3970
|
+
([cellStampMaps, rowTime]) => {
|
|
3971
|
+
const rowObj = {};
|
|
3972
|
+
collForEach(touchedRow, (cellId) => {
|
|
3973
|
+
ifNotUndefined(
|
|
3974
|
+
mapGet(cellStampMaps, cellId),
|
|
3975
|
+
([cell, time]) => (rowObj[cellId] = newStamp(cell, time)),
|
|
3976
|
+
);
|
|
3977
|
+
});
|
|
3978
|
+
tableObj[rowId] = newStamp(rowObj, rowTime);
|
|
3979
|
+
},
|
|
3980
|
+
),
|
|
3981
|
+
);
|
|
3982
|
+
tablesObj[tableId] = newStamp(tableObj, tableTime);
|
|
3983
|
+
},
|
|
3984
|
+
),
|
|
3985
|
+
);
|
|
3986
|
+
const valuesObj = {};
|
|
3987
|
+
collForEach(touchedValues, (valueId) =>
|
|
3988
|
+
ifNotUndefined(
|
|
3989
|
+
mapGet(valueStampMaps, valueId),
|
|
3990
|
+
([value, time]) => (valuesObj[valueId] = newStamp(value, time)),
|
|
3991
|
+
),
|
|
3992
|
+
);
|
|
3993
|
+
return [
|
|
3994
|
+
newStamp(tablesObj, tablesTime),
|
|
3995
|
+
newStamp(valuesObj, valuesTime),
|
|
3996
|
+
1,
|
|
3997
|
+
];
|
|
3998
|
+
};
|
|
3999
|
+
const applyMergeableChanges = (mergeableChanges) =>
|
|
4000
|
+
disableListeningToRawStoreChanges(() =>
|
|
4001
|
+
store.applyChanges(mergeContentOrChanges(mergeableChanges)),
|
|
4002
|
+
);
|
|
4003
|
+
const merge = (mergeableStore2) => {
|
|
4004
|
+
const mergeableChanges = getMergeableContent();
|
|
4005
|
+
const mergeableChanges2 = mergeableStore2.getMergeableContent();
|
|
4006
|
+
mergeableStore2.applyMergeableChanges(mergeableChanges);
|
|
4007
|
+
return applyMergeableChanges(mergeableChanges2);
|
|
4008
|
+
};
|
|
4009
|
+
const mergeableStore = {
|
|
4010
|
+
getId,
|
|
4011
|
+
getMergeableContent,
|
|
4012
|
+
getMergeableContentHashes,
|
|
4013
|
+
getMergeableTableHashes,
|
|
4014
|
+
getMergeableTableDiff,
|
|
4015
|
+
getMergeableRowHashes,
|
|
4016
|
+
getMergeableRowDiff,
|
|
4017
|
+
getMergeableCellHashes,
|
|
4018
|
+
getMergeableCellDiff,
|
|
4019
|
+
getMergeableValuesHashes,
|
|
4020
|
+
getMergeableValueDiff,
|
|
4021
|
+
setMergeableContent,
|
|
4022
|
+
setDefaultContent,
|
|
4023
|
+
getTransactionMergeableChanges,
|
|
4024
|
+
applyMergeableChanges,
|
|
4025
|
+
merge,
|
|
4026
|
+
};
|
|
4027
|
+
store.setInternalListeners(
|
|
4028
|
+
preStartTransaction,
|
|
4029
|
+
preFinishTransaction,
|
|
4030
|
+
postFinishTransaction,
|
|
4031
|
+
cellChanged,
|
|
4032
|
+
valueChanged,
|
|
4033
|
+
);
|
|
4034
|
+
objToArray(
|
|
4035
|
+
store,
|
|
4036
|
+
(method, name) =>
|
|
4037
|
+
(mergeableStore[name] = // fluent methods
|
|
4038
|
+
strStartsWith(name, 'set') ||
|
|
4039
|
+
strStartsWith(name, 'del') ||
|
|
4040
|
+
strStartsWith(name, 'apply') ||
|
|
4041
|
+
strEndsWith(name, 'Transaction') ||
|
|
4042
|
+
name == 'callListener'
|
|
4043
|
+
? (...args) => {
|
|
4044
|
+
method(...args);
|
|
4045
|
+
return mergeableStore;
|
|
4046
|
+
}
|
|
4047
|
+
: strStartsWith(name, 'add') && strEndsWith(name, 'Listener')
|
|
4048
|
+
? (...args) => {
|
|
4049
|
+
const listenerArg = LISTENER_ARGS[slice(name, 3, -8)] ?? 0;
|
|
4050
|
+
const listener = args[listenerArg];
|
|
4051
|
+
args[listenerArg] = (_store, ...args2) =>
|
|
4052
|
+
listener(mergeableStore, ...args2);
|
|
4053
|
+
return method(...args);
|
|
4054
|
+
}
|
|
4055
|
+
: method),
|
|
4056
|
+
);
|
|
4057
|
+
return objFreeze(mergeableStore);
|
|
4058
|
+
};
|
|
4059
|
+
|
|
3209
4060
|
export {
|
|
3210
4061
|
createCheckpoints,
|
|
3211
4062
|
createCustomPersister,
|
|
4063
|
+
createCustomSynchronizer,
|
|
3212
4064
|
createIndexes,
|
|
4065
|
+
createMergeableStore,
|
|
3213
4066
|
createMetrics,
|
|
3214
4067
|
createQueries,
|
|
3215
4068
|
createRelationships,
|