@multiplatform.one/frappe 6.1.0 → 6.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (792) hide show
  1. package/README.md +38 -12
  2. package/dist/cjs/auth.cjs +1 -1
  3. package/dist/cjs/auth.native.js.map +1 -1
  4. package/dist/cjs/call.cjs +1 -1
  5. package/dist/cjs/call.native.js.map +1 -1
  6. package/dist/cjs/collection.cjs +18 -4
  7. package/dist/cjs/collection.native.js +18 -4
  8. package/dist/cjs/collection.native.js.map +1 -1
  9. package/dist/cjs/core/http.cjs +92 -9
  10. package/dist/cjs/core/http.native.js +96 -7
  11. package/dist/cjs/core/http.native.js.map +1 -1
  12. package/dist/cjs/db.cjs +7 -7
  13. package/dist/cjs/db.native.js +4 -4
  14. package/dist/cjs/db.native.js.map +1 -1
  15. package/dist/cjs/doctype.cjs +97 -39
  16. package/dist/cjs/doctype.native.js +116 -46
  17. package/dist/cjs/doctype.native.js.map +1 -1
  18. package/dist/cjs/file.cjs +1 -1
  19. package/dist/cjs/file.native.js.map +1 -1
  20. package/dist/cjs/fixtureDb.cjs +3 -2
  21. package/dist/cjs/fixtureDb.native.js +2 -1
  22. package/dist/cjs/fixtureDb.native.js.map +1 -1
  23. package/dist/cjs/frappeApp.cjs +15 -14
  24. package/dist/cjs/frappeApp.native.js +16 -14
  25. package/dist/cjs/frappeApp.native.js.map +1 -1
  26. package/dist/cjs/frappeReact.cjs +198 -18
  27. package/dist/cjs/frappeReact.native.js +241 -18
  28. package/dist/cjs/frappeReact.native.js.map +1 -1
  29. package/dist/cjs/index.cjs +9 -4
  30. package/dist/cjs/index.native.js +9 -4
  31. package/dist/cjs/index.native.js.map +1 -1
  32. package/dist/cjs/pacer.cjs +2 -2
  33. package/dist/cjs/pacer.native.js +2 -2
  34. package/dist/cjs/pacer.native.js.map +1 -1
  35. package/dist/cjs/realtime.cjs +186 -46
  36. package/dist/cjs/realtime.native.js +268 -48
  37. package/dist/cjs/realtime.native.js.map +1 -1
  38. package/dist/cjs/sync/backfill.cjs +32 -27
  39. package/dist/cjs/sync/backfill.native.js +49 -43
  40. package/dist/cjs/sync/backfill.native.js.map +1 -1
  41. package/dist/cjs/sync/index.cjs +90 -24
  42. package/dist/cjs/sync/index.native.js +112 -10
  43. package/dist/cjs/sync/index.native.js.map +1 -1
  44. package/dist/cjs/sync/merge.cjs +0 -3
  45. package/dist/cjs/sync/merge.native.js +0 -3
  46. package/dist/cjs/sync/merge.native.js.map +1 -1
  47. package/dist/cjs/sync/mutationEngine.cjs +25 -19
  48. package/dist/cjs/sync/mutationEngine.native.js +16 -13
  49. package/dist/cjs/sync/mutationEngine.native.js.map +1 -1
  50. package/dist/cjs/sync/mutationJournal.cjs +9 -4
  51. package/dist/cjs/sync/mutationJournal.native.js +7 -4
  52. package/dist/cjs/sync/mutationJournal.native.js.map +1 -1
  53. package/dist/cjs/sync/normalizedCache.cjs +7 -3
  54. package/dist/cjs/sync/normalizedCache.native.js +7 -2
  55. package/dist/cjs/sync/normalizedCache.native.js.map +1 -1
  56. package/dist/cjs/sync/persistence.cjs +63 -31
  57. package/dist/cjs/sync/persistence.native.js +120 -63
  58. package/dist/cjs/sync/persistence.native.js.map +1 -1
  59. package/dist/cjs/sync/realtime.cjs +124 -13
  60. package/dist/cjs/sync/realtime.native.js +163 -20
  61. package/dist/cjs/sync/realtime.native.js.map +1 -1
  62. package/dist/cjs/sync/rehydration.cjs +16 -10
  63. package/dist/cjs/sync/rehydration.native.js +16 -14
  64. package/dist/cjs/sync/rehydration.native.js.map +1 -1
  65. package/dist/cjs/sync/storage.cjs +3 -3
  66. package/dist/cjs/sync/storage.native.js +1 -1
  67. package/dist/cjs/sync/storage.native.js.map +1 -1
  68. package/dist/cjs/sync/subscriptionManager.cjs +255 -65
  69. package/dist/cjs/sync/subscriptionManager.native.js +330 -93
  70. package/dist/cjs/sync/subscriptionManager.native.js.map +1 -1
  71. package/dist/cjs/sync/types.cjs +2 -0
  72. package/dist/cjs/sync/types.native.js +2 -0
  73. package/dist/cjs/sync/types.native.js.map +1 -1
  74. package/dist/cjs/sync/virtualPageManager.cjs +9 -9
  75. package/dist/cjs/sync/virtualPageManager.native.js +5 -9
  76. package/dist/cjs/sync/virtualPageManager.native.js.map +1 -1
  77. package/dist/cjs/useLiveQuery.cjs +52 -0
  78. package/dist/cjs/useLiveQuery.native.js +59 -0
  79. package/dist/cjs/useLiveQuery.native.js.map +1 -0
  80. package/dist/cjs/util.cjs +11 -2
  81. package/dist/cjs/util.native.js +16 -2
  82. package/dist/cjs/util.native.js.map +1 -1
  83. package/dist/esm/auth.mjs +1 -1
  84. package/dist/esm/auth.mjs.map +1 -1
  85. package/dist/esm/auth.native.js.map +1 -1
  86. package/dist/esm/call.mjs +1 -1
  87. package/dist/esm/call.mjs.map +1 -1
  88. package/dist/esm/call.native.js.map +1 -1
  89. package/dist/esm/collection.mjs +18 -4
  90. package/dist/esm/collection.mjs.map +1 -1
  91. package/dist/esm/collection.native.js +18 -4
  92. package/dist/esm/collection.native.js.map +1 -1
  93. package/dist/esm/core/http.mjs +93 -10
  94. package/dist/esm/core/http.mjs.map +1 -1
  95. package/dist/esm/core/http.native.js +97 -8
  96. package/dist/esm/core/http.native.js.map +1 -1
  97. package/dist/esm/db.mjs +7 -7
  98. package/dist/esm/db.mjs.map +1 -1
  99. package/dist/esm/db.native.js +4 -4
  100. package/dist/esm/db.native.js.map +1 -1
  101. package/dist/esm/doctype.mjs +96 -39
  102. package/dist/esm/doctype.mjs.map +1 -1
  103. package/dist/esm/doctype.native.js +115 -46
  104. package/dist/esm/doctype.native.js.map +1 -1
  105. package/dist/esm/file.mjs +1 -1
  106. package/dist/esm/file.mjs.map +1 -1
  107. package/dist/esm/file.native.js.map +1 -1
  108. package/dist/esm/fixtureDb.mjs +3 -2
  109. package/dist/esm/fixtureDb.mjs.map +1 -1
  110. package/dist/esm/fixtureDb.native.js +2 -1
  111. package/dist/esm/fixtureDb.native.js.map +1 -1
  112. package/dist/esm/frappeApp.mjs +15 -14
  113. package/dist/esm/frappeApp.mjs.map +1 -1
  114. package/dist/esm/frappeApp.native.js +16 -14
  115. package/dist/esm/frappeApp.native.js.map +1 -1
  116. package/dist/esm/frappeReact.mjs +197 -19
  117. package/dist/esm/frappeReact.mjs.map +1 -1
  118. package/dist/esm/frappeReact.native.js +240 -19
  119. package/dist/esm/frappeReact.native.js.map +1 -1
  120. package/dist/esm/index.mjs +5 -4
  121. package/dist/esm/index.mjs.map +1 -1
  122. package/dist/esm/index.native.js +5 -4
  123. package/dist/esm/index.native.js.map +1 -1
  124. package/dist/esm/pacer.mjs +1 -1
  125. package/dist/esm/pacer.native.js +1 -1
  126. package/dist/esm/realtime.mjs +187 -47
  127. package/dist/esm/realtime.mjs.map +1 -1
  128. package/dist/esm/realtime.native.js +269 -49
  129. package/dist/esm/realtime.native.js.map +1 -1
  130. package/dist/esm/sync/backfill.mjs +32 -27
  131. package/dist/esm/sync/backfill.mjs.map +1 -1
  132. package/dist/esm/sync/backfill.native.js +49 -43
  133. package/dist/esm/sync/backfill.native.js.map +1 -1
  134. package/dist/esm/sync/index.mjs +90 -24
  135. package/dist/esm/sync/index.mjs.map +1 -1
  136. package/dist/esm/sync/index.native.js +112 -10
  137. package/dist/esm/sync/index.native.js.map +1 -1
  138. package/dist/esm/sync/merge.mjs +1 -1
  139. package/dist/esm/sync/merge.mjs.map +1 -1
  140. package/dist/esm/sync/merge.native.js +1 -1
  141. package/dist/esm/sync/merge.native.js.map +1 -1
  142. package/dist/esm/sync/mutationEngine.mjs +25 -19
  143. package/dist/esm/sync/mutationEngine.mjs.map +1 -1
  144. package/dist/esm/sync/mutationEngine.native.js +16 -13
  145. package/dist/esm/sync/mutationEngine.native.js.map +1 -1
  146. package/dist/esm/sync/mutationJournal.mjs +9 -4
  147. package/dist/esm/sync/mutationJournal.mjs.map +1 -1
  148. package/dist/esm/sync/mutationJournal.native.js +7 -4
  149. package/dist/esm/sync/mutationJournal.native.js.map +1 -1
  150. package/dist/esm/sync/normalizedCache.mjs +7 -3
  151. package/dist/esm/sync/normalizedCache.mjs.map +1 -1
  152. package/dist/esm/sync/normalizedCache.native.js +7 -2
  153. package/dist/esm/sync/normalizedCache.native.js.map +1 -1
  154. package/dist/esm/sync/persistence.mjs +64 -32
  155. package/dist/esm/sync/persistence.mjs.map +1 -1
  156. package/dist/esm/sync/persistence.native.js +121 -64
  157. package/dist/esm/sync/persistence.native.js.map +1 -1
  158. package/dist/esm/sync/realtime.mjs +124 -13
  159. package/dist/esm/sync/realtime.mjs.map +1 -1
  160. package/dist/esm/sync/realtime.native.js +163 -20
  161. package/dist/esm/sync/realtime.native.js.map +1 -1
  162. package/dist/esm/sync/rehydration.mjs +16 -10
  163. package/dist/esm/sync/rehydration.mjs.map +1 -1
  164. package/dist/esm/sync/rehydration.native.js +16 -14
  165. package/dist/esm/sync/rehydration.native.js.map +1 -1
  166. package/dist/esm/sync/storage.mjs +3 -3
  167. package/dist/esm/sync/storage.mjs.map +1 -1
  168. package/dist/esm/sync/storage.native.js +1 -1
  169. package/dist/esm/sync/storage.native.js.map +1 -1
  170. package/dist/esm/sync/subscriptionManager.mjs +255 -65
  171. package/dist/esm/sync/subscriptionManager.mjs.map +1 -1
  172. package/dist/esm/sync/subscriptionManager.native.js +330 -93
  173. package/dist/esm/sync/subscriptionManager.native.js.map +1 -1
  174. package/dist/esm/sync/types.mjs +2 -0
  175. package/dist/esm/sync/types.mjs.map +1 -1
  176. package/dist/esm/sync/types.native.js +2 -0
  177. package/dist/esm/sync/types.native.js.map +1 -1
  178. package/dist/esm/sync/virtualPageManager.mjs +9 -9
  179. package/dist/esm/sync/virtualPageManager.mjs.map +1 -1
  180. package/dist/esm/sync/virtualPageManager.native.js +5 -9
  181. package/dist/esm/sync/virtualPageManager.native.js.map +1 -1
  182. package/dist/esm/useLiveQuery.mjs +26 -0
  183. package/dist/esm/useLiveQuery.mjs.map +1 -0
  184. package/dist/esm/useLiveQuery.native.js +30 -0
  185. package/dist/esm/useLiveQuery.native.js.map +1 -0
  186. package/dist/esm/util.mjs +10 -2
  187. package/dist/esm/util.mjs.map +1 -1
  188. package/dist/esm/util.native.js +15 -2
  189. package/dist/esm/util.native.js.map +1 -1
  190. package/dist/jsx/auth.mjs +1 -1
  191. package/dist/jsx/auth.mjs.map +1 -1
  192. package/dist/jsx/auth.native.js.map +1 -1
  193. package/dist/jsx/call.mjs +1 -1
  194. package/dist/jsx/call.mjs.map +1 -1
  195. package/dist/jsx/call.native.js.map +1 -1
  196. package/dist/jsx/collection.mjs +18 -4
  197. package/dist/jsx/collection.mjs.map +1 -1
  198. package/dist/jsx/collection.native.js +18 -4
  199. package/dist/jsx/collection.native.js.map +1 -1
  200. package/dist/jsx/core/http.mjs +93 -10
  201. package/dist/jsx/core/http.mjs.map +1 -1
  202. package/dist/jsx/core/http.native.js +96 -7
  203. package/dist/jsx/core/http.native.js.map +1 -1
  204. package/dist/jsx/db.mjs +7 -7
  205. package/dist/jsx/db.mjs.map +1 -1
  206. package/dist/jsx/db.native.js +4 -4
  207. package/dist/jsx/db.native.js.map +1 -1
  208. package/dist/jsx/doctype.mjs +96 -39
  209. package/dist/jsx/doctype.mjs.map +1 -1
  210. package/dist/jsx/doctype.native.js +116 -46
  211. package/dist/jsx/doctype.native.js.map +1 -1
  212. package/dist/jsx/file.mjs +1 -1
  213. package/dist/jsx/file.mjs.map +1 -1
  214. package/dist/jsx/file.native.js.map +1 -1
  215. package/dist/jsx/fixtureDb.mjs +3 -2
  216. package/dist/jsx/fixtureDb.mjs.map +1 -1
  217. package/dist/jsx/fixtureDb.native.js +2 -1
  218. package/dist/jsx/fixtureDb.native.js.map +1 -1
  219. package/dist/jsx/frappeApp.mjs +15 -14
  220. package/dist/jsx/frappeApp.mjs.map +1 -1
  221. package/dist/jsx/frappeApp.native.js +16 -14
  222. package/dist/jsx/frappeApp.native.js.map +1 -1
  223. package/dist/jsx/frappeReact.mjs +197 -19
  224. package/dist/jsx/frappeReact.mjs.map +1 -1
  225. package/dist/jsx/frappeReact.native.js +241 -18
  226. package/dist/jsx/frappeReact.native.js.map +1 -1
  227. package/dist/jsx/index.js +5 -4
  228. package/dist/jsx/index.js.map +1 -1
  229. package/dist/jsx/index.mjs +5 -4
  230. package/dist/jsx/index.mjs.map +1 -1
  231. package/dist/jsx/index.native.js +9 -4
  232. package/dist/jsx/index.native.js.map +1 -1
  233. package/dist/jsx/pacer.mjs +1 -1
  234. package/dist/jsx/pacer.native.js +2 -2
  235. package/dist/jsx/pacer.native.js.map +1 -1
  236. package/dist/jsx/realtime.mjs +187 -47
  237. package/dist/jsx/realtime.mjs.map +1 -1
  238. package/dist/jsx/realtime.native.js +268 -48
  239. package/dist/jsx/realtime.native.js.map +1 -1
  240. package/dist/jsx/sync/backfill.mjs +32 -27
  241. package/dist/jsx/sync/backfill.mjs.map +1 -1
  242. package/dist/jsx/sync/backfill.native.js +49 -43
  243. package/dist/jsx/sync/backfill.native.js.map +1 -1
  244. package/dist/jsx/sync/index.mjs +90 -24
  245. package/dist/jsx/sync/index.mjs.map +1 -1
  246. package/dist/jsx/sync/index.native.js +112 -10
  247. package/dist/jsx/sync/index.native.js.map +1 -1
  248. package/dist/jsx/sync/merge.mjs +1 -1
  249. package/dist/jsx/sync/merge.mjs.map +1 -1
  250. package/dist/jsx/sync/merge.native.js +0 -3
  251. package/dist/jsx/sync/merge.native.js.map +1 -1
  252. package/dist/jsx/sync/mutationEngine.mjs +25 -19
  253. package/dist/jsx/sync/mutationEngine.mjs.map +1 -1
  254. package/dist/jsx/sync/mutationEngine.native.js +16 -13
  255. package/dist/jsx/sync/mutationEngine.native.js.map +1 -1
  256. package/dist/jsx/sync/mutationJournal.mjs +9 -4
  257. package/dist/jsx/sync/mutationJournal.mjs.map +1 -1
  258. package/dist/jsx/sync/mutationJournal.native.js +7 -4
  259. package/dist/jsx/sync/mutationJournal.native.js.map +1 -1
  260. package/dist/jsx/sync/normalizedCache.mjs +7 -3
  261. package/dist/jsx/sync/normalizedCache.mjs.map +1 -1
  262. package/dist/jsx/sync/normalizedCache.native.js +7 -2
  263. package/dist/jsx/sync/normalizedCache.native.js.map +1 -1
  264. package/dist/jsx/sync/persistence.mjs +64 -32
  265. package/dist/jsx/sync/persistence.mjs.map +1 -1
  266. package/dist/jsx/sync/persistence.native.js +120 -63
  267. package/dist/jsx/sync/persistence.native.js.map +1 -1
  268. package/dist/jsx/sync/realtime.mjs +124 -13
  269. package/dist/jsx/sync/realtime.mjs.map +1 -1
  270. package/dist/jsx/sync/realtime.native.js +163 -20
  271. package/dist/jsx/sync/realtime.native.js.map +1 -1
  272. package/dist/jsx/sync/rehydration.mjs +16 -10
  273. package/dist/jsx/sync/rehydration.mjs.map +1 -1
  274. package/dist/jsx/sync/rehydration.native.js +16 -14
  275. package/dist/jsx/sync/rehydration.native.js.map +1 -1
  276. package/dist/jsx/sync/storage.mjs +3 -3
  277. package/dist/jsx/sync/storage.mjs.map +1 -1
  278. package/dist/jsx/sync/storage.native.js +1 -1
  279. package/dist/jsx/sync/storage.native.js.map +1 -1
  280. package/dist/jsx/sync/subscriptionManager.mjs +255 -65
  281. package/dist/jsx/sync/subscriptionManager.mjs.map +1 -1
  282. package/dist/jsx/sync/subscriptionManager.native.js +330 -93
  283. package/dist/jsx/sync/subscriptionManager.native.js.map +1 -1
  284. package/dist/jsx/sync/types.mjs +2 -0
  285. package/dist/jsx/sync/types.mjs.map +1 -1
  286. package/dist/jsx/sync/types.native.js +2 -0
  287. package/dist/jsx/sync/types.native.js.map +1 -1
  288. package/dist/jsx/sync/virtualPageManager.mjs +9 -9
  289. package/dist/jsx/sync/virtualPageManager.mjs.map +1 -1
  290. package/dist/jsx/sync/virtualPageManager.native.js +5 -9
  291. package/dist/jsx/sync/virtualPageManager.native.js.map +1 -1
  292. package/dist/jsx/useLiveQuery.mjs +26 -0
  293. package/dist/jsx/useLiveQuery.mjs.map +1 -0
  294. package/dist/jsx/useLiveQuery.native.js +59 -0
  295. package/dist/jsx/useLiveQuery.native.js.map +1 -0
  296. package/dist/jsx/util.mjs +10 -2
  297. package/dist/jsx/util.mjs.map +1 -1
  298. package/dist/jsx/util.native.js +16 -2
  299. package/dist/jsx/util.native.js.map +1 -1
  300. package/package.json +20 -17
  301. package/src/auth.ts +5 -1
  302. package/src/call.ts +5 -1
  303. package/src/collection.spec.ts +55 -0
  304. package/src/collection.ts +33 -4
  305. package/src/core/http.spec.ts +66 -0
  306. package/src/core/http.ts +115 -9
  307. package/src/core/httpNative.spec.ts +234 -0
  308. package/src/core/types.ts +2 -0
  309. package/src/db.spec.ts +91 -51
  310. package/src/db.ts +27 -8
  311. package/src/doctype.spec.ts +247 -39
  312. package/src/doctype.ts +203 -53
  313. package/src/file.ts +5 -1
  314. package/src/fixtureDb.ts +13 -2
  315. package/src/frappeApp.ts +18 -19
  316. package/src/frappeReact.spec.ts +565 -1
  317. package/src/frappeReact.ts +445 -37
  318. package/src/frappeReactLiveQueryGc.spec.ts +320 -0
  319. package/src/frappeReactNative.spec.ts +65 -0
  320. package/src/index.ts +10 -9
  321. package/src/pacer.ts +1 -1
  322. package/src/realtime.spec.ts +464 -20
  323. package/src/realtime.ts +284 -46
  324. package/src/sync/backfill.spec.ts +43 -0
  325. package/src/sync/backfill.ts +59 -39
  326. package/src/sync/debug.spec.ts +36 -0
  327. package/src/sync/filterValidation.spec.ts +197 -0
  328. package/src/sync/index.ts +98 -7
  329. package/src/sync/merge.ts +3 -3
  330. package/src/sync/mutationEngine.spec.ts +36 -4
  331. package/src/sync/mutationEngine.ts +30 -11
  332. package/src/sync/mutationJournal.ts +18 -4
  333. package/src/sync/normalizedCache.spec.ts +102 -0
  334. package/src/sync/normalizedCache.ts +19 -3
  335. package/src/sync/offlineRestore.spec.ts +423 -0
  336. package/src/sync/persistence.spec.ts +39 -7
  337. package/src/sync/persistence.ts +90 -18
  338. package/src/sync/persistenceGjs.spec.ts +143 -0
  339. package/src/sync/persistenceNative.spec.ts +139 -0
  340. package/src/sync/realtime.spec.ts +18 -1
  341. package/src/sync/realtime.ts +161 -13
  342. package/src/sync/rehydration.ts +23 -5
  343. package/src/sync/storage.ts +5 -4
  344. package/src/sync/subscriptionManager.spec.ts +94 -0
  345. package/src/sync/subscriptionManager.ts +304 -82
  346. package/src/sync/syncModule.spec.ts +137 -0
  347. package/src/sync/types.ts +39 -0
  348. package/src/sync/virtualPageManager.ts +8 -4
  349. package/src/useLiveQuery.ts +58 -0
  350. package/src/util.spec.ts +35 -4
  351. package/src/util.ts +34 -7
  352. package/types/auth.d.ts +13 -0
  353. package/types/auth.d.ts.map +1 -0
  354. package/types/call.d.ts +10 -0
  355. package/types/call.d.ts.map +1 -0
  356. package/types/collection.d.ts +127 -0
  357. package/types/collection.d.ts.map +1 -0
  358. package/types/common/types.d.ts +35 -0
  359. package/types/common/types.d.ts.map +1 -0
  360. package/types/core/http.d.ts +86 -0
  361. package/types/core/http.d.ts.map +1 -0
  362. package/types/core/types.d.ts +74 -0
  363. package/types/core/types.d.ts.map +1 -0
  364. package/types/core/wire.d.ts +405 -0
  365. package/types/core/wire.d.ts.map +1 -0
  366. package/types/db.d.ts +244 -0
  367. package/types/db.d.ts.map +1 -0
  368. package/types/devtools/FrappeDevtoolsPanel.d.ts +7 -0
  369. package/types/devtools/FrappeDevtoolsPanel.d.ts.map +1 -0
  370. package/types/devtools/index.d.ts +4 -0
  371. package/types/devtools/index.d.ts.map +1 -0
  372. package/types/devtools/plugin.d.ts +9 -0
  373. package/types/devtools/plugin.d.ts.map +1 -0
  374. package/types/devtools/theme.d.ts +15 -0
  375. package/types/devtools/theme.d.ts.map +1 -0
  376. package/types/doctype.d.ts +256 -0
  377. package/types/doctype.d.ts.map +1 -0
  378. package/types/file.d.ts +15 -0
  379. package/types/file.d.ts.map +1 -0
  380. package/types/fixtureDb.d.ts +76 -0
  381. package/types/fixtureDb.d.ts.map +1 -0
  382. package/types/fixtures.d.ts +55 -0
  383. package/types/fixtures.d.ts.map +1 -0
  384. package/types/frappeApp.d.ts +45 -0
  385. package/types/frappeApp.d.ts.map +1 -0
  386. package/types/frappeReact.d.ts +270 -0
  387. package/types/frappeReact.d.ts.map +1 -0
  388. package/types/index.d.ts +44 -0
  389. package/types/index.d.ts.map +1 -0
  390. package/types/optimistic.d.ts +38 -0
  391. package/types/optimistic.d.ts.map +1 -0
  392. package/types/pacer.d.ts +193 -0
  393. package/types/pacer.d.ts.map +1 -0
  394. package/types/plugin/index.d.ts +11 -0
  395. package/types/plugin/index.d.ts.map +1 -0
  396. package/types/realtime.d.ts +121 -0
  397. package/types/realtime.d.ts.map +1 -0
  398. package/types/sync/backfill.d.ts +60 -0
  399. package/types/sync/backfill.d.ts.map +1 -0
  400. package/types/sync/filters.d.ts +101 -0
  401. package/types/sync/filters.d.ts.map +1 -0
  402. package/types/sync/index.d.ts +181 -0
  403. package/types/sync/index.d.ts.map +1 -0
  404. package/types/sync/merge.d.ts +59 -0
  405. package/types/sync/merge.d.ts.map +1 -0
  406. package/types/sync/mutationEngine.d.ts +117 -0
  407. package/types/sync/mutationEngine.d.ts.map +1 -0
  408. package/types/sync/mutationJournal.d.ts +60 -0
  409. package/types/sync/mutationJournal.d.ts.map +1 -0
  410. package/types/sync/normalizedCache.d.ts +59 -0
  411. package/types/sync/normalizedCache.d.ts.map +1 -0
  412. package/types/sync/persistence.d.ts +185 -0
  413. package/types/sync/persistence.d.ts.map +1 -0
  414. package/types/sync/realtime.d.ts +121 -0
  415. package/types/sync/realtime.d.ts.map +1 -0
  416. package/types/sync/rehydration.d.ts +109 -0
  417. package/types/sync/rehydration.d.ts.map +1 -0
  418. package/types/sync/storage.d.ts +65 -0
  419. package/types/sync/storage.d.ts.map +1 -0
  420. package/types/sync/subscriptionManager.d.ts +161 -0
  421. package/types/sync/subscriptionManager.d.ts.map +1 -0
  422. package/types/sync/types.d.ts +435 -0
  423. package/types/sync/types.d.ts.map +1 -0
  424. package/types/sync/virtualPageManager.d.ts +190 -0
  425. package/types/sync/virtualPageManager.d.ts.map +1 -0
  426. package/types/useLiveQuery.d.ts +16 -0
  427. package/types/useLiveQuery.d.ts.map +1 -0
  428. package/types/util.d.ts +24 -0
  429. package/types/util.d.ts.map +1 -0
  430. package/dist/cjs/auth.spec.cjs +0 -322
  431. package/dist/cjs/auth.spec.native.js +0 -329
  432. package/dist/cjs/auth.spec.native.js.map +0 -1
  433. package/dist/cjs/call.spec.cjs +0 -427
  434. package/dist/cjs/call.spec.native.js +0 -430
  435. package/dist/cjs/call.spec.native.js.map +0 -1
  436. package/dist/cjs/collection.spec.cjs +0 -186
  437. package/dist/cjs/collection.spec.native.js +0 -216
  438. package/dist/cjs/collection.spec.native.js.map +0 -1
  439. package/dist/cjs/common/types.spec.cjs +0 -266
  440. package/dist/cjs/common/types.spec.native.js +0 -271
  441. package/dist/cjs/common/types.spec.native.js.map +0 -1
  442. package/dist/cjs/core/http.spec.cjs +0 -1259
  443. package/dist/cjs/core/http.spec.native.js +0 -1401
  444. package/dist/cjs/core/http.spec.native.js.map +0 -1
  445. package/dist/cjs/core/wire.spec.cjs +0 -478
  446. package/dist/cjs/core/wire.spec.native.js +0 -482
  447. package/dist/cjs/core/wire.spec.native.js.map +0 -1
  448. package/dist/cjs/db.spec.cjs +0 -862
  449. package/dist/cjs/db.spec.native.js +0 -865
  450. package/dist/cjs/db.spec.native.js.map +0 -1
  451. package/dist/cjs/doctype.spec.cjs +0 -460
  452. package/dist/cjs/doctype.spec.native.js +0 -538
  453. package/dist/cjs/doctype.spec.native.js.map +0 -1
  454. package/dist/cjs/file.spec.cjs +0 -315
  455. package/dist/cjs/file.spec.native.js +0 -342
  456. package/dist/cjs/file.spec.native.js.map +0 -1
  457. package/dist/cjs/frappeApp.spec.cjs +0 -306
  458. package/dist/cjs/frappeApp.spec.native.js +0 -308
  459. package/dist/cjs/frappeApp.spec.native.js.map +0 -1
  460. package/dist/cjs/frappeReact.spec.cjs +0 -531
  461. package/dist/cjs/frappeReact.spec.native.js +0 -670
  462. package/dist/cjs/frappeReact.spec.native.js.map +0 -1
  463. package/dist/cjs/optimistic.spec.cjs +0 -11
  464. package/dist/cjs/optimistic.spec.native.js +0 -19
  465. package/dist/cjs/optimistic.spec.native.js.map +0 -1
  466. package/dist/cjs/pacer.spec.cjs +0 -470
  467. package/dist/cjs/pacer.spec.native.js +0 -537
  468. package/dist/cjs/pacer.spec.native.js.map +0 -1
  469. package/dist/cjs/realtime.spec.cjs +0 -326
  470. package/dist/cjs/realtime.spec.native.js +0 -392
  471. package/dist/cjs/realtime.spec.native.js.map +0 -1
  472. package/dist/cjs/sync/backfill.spec.cjs +0 -586
  473. package/dist/cjs/sync/backfill.spec.native.js +0 -712
  474. package/dist/cjs/sync/backfill.spec.native.js.map +0 -1
  475. package/dist/cjs/sync/debug.spec.cjs +0 -125
  476. package/dist/cjs/sync/debug.spec.native.js +0 -133
  477. package/dist/cjs/sync/debug.spec.native.js.map +0 -1
  478. package/dist/cjs/sync/filters.spec.cjs +0 -168
  479. package/dist/cjs/sync/filters.spec.native.js +0 -173
  480. package/dist/cjs/sync/filters.spec.native.js.map +0 -1
  481. package/dist/cjs/sync/merge.spec.cjs +0 -908
  482. package/dist/cjs/sync/merge.spec.native.js +0 -937
  483. package/dist/cjs/sync/merge.spec.native.js.map +0 -1
  484. package/dist/cjs/sync/multiOrderBy.spec.cjs +0 -165
  485. package/dist/cjs/sync/multiOrderBy.spec.native.js +0 -229
  486. package/dist/cjs/sync/multiOrderBy.spec.native.js.map +0 -1
  487. package/dist/cjs/sync/mutationEngine.spec.cjs +0 -1158
  488. package/dist/cjs/sync/mutationEngine.spec.native.js +0 -1173
  489. package/dist/cjs/sync/mutationEngine.spec.native.js.map +0 -1
  490. package/dist/cjs/sync/mutationJournal.spec.cjs +0 -330
  491. package/dist/cjs/sync/mutationJournal.spec.native.js +0 -333
  492. package/dist/cjs/sync/mutationJournal.spec.native.js.map +0 -1
  493. package/dist/cjs/sync/mutations.spec.cjs +0 -327
  494. package/dist/cjs/sync/mutations.spec.native.js +0 -330
  495. package/dist/cjs/sync/mutations.spec.native.js.map +0 -1
  496. package/dist/cjs/sync/normalizedCache.spec.cjs +0 -302
  497. package/dist/cjs/sync/normalizedCache.spec.native.js +0 -311
  498. package/dist/cjs/sync/normalizedCache.spec.native.js.map +0 -1
  499. package/dist/cjs/sync/persistence.spec.cjs +0 -562
  500. package/dist/cjs/sync/persistence.spec.native.js +0 -572
  501. package/dist/cjs/sync/persistence.spec.native.js.map +0 -1
  502. package/dist/cjs/sync/realtime.spec.cjs +0 -499
  503. package/dist/cjs/sync/realtime.spec.native.js +0 -512
  504. package/dist/cjs/sync/realtime.spec.native.js.map +0 -1
  505. package/dist/cjs/sync/rehydration.spec.cjs +0 -731
  506. package/dist/cjs/sync/rehydration.spec.native.js +0 -736
  507. package/dist/cjs/sync/rehydration.spec.native.js.map +0 -1
  508. package/dist/cjs/sync/storage.spec.cjs +0 -446
  509. package/dist/cjs/sync/storage.spec.native.js +0 -470
  510. package/dist/cjs/sync/storage.spec.native.js.map +0 -1
  511. package/dist/cjs/sync/subscriptionManager.spec.cjs +0 -1102
  512. package/dist/cjs/sync/subscriptionManager.spec.native.js +0 -1136
  513. package/dist/cjs/sync/subscriptionManager.spec.native.js.map +0 -1
  514. package/dist/cjs/sync/subscriptions.spec.cjs +0 -937
  515. package/dist/cjs/sync/subscriptions.spec.native.js +0 -969
  516. package/dist/cjs/sync/subscriptions.spec.native.js.map +0 -1
  517. package/dist/cjs/sync/syncModule.spec.cjs +0 -206
  518. package/dist/cjs/sync/syncModule.spec.native.js +0 -222
  519. package/dist/cjs/sync/syncModule.spec.native.js.map +0 -1
  520. package/dist/cjs/sync/types.spec.cjs +0 -246
  521. package/dist/cjs/sync/types.spec.native.js +0 -256
  522. package/dist/cjs/sync/types.spec.native.js.map +0 -1
  523. package/dist/cjs/sync/virtualPageManager.spec.cjs +0 -801
  524. package/dist/cjs/sync/virtualPageManager.spec.native.js +0 -873
  525. package/dist/cjs/sync/virtualPageManager.spec.native.js.map +0 -1
  526. package/dist/cjs/util.spec.cjs +0 -43
  527. package/dist/cjs/util.spec.native.js +0 -48
  528. package/dist/cjs/util.spec.native.js.map +0 -1
  529. package/dist/esm/auth.spec.mjs +0 -323
  530. package/dist/esm/auth.spec.mjs.map +0 -1
  531. package/dist/esm/auth.spec.native.js +0 -327
  532. package/dist/esm/auth.spec.native.js.map +0 -1
  533. package/dist/esm/call.spec.mjs +0 -428
  534. package/dist/esm/call.spec.mjs.map +0 -1
  535. package/dist/esm/call.spec.native.js +0 -428
  536. package/dist/esm/call.spec.native.js.map +0 -1
  537. package/dist/esm/collection.spec.mjs +0 -187
  538. package/dist/esm/collection.spec.mjs.map +0 -1
  539. package/dist/esm/collection.spec.native.js +0 -214
  540. package/dist/esm/collection.spec.native.js.map +0 -1
  541. package/dist/esm/common/types.spec.mjs +0 -267
  542. package/dist/esm/common/types.spec.mjs.map +0 -1
  543. package/dist/esm/common/types.spec.native.js +0 -269
  544. package/dist/esm/common/types.spec.native.js.map +0 -1
  545. package/dist/esm/core/http.spec.mjs +0 -1260
  546. package/dist/esm/core/http.spec.mjs.map +0 -1
  547. package/dist/esm/core/http.spec.native.js +0 -1399
  548. package/dist/esm/core/http.spec.native.js.map +0 -1
  549. package/dist/esm/core/wire.spec.mjs +0 -479
  550. package/dist/esm/core/wire.spec.mjs.map +0 -1
  551. package/dist/esm/core/wire.spec.native.js +0 -480
  552. package/dist/esm/core/wire.spec.native.js.map +0 -1
  553. package/dist/esm/db.spec.mjs +0 -863
  554. package/dist/esm/db.spec.mjs.map +0 -1
  555. package/dist/esm/db.spec.native.js +0 -863
  556. package/dist/esm/db.spec.native.js.map +0 -1
  557. package/dist/esm/doctype.spec.mjs +0 -461
  558. package/dist/esm/doctype.spec.mjs.map +0 -1
  559. package/dist/esm/doctype.spec.native.js +0 -536
  560. package/dist/esm/doctype.spec.native.js.map +0 -1
  561. package/dist/esm/file.spec.mjs +0 -316
  562. package/dist/esm/file.spec.mjs.map +0 -1
  563. package/dist/esm/file.spec.native.js +0 -340
  564. package/dist/esm/file.spec.native.js.map +0 -1
  565. package/dist/esm/frappeApp.spec.mjs +0 -307
  566. package/dist/esm/frappeApp.spec.mjs.map +0 -1
  567. package/dist/esm/frappeApp.spec.native.js +0 -306
  568. package/dist/esm/frappeApp.spec.native.js.map +0 -1
  569. package/dist/esm/frappeReact.spec.mjs +0 -532
  570. package/dist/esm/frappeReact.spec.mjs.map +0 -1
  571. package/dist/esm/frappeReact.spec.native.js +0 -668
  572. package/dist/esm/frappeReact.spec.native.js.map +0 -1
  573. package/dist/esm/optimistic.spec.mjs +0 -12
  574. package/dist/esm/optimistic.spec.mjs.map +0 -1
  575. package/dist/esm/optimistic.spec.native.js +0 -17
  576. package/dist/esm/optimistic.spec.native.js.map +0 -1
  577. package/dist/esm/pacer.spec.mjs +0 -447
  578. package/dist/esm/pacer.spec.mjs.map +0 -1
  579. package/dist/esm/pacer.spec.native.js +0 -511
  580. package/dist/esm/pacer.spec.native.js.map +0 -1
  581. package/dist/esm/realtime.spec.mjs +0 -327
  582. package/dist/esm/realtime.spec.mjs.map +0 -1
  583. package/dist/esm/realtime.spec.native.js +0 -390
  584. package/dist/esm/realtime.spec.native.js.map +0 -1
  585. package/dist/esm/sync/backfill.spec.mjs +0 -563
  586. package/dist/esm/sync/backfill.spec.mjs.map +0 -1
  587. package/dist/esm/sync/backfill.spec.native.js +0 -686
  588. package/dist/esm/sync/backfill.spec.native.js.map +0 -1
  589. package/dist/esm/sync/debug.spec.mjs +0 -102
  590. package/dist/esm/sync/debug.spec.mjs.map +0 -1
  591. package/dist/esm/sync/debug.spec.native.js +0 -107
  592. package/dist/esm/sync/debug.spec.native.js.map +0 -1
  593. package/dist/esm/sync/filters.spec.mjs +0 -169
  594. package/dist/esm/sync/filters.spec.mjs.map +0 -1
  595. package/dist/esm/sync/filters.spec.native.js +0 -171
  596. package/dist/esm/sync/filters.spec.native.js.map +0 -1
  597. package/dist/esm/sync/merge.spec.mjs +0 -909
  598. package/dist/esm/sync/merge.spec.mjs.map +0 -1
  599. package/dist/esm/sync/merge.spec.native.js +0 -935
  600. package/dist/esm/sync/merge.spec.native.js.map +0 -1
  601. package/dist/esm/sync/multiOrderBy.spec.mjs +0 -166
  602. package/dist/esm/sync/multiOrderBy.spec.mjs.map +0 -1
  603. package/dist/esm/sync/multiOrderBy.spec.native.js +0 -227
  604. package/dist/esm/sync/multiOrderBy.spec.native.js.map +0 -1
  605. package/dist/esm/sync/mutationEngine.spec.mjs +0 -1159
  606. package/dist/esm/sync/mutationEngine.spec.mjs.map +0 -1
  607. package/dist/esm/sync/mutationEngine.spec.native.js +0 -1171
  608. package/dist/esm/sync/mutationEngine.spec.native.js.map +0 -1
  609. package/dist/esm/sync/mutationJournal.spec.mjs +0 -331
  610. package/dist/esm/sync/mutationJournal.spec.mjs.map +0 -1
  611. package/dist/esm/sync/mutationJournal.spec.native.js +0 -331
  612. package/dist/esm/sync/mutationJournal.spec.native.js.map +0 -1
  613. package/dist/esm/sync/mutations.spec.mjs +0 -328
  614. package/dist/esm/sync/mutations.spec.mjs.map +0 -1
  615. package/dist/esm/sync/mutations.spec.native.js +0 -328
  616. package/dist/esm/sync/mutations.spec.native.js.map +0 -1
  617. package/dist/esm/sync/normalizedCache.spec.mjs +0 -303
  618. package/dist/esm/sync/normalizedCache.spec.mjs.map +0 -1
  619. package/dist/esm/sync/normalizedCache.spec.native.js +0 -309
  620. package/dist/esm/sync/normalizedCache.spec.native.js.map +0 -1
  621. package/dist/esm/sync/persistence.spec.mjs +0 -563
  622. package/dist/esm/sync/persistence.spec.mjs.map +0 -1
  623. package/dist/esm/sync/persistence.spec.native.js +0 -570
  624. package/dist/esm/sync/persistence.spec.native.js.map +0 -1
  625. package/dist/esm/sync/realtime.spec.mjs +0 -500
  626. package/dist/esm/sync/realtime.spec.mjs.map +0 -1
  627. package/dist/esm/sync/realtime.spec.native.js +0 -510
  628. package/dist/esm/sync/realtime.spec.native.js.map +0 -1
  629. package/dist/esm/sync/rehydration.spec.mjs +0 -732
  630. package/dist/esm/sync/rehydration.spec.mjs.map +0 -1
  631. package/dist/esm/sync/rehydration.spec.native.js +0 -734
  632. package/dist/esm/sync/rehydration.spec.native.js.map +0 -1
  633. package/dist/esm/sync/storage.spec.mjs +0 -423
  634. package/dist/esm/sync/storage.spec.mjs.map +0 -1
  635. package/dist/esm/sync/storage.spec.native.js +0 -444
  636. package/dist/esm/sync/storage.spec.native.js.map +0 -1
  637. package/dist/esm/sync/subscriptionManager.spec.mjs +0 -1079
  638. package/dist/esm/sync/subscriptionManager.spec.mjs.map +0 -1
  639. package/dist/esm/sync/subscriptionManager.spec.native.js +0 -1110
  640. package/dist/esm/sync/subscriptionManager.spec.native.js.map +0 -1
  641. package/dist/esm/sync/subscriptions.spec.mjs +0 -914
  642. package/dist/esm/sync/subscriptions.spec.mjs.map +0 -1
  643. package/dist/esm/sync/subscriptions.spec.native.js +0 -943
  644. package/dist/esm/sync/subscriptions.spec.native.js.map +0 -1
  645. package/dist/esm/sync/syncModule.spec.mjs +0 -207
  646. package/dist/esm/sync/syncModule.spec.mjs.map +0 -1
  647. package/dist/esm/sync/syncModule.spec.native.js +0 -220
  648. package/dist/esm/sync/syncModule.spec.native.js.map +0 -1
  649. package/dist/esm/sync/types.spec.mjs +0 -247
  650. package/dist/esm/sync/types.spec.mjs.map +0 -1
  651. package/dist/esm/sync/types.spec.native.js +0 -254
  652. package/dist/esm/sync/types.spec.native.js.map +0 -1
  653. package/dist/esm/sync/virtualPageManager.spec.mjs +0 -802
  654. package/dist/esm/sync/virtualPageManager.spec.mjs.map +0 -1
  655. package/dist/esm/sync/virtualPageManager.spec.native.js +0 -871
  656. package/dist/esm/sync/virtualPageManager.spec.native.js.map +0 -1
  657. package/dist/esm/util.spec.mjs +0 -20
  658. package/dist/esm/util.spec.mjs.map +0 -1
  659. package/dist/esm/util.spec.native.js +0 -22
  660. package/dist/esm/util.spec.native.js.map +0 -1
  661. package/dist/jsx/auth.spec.mjs +0 -323
  662. package/dist/jsx/auth.spec.mjs.map +0 -1
  663. package/dist/jsx/auth.spec.native.js +0 -329
  664. package/dist/jsx/auth.spec.native.js.map +0 -1
  665. package/dist/jsx/call.spec.mjs +0 -428
  666. package/dist/jsx/call.spec.mjs.map +0 -1
  667. package/dist/jsx/call.spec.native.js +0 -430
  668. package/dist/jsx/call.spec.native.js.map +0 -1
  669. package/dist/jsx/collection.spec.mjs +0 -187
  670. package/dist/jsx/collection.spec.mjs.map +0 -1
  671. package/dist/jsx/collection.spec.native.js +0 -216
  672. package/dist/jsx/collection.spec.native.js.map +0 -1
  673. package/dist/jsx/common/types.spec.mjs +0 -267
  674. package/dist/jsx/common/types.spec.mjs.map +0 -1
  675. package/dist/jsx/common/types.spec.native.js +0 -271
  676. package/dist/jsx/common/types.spec.native.js.map +0 -1
  677. package/dist/jsx/core/http.spec.mjs +0 -1260
  678. package/dist/jsx/core/http.spec.mjs.map +0 -1
  679. package/dist/jsx/core/http.spec.native.js +0 -1401
  680. package/dist/jsx/core/http.spec.native.js.map +0 -1
  681. package/dist/jsx/core/wire.spec.mjs +0 -479
  682. package/dist/jsx/core/wire.spec.mjs.map +0 -1
  683. package/dist/jsx/core/wire.spec.native.js +0 -482
  684. package/dist/jsx/core/wire.spec.native.js.map +0 -1
  685. package/dist/jsx/db.spec.mjs +0 -863
  686. package/dist/jsx/db.spec.mjs.map +0 -1
  687. package/dist/jsx/db.spec.native.js +0 -865
  688. package/dist/jsx/db.spec.native.js.map +0 -1
  689. package/dist/jsx/doctype.spec.mjs +0 -461
  690. package/dist/jsx/doctype.spec.mjs.map +0 -1
  691. package/dist/jsx/doctype.spec.native.js +0 -538
  692. package/dist/jsx/doctype.spec.native.js.map +0 -1
  693. package/dist/jsx/file.spec.mjs +0 -316
  694. package/dist/jsx/file.spec.mjs.map +0 -1
  695. package/dist/jsx/file.spec.native.js +0 -342
  696. package/dist/jsx/file.spec.native.js.map +0 -1
  697. package/dist/jsx/frappeApp.spec.mjs +0 -307
  698. package/dist/jsx/frappeApp.spec.mjs.map +0 -1
  699. package/dist/jsx/frappeApp.spec.native.js +0 -308
  700. package/dist/jsx/frappeApp.spec.native.js.map +0 -1
  701. package/dist/jsx/frappeReact.spec.mjs +0 -532
  702. package/dist/jsx/frappeReact.spec.mjs.map +0 -1
  703. package/dist/jsx/frappeReact.spec.native.js +0 -670
  704. package/dist/jsx/frappeReact.spec.native.js.map +0 -1
  705. package/dist/jsx/optimistic.spec.mjs +0 -12
  706. package/dist/jsx/optimistic.spec.mjs.map +0 -1
  707. package/dist/jsx/optimistic.spec.native.js +0 -19
  708. package/dist/jsx/optimistic.spec.native.js.map +0 -1
  709. package/dist/jsx/pacer.spec.mjs +0 -447
  710. package/dist/jsx/pacer.spec.mjs.map +0 -1
  711. package/dist/jsx/pacer.spec.native.js +0 -537
  712. package/dist/jsx/pacer.spec.native.js.map +0 -1
  713. package/dist/jsx/realtime.spec.mjs +0 -327
  714. package/dist/jsx/realtime.spec.mjs.map +0 -1
  715. package/dist/jsx/realtime.spec.native.js +0 -392
  716. package/dist/jsx/realtime.spec.native.js.map +0 -1
  717. package/dist/jsx/sync/backfill.spec.mjs +0 -563
  718. package/dist/jsx/sync/backfill.spec.mjs.map +0 -1
  719. package/dist/jsx/sync/backfill.spec.native.js +0 -712
  720. package/dist/jsx/sync/backfill.spec.native.js.map +0 -1
  721. package/dist/jsx/sync/debug.spec.mjs +0 -102
  722. package/dist/jsx/sync/debug.spec.mjs.map +0 -1
  723. package/dist/jsx/sync/debug.spec.native.js +0 -133
  724. package/dist/jsx/sync/debug.spec.native.js.map +0 -1
  725. package/dist/jsx/sync/filters.spec.mjs +0 -169
  726. package/dist/jsx/sync/filters.spec.mjs.map +0 -1
  727. package/dist/jsx/sync/filters.spec.native.js +0 -173
  728. package/dist/jsx/sync/filters.spec.native.js.map +0 -1
  729. package/dist/jsx/sync/merge.spec.mjs +0 -909
  730. package/dist/jsx/sync/merge.spec.mjs.map +0 -1
  731. package/dist/jsx/sync/merge.spec.native.js +0 -937
  732. package/dist/jsx/sync/merge.spec.native.js.map +0 -1
  733. package/dist/jsx/sync/multiOrderBy.spec.mjs +0 -166
  734. package/dist/jsx/sync/multiOrderBy.spec.mjs.map +0 -1
  735. package/dist/jsx/sync/multiOrderBy.spec.native.js +0 -229
  736. package/dist/jsx/sync/multiOrderBy.spec.native.js.map +0 -1
  737. package/dist/jsx/sync/mutationEngine.spec.mjs +0 -1159
  738. package/dist/jsx/sync/mutationEngine.spec.mjs.map +0 -1
  739. package/dist/jsx/sync/mutationEngine.spec.native.js +0 -1173
  740. package/dist/jsx/sync/mutationEngine.spec.native.js.map +0 -1
  741. package/dist/jsx/sync/mutationJournal.spec.mjs +0 -331
  742. package/dist/jsx/sync/mutationJournal.spec.mjs.map +0 -1
  743. package/dist/jsx/sync/mutationJournal.spec.native.js +0 -333
  744. package/dist/jsx/sync/mutationJournal.spec.native.js.map +0 -1
  745. package/dist/jsx/sync/mutations.spec.mjs +0 -328
  746. package/dist/jsx/sync/mutations.spec.mjs.map +0 -1
  747. package/dist/jsx/sync/mutations.spec.native.js +0 -330
  748. package/dist/jsx/sync/mutations.spec.native.js.map +0 -1
  749. package/dist/jsx/sync/normalizedCache.spec.mjs +0 -303
  750. package/dist/jsx/sync/normalizedCache.spec.mjs.map +0 -1
  751. package/dist/jsx/sync/normalizedCache.spec.native.js +0 -311
  752. package/dist/jsx/sync/normalizedCache.spec.native.js.map +0 -1
  753. package/dist/jsx/sync/persistence.spec.mjs +0 -563
  754. package/dist/jsx/sync/persistence.spec.mjs.map +0 -1
  755. package/dist/jsx/sync/persistence.spec.native.js +0 -572
  756. package/dist/jsx/sync/persistence.spec.native.js.map +0 -1
  757. package/dist/jsx/sync/realtime.spec.mjs +0 -500
  758. package/dist/jsx/sync/realtime.spec.mjs.map +0 -1
  759. package/dist/jsx/sync/realtime.spec.native.js +0 -512
  760. package/dist/jsx/sync/realtime.spec.native.js.map +0 -1
  761. package/dist/jsx/sync/rehydration.spec.mjs +0 -732
  762. package/dist/jsx/sync/rehydration.spec.mjs.map +0 -1
  763. package/dist/jsx/sync/rehydration.spec.native.js +0 -736
  764. package/dist/jsx/sync/rehydration.spec.native.js.map +0 -1
  765. package/dist/jsx/sync/storage.spec.mjs +0 -423
  766. package/dist/jsx/sync/storage.spec.mjs.map +0 -1
  767. package/dist/jsx/sync/storage.spec.native.js +0 -470
  768. package/dist/jsx/sync/storage.spec.native.js.map +0 -1
  769. package/dist/jsx/sync/subscriptionManager.spec.mjs +0 -1079
  770. package/dist/jsx/sync/subscriptionManager.spec.mjs.map +0 -1
  771. package/dist/jsx/sync/subscriptionManager.spec.native.js +0 -1136
  772. package/dist/jsx/sync/subscriptionManager.spec.native.js.map +0 -1
  773. package/dist/jsx/sync/subscriptions.spec.mjs +0 -914
  774. package/dist/jsx/sync/subscriptions.spec.mjs.map +0 -1
  775. package/dist/jsx/sync/subscriptions.spec.native.js +0 -969
  776. package/dist/jsx/sync/subscriptions.spec.native.js.map +0 -1
  777. package/dist/jsx/sync/syncModule.spec.mjs +0 -207
  778. package/dist/jsx/sync/syncModule.spec.mjs.map +0 -1
  779. package/dist/jsx/sync/syncModule.spec.native.js +0 -222
  780. package/dist/jsx/sync/syncModule.spec.native.js.map +0 -1
  781. package/dist/jsx/sync/types.spec.mjs +0 -247
  782. package/dist/jsx/sync/types.spec.mjs.map +0 -1
  783. package/dist/jsx/sync/types.spec.native.js +0 -256
  784. package/dist/jsx/sync/types.spec.native.js.map +0 -1
  785. package/dist/jsx/sync/virtualPageManager.spec.mjs +0 -802
  786. package/dist/jsx/sync/virtualPageManager.spec.mjs.map +0 -1
  787. package/dist/jsx/sync/virtualPageManager.spec.native.js +0 -873
  788. package/dist/jsx/sync/virtualPageManager.spec.native.js.map +0 -1
  789. package/dist/jsx/util.spec.mjs +0 -20
  790. package/dist/jsx/util.spec.mjs.map +0 -1
  791. package/dist/jsx/util.spec.native.js +0 -48
  792. package/dist/jsx/util.spec.native.js.map +0 -1
