@multiplatform.one/frappe 6.1.0 → 6.3.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +38 -12
- package/dist/cjs/auth.cjs +1 -1
- package/dist/cjs/auth.native.js.map +1 -1
- package/dist/cjs/call.cjs +1 -1
- package/dist/cjs/call.native.js.map +1 -1
- package/dist/cjs/collection.cjs +18 -4
- package/dist/cjs/collection.native.js +18 -4
- package/dist/cjs/collection.native.js.map +1 -1
- package/dist/cjs/core/http.cjs +92 -9
- package/dist/cjs/core/http.native.js +96 -7
- package/dist/cjs/core/http.native.js.map +1 -1
- package/dist/cjs/db.cjs +7 -7
- package/dist/cjs/db.native.js +4 -4
- package/dist/cjs/db.native.js.map +1 -1
- package/dist/cjs/doctype.cjs +97 -39
- package/dist/cjs/doctype.native.js +116 -46
- package/dist/cjs/doctype.native.js.map +1 -1
- package/dist/cjs/file.cjs +1 -1
- package/dist/cjs/file.native.js.map +1 -1
- package/dist/cjs/fixtureDb.cjs +3 -2
- package/dist/cjs/fixtureDb.native.js +2 -1
- package/dist/cjs/fixtureDb.native.js.map +1 -1
- package/dist/cjs/frappeApp.cjs +15 -14
- package/dist/cjs/frappeApp.native.js +16 -14
- package/dist/cjs/frappeApp.native.js.map +1 -1
- package/dist/cjs/frappeReact.cjs +198 -18
- package/dist/cjs/frappeReact.native.js +241 -18
- package/dist/cjs/frappeReact.native.js.map +1 -1
- package/dist/cjs/index.cjs +9 -4
- package/dist/cjs/index.native.js +9 -4
- package/dist/cjs/index.native.js.map +1 -1
- package/dist/cjs/pacer.cjs +2 -2
- package/dist/cjs/pacer.native.js +2 -2
- package/dist/cjs/pacer.native.js.map +1 -1
- package/dist/cjs/realtime.cjs +186 -46
- package/dist/cjs/realtime.native.js +268 -48
- package/dist/cjs/realtime.native.js.map +1 -1
- package/dist/cjs/sync/backfill.cjs +32 -27
- package/dist/cjs/sync/backfill.native.js +49 -43
- package/dist/cjs/sync/backfill.native.js.map +1 -1
- package/dist/cjs/sync/index.cjs +90 -24
- package/dist/cjs/sync/index.native.js +112 -10
- package/dist/cjs/sync/index.native.js.map +1 -1
- package/dist/cjs/sync/merge.cjs +0 -3
- package/dist/cjs/sync/merge.native.js +0 -3
- package/dist/cjs/sync/merge.native.js.map +1 -1
- package/dist/cjs/sync/mutationEngine.cjs +25 -19
- package/dist/cjs/sync/mutationEngine.native.js +16 -13
- package/dist/cjs/sync/mutationEngine.native.js.map +1 -1
- package/dist/cjs/sync/mutationJournal.cjs +9 -4
- package/dist/cjs/sync/mutationJournal.native.js +7 -4
- package/dist/cjs/sync/mutationJournal.native.js.map +1 -1
- package/dist/cjs/sync/normalizedCache.cjs +7 -3
- package/dist/cjs/sync/normalizedCache.native.js +7 -2
- package/dist/cjs/sync/normalizedCache.native.js.map +1 -1
- package/dist/cjs/sync/persistence.cjs +63 -31
- package/dist/cjs/sync/persistence.native.js +120 -63
- package/dist/cjs/sync/persistence.native.js.map +1 -1
- package/dist/cjs/sync/realtime.cjs +124 -13
- package/dist/cjs/sync/realtime.native.js +163 -20
- package/dist/cjs/sync/realtime.native.js.map +1 -1
- package/dist/cjs/sync/rehydration.cjs +16 -10
- package/dist/cjs/sync/rehydration.native.js +16 -14
- package/dist/cjs/sync/rehydration.native.js.map +1 -1
- package/dist/cjs/sync/storage.cjs +3 -3
- package/dist/cjs/sync/storage.native.js +1 -1
- package/dist/cjs/sync/storage.native.js.map +1 -1
- package/dist/cjs/sync/subscriptionManager.cjs +255 -65
- package/dist/cjs/sync/subscriptionManager.native.js +330 -93
- package/dist/cjs/sync/subscriptionManager.native.js.map +1 -1
- package/dist/cjs/sync/types.cjs +2 -0
- package/dist/cjs/sync/types.native.js +2 -0
- package/dist/cjs/sync/types.native.js.map +1 -1
- package/dist/cjs/sync/virtualPageManager.cjs +9 -9
- package/dist/cjs/sync/virtualPageManager.native.js +5 -9
- package/dist/cjs/sync/virtualPageManager.native.js.map +1 -1
- package/dist/cjs/useLiveQuery.cjs +52 -0
- package/dist/cjs/useLiveQuery.native.js +59 -0
- package/dist/cjs/useLiveQuery.native.js.map +1 -0
- package/dist/cjs/util.cjs +11 -2
- package/dist/cjs/util.native.js +16 -2
- package/dist/cjs/util.native.js.map +1 -1
- package/dist/esm/auth.mjs +1 -1
- package/dist/esm/auth.mjs.map +1 -1
- package/dist/esm/auth.native.js.map +1 -1
- package/dist/esm/call.mjs +1 -1
- package/dist/esm/call.mjs.map +1 -1
- package/dist/esm/call.native.js.map +1 -1
- package/dist/esm/collection.mjs +18 -4
- package/dist/esm/collection.mjs.map +1 -1
- package/dist/esm/collection.native.js +18 -4
- package/dist/esm/collection.native.js.map +1 -1
- package/dist/esm/core/http.mjs +93 -10
- package/dist/esm/core/http.mjs.map +1 -1
- package/dist/esm/core/http.native.js +97 -8
- package/dist/esm/core/http.native.js.map +1 -1
- package/dist/esm/db.mjs +7 -7
- package/dist/esm/db.mjs.map +1 -1
- package/dist/esm/db.native.js +4 -4
- package/dist/esm/db.native.js.map +1 -1
- package/dist/esm/doctype.mjs +96 -39
- package/dist/esm/doctype.mjs.map +1 -1
- package/dist/esm/doctype.native.js +115 -46
- package/dist/esm/doctype.native.js.map +1 -1
- package/dist/esm/file.mjs +1 -1
- package/dist/esm/file.mjs.map +1 -1
- package/dist/esm/file.native.js.map +1 -1
- package/dist/esm/fixtureDb.mjs +3 -2
- package/dist/esm/fixtureDb.mjs.map +1 -1
- package/dist/esm/fixtureDb.native.js +2 -1
- package/dist/esm/fixtureDb.native.js.map +1 -1
- package/dist/esm/frappeApp.mjs +15 -14
- package/dist/esm/frappeApp.mjs.map +1 -1
- package/dist/esm/frappeApp.native.js +16 -14
- package/dist/esm/frappeApp.native.js.map +1 -1
- package/dist/esm/frappeReact.mjs +197 -19
- package/dist/esm/frappeReact.mjs.map +1 -1
- package/dist/esm/frappeReact.native.js +240 -19
- package/dist/esm/frappeReact.native.js.map +1 -1
- package/dist/esm/index.mjs +5 -4
- package/dist/esm/index.mjs.map +1 -1
- package/dist/esm/index.native.js +5 -4
- package/dist/esm/index.native.js.map +1 -1
- package/dist/esm/pacer.mjs +1 -1
- package/dist/esm/pacer.native.js +1 -1
- package/dist/esm/realtime.mjs +187 -47
- package/dist/esm/realtime.mjs.map +1 -1
- package/dist/esm/realtime.native.js +269 -49
- package/dist/esm/realtime.native.js.map +1 -1
- package/dist/esm/sync/backfill.mjs +32 -27
- package/dist/esm/sync/backfill.mjs.map +1 -1
- package/dist/esm/sync/backfill.native.js +49 -43
- package/dist/esm/sync/backfill.native.js.map +1 -1
- package/dist/esm/sync/index.mjs +90 -24
- package/dist/esm/sync/index.mjs.map +1 -1
- package/dist/esm/sync/index.native.js +112 -10
- package/dist/esm/sync/index.native.js.map +1 -1
- package/dist/esm/sync/merge.mjs +1 -1
- package/dist/esm/sync/merge.mjs.map +1 -1
- package/dist/esm/sync/merge.native.js +1 -1
- package/dist/esm/sync/merge.native.js.map +1 -1
- package/dist/esm/sync/mutationEngine.mjs +25 -19
- package/dist/esm/sync/mutationEngine.mjs.map +1 -1
- package/dist/esm/sync/mutationEngine.native.js +16 -13
- package/dist/esm/sync/mutationEngine.native.js.map +1 -1
- package/dist/esm/sync/mutationJournal.mjs +9 -4
- package/dist/esm/sync/mutationJournal.mjs.map +1 -1
- package/dist/esm/sync/mutationJournal.native.js +7 -4
- package/dist/esm/sync/mutationJournal.native.js.map +1 -1
- package/dist/esm/sync/normalizedCache.mjs +7 -3
- package/dist/esm/sync/normalizedCache.mjs.map +1 -1
- package/dist/esm/sync/normalizedCache.native.js +7 -2
- package/dist/esm/sync/normalizedCache.native.js.map +1 -1
- package/dist/esm/sync/persistence.mjs +64 -32
- package/dist/esm/sync/persistence.mjs.map +1 -1
- package/dist/esm/sync/persistence.native.js +121 -64
- package/dist/esm/sync/persistence.native.js.map +1 -1
- package/dist/esm/sync/realtime.mjs +124 -13
- package/dist/esm/sync/realtime.mjs.map +1 -1
- package/dist/esm/sync/realtime.native.js +163 -20
- package/dist/esm/sync/realtime.native.js.map +1 -1
- package/dist/esm/sync/rehydration.mjs +16 -10
- package/dist/esm/sync/rehydration.mjs.map +1 -1
- package/dist/esm/sync/rehydration.native.js +16 -14
- package/dist/esm/sync/rehydration.native.js.map +1 -1
- package/dist/esm/sync/storage.mjs +3 -3
- package/dist/esm/sync/storage.mjs.map +1 -1
- package/dist/esm/sync/storage.native.js +1 -1
- package/dist/esm/sync/storage.native.js.map +1 -1
- package/dist/esm/sync/subscriptionManager.mjs +255 -65
- package/dist/esm/sync/subscriptionManager.mjs.map +1 -1
- package/dist/esm/sync/subscriptionManager.native.js +330 -93
- package/dist/esm/sync/subscriptionManager.native.js.map +1 -1
- package/dist/esm/sync/types.mjs +2 -0
- package/dist/esm/sync/types.mjs.map +1 -1
- package/dist/esm/sync/types.native.js +2 -0
- package/dist/esm/sync/types.native.js.map +1 -1
- package/dist/esm/sync/virtualPageManager.mjs +9 -9
- package/dist/esm/sync/virtualPageManager.mjs.map +1 -1
- package/dist/esm/sync/virtualPageManager.native.js +5 -9
- package/dist/esm/sync/virtualPageManager.native.js.map +1 -1
- package/dist/esm/useLiveQuery.mjs +26 -0
- package/dist/esm/useLiveQuery.mjs.map +1 -0
- package/dist/esm/useLiveQuery.native.js +30 -0
- package/dist/esm/useLiveQuery.native.js.map +1 -0
- package/dist/esm/util.mjs +10 -2
- package/dist/esm/util.mjs.map +1 -1
- package/dist/esm/util.native.js +15 -2
- package/dist/esm/util.native.js.map +1 -1
- package/dist/jsx/auth.mjs +1 -1
- package/dist/jsx/auth.mjs.map +1 -1
- package/dist/jsx/auth.native.js.map +1 -1
- package/dist/jsx/call.mjs +1 -1
- package/dist/jsx/call.mjs.map +1 -1
- package/dist/jsx/call.native.js.map +1 -1
- package/dist/jsx/collection.mjs +18 -4
- package/dist/jsx/collection.mjs.map +1 -1
- package/dist/jsx/collection.native.js +18 -4
- package/dist/jsx/collection.native.js.map +1 -1
- package/dist/jsx/core/http.mjs +93 -10
- package/dist/jsx/core/http.mjs.map +1 -1
- package/dist/jsx/core/http.native.js +96 -7
- package/dist/jsx/core/http.native.js.map +1 -1
- package/dist/jsx/db.mjs +7 -7
- package/dist/jsx/db.mjs.map +1 -1
- package/dist/jsx/db.native.js +4 -4
- package/dist/jsx/db.native.js.map +1 -1
- package/dist/jsx/doctype.mjs +96 -39
- package/dist/jsx/doctype.mjs.map +1 -1
- package/dist/jsx/doctype.native.js +116 -46
- package/dist/jsx/doctype.native.js.map +1 -1
- package/dist/jsx/file.mjs +1 -1
- package/dist/jsx/file.mjs.map +1 -1
- package/dist/jsx/file.native.js.map +1 -1
- package/dist/jsx/fixtureDb.mjs +3 -2
- package/dist/jsx/fixtureDb.mjs.map +1 -1
- package/dist/jsx/fixtureDb.native.js +2 -1
- package/dist/jsx/fixtureDb.native.js.map +1 -1
- package/dist/jsx/frappeApp.mjs +15 -14
- package/dist/jsx/frappeApp.mjs.map +1 -1
- package/dist/jsx/frappeApp.native.js +16 -14
- package/dist/jsx/frappeApp.native.js.map +1 -1
- package/dist/jsx/frappeReact.mjs +197 -19
- package/dist/jsx/frappeReact.mjs.map +1 -1
- package/dist/jsx/frappeReact.native.js +241 -18
- package/dist/jsx/frappeReact.native.js.map +1 -1
- package/dist/jsx/index.js +5 -4
- package/dist/jsx/index.js.map +1 -1
- package/dist/jsx/index.mjs +5 -4
- package/dist/jsx/index.mjs.map +1 -1
- package/dist/jsx/index.native.js +9 -4
- package/dist/jsx/index.native.js.map +1 -1
- package/dist/jsx/pacer.mjs +1 -1
- package/dist/jsx/pacer.native.js +2 -2
- package/dist/jsx/pacer.native.js.map +1 -1
- package/dist/jsx/realtime.mjs +187 -47
- package/dist/jsx/realtime.mjs.map +1 -1
- package/dist/jsx/realtime.native.js +268 -48
- package/dist/jsx/realtime.native.js.map +1 -1
- package/dist/jsx/sync/backfill.mjs +32 -27
- package/dist/jsx/sync/backfill.mjs.map +1 -1
- package/dist/jsx/sync/backfill.native.js +49 -43
- package/dist/jsx/sync/backfill.native.js.map +1 -1
- package/dist/jsx/sync/index.mjs +90 -24
- package/dist/jsx/sync/index.mjs.map +1 -1
- package/dist/jsx/sync/index.native.js +112 -10
- package/dist/jsx/sync/index.native.js.map +1 -1
- package/dist/jsx/sync/merge.mjs +1 -1
- package/dist/jsx/sync/merge.mjs.map +1 -1
- package/dist/jsx/sync/merge.native.js +0 -3
- package/dist/jsx/sync/merge.native.js.map +1 -1
- package/dist/jsx/sync/mutationEngine.mjs +25 -19
- package/dist/jsx/sync/mutationEngine.mjs.map +1 -1
- package/dist/jsx/sync/mutationEngine.native.js +16 -13
- package/dist/jsx/sync/mutationEngine.native.js.map +1 -1
- package/dist/jsx/sync/mutationJournal.mjs +9 -4
- package/dist/jsx/sync/mutationJournal.mjs.map +1 -1
- package/dist/jsx/sync/mutationJournal.native.js +7 -4
- package/dist/jsx/sync/mutationJournal.native.js.map +1 -1
- package/dist/jsx/sync/normalizedCache.mjs +7 -3
- package/dist/jsx/sync/normalizedCache.mjs.map +1 -1
- package/dist/jsx/sync/normalizedCache.native.js +7 -2
- package/dist/jsx/sync/normalizedCache.native.js.map +1 -1
- package/dist/jsx/sync/persistence.mjs +64 -32
- package/dist/jsx/sync/persistence.mjs.map +1 -1
- package/dist/jsx/sync/persistence.native.js +120 -63
- package/dist/jsx/sync/persistence.native.js.map +1 -1
- package/dist/jsx/sync/realtime.mjs +124 -13
- package/dist/jsx/sync/realtime.mjs.map +1 -1
- package/dist/jsx/sync/realtime.native.js +163 -20
- package/dist/jsx/sync/realtime.native.js.map +1 -1
- package/dist/jsx/sync/rehydration.mjs +16 -10
- package/dist/jsx/sync/rehydration.mjs.map +1 -1
- package/dist/jsx/sync/rehydration.native.js +16 -14
- package/dist/jsx/sync/rehydration.native.js.map +1 -1
- package/dist/jsx/sync/storage.mjs +3 -3
- package/dist/jsx/sync/storage.mjs.map +1 -1
- package/dist/jsx/sync/storage.native.js +1 -1
- package/dist/jsx/sync/storage.native.js.map +1 -1
- package/dist/jsx/sync/subscriptionManager.mjs +255 -65
- package/dist/jsx/sync/subscriptionManager.mjs.map +1 -1
- package/dist/jsx/sync/subscriptionManager.native.js +330 -93
- package/dist/jsx/sync/subscriptionManager.native.js.map +1 -1
- package/dist/jsx/sync/types.mjs +2 -0
- package/dist/jsx/sync/types.mjs.map +1 -1
- package/dist/jsx/sync/types.native.js +2 -0
- package/dist/jsx/sync/types.native.js.map +1 -1
- package/dist/jsx/sync/virtualPageManager.mjs +9 -9
- package/dist/jsx/sync/virtualPageManager.mjs.map +1 -1
- package/dist/jsx/sync/virtualPageManager.native.js +5 -9
- package/dist/jsx/sync/virtualPageManager.native.js.map +1 -1
- package/dist/jsx/useLiveQuery.mjs +26 -0
- package/dist/jsx/useLiveQuery.mjs.map +1 -0
- package/dist/jsx/useLiveQuery.native.js +59 -0
- package/dist/jsx/useLiveQuery.native.js.map +1 -0
- package/dist/jsx/util.mjs +10 -2
- package/dist/jsx/util.mjs.map +1 -1
- package/dist/jsx/util.native.js +16 -2
- package/dist/jsx/util.native.js.map +1 -1
- package/package.json +20 -17
- package/src/auth.ts +5 -1
- package/src/call.ts +5 -1
- package/src/collection.spec.ts +55 -0
- package/src/collection.ts +33 -4
- package/src/core/http.spec.ts +66 -0
- package/src/core/http.ts +115 -9
- package/src/core/httpNative.spec.ts +234 -0
- package/src/core/types.ts +2 -0
- package/src/db.spec.ts +91 -51
- package/src/db.ts +27 -8
- package/src/doctype.spec.ts +247 -39
- package/src/doctype.ts +203 -53
- package/src/file.ts +5 -1
- package/src/fixtureDb.ts +13 -2
- package/src/frappeApp.ts +18 -19
- package/src/frappeReact.spec.ts +565 -1
- package/src/frappeReact.ts +445 -37
- package/src/frappeReactLiveQueryGc.spec.ts +320 -0
- package/src/frappeReactNative.spec.ts +65 -0
- package/src/index.ts +10 -9
- package/src/pacer.ts +1 -1
- package/src/realtime.spec.ts +464 -20
- package/src/realtime.ts +284 -46
- package/src/sync/backfill.spec.ts +43 -0
- package/src/sync/backfill.ts +59 -39
- package/src/sync/debug.spec.ts +36 -0
- package/src/sync/filterValidation.spec.ts +197 -0
- package/src/sync/index.ts +98 -7
- package/src/sync/merge.ts +3 -3
- package/src/sync/mutationEngine.spec.ts +36 -4
- package/src/sync/mutationEngine.ts +30 -11
- package/src/sync/mutationJournal.ts +18 -4
- package/src/sync/normalizedCache.spec.ts +102 -0
- package/src/sync/normalizedCache.ts +19 -3
- package/src/sync/offlineRestore.spec.ts +423 -0
- package/src/sync/persistence.spec.ts +39 -7
- package/src/sync/persistence.ts +90 -18
- package/src/sync/persistenceGjs.spec.ts +143 -0
- package/src/sync/persistenceNative.spec.ts +139 -0
- package/src/sync/realtime.spec.ts +18 -1
- package/src/sync/realtime.ts +161 -13
- package/src/sync/rehydration.ts +23 -5
- package/src/sync/storage.ts +5 -4
- package/src/sync/subscriptionManager.spec.ts +94 -0
- package/src/sync/subscriptionManager.ts +304 -82
- package/src/sync/syncModule.spec.ts +137 -0
- package/src/sync/types.ts +39 -0
- package/src/sync/virtualPageManager.ts +8 -4
- package/src/useLiveQuery.ts +58 -0
- package/src/util.spec.ts +35 -4
- package/src/util.ts +34 -7
- package/types/auth.d.ts +13 -0
- package/types/auth.d.ts.map +1 -0
- package/types/call.d.ts +10 -0
- package/types/call.d.ts.map +1 -0
- package/types/collection.d.ts +127 -0
- package/types/collection.d.ts.map +1 -0
- package/types/common/types.d.ts +35 -0
- package/types/common/types.d.ts.map +1 -0
- package/types/core/http.d.ts +86 -0
- package/types/core/http.d.ts.map +1 -0
- package/types/core/types.d.ts +74 -0
- package/types/core/types.d.ts.map +1 -0
- package/types/core/wire.d.ts +405 -0
- package/types/core/wire.d.ts.map +1 -0
- package/types/db.d.ts +244 -0
- package/types/db.d.ts.map +1 -0
- package/types/devtools/FrappeDevtoolsPanel.d.ts +7 -0
- package/types/devtools/FrappeDevtoolsPanel.d.ts.map +1 -0
- package/types/devtools/index.d.ts +4 -0
- package/types/devtools/index.d.ts.map +1 -0
- package/types/devtools/plugin.d.ts +9 -0
- package/types/devtools/plugin.d.ts.map +1 -0
- package/types/devtools/theme.d.ts +15 -0
- package/types/devtools/theme.d.ts.map +1 -0
- package/types/doctype.d.ts +256 -0
- package/types/doctype.d.ts.map +1 -0
- package/types/file.d.ts +15 -0
- package/types/file.d.ts.map +1 -0
- package/types/fixtureDb.d.ts +76 -0
- package/types/fixtureDb.d.ts.map +1 -0
- package/types/fixtures.d.ts +55 -0
- package/types/fixtures.d.ts.map +1 -0
- package/types/frappeApp.d.ts +45 -0
- package/types/frappeApp.d.ts.map +1 -0
- package/types/frappeReact.d.ts +270 -0
- package/types/frappeReact.d.ts.map +1 -0
- package/types/index.d.ts +44 -0
- package/types/index.d.ts.map +1 -0
- package/types/optimistic.d.ts +38 -0
- package/types/optimistic.d.ts.map +1 -0
- package/types/pacer.d.ts +193 -0
- package/types/pacer.d.ts.map +1 -0
- package/types/plugin/index.d.ts +11 -0
- package/types/plugin/index.d.ts.map +1 -0
- package/types/realtime.d.ts +121 -0
- package/types/realtime.d.ts.map +1 -0
- package/types/sync/backfill.d.ts +60 -0
- package/types/sync/backfill.d.ts.map +1 -0
- package/types/sync/filters.d.ts +101 -0
- package/types/sync/filters.d.ts.map +1 -0
- package/types/sync/index.d.ts +181 -0
- package/types/sync/index.d.ts.map +1 -0
- package/types/sync/merge.d.ts +59 -0
- package/types/sync/merge.d.ts.map +1 -0
- package/types/sync/mutationEngine.d.ts +117 -0
- package/types/sync/mutationEngine.d.ts.map +1 -0
- package/types/sync/mutationJournal.d.ts +60 -0
- package/types/sync/mutationJournal.d.ts.map +1 -0
- package/types/sync/normalizedCache.d.ts +59 -0
- package/types/sync/normalizedCache.d.ts.map +1 -0
- package/types/sync/persistence.d.ts +185 -0
- package/types/sync/persistence.d.ts.map +1 -0
- package/types/sync/realtime.d.ts +121 -0
- package/types/sync/realtime.d.ts.map +1 -0
- package/types/sync/rehydration.d.ts +109 -0
- package/types/sync/rehydration.d.ts.map +1 -0
- package/types/sync/storage.d.ts +65 -0
- package/types/sync/storage.d.ts.map +1 -0
- package/types/sync/subscriptionManager.d.ts +161 -0
- package/types/sync/subscriptionManager.d.ts.map +1 -0
- package/types/sync/types.d.ts +435 -0
- package/types/sync/types.d.ts.map +1 -0
- package/types/sync/virtualPageManager.d.ts +190 -0
- package/types/sync/virtualPageManager.d.ts.map +1 -0
- package/types/useLiveQuery.d.ts +16 -0
- package/types/useLiveQuery.d.ts.map +1 -0
- package/types/util.d.ts +24 -0
- package/types/util.d.ts.map +1 -0
- package/dist/cjs/auth.spec.cjs +0 -322
- package/dist/cjs/auth.spec.native.js +0 -329
- package/dist/cjs/auth.spec.native.js.map +0 -1
- package/dist/cjs/call.spec.cjs +0 -427
- package/dist/cjs/call.spec.native.js +0 -430
- package/dist/cjs/call.spec.native.js.map +0 -1
- package/dist/cjs/collection.spec.cjs +0 -186
- package/dist/cjs/collection.spec.native.js +0 -216
- package/dist/cjs/collection.spec.native.js.map +0 -1
- package/dist/cjs/common/types.spec.cjs +0 -266
- package/dist/cjs/common/types.spec.native.js +0 -271
- package/dist/cjs/common/types.spec.native.js.map +0 -1
- package/dist/cjs/core/http.spec.cjs +0 -1259
- package/dist/cjs/core/http.spec.native.js +0 -1401
- package/dist/cjs/core/http.spec.native.js.map +0 -1
- package/dist/cjs/core/wire.spec.cjs +0 -478
- package/dist/cjs/core/wire.spec.native.js +0 -482
- package/dist/cjs/core/wire.spec.native.js.map +0 -1
- package/dist/cjs/db.spec.cjs +0 -862
- package/dist/cjs/db.spec.native.js +0 -865
- package/dist/cjs/db.spec.native.js.map +0 -1
- package/dist/cjs/doctype.spec.cjs +0 -460
- package/dist/cjs/doctype.spec.native.js +0 -538
- package/dist/cjs/doctype.spec.native.js.map +0 -1
- package/dist/cjs/file.spec.cjs +0 -315
- package/dist/cjs/file.spec.native.js +0 -342
- package/dist/cjs/file.spec.native.js.map +0 -1
- package/dist/cjs/frappeApp.spec.cjs +0 -306
- package/dist/cjs/frappeApp.spec.native.js +0 -308
- package/dist/cjs/frappeApp.spec.native.js.map +0 -1
- package/dist/cjs/frappeReact.spec.cjs +0 -531
- package/dist/cjs/frappeReact.spec.native.js +0 -670
- package/dist/cjs/frappeReact.spec.native.js.map +0 -1
- package/dist/cjs/optimistic.spec.cjs +0 -11
- package/dist/cjs/optimistic.spec.native.js +0 -19
- package/dist/cjs/optimistic.spec.native.js.map +0 -1
- package/dist/cjs/pacer.spec.cjs +0 -470
- package/dist/cjs/pacer.spec.native.js +0 -537
- package/dist/cjs/pacer.spec.native.js.map +0 -1
- package/dist/cjs/realtime.spec.cjs +0 -326
- package/dist/cjs/realtime.spec.native.js +0 -392
- package/dist/cjs/realtime.spec.native.js.map +0 -1
- package/dist/cjs/sync/backfill.spec.cjs +0 -586
- package/dist/cjs/sync/backfill.spec.native.js +0 -712
- package/dist/cjs/sync/backfill.spec.native.js.map +0 -1
- package/dist/cjs/sync/debug.spec.cjs +0 -125
- package/dist/cjs/sync/debug.spec.native.js +0 -133
- package/dist/cjs/sync/debug.spec.native.js.map +0 -1
- package/dist/cjs/sync/filters.spec.cjs +0 -168
- package/dist/cjs/sync/filters.spec.native.js +0 -173
- package/dist/cjs/sync/filters.spec.native.js.map +0 -1
- package/dist/cjs/sync/merge.spec.cjs +0 -908
- package/dist/cjs/sync/merge.spec.native.js +0 -937
- package/dist/cjs/sync/merge.spec.native.js.map +0 -1
- package/dist/cjs/sync/multiOrderBy.spec.cjs +0 -165
- package/dist/cjs/sync/multiOrderBy.spec.native.js +0 -229
- package/dist/cjs/sync/multiOrderBy.spec.native.js.map +0 -1
- package/dist/cjs/sync/mutationEngine.spec.cjs +0 -1158
- package/dist/cjs/sync/mutationEngine.spec.native.js +0 -1173
- package/dist/cjs/sync/mutationEngine.spec.native.js.map +0 -1
- package/dist/cjs/sync/mutationJournal.spec.cjs +0 -330
- package/dist/cjs/sync/mutationJournal.spec.native.js +0 -333
- package/dist/cjs/sync/mutationJournal.spec.native.js.map +0 -1
- package/dist/cjs/sync/mutations.spec.cjs +0 -327
- package/dist/cjs/sync/mutations.spec.native.js +0 -330
- package/dist/cjs/sync/mutations.spec.native.js.map +0 -1
- package/dist/cjs/sync/normalizedCache.spec.cjs +0 -302
- package/dist/cjs/sync/normalizedCache.spec.native.js +0 -311
- package/dist/cjs/sync/normalizedCache.spec.native.js.map +0 -1
- package/dist/cjs/sync/persistence.spec.cjs +0 -562
- package/dist/cjs/sync/persistence.spec.native.js +0 -572
- package/dist/cjs/sync/persistence.spec.native.js.map +0 -1
- package/dist/cjs/sync/realtime.spec.cjs +0 -499
- package/dist/cjs/sync/realtime.spec.native.js +0 -512
- package/dist/cjs/sync/realtime.spec.native.js.map +0 -1
- package/dist/cjs/sync/rehydration.spec.cjs +0 -731
- package/dist/cjs/sync/rehydration.spec.native.js +0 -736
- package/dist/cjs/sync/rehydration.spec.native.js.map +0 -1
- package/dist/cjs/sync/storage.spec.cjs +0 -446
- package/dist/cjs/sync/storage.spec.native.js +0 -470
- package/dist/cjs/sync/storage.spec.native.js.map +0 -1
- package/dist/cjs/sync/subscriptionManager.spec.cjs +0 -1102
- package/dist/cjs/sync/subscriptionManager.spec.native.js +0 -1136
- package/dist/cjs/sync/subscriptionManager.spec.native.js.map +0 -1
- package/dist/cjs/sync/subscriptions.spec.cjs +0 -937
- package/dist/cjs/sync/subscriptions.spec.native.js +0 -969
- package/dist/cjs/sync/subscriptions.spec.native.js.map +0 -1
- package/dist/cjs/sync/syncModule.spec.cjs +0 -206
- package/dist/cjs/sync/syncModule.spec.native.js +0 -222
- package/dist/cjs/sync/syncModule.spec.native.js.map +0 -1
- package/dist/cjs/sync/types.spec.cjs +0 -246
- package/dist/cjs/sync/types.spec.native.js +0 -256
- package/dist/cjs/sync/types.spec.native.js.map +0 -1
- package/dist/cjs/sync/virtualPageManager.spec.cjs +0 -801
- package/dist/cjs/sync/virtualPageManager.spec.native.js +0 -873
- package/dist/cjs/sync/virtualPageManager.spec.native.js.map +0 -1
- package/dist/cjs/util.spec.cjs +0 -43
- package/dist/cjs/util.spec.native.js +0 -48
- package/dist/cjs/util.spec.native.js.map +0 -1
- package/dist/esm/auth.spec.mjs +0 -323
- package/dist/esm/auth.spec.mjs.map +0 -1
- package/dist/esm/auth.spec.native.js +0 -327
- package/dist/esm/auth.spec.native.js.map +0 -1
- package/dist/esm/call.spec.mjs +0 -428
- package/dist/esm/call.spec.mjs.map +0 -1
- package/dist/esm/call.spec.native.js +0 -428
- package/dist/esm/call.spec.native.js.map +0 -1
- package/dist/esm/collection.spec.mjs +0 -187
- package/dist/esm/collection.spec.mjs.map +0 -1
- package/dist/esm/collection.spec.native.js +0 -214
- package/dist/esm/collection.spec.native.js.map +0 -1
- package/dist/esm/common/types.spec.mjs +0 -267
- package/dist/esm/common/types.spec.mjs.map +0 -1
- package/dist/esm/common/types.spec.native.js +0 -269
- package/dist/esm/common/types.spec.native.js.map +0 -1
- package/dist/esm/core/http.spec.mjs +0 -1260
- package/dist/esm/core/http.spec.mjs.map +0 -1
- package/dist/esm/core/http.spec.native.js +0 -1399
- package/dist/esm/core/http.spec.native.js.map +0 -1
- package/dist/esm/core/wire.spec.mjs +0 -479
- package/dist/esm/core/wire.spec.mjs.map +0 -1
- package/dist/esm/core/wire.spec.native.js +0 -480
- package/dist/esm/core/wire.spec.native.js.map +0 -1
- package/dist/esm/db.spec.mjs +0 -863
- package/dist/esm/db.spec.mjs.map +0 -1
- package/dist/esm/db.spec.native.js +0 -863
- package/dist/esm/db.spec.native.js.map +0 -1
- package/dist/esm/doctype.spec.mjs +0 -461
- package/dist/esm/doctype.spec.mjs.map +0 -1
- package/dist/esm/doctype.spec.native.js +0 -536
- package/dist/esm/doctype.spec.native.js.map +0 -1
- package/dist/esm/file.spec.mjs +0 -316
- package/dist/esm/file.spec.mjs.map +0 -1
- package/dist/esm/file.spec.native.js +0 -340
- package/dist/esm/file.spec.native.js.map +0 -1
- package/dist/esm/frappeApp.spec.mjs +0 -307
- package/dist/esm/frappeApp.spec.mjs.map +0 -1
- package/dist/esm/frappeApp.spec.native.js +0 -306
- package/dist/esm/frappeApp.spec.native.js.map +0 -1
- package/dist/esm/frappeReact.spec.mjs +0 -532
- package/dist/esm/frappeReact.spec.mjs.map +0 -1
- package/dist/esm/frappeReact.spec.native.js +0 -668
- package/dist/esm/frappeReact.spec.native.js.map +0 -1
- package/dist/esm/optimistic.spec.mjs +0 -12
- package/dist/esm/optimistic.spec.mjs.map +0 -1
- package/dist/esm/optimistic.spec.native.js +0 -17
- package/dist/esm/optimistic.spec.native.js.map +0 -1
- package/dist/esm/pacer.spec.mjs +0 -447
- package/dist/esm/pacer.spec.mjs.map +0 -1
- package/dist/esm/pacer.spec.native.js +0 -511
- package/dist/esm/pacer.spec.native.js.map +0 -1
- package/dist/esm/realtime.spec.mjs +0 -327
- package/dist/esm/realtime.spec.mjs.map +0 -1
- package/dist/esm/realtime.spec.native.js +0 -390
- package/dist/esm/realtime.spec.native.js.map +0 -1
- package/dist/esm/sync/backfill.spec.mjs +0 -563
- package/dist/esm/sync/backfill.spec.mjs.map +0 -1
- package/dist/esm/sync/backfill.spec.native.js +0 -686
- package/dist/esm/sync/backfill.spec.native.js.map +0 -1
- package/dist/esm/sync/debug.spec.mjs +0 -102
- package/dist/esm/sync/debug.spec.mjs.map +0 -1
- package/dist/esm/sync/debug.spec.native.js +0 -107
- package/dist/esm/sync/debug.spec.native.js.map +0 -1
- package/dist/esm/sync/filters.spec.mjs +0 -169
- package/dist/esm/sync/filters.spec.mjs.map +0 -1
- package/dist/esm/sync/filters.spec.native.js +0 -171
- package/dist/esm/sync/filters.spec.native.js.map +0 -1
- package/dist/esm/sync/merge.spec.mjs +0 -909
- package/dist/esm/sync/merge.spec.mjs.map +0 -1
- package/dist/esm/sync/merge.spec.native.js +0 -935
- package/dist/esm/sync/merge.spec.native.js.map +0 -1
- package/dist/esm/sync/multiOrderBy.spec.mjs +0 -166
- package/dist/esm/sync/multiOrderBy.spec.mjs.map +0 -1
- package/dist/esm/sync/multiOrderBy.spec.native.js +0 -227
- package/dist/esm/sync/multiOrderBy.spec.native.js.map +0 -1
- package/dist/esm/sync/mutationEngine.spec.mjs +0 -1159
- package/dist/esm/sync/mutationEngine.spec.mjs.map +0 -1
- package/dist/esm/sync/mutationEngine.spec.native.js +0 -1171
- package/dist/esm/sync/mutationEngine.spec.native.js.map +0 -1
- package/dist/esm/sync/mutationJournal.spec.mjs +0 -331
- package/dist/esm/sync/mutationJournal.spec.mjs.map +0 -1
- package/dist/esm/sync/mutationJournal.spec.native.js +0 -331
- package/dist/esm/sync/mutationJournal.spec.native.js.map +0 -1
- package/dist/esm/sync/mutations.spec.mjs +0 -328
- package/dist/esm/sync/mutations.spec.mjs.map +0 -1
- package/dist/esm/sync/mutations.spec.native.js +0 -328
- package/dist/esm/sync/mutations.spec.native.js.map +0 -1
- package/dist/esm/sync/normalizedCache.spec.mjs +0 -303
- package/dist/esm/sync/normalizedCache.spec.mjs.map +0 -1
- package/dist/esm/sync/normalizedCache.spec.native.js +0 -309
- package/dist/esm/sync/normalizedCache.spec.native.js.map +0 -1
- package/dist/esm/sync/persistence.spec.mjs +0 -563
- package/dist/esm/sync/persistence.spec.mjs.map +0 -1
- package/dist/esm/sync/persistence.spec.native.js +0 -570
- package/dist/esm/sync/persistence.spec.native.js.map +0 -1
- package/dist/esm/sync/realtime.spec.mjs +0 -500
- package/dist/esm/sync/realtime.spec.mjs.map +0 -1
- package/dist/esm/sync/realtime.spec.native.js +0 -510
- package/dist/esm/sync/realtime.spec.native.js.map +0 -1
- package/dist/esm/sync/rehydration.spec.mjs +0 -732
- package/dist/esm/sync/rehydration.spec.mjs.map +0 -1
- package/dist/esm/sync/rehydration.spec.native.js +0 -734
- package/dist/esm/sync/rehydration.spec.native.js.map +0 -1
- package/dist/esm/sync/storage.spec.mjs +0 -423
- package/dist/esm/sync/storage.spec.mjs.map +0 -1
- package/dist/esm/sync/storage.spec.native.js +0 -444
- package/dist/esm/sync/storage.spec.native.js.map +0 -1
- package/dist/esm/sync/subscriptionManager.spec.mjs +0 -1079
- package/dist/esm/sync/subscriptionManager.spec.mjs.map +0 -1
- package/dist/esm/sync/subscriptionManager.spec.native.js +0 -1110
- package/dist/esm/sync/subscriptionManager.spec.native.js.map +0 -1
- package/dist/esm/sync/subscriptions.spec.mjs +0 -914
- package/dist/esm/sync/subscriptions.spec.mjs.map +0 -1
- package/dist/esm/sync/subscriptions.spec.native.js +0 -943
- package/dist/esm/sync/subscriptions.spec.native.js.map +0 -1
- package/dist/esm/sync/syncModule.spec.mjs +0 -207
- package/dist/esm/sync/syncModule.spec.mjs.map +0 -1
- package/dist/esm/sync/syncModule.spec.native.js +0 -220
- package/dist/esm/sync/syncModule.spec.native.js.map +0 -1
- package/dist/esm/sync/types.spec.mjs +0 -247
- package/dist/esm/sync/types.spec.mjs.map +0 -1
- package/dist/esm/sync/types.spec.native.js +0 -254
- package/dist/esm/sync/types.spec.native.js.map +0 -1
- package/dist/esm/sync/virtualPageManager.spec.mjs +0 -802
- package/dist/esm/sync/virtualPageManager.spec.mjs.map +0 -1
- package/dist/esm/sync/virtualPageManager.spec.native.js +0 -871
- package/dist/esm/sync/virtualPageManager.spec.native.js.map +0 -1
- package/dist/esm/util.spec.mjs +0 -20
- package/dist/esm/util.spec.mjs.map +0 -1
- package/dist/esm/util.spec.native.js +0 -22
- package/dist/esm/util.spec.native.js.map +0 -1
- package/dist/jsx/auth.spec.mjs +0 -323
- package/dist/jsx/auth.spec.mjs.map +0 -1
- package/dist/jsx/auth.spec.native.js +0 -329
- package/dist/jsx/auth.spec.native.js.map +0 -1
- package/dist/jsx/call.spec.mjs +0 -428
- package/dist/jsx/call.spec.mjs.map +0 -1
- package/dist/jsx/call.spec.native.js +0 -430
- package/dist/jsx/call.spec.native.js.map +0 -1
- package/dist/jsx/collection.spec.mjs +0 -187
- package/dist/jsx/collection.spec.mjs.map +0 -1
- package/dist/jsx/collection.spec.native.js +0 -216
- package/dist/jsx/collection.spec.native.js.map +0 -1
- package/dist/jsx/common/types.spec.mjs +0 -267
- package/dist/jsx/common/types.spec.mjs.map +0 -1
- package/dist/jsx/common/types.spec.native.js +0 -271
- package/dist/jsx/common/types.spec.native.js.map +0 -1
- package/dist/jsx/core/http.spec.mjs +0 -1260
- package/dist/jsx/core/http.spec.mjs.map +0 -1
- package/dist/jsx/core/http.spec.native.js +0 -1401
- package/dist/jsx/core/http.spec.native.js.map +0 -1
- package/dist/jsx/core/wire.spec.mjs +0 -479
- package/dist/jsx/core/wire.spec.mjs.map +0 -1
- package/dist/jsx/core/wire.spec.native.js +0 -482
- package/dist/jsx/core/wire.spec.native.js.map +0 -1
- package/dist/jsx/db.spec.mjs +0 -863
- package/dist/jsx/db.spec.mjs.map +0 -1
- package/dist/jsx/db.spec.native.js +0 -865
- package/dist/jsx/db.spec.native.js.map +0 -1
- package/dist/jsx/doctype.spec.mjs +0 -461
- package/dist/jsx/doctype.spec.mjs.map +0 -1
- package/dist/jsx/doctype.spec.native.js +0 -538
- package/dist/jsx/doctype.spec.native.js.map +0 -1
- package/dist/jsx/file.spec.mjs +0 -316
- package/dist/jsx/file.spec.mjs.map +0 -1
- package/dist/jsx/file.spec.native.js +0 -342
- package/dist/jsx/file.spec.native.js.map +0 -1
- package/dist/jsx/frappeApp.spec.mjs +0 -307
- package/dist/jsx/frappeApp.spec.mjs.map +0 -1
- package/dist/jsx/frappeApp.spec.native.js +0 -308
- package/dist/jsx/frappeApp.spec.native.js.map +0 -1
- package/dist/jsx/frappeReact.spec.mjs +0 -532
- package/dist/jsx/frappeReact.spec.mjs.map +0 -1
- package/dist/jsx/frappeReact.spec.native.js +0 -670
- package/dist/jsx/frappeReact.spec.native.js.map +0 -1
- package/dist/jsx/optimistic.spec.mjs +0 -12
- package/dist/jsx/optimistic.spec.mjs.map +0 -1
- package/dist/jsx/optimistic.spec.native.js +0 -19
- package/dist/jsx/optimistic.spec.native.js.map +0 -1
- package/dist/jsx/pacer.spec.mjs +0 -447
- package/dist/jsx/pacer.spec.mjs.map +0 -1
- package/dist/jsx/pacer.spec.native.js +0 -537
- package/dist/jsx/pacer.spec.native.js.map +0 -1
- package/dist/jsx/realtime.spec.mjs +0 -327
- package/dist/jsx/realtime.spec.mjs.map +0 -1
- package/dist/jsx/realtime.spec.native.js +0 -392
- package/dist/jsx/realtime.spec.native.js.map +0 -1
- package/dist/jsx/sync/backfill.spec.mjs +0 -563
- package/dist/jsx/sync/backfill.spec.mjs.map +0 -1
- package/dist/jsx/sync/backfill.spec.native.js +0 -712
- package/dist/jsx/sync/backfill.spec.native.js.map +0 -1
- package/dist/jsx/sync/debug.spec.mjs +0 -102
- package/dist/jsx/sync/debug.spec.mjs.map +0 -1
- package/dist/jsx/sync/debug.spec.native.js +0 -133
- package/dist/jsx/sync/debug.spec.native.js.map +0 -1
- package/dist/jsx/sync/filters.spec.mjs +0 -169
- package/dist/jsx/sync/filters.spec.mjs.map +0 -1
- package/dist/jsx/sync/filters.spec.native.js +0 -173
- package/dist/jsx/sync/filters.spec.native.js.map +0 -1
- package/dist/jsx/sync/merge.spec.mjs +0 -909
- package/dist/jsx/sync/merge.spec.mjs.map +0 -1
- package/dist/jsx/sync/merge.spec.native.js +0 -937
- package/dist/jsx/sync/merge.spec.native.js.map +0 -1
- package/dist/jsx/sync/multiOrderBy.spec.mjs +0 -166
- package/dist/jsx/sync/multiOrderBy.spec.mjs.map +0 -1
- package/dist/jsx/sync/multiOrderBy.spec.native.js +0 -229
- package/dist/jsx/sync/multiOrderBy.spec.native.js.map +0 -1
- package/dist/jsx/sync/mutationEngine.spec.mjs +0 -1159
- package/dist/jsx/sync/mutationEngine.spec.mjs.map +0 -1
- package/dist/jsx/sync/mutationEngine.spec.native.js +0 -1173
- package/dist/jsx/sync/mutationEngine.spec.native.js.map +0 -1
- package/dist/jsx/sync/mutationJournal.spec.mjs +0 -331
- package/dist/jsx/sync/mutationJournal.spec.mjs.map +0 -1
- package/dist/jsx/sync/mutationJournal.spec.native.js +0 -333
- package/dist/jsx/sync/mutationJournal.spec.native.js.map +0 -1
- package/dist/jsx/sync/mutations.spec.mjs +0 -328
- package/dist/jsx/sync/mutations.spec.mjs.map +0 -1
- package/dist/jsx/sync/mutations.spec.native.js +0 -330
- package/dist/jsx/sync/mutations.spec.native.js.map +0 -1
- package/dist/jsx/sync/normalizedCache.spec.mjs +0 -303
- package/dist/jsx/sync/normalizedCache.spec.mjs.map +0 -1
- package/dist/jsx/sync/normalizedCache.spec.native.js +0 -311
- package/dist/jsx/sync/normalizedCache.spec.native.js.map +0 -1
- package/dist/jsx/sync/persistence.spec.mjs +0 -563
- package/dist/jsx/sync/persistence.spec.mjs.map +0 -1
- package/dist/jsx/sync/persistence.spec.native.js +0 -572
- package/dist/jsx/sync/persistence.spec.native.js.map +0 -1
- package/dist/jsx/sync/realtime.spec.mjs +0 -500
- package/dist/jsx/sync/realtime.spec.mjs.map +0 -1
- package/dist/jsx/sync/realtime.spec.native.js +0 -512
- package/dist/jsx/sync/realtime.spec.native.js.map +0 -1
- package/dist/jsx/sync/rehydration.spec.mjs +0 -732
- package/dist/jsx/sync/rehydration.spec.mjs.map +0 -1
- package/dist/jsx/sync/rehydration.spec.native.js +0 -736
- package/dist/jsx/sync/rehydration.spec.native.js.map +0 -1
- package/dist/jsx/sync/storage.spec.mjs +0 -423
- package/dist/jsx/sync/storage.spec.mjs.map +0 -1
- package/dist/jsx/sync/storage.spec.native.js +0 -470
- package/dist/jsx/sync/storage.spec.native.js.map +0 -1
- package/dist/jsx/sync/subscriptionManager.spec.mjs +0 -1079
- package/dist/jsx/sync/subscriptionManager.spec.mjs.map +0 -1
- package/dist/jsx/sync/subscriptionManager.spec.native.js +0 -1136
- package/dist/jsx/sync/subscriptionManager.spec.native.js.map +0 -1
- package/dist/jsx/sync/subscriptions.spec.mjs +0 -914
- package/dist/jsx/sync/subscriptions.spec.mjs.map +0 -1
- package/dist/jsx/sync/subscriptions.spec.native.js +0 -969
- package/dist/jsx/sync/subscriptions.spec.native.js.map +0 -1
- package/dist/jsx/sync/syncModule.spec.mjs +0 -207
- package/dist/jsx/sync/syncModule.spec.mjs.map +0 -1
- package/dist/jsx/sync/syncModule.spec.native.js +0 -222
- package/dist/jsx/sync/syncModule.spec.native.js.map +0 -1
- package/dist/jsx/sync/types.spec.mjs +0 -247
- package/dist/jsx/sync/types.spec.mjs.map +0 -1
- package/dist/jsx/sync/types.spec.native.js +0 -256
- package/dist/jsx/sync/types.spec.native.js.map +0 -1
- package/dist/jsx/sync/virtualPageManager.spec.mjs +0 -802
- package/dist/jsx/sync/virtualPageManager.spec.mjs.map +0 -1
- package/dist/jsx/sync/virtualPageManager.spec.native.js +0 -873
- package/dist/jsx/sync/virtualPageManager.spec.native.js.map +0 -1
- package/dist/jsx/util.spec.mjs +0 -20
- package/dist/jsx/util.spec.mjs.map +0 -1
- package/dist/jsx/util.spec.native.js +0 -48
- package/dist/jsx/util.spec.native.js.map +0 -1
package/src/frappeReact.ts
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { isWindowDefined } from "@multiplatform.one/platform";
|
|
1
2
|
import type { Collection } from "@tanstack/db";
|
|
2
3
|
import { useCallback, useEffect, useRef, useState } from "react";
|
|
3
4
|
import { createFrappeCollection, type FrappeCollectionOptionsConfig } from "./collection";
|
|
@@ -26,9 +27,17 @@ export interface UseFrappeCollectionConfig {
|
|
|
26
27
|
useToken?: boolean;
|
|
27
28
|
token?: string | (() => string | Promise<string>);
|
|
28
29
|
type?: string;
|
|
30
|
+
/** Session id for Socket.IO cookie auth on Node / React Native */
|
|
31
|
+
sessionId?: string | (() => string | Promise<string>);
|
|
29
32
|
};
|
|
30
33
|
/** Sync options for the SyncModule */
|
|
31
34
|
syncOptions?: import("./sync/types").SyncOptions;
|
|
35
|
+
/**
|
|
36
|
+
* Extra Socket.IO client options merged over the defaults — e.g.
|
|
37
|
+
* `{ transports: ["polling", "websocket"] }` behind dev proxies that can't
|
|
38
|
+
* forward WebSocket upgrades (websocket-first would never connect there).
|
|
39
|
+
*/
|
|
40
|
+
socketOptions?: import("./realtime").RealtimeConfig["socketOptions"];
|
|
32
41
|
/** Fixture provider for testing (used by frappe-ui in development) */
|
|
33
42
|
fixtures?: import("./fixtures").FixtureProvider;
|
|
34
43
|
}
|
|
@@ -58,8 +67,11 @@ export function __getActiveSyncModule(): SyncModule | undefined {
|
|
|
58
67
|
* Fixture-mode SyncModules are keyed by the FixtureProvider instance so
|
|
59
68
|
* different fixture sets never share cached state (important in tests).
|
|
60
69
|
*
|
|
61
|
-
* Returns `undefined` during SSR (Node.js) because
|
|
62
|
-
*
|
|
70
|
+
* Returns `undefined` during SSR (Node.js) because a server render must not
|
|
71
|
+
* open sockets or share client caches. Every real client runtime constructs
|
|
72
|
+
* the module: web, React Native, and GJS/GNOME (isBrowser() covers all
|
|
73
|
+
* three; the engine's storage/BroadcastChannel/window usages are guarded
|
|
74
|
+
* per platform).
|
|
63
75
|
*/
|
|
64
76
|
function getSyncModule(config: UseFrappeCollectionConfig): SyncModule | undefined {
|
|
65
77
|
if (!isBrowser()) return undefined;
|
|
@@ -77,11 +89,20 @@ function getSyncModule(config: UseFrappeCollectionConfig): SyncModule | undefine
|
|
|
77
89
|
const key = config.baseURL;
|
|
78
90
|
let sync = syncModuleCache.get(key);
|
|
79
91
|
if (!sync) {
|
|
92
|
+
// The FIRST config for a baseURL wins for every later consumer (the
|
|
93
|
+
// module is shared) — surface what it was constructed with so a
|
|
94
|
+
// missing persistKey/cdcInterval is traceable to the winning mount.
|
|
95
|
+
console.debug(
|
|
96
|
+
`[frappe-sync] SyncModule created for ${key} ` +
|
|
97
|
+
`(persistKey=${config.syncOptions?.persistKey ?? "none"}, ` +
|
|
98
|
+
`cdcInterval=${config.syncOptions?.cdcInterval ?? "off"})`,
|
|
99
|
+
);
|
|
80
100
|
const authConfig: AuthConfig | undefined = config.auth
|
|
81
101
|
? {
|
|
82
102
|
useToken: config.auth.useToken,
|
|
83
103
|
token: config.auth.token,
|
|
84
104
|
type: config.auth.type as AuthConfig["type"],
|
|
105
|
+
sessionId: config.auth.sessionId,
|
|
85
106
|
}
|
|
86
107
|
: undefined;
|
|
87
108
|
const http = new HttpClient(config.baseURL, authConfig);
|
|
@@ -90,6 +111,7 @@ function getSyncModule(config: UseFrappeCollectionConfig): SyncModule | undefine
|
|
|
90
111
|
baseURL: config.baseURL,
|
|
91
112
|
socketPort: config.socketPort,
|
|
92
113
|
auth: authConfig,
|
|
114
|
+
socketOptions: config.socketOptions,
|
|
93
115
|
};
|
|
94
116
|
sync = new SyncModule(db, new RealtimeModule(realtimeConfig), config.syncOptions);
|
|
95
117
|
syncModuleCache.set(key, sync);
|
|
@@ -97,12 +119,280 @@ function getSyncModule(config: UseFrappeCollectionConfig): SyncModule | undefine
|
|
|
97
119
|
return sync;
|
|
98
120
|
}
|
|
99
121
|
|
|
122
|
+
// ---------------------------------------------------------------------------
|
|
123
|
+
// Shared collection cache
|
|
124
|
+
// ---------------------------------------------------------------------------
|
|
125
|
+
//
|
|
126
|
+
// One Collection per (SyncModule, doctype, options) so N consumers of the
|
|
127
|
+
// same subscription shape share one collection — one initial fetch, one
|
|
128
|
+
// SyncModule subscription, one realtime room — instead of N (e.g. the desk
|
|
129
|
+
// form page's FrappeForm + DeskFormSidebar both subscribing to the same doc).
|
|
130
|
+
//
|
|
131
|
+
// Entries are refcounted by mounted hook instances. When the last consumer
|
|
132
|
+
// unmounts, the entry is cleaned up after a short grace period (covers
|
|
133
|
+
// StrictMode remounts and quick route transitions). Because live queries
|
|
134
|
+
// subscribe to the collection OUTSIDE the hook refcount (synchronously during
|
|
135
|
+
// render, detaching asynchronously via TanStack DB's own GC), the grace GC
|
|
136
|
+
// additionally defers — keeping the entry cached — while
|
|
137
|
+
// `collection.subscriberCount > 0`, bounded by SHARED_COLLECTION_GC_FORCE_MS
|
|
138
|
+
// so leaked queries from never-committed renders can't pin the subscription
|
|
139
|
+
// forever. The outer WeakMap keys on the SyncModule instance, which
|
|
140
|
+
// `getSyncModule` already dedupes per baseURL (live) / per FixtureProvider
|
|
141
|
+
// (fixtures) — so fixture sets never share cached collections across tests,
|
|
142
|
+
// and the cache dies with its provider.
|
|
143
|
+
|
|
144
|
+
interface SharedCollectionEntry {
|
|
145
|
+
collection: Collection<any, string>;
|
|
146
|
+
refCount: number;
|
|
147
|
+
gcTimer: ReturnType<typeof setTimeout> | undefined;
|
|
148
|
+
/** While the hook refcount is 0 but live queries still subscribe to the
|
|
149
|
+
* collection, GC is deferred — until this wall-clock deadline, after which
|
|
150
|
+
* the entry is force-cleaned (leak guard for queries created by renders
|
|
151
|
+
* that never committed; see scheduleEntryGc). Reset on every retain. */
|
|
152
|
+
gcForceDeadline: number | undefined;
|
|
153
|
+
/** Per-consumer onSyncError handlers, fanned out from the one collection. */
|
|
154
|
+
errorHandlers: Set<(error: unknown) => void>;
|
|
155
|
+
/** Initial-sync failure. The entry HOLDS its error state while any consumer
|
|
156
|
+
* retains it: re-renders keep acquiring the same errored entry, so an
|
|
157
|
+
* error-in-state consumer cannot loop failing fetches (the retry storm that
|
|
158
|
+
* froze error/loading stories). The flag is replayed on retain so a
|
|
159
|
+
* consumer whose render raced the failure — or that mounts later while the
|
|
160
|
+
* error is held — still surfaces it. The entry is evicted when the LAST
|
|
161
|
+
* consumer releases it, so the next mount (an explicit Retry remount, per
|
|
162
|
+
* the consumer retry contract) is the one place a fresh sync attempt
|
|
163
|
+
* starts. */
|
|
164
|
+
hasSyncError: boolean;
|
|
165
|
+
lastSyncError: unknown;
|
|
166
|
+
cleaned: boolean;
|
|
167
|
+
}
|
|
168
|
+
|
|
169
|
+
const sharedCollectionCaches = new WeakMap<SyncModule, Map<string, SharedCollectionEntry>>();
|
|
170
|
+
|
|
171
|
+
/** Grace before an unreferenced entry is cleaned up (also the leak guard for
|
|
172
|
+
* entries created by renders that never committed). */
|
|
173
|
+
const SHARED_COLLECTION_GC_MS = 1_000;
|
|
174
|
+
|
|
175
|
+
/** How long an unreferenced entry may stay alive because live queries still
|
|
176
|
+
* subscribe to its collection, before GC stops deferring and force-cleans.
|
|
177
|
+
* Covers every legitimate straggler — an unmounted `useLiveQuery`'s detach
|
|
178
|
+
* runs through TanStack DB's own GC + requestIdleCallback (~1–2s), and a
|
|
179
|
+
* suspended tree that commits re-retains long before this — while still
|
|
180
|
+
* reclaiming collections pinned by leaked queries (a live query created by a
|
|
181
|
+
* render that never committed never receives a subscriber, and TanStack DB
|
|
182
|
+
* only arms a live query's own GC when a subscriber detaches). */
|
|
183
|
+
const SHARED_COLLECTION_GC_FORCE_MS = 30_000;
|
|
184
|
+
|
|
185
|
+
/** True when TanStack DB has torn this collection down (`cleanup()` ran and
|
|
186
|
+
* sync has not been restarted). Attached live queries are permanently broken
|
|
187
|
+
* at that point — TanStack transitions them to an error state they never
|
|
188
|
+
* leave — so consumers must be handed a FRESH collection instance. */
|
|
189
|
+
function collectionIsCleanedUp(collection: Collection<any, string>): boolean {
|
|
190
|
+
return (collection as { status?: string }).status === "cleaned-up";
|
|
191
|
+
}
|
|
192
|
+
|
|
193
|
+
/** Everything that changes what the underlying subscription fetches. */
|
|
194
|
+
function collectionOptionsKey(
|
|
195
|
+
doctype: string,
|
|
196
|
+
options?: Omit<FrappeCollectionOptionsConfig<any>, "sync">,
|
|
197
|
+
): string {
|
|
198
|
+
return [
|
|
199
|
+
doctype,
|
|
200
|
+
JSON.stringify(options?.fields),
|
|
201
|
+
JSON.stringify(options?.filters),
|
|
202
|
+
JSON.stringify(options?.orderBy),
|
|
203
|
+
String(options?.limit),
|
|
204
|
+
String(options?.id),
|
|
205
|
+
].join("|");
|
|
206
|
+
}
|
|
207
|
+
|
|
208
|
+
function scheduleEntryGc(
|
|
209
|
+
cache: Map<string, SharedCollectionEntry>,
|
|
210
|
+
key: string,
|
|
211
|
+
entry: SharedCollectionEntry,
|
|
212
|
+
): void {
|
|
213
|
+
if (entry.gcTimer) clearTimeout(entry.gcTimer);
|
|
214
|
+
entry.gcTimer = setTimeout(() => {
|
|
215
|
+
entry.gcTimer = undefined;
|
|
216
|
+
if (entry.refCount > 0 || entry.cleaned) return;
|
|
217
|
+
// The hook refcount doesn't cover live queries: `useLiveQuery` attaches
|
|
218
|
+
// to the collection synchronously during render (before the retain
|
|
219
|
+
// effect commits) and detaches asynchronously after unmount (TanStack
|
|
220
|
+
// DB's own GC + an idle callback). Calling cleanup() while any query is
|
|
221
|
+
// attached permanently errors it ("Source collection … was manually
|
|
222
|
+
// cleaned up while live query … depends on it") — and a query erroring
|
|
223
|
+
// while still loading never notifies React, wedging `isLoading` gates
|
|
224
|
+
// (the "Loading workspaces…" stick). Defer GC while subscribers remain;
|
|
225
|
+
// the entry stays cached so a remount reuses the SAME live collection.
|
|
226
|
+
const subscriberCount = (entry.collection as { subscriberCount?: number }).subscriberCount ?? 0;
|
|
227
|
+
if (subscriberCount > 0) {
|
|
228
|
+
entry.gcForceDeadline ??= Date.now() + SHARED_COLLECTION_GC_FORCE_MS;
|
|
229
|
+
if (Date.now() < entry.gcForceDeadline) {
|
|
230
|
+
scheduleEntryGc(cache, key, entry);
|
|
231
|
+
return;
|
|
232
|
+
}
|
|
233
|
+
// Past the deadline: a leaked query (created by a render that never
|
|
234
|
+
// committed — TanStack DB never GCs a live query that never had a
|
|
235
|
+
// subscriber) is pinning the sync subscription + realtime room.
|
|
236
|
+
// Force-clean; any consumer that appears later gets a fresh instance
|
|
237
|
+
// via the stale-entry paths in getOrCreateSharedCollection / the hook.
|
|
238
|
+
}
|
|
239
|
+
entry.cleaned = true;
|
|
240
|
+
entry.gcForceDeadline = undefined;
|
|
241
|
+
if (cache.get(key) === entry) cache.delete(key);
|
|
242
|
+
// Best-effort: Collection.cleanup() stops the sync (unsubscribes from the
|
|
243
|
+
// SyncModule, leaving the realtime room). A consumer that raced eviction
|
|
244
|
+
// still works — TanStack DB restarts a cleaned-up collection on next use.
|
|
245
|
+
Promise.resolve(entry.collection.cleanup?.()).catch(() => {});
|
|
246
|
+
}, SHARED_COLLECTION_GC_MS);
|
|
247
|
+
}
|
|
248
|
+
|
|
249
|
+
function getOrCreateSharedCollection<TDoc extends object & { name: string; doctype: string }>(
|
|
250
|
+
syncModule: SyncModule,
|
|
251
|
+
doctype: string,
|
|
252
|
+
options: Omit<FrappeCollectionOptionsConfig<TDoc>, "sync"> | undefined,
|
|
253
|
+
key: string,
|
|
254
|
+
): { cache: Map<string, SharedCollectionEntry>; entry: SharedCollectionEntry } {
|
|
255
|
+
let existingCache = sharedCollectionCaches.get(syncModule);
|
|
256
|
+
if (!existingCache) {
|
|
257
|
+
existingCache = new Map();
|
|
258
|
+
sharedCollectionCaches.set(syncModule, existingCache);
|
|
259
|
+
}
|
|
260
|
+
const cache = existingCache;
|
|
261
|
+
let entry = cache.get(key);
|
|
262
|
+
// A cached entry whose collection was cleaned up out-of-band (manual
|
|
263
|
+
// cleanup() call, TanStack DB's own idle GC) is stale: queries attached at
|
|
264
|
+
// cleanup time are permanently errored, so hand out a fresh instance.
|
|
265
|
+
if (entry && !entry.cleaned && collectionIsCleanedUp(entry.collection)) {
|
|
266
|
+
entry.cleaned = true;
|
|
267
|
+
if (entry.gcTimer) {
|
|
268
|
+
clearTimeout(entry.gcTimer);
|
|
269
|
+
entry.gcTimer = undefined;
|
|
270
|
+
}
|
|
271
|
+
}
|
|
272
|
+
if (!entry || entry.cleaned) {
|
|
273
|
+
const created: SharedCollectionEntry = {
|
|
274
|
+
collection: undefined as unknown as Collection<any, string>,
|
|
275
|
+
refCount: 0,
|
|
276
|
+
gcTimer: undefined,
|
|
277
|
+
gcForceDeadline: undefined,
|
|
278
|
+
errorHandlers: new Set(),
|
|
279
|
+
hasSyncError: false,
|
|
280
|
+
lastSyncError: undefined,
|
|
281
|
+
cleaned: false,
|
|
282
|
+
};
|
|
283
|
+
created.collection = createFrappeCollection<TDoc>(doctype, {
|
|
284
|
+
...options,
|
|
285
|
+
sync: syncModule,
|
|
286
|
+
onSyncError: (error) => {
|
|
287
|
+
created.hasSyncError = true;
|
|
288
|
+
created.lastSyncError = error;
|
|
289
|
+
// Do NOT evict here. The error handlers below typically setState in
|
|
290
|
+
// consumers → re-render → render-time acquire; evicting now would
|
|
291
|
+
// hand that very re-render a fresh entry with a fresh failing sync,
|
|
292
|
+
// looping fetch → error → re-render forever (the retry storm — it
|
|
293
|
+
// OOM'd vitest workers and froze storybook renderers). The errored
|
|
294
|
+
// entry stays cached and shared so mounted consumers reach a stable
|
|
295
|
+
// fixpoint; releaseSharedCollection evicts it when the last holder
|
|
296
|
+
// unmounts, giving the NEXT mount (an explicit Retry) one fresh
|
|
297
|
+
// attempt.
|
|
298
|
+
for (const handler of created.errorHandlers) handler(error);
|
|
299
|
+
},
|
|
300
|
+
});
|
|
301
|
+
cache.set(key, created);
|
|
302
|
+
// Provisional GC: if no consumer ever retains this entry (the creating
|
|
303
|
+
// render was discarded), it must not leak a live subscription.
|
|
304
|
+
scheduleEntryGc(cache, key, created);
|
|
305
|
+
entry = created;
|
|
306
|
+
}
|
|
307
|
+
return { cache, entry };
|
|
308
|
+
}
|
|
309
|
+
|
|
310
|
+
function retainSharedCollection(
|
|
311
|
+
entry: SharedCollectionEntry,
|
|
312
|
+
onSyncError: (error: unknown) => void,
|
|
313
|
+
): void {
|
|
314
|
+
entry.refCount++;
|
|
315
|
+
if (entry.gcTimer) {
|
|
316
|
+
clearTimeout(entry.gcTimer);
|
|
317
|
+
entry.gcTimer = undefined;
|
|
318
|
+
}
|
|
319
|
+
entry.gcForceDeadline = undefined;
|
|
320
|
+
entry.errorHandlers.add(onSyncError);
|
|
321
|
+
if (entry.hasSyncError) onSyncError(entry.lastSyncError);
|
|
322
|
+
}
|
|
323
|
+
|
|
324
|
+
function releaseSharedCollection(
|
|
325
|
+
cache: Map<string, SharedCollectionEntry>,
|
|
326
|
+
key: string,
|
|
327
|
+
entry: SharedCollectionEntry,
|
|
328
|
+
onSyncError: (error: unknown) => void,
|
|
329
|
+
): void {
|
|
330
|
+
entry.errorHandlers.delete(onSyncError);
|
|
331
|
+
entry.refCount = Math.max(0, entry.refCount - 1);
|
|
332
|
+
if (entry.refCount > 0 || entry.cleaned) return;
|
|
333
|
+
if (entry.hasSyncError) {
|
|
334
|
+
// Last holder of an errored entry released: evict + mark cleaned NOW (no
|
|
335
|
+
// grace) so the next mount starts a fresh sync attempt. This is what
|
|
336
|
+
// makes a consumer's Retry-by-remount contract work — the remounting
|
|
337
|
+
// body's effect finds this entry `cleaned`, bumps, and acquires a fresh
|
|
338
|
+
// one. A grace period here would hand the retry the same stale error
|
|
339
|
+
// back. The underlying collection is cleaned up once its live queries
|
|
340
|
+
// detach (an immediate cleanup() would hard-error queries created in the
|
|
341
|
+
// same commit — unmount ordering runs this release before useLiveQuery's
|
|
342
|
+
// own detach).
|
|
343
|
+
entry.cleaned = true;
|
|
344
|
+
if (entry.gcTimer) {
|
|
345
|
+
clearTimeout(entry.gcTimer);
|
|
346
|
+
entry.gcTimer = undefined;
|
|
347
|
+
}
|
|
348
|
+
entry.gcForceDeadline = undefined;
|
|
349
|
+
if (cache.get(key) === entry) cache.delete(key);
|
|
350
|
+
cleanupEntryCollectionWhenIdle(entry);
|
|
351
|
+
return;
|
|
352
|
+
}
|
|
353
|
+
scheduleEntryGc(cache, key, entry);
|
|
354
|
+
}
|
|
355
|
+
|
|
100
356
|
/**
|
|
101
|
-
*
|
|
357
|
+
* Cleans up an already-evicted entry's collection once no live queries are
|
|
358
|
+
* attached — polling on the GC cadence, bounded by the force window (leaked
|
|
359
|
+
* queries from never-committed renders would otherwise pin the sync
|
|
360
|
+
* subscription forever). The entry must already be marked `cleaned` and
|
|
361
|
+
* removed from the cache: nothing re-acquires it, so the only remaining
|
|
362
|
+
* subscribers are queries mid-detach.
|
|
363
|
+
*/
|
|
364
|
+
function cleanupEntryCollectionWhenIdle(entry: SharedCollectionEntry): void {
|
|
365
|
+
const deadline = Date.now() + SHARED_COLLECTION_GC_FORCE_MS;
|
|
366
|
+
const tick = () => {
|
|
367
|
+
entry.gcTimer = undefined;
|
|
368
|
+
const subscriberCount = (entry.collection as { subscriberCount?: number }).subscriberCount ?? 0;
|
|
369
|
+
if (subscriberCount > 0 && Date.now() < deadline) {
|
|
370
|
+
entry.gcTimer = setTimeout(tick, SHARED_COLLECTION_GC_MS);
|
|
371
|
+
return;
|
|
372
|
+
}
|
|
373
|
+
Promise.resolve(entry.collection.cleanup?.()).catch(() => {});
|
|
374
|
+
};
|
|
375
|
+
entry.gcTimer = setTimeout(tick, SHARED_COLLECTION_GC_MS);
|
|
376
|
+
}
|
|
377
|
+
|
|
378
|
+
/**
|
|
379
|
+
* React hook that returns a TanStack DB Collection backed by a Frappe doctype.
|
|
102
380
|
*
|
|
103
|
-
*
|
|
104
|
-
*
|
|
105
|
-
*
|
|
381
|
+
* Collections are shared: every hook instance with the same connection,
|
|
382
|
+
* doctype, and options (fields/filters/orderBy/limit/id) receives the SAME
|
|
383
|
+
* collection instance backed by ONE SyncModule subscription and ONE realtime
|
|
384
|
+
* room. Instances are refcounted — the shared collection is cleaned up
|
|
385
|
+
* shortly after the last consumer unmounts. `onSyncError` callbacks are
|
|
386
|
+
* per-consumer: each mounted consumer's handler fires (replayed on retain
|
|
387
|
+
* for late mounts). A failed initial sync is HELD by the entry while any
|
|
388
|
+
* consumer retains it — error-state re-renders reuse the same errored
|
|
389
|
+
* collection instead of looping fresh failing syncs — and the entry is
|
|
390
|
+
* evicted when the last consumer releases it, so the next mount (an
|
|
391
|
+
* explicit Retry remount) starts exactly one fresh attempt.
|
|
392
|
+
*
|
|
393
|
+
* The collection is stable across re-renders. It can be used with
|
|
394
|
+
* `useLiveQuery` for reactive queries and has `.insert()`, `.update()`,
|
|
395
|
+
* `.delete()` methods for mutations.
|
|
106
396
|
*
|
|
107
397
|
* @typeParam TDoc - The Frappe document type
|
|
108
398
|
* @param config - Connection configuration (baseURL, auth)
|
|
@@ -135,41 +425,156 @@ export function useFrappeCollection<TDoc extends object & { name: string; doctyp
|
|
|
135
425
|
doctype: string,
|
|
136
426
|
options?: Omit<FrappeCollectionOptionsConfig<TDoc>, "sync">,
|
|
137
427
|
): Collection<TDoc, string> | undefined {
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
const
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
//
|
|
149
|
-
//
|
|
150
|
-
|
|
151
|
-
|
|
428
|
+
// Consumers pass inline onSyncError closures; keep one stable wrapper per
|
|
429
|
+
// hook instance so the entry's handler registry doesn't churn every render.
|
|
430
|
+
const errorHandlerRef = useRef(options?.onSyncError);
|
|
431
|
+
errorHandlerRef.current = options?.onSyncError;
|
|
432
|
+
const stableErrorHandler = useCallback((error: unknown) => {
|
|
433
|
+
errorHandlerRef.current?.(error);
|
|
434
|
+
}, []);
|
|
435
|
+
|
|
436
|
+
const [, setStaleEntryBump] = useState(0);
|
|
437
|
+
|
|
438
|
+
// Resolve the shared entry during render so the collection is available on
|
|
439
|
+
// the FIRST render (same contract as before the cache). An empty doctype is
|
|
440
|
+
// treated like an undefined config: consumers such as DynamicLink pass ""
|
|
441
|
+
// before a doctype is chosen, and syncing doctype "" fires a bogus
|
|
442
|
+
// `/api/v2/document/` 404. During SSR, getSyncModule returns undefined —
|
|
443
|
+
// the component renders a loading state and the client hydration pass
|
|
444
|
+
// creates the real collection.
|
|
445
|
+
let cache: Map<string, SharedCollectionEntry> | undefined;
|
|
446
|
+
let key = "";
|
|
447
|
+
let entry: SharedCollectionEntry | undefined;
|
|
448
|
+
if (config && doctype) {
|
|
152
449
|
const syncModule = getSyncModule(config);
|
|
153
|
-
// During SSR, getSyncModule returns undefined – leave the collection
|
|
154
|
-
// as undefined so the component renders a loading state. The client
|
|
155
|
-
// hydration pass will create the real collection.
|
|
156
450
|
if (syncModule) {
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
sync: syncModule,
|
|
160
|
-
});
|
|
161
|
-
configKeyRef.current = configKey;
|
|
451
|
+
key = collectionOptionsKey(doctype, options);
|
|
452
|
+
({ cache, entry } = getOrCreateSharedCollection<TDoc>(syncModule, doctype, options, key));
|
|
162
453
|
}
|
|
163
|
-
// NOTE: configKeyRef is NOT set when syncModule is undefined (SSR),
|
|
164
|
-
// so on client hydration the hook will retry and create the collection.
|
|
165
454
|
}
|
|
166
455
|
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
456
|
+
useEffect(() => {
|
|
457
|
+
if (!entry || !cache) return;
|
|
458
|
+
if (entry.cleaned || collectionIsCleanedUp(entry.collection)) {
|
|
459
|
+
// Lost an eviction race between render and commit (needs a multi-second
|
|
460
|
+
// stall) — re-render to pick up a fresh entry from the cache.
|
|
461
|
+
setStaleEntryBump((n) => n + 1);
|
|
462
|
+
return;
|
|
463
|
+
}
|
|
464
|
+
const retained = entry;
|
|
465
|
+
const retainedCache = cache;
|
|
466
|
+
const retainedKey = key;
|
|
467
|
+
retainSharedCollection(retained, stableErrorHandler);
|
|
468
|
+
// Revive on out-of-band cleanup (a manual cleanup() call or TanStack DB's
|
|
469
|
+
// own idle GC after every query detached): live queries attached at
|
|
470
|
+
// cleanup time are permanently errored and never notify React on their
|
|
471
|
+
// own, so mark the entry stale and re-render — consumers pick up a fresh
|
|
472
|
+
// collection instance, which restarts their live queries.
|
|
473
|
+
const unsubscribeStatus = (
|
|
474
|
+
retained.collection as {
|
|
475
|
+
on?: (event: "status:change", cb: (event: { status?: string }) => void) => () => void;
|
|
476
|
+
}
|
|
477
|
+
).on?.("status:change", (event) => {
|
|
478
|
+
if (event?.status !== "cleaned-up" || retained.cleaned) return;
|
|
479
|
+
retained.cleaned = true;
|
|
480
|
+
setStaleEntryBump((n) => n + 1);
|
|
481
|
+
});
|
|
482
|
+
return () => {
|
|
483
|
+
unsubscribeStatus?.();
|
|
484
|
+
releaseSharedCollection(retainedCache, retainedKey, retained, stableErrorHandler);
|
|
485
|
+
};
|
|
486
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
487
|
+
}, [entry, stableErrorHandler]);
|
|
488
|
+
|
|
489
|
+
return entry ? (entry.collection as Collection<TDoc, string>) : undefined;
|
|
490
|
+
}
|
|
491
|
+
|
|
492
|
+
// ---------------------------------------------------------------------------
|
|
493
|
+
// Connection / realtime hooks
|
|
494
|
+
// ---------------------------------------------------------------------------
|
|
495
|
+
|
|
496
|
+
/** Snapshot returned by {@link useFrappeConnection}. */
|
|
497
|
+
export interface FrappeConnectionState {
|
|
498
|
+
/** Socket connected right now. */
|
|
499
|
+
connected: boolean;
|
|
500
|
+
/** Socket has connected at least once this session. */
|
|
501
|
+
everConnected: boolean;
|
|
502
|
+
}
|
|
503
|
+
|
|
504
|
+
const DISCONNECTED_STATE: FrappeConnectionState = Object.freeze({
|
|
505
|
+
connected: false,
|
|
506
|
+
everConnected: false,
|
|
507
|
+
});
|
|
508
|
+
|
|
509
|
+
/**
|
|
510
|
+
* React hook exposing the realtime socket state for the given connection.
|
|
511
|
+
*
|
|
512
|
+
* `connected` flips on every socket connect/disconnect; `everConnected`
|
|
513
|
+
* distinguishes "reconnecting" (show an indicator) from "realtime was never
|
|
514
|
+
* up" (fixture mode / SSR / no socket — show nothing). Fixture-backed
|
|
515
|
+
* configs always report disconnected/never-connected.
|
|
516
|
+
*/
|
|
517
|
+
export function useFrappeConnection(
|
|
518
|
+
config: UseFrappeCollectionConfig | undefined,
|
|
519
|
+
): FrappeConnectionState {
|
|
520
|
+
const [state, setState] = useState<FrappeConnectionState>(DISCONNECTED_STATE);
|
|
521
|
+
|
|
522
|
+
useEffect(() => {
|
|
523
|
+
if (!config || config.fixtures || !isBrowser()) return;
|
|
524
|
+
const syncModule = getSyncModule(config);
|
|
525
|
+
if (!syncModule) return;
|
|
526
|
+
|
|
527
|
+
const read = () => {
|
|
528
|
+
const next = syncModule.getConnectionState();
|
|
529
|
+
setState((prev) =>
|
|
530
|
+
prev.connected === next.connected && prev.everConnected === next.everConnected
|
|
531
|
+
? prev
|
|
532
|
+
: next,
|
|
533
|
+
);
|
|
534
|
+
};
|
|
535
|
+
read();
|
|
536
|
+
return syncModule.subscribeStore(read);
|
|
537
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
538
|
+
}, [config?.baseURL, !!config?.fixtures]);
|
|
539
|
+
|
|
540
|
+
return state;
|
|
541
|
+
}
|
|
542
|
+
|
|
543
|
+
/**
|
|
544
|
+
* React hook that joins a doctype's realtime room and invokes `onEvent`
|
|
545
|
+
* for every realtime event targeting that doctype (doc_update, list_update,
|
|
546
|
+
* doc_deleted). Intended for consumers that manage their own fetching
|
|
547
|
+
* (e.g. server-side paginated tables) and want live invalidation hints.
|
|
548
|
+
*
|
|
549
|
+
* The handler is kept in a ref, so an inline function is fine.
|
|
550
|
+
*/
|
|
551
|
+
export function useFrappeDoctypeEvents(
|
|
552
|
+
config: UseFrappeCollectionConfig | undefined,
|
|
553
|
+
doctype: string,
|
|
554
|
+
onEvent: (event: { type: string; payload?: unknown }) => void,
|
|
555
|
+
enabled = true,
|
|
556
|
+
): void {
|
|
557
|
+
const handlerRef = useRef(onEvent);
|
|
558
|
+
handlerRef.current = onEvent;
|
|
559
|
+
|
|
560
|
+
useEffect(() => {
|
|
561
|
+
if (!enabled || !config || config.fixtures || !doctype || !isBrowser()) return;
|
|
562
|
+
const syncModule = getSyncModule(config);
|
|
563
|
+
if (!syncModule) return;
|
|
171
564
|
|
|
172
|
-
|
|
565
|
+
syncModule.watchDoctype(doctype);
|
|
566
|
+
const unsubscribe = syncModule.subscribeRealtimeEvents((event) => {
|
|
567
|
+
const payload = event.payload as { doctype?: string } | undefined;
|
|
568
|
+
if (payload?.doctype && payload.doctype !== doctype) return;
|
|
569
|
+
handlerRef.current({ type: event.type as string, payload: event.payload });
|
|
570
|
+
});
|
|
571
|
+
|
|
572
|
+
return () => {
|
|
573
|
+
unsubscribe();
|
|
574
|
+
syncModule.unwatchDoctype(doctype);
|
|
575
|
+
};
|
|
576
|
+
// eslint-disable-next-line react-hooks/exhaustive-deps
|
|
577
|
+
}, [enabled, config?.baseURL, !!config?.fixtures, doctype]);
|
|
173
578
|
}
|
|
174
579
|
|
|
175
580
|
// ---------------------------------------------------------------------------
|
|
@@ -279,9 +684,12 @@ export function useInfiniteScroll(config: UseInfiniteScrollConfig): UseInfiniteS
|
|
|
279
684
|
}
|
|
280
685
|
}, [hasMore, isLoading, isLoadingMore, onLoadMore, debounceMs]);
|
|
281
686
|
|
|
282
|
-
// Set up IntersectionObserver
|
|
687
|
+
// Set up IntersectionObserver — web only. isBrowser() is TRUE on React
|
|
688
|
+
// Native (it gates the sync pipeline, which runs there), but
|
|
689
|
+
// IntersectionObserver is a DOM API: gate on window presence + the
|
|
690
|
+
// constructor itself so the hook is a safe no-op on native.
|
|
283
691
|
useEffect(() => {
|
|
284
|
-
if (!
|
|
692
|
+
if (!isWindowDefined || typeof IntersectionObserver === "undefined" || !enabled) return;
|
|
285
693
|
|
|
286
694
|
const node = sentinelNodeRef.current;
|
|
287
695
|
if (!node) return;
|