@multiplatform.one/frappe 6.0.4 → 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.
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 +11 -3
  187. package/dist/esm/util.mjs.map +1 -1
  188. package/dist/esm/util.native.js +16 -3
  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 +11 -3
  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 +446 -38
  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 +2 -2
  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 +37 -2
  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
@@ -93,6 +93,42 @@ describe("SyncModule.__debug()", () => {
93
93
  expect(typeof debug.connection.socketConnected).toBe("boolean");
94
94
  });
95
95
 
96
+ it("treats missing navigator.onLine as online (React Native)", () => {
97
+ // RN has a navigator object but no onLine property — the old ternary
98
+ // surfaced `undefined`, rendering as "offline" in devtools.
99
+ const originalNavigator = globalThis.navigator;
100
+ Object.defineProperty(globalThis, "navigator", {
101
+ value: { product: "ReactNative" },
102
+ writable: true,
103
+ configurable: true,
104
+ });
105
+
106
+ expect(syncModule.__debug().connection.isOnline).toBe(true);
107
+
108
+ Object.defineProperty(globalThis, "navigator", {
109
+ value: originalNavigator,
110
+ writable: true,
111
+ configurable: true,
112
+ });
113
+ });
114
+
115
+ it("still reports offline when navigator.onLine is explicitly false (web)", () => {
116
+ const originalNavigator = globalThis.navigator;
117
+ Object.defineProperty(globalThis, "navigator", {
118
+ value: { onLine: false },
119
+ writable: true,
120
+ configurable: true,
121
+ });
122
+
123
+ expect(syncModule.__debug().connection.isOnline).toBe(false);
124
+
125
+ Object.defineProperty(globalThis, "navigator", {
126
+ value: originalNavigator,
127
+ writable: true,
128
+ configurable: true,
129
+ });
130
+ });
131
+
96
132
  it("mutation journal has correct structure", async () => {
97
133
  await syncModule.subscribe({
98
134
  doctype: "ToDo",
@@ -0,0 +1,197 @@
1
+ /**
2
+ * Filter toolkit contracts beyond matchesFilters (covered in filters.spec):
3
+ * schema validation (validateFilters strict/lenient), normalization of
4
+ * object filters to tuples, filter-field extraction, display formatting,
5
+ * getDoc fast-path extraction (extractSingleName), and the tree-operator
6
+ * client/server evaluation gate the sync engine keys off.
7
+ */
8
+
9
+ import { describe, expect, it } from "vitest";
10
+ import {
11
+ canEvaluateClientSide,
12
+ extractFilterFields,
13
+ extractSingleName,
14
+ FilterOperator,
15
+ formatFilter,
16
+ getClientEvaluationBlockers,
17
+ hasServerOnlyOperators,
18
+ isTreeOperator,
19
+ normalizeFilters,
20
+ validateFilters,
21
+ type FilterTuple,
22
+ } from "./filters";
23
+
24
+ const schema = [
25
+ { fieldname: "title", fieldtype: "Data" },
26
+ { fieldname: "amount", fieldtype: "Currency" },
27
+ { fieldname: "status", fieldtype: "Select" },
28
+ { fieldname: "attachment", fieldtype: "Attach" },
29
+ ];
30
+
31
+ describe("validateFilters", () => {
32
+ it("passes valid filters against the schema", () => {
33
+ const result = validateFilters(
34
+ [
35
+ ["title", "like", "%report%"],
36
+ ["amount", ">", 100],
37
+ ["status", "in", ["Open", "Closed"]],
38
+ ],
39
+ schema,
40
+ );
41
+ expect(result.valid).toBe(true);
42
+ expect(result.errors).toEqual([]);
43
+ expect(result.warnings).toEqual([]);
44
+ });
45
+
46
+ it("treats empty filters as valid", () => {
47
+ expect(validateFilters(null, schema).valid).toBe(true);
48
+ expect(validateFilters(undefined, schema).valid).toBe(true);
49
+ });
50
+
51
+ it("accepts standard fields that are not in the schema", () => {
52
+ const result = validateFilters([["modified", ">", "2024-01-01"]], schema);
53
+ expect(result.valid).toBe(true);
54
+ expect(result.warnings).toEqual([]);
55
+ });
56
+
57
+ it("warns about unknown fields by default but errors in strict mode", () => {
58
+ const lenient = validateFilters([["custom_field", "=", 1]], schema);
59
+ expect(lenient.valid).toBe(true);
60
+ expect(lenient.warnings[0]).toContain("custom_field");
61
+
62
+ const strict = validateFilters([["custom_field", "=", 1]], schema, { strict: true });
63
+ expect(strict.valid).toBe(false);
64
+ expect(strict.errors[0]).toMatchObject({ field: "custom_field", code: "unknown_field" });
65
+ });
66
+
67
+ it("rejects invalid operators", () => {
68
+ const result = validateFilters([["title", "resembles", "x"]], schema);
69
+ expect(result.valid).toBe(false);
70
+ expect(result.errors[0]).toMatchObject({ field: "title", code: "invalid_operator" });
71
+ });
72
+
73
+ it("warns when LIKE is used on non-text fields", () => {
74
+ const result = validateFilters([["amount", "like", "%5%"]], schema);
75
+ expect(result.valid).toBe(true);
76
+ expect(result.warnings[0]).toContain("LIKE operator on non-text field");
77
+ });
78
+
79
+ it("warns when comparisons hit non-comparable fields", () => {
80
+ const result = validateFilters([["attachment", ">", 3]], schema);
81
+ expect(result.valid).toBe(true);
82
+ expect(result.warnings[0]).toContain("Comparison operator on non-numeric/date field");
83
+ });
84
+
85
+ it("requires arrays for IN and exactly two values for BETWEEN", () => {
86
+ const inResult = validateFilters([["status", "in", "Open"]], schema);
87
+ expect(inResult.valid).toBe(false);
88
+ expect(inResult.errors[0].code).toBe("invalid_value");
89
+
90
+ const betweenResult = validateFilters([["amount", "between", [1]]], schema);
91
+ expect(betweenResult.valid).toBe(false);
92
+ expect(betweenResult.errors[0].code).toBe("invalid_value");
93
+
94
+ const ok = validateFilters([["amount", "between", [1, 10]]], schema);
95
+ expect(ok.valid).toBe(true);
96
+ });
97
+
98
+ it("validates object-format filters for unknown fields", () => {
99
+ const lenient = validateFilters({ ghost: 1, title: "x" }, schema);
100
+ expect(lenient.valid).toBe(true);
101
+ expect(lenient.warnings).toHaveLength(1);
102
+
103
+ const strict = validateFilters({ ghost: 1 }, schema, { strict: true });
104
+ expect(strict.valid).toBe(false);
105
+ expect(strict.errors[0].field).toBe("ghost");
106
+ });
107
+ });
108
+
109
+ describe("normalizeFilters / extractFilterFields", () => {
110
+ it("passes tuple filters through and converts object filters to equality tuples", () => {
111
+ const tuples: FilterTuple[] = [["title", "like", "%x%"]];
112
+ expect(normalizeFilters(tuples)).toBe(tuples);
113
+ expect(normalizeFilters({ status: "Open", amount: 5 })).toEqual([
114
+ ["status", FilterOperator.Equals, "Open"],
115
+ ["amount", FilterOperator.Equals, 5],
116
+ ]);
117
+ expect(normalizeFilters(null)).toEqual([]);
118
+ });
119
+
120
+ it("extracts unique filter field names", () => {
121
+ expect(
122
+ extractFilterFields([
123
+ ["title", "like", "%a%"],
124
+ ["title", "!=", "b"],
125
+ ["amount", ">", 1],
126
+ ]),
127
+ ).toEqual(["title", "amount"]);
128
+ expect(extractFilterFields(null)).toEqual([]);
129
+ });
130
+ });
131
+
132
+ describe("formatFilter", () => {
133
+ it("formats scalar, string, array, and null values", () => {
134
+ expect(formatFilter(["amount", ">", 5])).toBe("amount > 5");
135
+ expect(formatFilter(["title", "like", "%x%"])).toBe('title like "%x%"');
136
+ expect(formatFilter(["status", "in", ["a", "b"]])).toBe('status in ["a", "b"]');
137
+ expect(formatFilter(["parent", "is", null])).toBe("parent is null");
138
+ });
139
+ });
140
+
141
+ describe("extractSingleName (getDoc fast path)", () => {
142
+ it("extracts the name from a single name-equality tuple", () => {
143
+ expect(extractSingleName([["name", "=", "DOC-001"]])).toBe("DOC-001");
144
+ expect(extractSingleName([["name", "==", "DOC-002"]])).toBe("DOC-002");
145
+ });
146
+
147
+ it("extracts the name from an object filter", () => {
148
+ expect(extractSingleName({ name: "DOC-003" })).toBe("DOC-003");
149
+ });
150
+
151
+ it("refuses multi-filter, non-name, non-equality, and non-string cases", () => {
152
+ expect(
153
+ extractSingleName([
154
+ ["name", "=", "DOC-001"],
155
+ ["status", "=", "Open"],
156
+ ]),
157
+ ).toBeUndefined();
158
+ expect(extractSingleName([["title", "=", "DOC-001"]])).toBeUndefined();
159
+ expect(extractSingleName([["name", "like", "DOC-%"]])).toBeUndefined();
160
+ expect(extractSingleName([["name", "=", 42]])).toBeUndefined();
161
+ expect(extractSingleName(null)).toBeUndefined();
162
+ });
163
+ });
164
+
165
+ describe("tree-operator evaluation gate", () => {
166
+ it("classifies tree operators as server-only", () => {
167
+ expect(isTreeOperator("ancestors of")).toBe(true);
168
+ expect(isTreeOperator("DESCENDANTS OF")).toBe(true);
169
+ expect(isTreeOperator("not ancestors of")).toBe(true);
170
+ expect(isTreeOperator("not descendants of")).toBe(true);
171
+ expect(isTreeOperator("=")).toBe(false);
172
+ expect(isTreeOperator("like")).toBe(false);
173
+ });
174
+
175
+ it("detects server-only operators inside filters", () => {
176
+ expect(hasServerOnlyOperators([["parent", "ancestors of", "Root"]])).toBe(true);
177
+ expect(hasServerOnlyOperators([["title", "like", "%x%"]])).toBe(false);
178
+ expect(hasServerOnlyOperators(null)).toBe(false);
179
+ expect(hasServerOnlyOperators({ status: "Open" })).toBe(false);
180
+ });
181
+
182
+ it("canEvaluateClientSide is the inverse gate", () => {
183
+ expect(canEvaluateClientSide([["parent", "descendants of", "Root"]])).toBe(false);
184
+ expect(canEvaluateClientSide([["status", "=", "Open"]])).toBe(true);
185
+ });
186
+
187
+ it("explains exactly which fields block client evaluation", () => {
188
+ const blockers = getClientEvaluationBlockers([
189
+ ["parent", "ancestors of", "Root"],
190
+ ["status", "=", "Open"],
191
+ ]);
192
+ expect(blockers).toHaveLength(1);
193
+ expect(blockers[0]).toContain('"parent"');
194
+ expect(blockers[0]).toContain("ancestors of");
195
+ expect(getClientEvaluationBlockers(null)).toEqual([]);
196
+ });
197
+ });
package/src/sync/index.ts CHANGED
@@ -17,9 +17,16 @@ import type {
17
17
  SyncOptions,
18
18
  FrappeDebugState,
19
19
  Mutation,
20
+ RealtimeEventType,
20
21
  SubscriptionQuery,
21
22
  } from "./types";
22
23
 
24
+ /** Realtime event forwarded to `subscribeRealtimeEvents` listeners. */
25
+ export interface SyncRealtimeEvent {
26
+ type: RealtimeEventType;
27
+ payload?: unknown;
28
+ }
29
+
23
30
  /**
24
31
  * Synchronization engine that provides Zero-style UX on top of Frappe's REST API.
25
32
  *
@@ -70,6 +77,8 @@ export class SyncModule {
70
77
  private normalizedCache: NormalizedCache;
71
78
  private mutationJournal: MutationJournal;
72
79
  private storeListeners = new Set<() => void>();
80
+ /** Listeners registered via `subscribeRealtimeEvents`. */
81
+ private realtimeEventListeners = new Set<(event: SyncRealtimeEvent) => void>();
73
82
  private subscriptionManager: SubscriptionManager;
74
83
  /** Mutation engine for optimistic updates and conflict resolution. */
75
84
  private mutationEngine: MutationEngine;
@@ -81,16 +90,19 @@ export class SyncModule {
81
90
  private rehydrationManager: RehydrationManager;
82
91
  /** Cleanup functions returned by lifecycle subscriptions. */
83
92
  private cleanupFocus?: () => void;
93
+ private cleanupFocusReplay?: () => void;
84
94
  private cleanupOnlineBackfill?: () => void;
85
95
  private cleanupOnlineReplay?: () => void;
86
96
  /** Timer handle for periodic CDC polling. */
87
97
  private cdcIntervalHandle?: ReturnType<typeof setInterval>;
88
-
89
- constructor(
90
- private readonly db: DbModule,
91
- private readonly realtime?: RealtimeModule,
92
- private readonly options: SyncOptions = {},
93
- ) {
98
+ private readonly db: DbModule;
99
+ private readonly realtime?: RealtimeModule;
100
+ private readonly options: SyncOptions;
101
+
102
+ constructor(db: DbModule, realtime?: RealtimeModule, options: SyncOptions = {}) {
103
+ this.db = db;
104
+ this.realtime = realtime;
105
+ this.options = options;
94
106
  // Initialize normalized cache with LRU eviction if maxCacheSize is set
95
107
  this.normalizedCache = new NormalizedCache({
96
108
  maxSize: this.options.maxCacheSize,
@@ -108,6 +120,7 @@ export class SyncModule {
108
120
  this.normalizedCache,
109
121
  this.subscriptionManager,
110
122
  this.mutationJournal,
123
+ () => this.emit(),
111
124
  );
112
125
 
113
126
  this.mutationEngine = new MutationEngine(
@@ -125,6 +138,13 @@ export class SyncModule {
125
138
  ...this.options,
126
139
  onResetCache: () => this.resetCache(),
127
140
  onBackfillAll: () => this.backfill({ scope: BackfillScope.All }),
141
+ // Realtime reconciliation mutates cache/membership outside the public
142
+ // mutate/backfill entry points — bridge those changes to store listeners.
143
+ onStoreChange: () => this.emit(),
144
+ onRealtimeEvent: (event) => {
145
+ this.options.onRealtimeEvent?.(event);
146
+ for (const listener of this.realtimeEventListeners) listener(event);
147
+ },
128
148
  };
129
149
 
130
150
  this.realtimeHandler = new RealtimeHandler(
@@ -153,6 +173,13 @@ export class SyncModule {
153
173
  */
154
174
  private setupWindowEvents() {
155
175
  this.cleanupFocus = onAppFocus(() => this.backfill({ scope: BackfillScope.All }));
176
+ // Journal replay on foreground: React Native never fires `online`
177
+ // (AppState is its only lifecycle signal), and on web this recovers
178
+ // server-restart cases where connectivity never flipped. Guarded so it
179
+ // is a strict no-op unless mutations are actually queued.
180
+ this.cleanupFocusReplay = onAppFocus(() => {
181
+ if (this.mutationJournal.listPending().length > 0) void this.replayPending();
182
+ });
156
183
  this.cleanupOnlineBackfill = onOnline(() => this.backfill({ scope: BackfillScope.All }));
157
184
  this.cleanupOnlineReplay = onOnline(() => this.replayPending());
158
185
 
@@ -166,10 +193,25 @@ export class SyncModule {
166
193
 
167
194
  /**
168
195
  * Creates a subscription, seeds cache with initial rows, and stores a backfill checkpoint.
196
+ *
197
+ * With persistence enabled, a query matching a subscription restored from
198
+ * the snapshot is re-adopted cache-first: the returned rows come from the
199
+ * restored cache and a background network refresh follows (`result.refresh`).
200
+ * If that refresh fails (offline), the cached membership keeps serving and
201
+ * the subscription is marked stale until the next successful backfill.
169
202
  */
170
203
  async subscribe<Data extends FrappeDocData>(query: SubscriptionQuery) {
204
+ // Wait for any persisted snapshot restore so a matching restored
205
+ // subscription can be adopted instead of racing the async load.
206
+ await this.persistenceManager.whenReady();
171
207
  const result = await this.subscriptionManager.subscribe<Data>(query);
208
+ // Join the doctype's realtime room so doc_update/list_update hints arrive
209
+ // for this subscription (refcounted; survives reconnects).
210
+ this.realtimeHandler.watchDoctype(query.doctype);
172
211
  this.emit();
212
+ // Adopted subscriptions refresh in the background; notify store listeners
213
+ // when the refresh lands (or marks the subscription stale). Never rejects.
214
+ if (result.refresh) void result.refresh.then(() => this.emit());
173
215
  return result;
174
216
  }
175
217
 
@@ -177,7 +219,9 @@ export class SyncModule {
177
219
  * Removes a subscription by id.
178
220
  */
179
221
  unsubscribe(subscriptionId: string) {
222
+ const subscription = this.subscriptionManager.getSubscription(subscriptionId);
180
223
  this.subscriptionManager.unsubscribe(subscriptionId);
224
+ if (subscription) this.realtimeHandler.unwatchDoctype(subscription.query.doctype);
181
225
  this.emit();
182
226
  }
183
227
 
@@ -279,6 +323,44 @@ export class SyncModule {
279
323
  };
280
324
  }
281
325
 
326
+ /**
327
+ * Registers a listener for raw realtime events (doc_update, list_update,
328
+ * doc_deleted, connected, …). Useful for consumers that manage their own
329
+ * fetching (e.g. server-side paginated tables) but still want live
330
+ * invalidation hints. Returns an unsubscribe function.
331
+ */
332
+ subscribeRealtimeEvents(listener: (event: SyncRealtimeEvent) => void): () => void {
333
+ this.realtimeEventListeners.add(listener);
334
+ return () => {
335
+ this.realtimeEventListeners.delete(listener);
336
+ };
337
+ }
338
+
339
+ /**
340
+ * Joins the realtime doctype room without creating a data subscription
341
+ * (refcounted). Pair with `unwatchDoctype` on cleanup. Used by consumers
342
+ * that fetch their own data but need the doctype's realtime hints.
343
+ */
344
+ watchDoctype(doctype: string): void {
345
+ this.realtimeHandler.watchDoctype(doctype);
346
+ }
347
+
348
+ /** Releases one `watchDoctype` reference. */
349
+ unwatchDoctype(doctype: string): void {
350
+ this.realtimeHandler.unwatchDoctype(doctype);
351
+ }
352
+
353
+ /**
354
+ * Live socket connection snapshot. `connected` is the state right now;
355
+ * `everConnected` distinguishes "reconnecting" from "realtime never up"
356
+ * (fixture mode, SSR, or no realtime module). Store listeners are
357
+ * notified on every flip, so read this inside a `subscribeStore` callback
358
+ * for a reactive indicator.
359
+ */
360
+ getConnectionState(): { connected: boolean; everConnected: boolean } {
361
+ return this.realtimeHandler.getConnectionState();
362
+ }
363
+
282
364
  /** Notifies listeners, schedules persistence, and broadcasts cross-tab changes. */
283
365
  private emit() {
284
366
  // Fan out local state changes to all subscribers
@@ -291,6 +373,8 @@ export class SyncModule {
291
373
 
292
374
  /** Clears subscriptions, cache, journal, and temp id mappings. */
293
375
  resetCache() {
376
+ // Leave all realtime doctype rooms alongside dropping the subscriptions
377
+ this.realtimeHandler.unwatchAll();
294
378
  // Drop all live subs, in-memory cache, journal, and temp mappings
295
379
  this.subscriptionManager.clear();
296
380
  this.normalizedCache.clear();
@@ -304,6 +388,7 @@ export class SyncModule {
304
388
  async dispose() {
305
389
  // Clear all listeners
306
390
  this.storeListeners.clear();
391
+ this.realtimeEventListeners.clear();
307
392
 
308
393
  // Clear subscriptions and cache
309
394
  this.resetCache();
@@ -317,9 +402,11 @@ export class SyncModule {
317
402
 
318
403
  // Remove lifecycle event listeners
319
404
  this.cleanupFocus?.();
405
+ this.cleanupFocusReplay?.();
320
406
  this.cleanupOnlineBackfill?.();
321
407
  this.cleanupOnlineReplay?.();
322
408
  this.cleanupFocus = undefined;
409
+ this.cleanupFocusReplay = undefined;
323
410
  this.cleanupOnlineBackfill = undefined;
324
411
  this.cleanupOnlineReplay = undefined;
325
412
 
@@ -350,6 +437,8 @@ export class SyncModule {
350
437
  tombstoneCount: sub.tombstones?.size ?? 0,
351
438
  checkpoint: sub.checkpoint,
352
439
  cursor: sub.cursor,
440
+ stale: sub.stale,
441
+ restored: this.subscriptionManager.isRestoredSubscription(sub.id),
353
442
  pageInfo,
354
443
  };
355
444
 
@@ -398,7 +487,9 @@ export class SyncModule {
398
487
  connection: {
399
488
  socketConnected: this.realtimeHandler.getIsConnected(),
400
489
  isLeader: this.persistenceManager.getIsLeader(),
401
- isOnline: typeof navigator !== "undefined" ? navigator.onLine : true,
490
+ // React Native has navigator but no onLine (undefined) — treat
491
+ // anything other than an explicit false as online.
492
+ isOnline: typeof navigator === "undefined" || navigator.onLine !== false,
402
493
  },
403
494
  };
404
495
  }
package/src/sync/merge.ts CHANGED
@@ -32,7 +32,7 @@ export function isObject(value: FrappeDocValue): value is Record<string, FrappeD
32
32
  return typeof value === "object" && value !== null && !Array.isArray(value);
33
33
  }
34
34
 
35
- export function isFrappeDoc(value: unknown): value is FrappeDoc<FrappeDocData> {
35
+ function isFrappeDoc(value: unknown): value is FrappeDoc<FrappeDocData> {
36
36
  return (
37
37
  typeof value === "object" &&
38
38
  value !== null &&
@@ -290,7 +290,7 @@ export function merge<Data extends FrappeDocData = FrappeDocData>(
290
290
  };
291
291
  }
292
292
 
293
- export function mergeObject(
293
+ function mergeObject(
294
294
  base: Record<string, FrappeDocValue>,
295
295
  client: Record<string, FrappeDocValue>,
296
296
  server: Record<string, FrappeDocValue>,
@@ -416,7 +416,7 @@ export function mergeChildTable(
416
416
  return sortChildTableByIdx(result);
417
417
  }
418
418
 
419
- export function sortChildTableByIdx(value: FrappeDocValue[]): FrappeDocValue[] {
419
+ function sortChildTableByIdx(value: FrappeDocValue[]): FrappeDocValue[] {
420
420
  const hasIndexField = value.some(
421
421
  (row) => isChildTableRow(row) && row.idx !== null && typeof row.idx === "number",
422
422
  );
@@ -603,6 +603,38 @@ describe("MutationEngine", () => {
603
603
  // Should not fetch the document after successful mutation
604
604
  expect(mockDb.getDoc).not.toHaveBeenCalled();
605
605
  });
606
+
607
+ it("should not refetch the deleted doc itself on delete when realtime is unhealthy", async () => {
608
+ // Regression: the post-mutation refetch used to include the DELETED
609
+ // doc — the server 404s, routing a confirmed delete into the
610
+ // error/rollback path (surfaced by FrappeTreeView's live delete spec
611
+ // running against a realtime-less fixture sync module).
612
+ mockRealtime.isHealthy.mockReturnValue(false);
613
+ mockDb.getDoc.mockClear();
614
+ mockDb.getDoc.mockImplementation(async (doctype: string, name: string) => {
615
+ if (doctype === "TestDoc" && name === "test-doc") {
616
+ throw new Error(`Document ${doctype}/${name} not found`);
617
+ }
618
+ return { ...mockDoc, doctype, name };
619
+ });
620
+
621
+ const mutation: DeleteMutation<FrappeDocData> = {
622
+ mutationId: "mut-del-refetch",
623
+ operation: Operation.Delete,
624
+ doc: { doctype: "TestDoc", name: "test-doc" },
625
+ version: undefined,
626
+ affected: [{ doctype: "RelatedDoc", name: "related-doc" }],
627
+ };
628
+
629
+ await mutationEngine.mutate(mutation);
630
+
631
+ // The tombstoned doc is never refetched…
632
+ expect(mockDb.getDoc).not.toHaveBeenCalledWith("TestDoc", "test-doc");
633
+ // …while related docs still refresh.
634
+ expect(mockDb.getDoc).toHaveBeenCalledWith("RelatedDoc", "related-doc");
635
+ expect(mockMutationJournal.confirm).toHaveBeenCalledWith("mut-del-refetch");
636
+ expect(mockMutationJournal.fail).not.toHaveBeenCalled();
637
+ });
606
638
  });
607
639
  });
608
640
 
@@ -680,8 +712,8 @@ describe("MutationEngine", () => {
680
712
 
681
713
  await expect(mutationEngine.mutate(mutation)).rejects.toThrow("Update failed");
682
714
 
683
- // Should restore snapshot
684
- expect(mockNormalizedCache.upsert).toHaveBeenCalledWith(mockDoc);
715
+ // Should restore snapshot wholesale (replace, not merge)
716
+ expect(mockNormalizedCache.upsert).toHaveBeenCalledWith(mockDoc, { replace: true });
685
717
  });
686
718
 
687
719
  it("should not rollback when offline", async () => {
@@ -1022,8 +1054,8 @@ describe("MutationEngine", () => {
1022
1054
 
1023
1055
  // Should still attempt snapshot rollback (upsert is called twice: once for optimistic update, once for rollback)
1024
1056
  expect(mockNormalizedCache.upsert).toHaveBeenCalledTimes(2);
1025
- // Last call should be the rollback with original snapshot
1026
- expect(mockNormalizedCache.upsert).toHaveBeenLastCalledWith(mockDoc);
1057
+ // Last call should be the rollback with original snapshot (wholesale replace)
1058
+ expect(mockNormalizedCache.upsert).toHaveBeenLastCalledWith(mockDoc, { replace: true });
1027
1059
  });
1028
1060
 
1029
1061
  it("should handle custom version fields", async () => {
@@ -47,16 +47,30 @@ export class MutationEngine {
47
47
  private pendingBatch: PendingBatchMutation<FrappeDocData>[] = [];
48
48
  /** Debouncer for batch processing */
49
49
  private batchDebouncer: Debouncer<() => Promise<void>>;
50
+ private readonly db: DbModule;
51
+ private readonly realtime: RealtimeModule | undefined;
52
+ private readonly normalizedCache: NormalizedCache;
53
+ private readonly mutationJournal: MutationJournal;
54
+ private readonly subscriptionManager: SubscriptionManager;
55
+ private readonly rehydrationManager: RehydrationManager;
56
+ private readonly options: SyncOptions;
50
57
 
51
58
  constructor(
52
- private readonly db: DbModule,
53
- private readonly realtime: RealtimeModule | undefined,
54
- private readonly normalizedCache: NormalizedCache,
55
- private readonly mutationJournal: MutationJournal,
56
- private readonly subscriptionManager: SubscriptionManager,
57
- private readonly rehydrationManager: RehydrationManager,
58
- private readonly options: SyncOptions = {},
59
+ db: DbModule,
60
+ realtime: RealtimeModule | undefined,
61
+ normalizedCache: NormalizedCache,
62
+ mutationJournal: MutationJournal,
63
+ subscriptionManager: SubscriptionManager,
64
+ rehydrationManager: RehydrationManager,
65
+ options: SyncOptions = {},
59
66
  ) {
67
+ this.db = db;
68
+ this.realtime = realtime;
69
+ this.normalizedCache = normalizedCache;
70
+ this.mutationJournal = mutationJournal;
71
+ this.subscriptionManager = subscriptionManager;
72
+ this.rehydrationManager = rehydrationManager;
73
+ this.options = options;
60
74
  // Initialize batch debouncer
61
75
  const batchDelay = options.batchDelay ?? 100;
62
76
  this.batchDebouncer = new Debouncer(() => this.flushBatch(), { wait: batchDelay });
@@ -434,7 +448,11 @@ export class MutationEngine {
434
448
  const docname = mutation.doc.name;
435
449
  const doctype = mutation.doc.doctype;
436
450
  const realName = (docname && this.temporaryIdToRealNameMap.get(docname)) || docname;
437
- if (realName) targets.push({ doctype, name: realName });
451
+ // A deleted doc no longer exists server-side — refetching it would 404
452
+ // and route a server-confirmed delete into the error/rollback path.
453
+ if (realName && mutation.operation !== Operation.Delete) {
454
+ targets.push({ doctype, name: realName });
455
+ }
438
456
  if (mutation.affected?.length) targets.push(...mutation.affected);
439
457
  // Fetch each target with user context to respect permissions and hidden fields
440
458
  for (const target of targets) {
@@ -493,9 +511,10 @@ export class MutationEngine {
493
511
  break;
494
512
 
495
513
  case Operation.Update:
496
- // Restore the original document from snapshot
514
+ // Restore the original document from snapshot (wholesale: an
515
+ // optimistic update may have added keys the snapshot never had)
497
516
  if (entry?.snapshot && docname) {
498
- this.normalizedCache.upsert(entry.snapshot);
517
+ this.normalizedCache.upsert(entry.snapshot, { replace: true });
499
518
  // Also update subscription memberships in case filters changed
500
519
  this.subscriptionManager.updateSubscriptionMembership(
501
520
  entry.snapshot as FrappeDoc<FrappeDocData>,
@@ -506,7 +525,7 @@ export class MutationEngine {
506
525
  case Operation.Delete:
507
526
  // Restore the deleted document from snapshot
508
527
  if (entry?.snapshot && docname) {
509
- this.normalizedCache.upsert(entry.snapshot);
528
+ this.normalizedCache.upsert(entry.snapshot, { replace: true });
510
529
  // Re-add to subscription memberships
511
530
  const restoredDoc = entry.snapshot as FrappeDoc<FrappeDocData>;
512
531
  for (const subscription of this.subscriptionManager.getAllSubscriptions().values()) {
@@ -27,6 +27,7 @@ export interface MutationJournalOptions {
27
27
 
28
28
  export class MutationJournal {
29
29
  private cleanupTimer?: ReturnType<typeof setInterval>;
30
+ private autoCleanupEnabled: boolean;
30
31
  private ttl = 24 * 60 * 60 * 1000;
31
32
  private pending = new Map<string, Pending>();
32
33
  private sequenceNumber = 0;
@@ -40,9 +41,12 @@ export class MutationJournal {
40
41
  this.storage = options.storage;
41
42
  this.loadSequenceNumber();
42
43
  }
43
- if (options?.enableAutoCleanup !== false) {
44
- this.startAutoCleanup();
45
- }
44
+ // Auto-cleanup is armed lazily on the first add() rather than at
45
+ // construction: an empty journal has nothing to expire, and an
46
+ // unconditional interval was a leaked handle for every SyncModule that
47
+ // never mutated (one per fixture set in tests/stories — the pending
48
+ // hour-long timers helped wedge vitest forks-worker teardown).
49
+ this.autoCleanupEnabled = options?.enableAutoCleanup !== false;
46
50
  }
47
51
 
48
52
  add(id: string, entry: Pending) {
@@ -51,6 +55,7 @@ export class MutationJournal {
51
55
  if (entry.ttl === undefined) entry.ttl = this.ttl;
52
56
  if (entry.retryCount === undefined) entry.retryCount = 0;
53
57
  this.pending.set(id, entry);
58
+ if (this.autoCleanupEnabled) this.startAutoCleanup();
54
59
  this.persistSequenceNumber();
55
60
  }
56
61
 
@@ -124,6 +129,7 @@ export class MutationJournal {
124
129
 
125
130
  clear() {
126
131
  this.pending.clear();
132
+ this.stopAutoCleanup();
127
133
  }
128
134
 
129
135
  dispose() {
@@ -141,7 +147,15 @@ export class MutationJournal {
141
147
  }
142
148
 
143
149
  private startAutoCleanup() {
144
- this.cleanupTimer = setInterval(() => this.cleanupExpired(), 60 * 60 * 1000);
150
+ if (this.cleanupTimer) return;
151
+ this.cleanupTimer = setInterval(
152
+ () => {
153
+ this.cleanupExpired();
154
+ // Disarm once drained; the next add() re-arms.
155
+ if (this.pending.size === 0) this.stopAutoCleanup();
156
+ },
157
+ 60 * 60 * 1000,
158
+ );
145
159
  }
146
160
 
147
161
  private loadSequenceNumber() {