@@ -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 the SyncModule relies
62
- * on browser-only APIs (localStorage, BroadcastChannel, window events).
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
- * React hook that creates and memoizes a TanStack DB Collection backed by a Frappe doctype.
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
- * The collection is created once and stable across re-renders. It can be used with
104
- * `useLiveQuery` for reactive queries and has `.insert()`, `.update()`, `.delete()`
105
- * methods for mutations.
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
- const collectionRef = useRef<Collection<TDoc, string> | undefined>(undefined);
139
- const configKeyRef = useRef<string>("");
140
-
141
- // Compute a stable key for the config (include fixtures flag so fixture vs live collections differ)
142
- const configKey = config
143
- ? `${config.baseURL}:${config.fixtures ? "fixture" : "live"}:${doctype}:${JSON.stringify(options?.fields)}:${JSON.stringify(options?.filters)}`
144
- : "";
145
-
146
- // Re-create the collection when config changes, OR when the collection is
147
- // still undefined on the client (can happen after SSR where SyncModule is
148
- // unavailable the configKey was stored during SSR but the collection was
149
- // never actually created).
150
- const needsCollection = config && (configKey !== configKeyRef.current || !collectionRef.current);
151
- if (needsCollection) {
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
- collectionRef.current = createFrappeCollection<TDoc>(doctype, {
158
- ...options,
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
- if (!config) {
168
- collectionRef.current = undefined;
169
- configKeyRef.current = "";
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
- return collectionRef.current;
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 (!isBrowser() || !enabled) return;
692
+ if (!isWindowDefined || typeof IntersectionObserver === "undefined" || !enabled) return;
285
693
 
286
694
  const node = sentinelNodeRef.current;
287
695
  if (!node) return;