svelte-firekit 0.1.9 → 0.2.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 (440) hide show
  1. package/README.md +550 -354
  2. package/dist/components/AuthGuard.svelte +64 -0
  3. package/dist/components/AuthGuard.svelte.d.ts +15 -0
  4. package/dist/components/Collection.svelte +62 -0
  5. package/dist/components/Collection.svelte.d.ts +39 -0
  6. package/dist/components/CustomGuard.svelte +87 -0
  7. package/dist/components/CustomGuard.svelte.d.ts +13 -0
  8. package/dist/components/Doc.svelte +56 -0
  9. package/dist/components/Doc.svelte.d.ts +36 -0
  10. package/dist/components/DownloadURL.svelte +48 -0
  11. package/dist/components/DownloadURL.svelte.d.ts +14 -0
  12. package/dist/components/FirebaseApp.svelte +81 -0
  13. package/dist/components/FirebaseApp.svelte.d.ts +12 -0
  14. package/dist/components/Node.svelte +54 -0
  15. package/dist/components/Node.svelte.d.ts +36 -0
  16. package/dist/components/SignedIn.svelte +22 -0
  17. package/dist/components/{firekit/signed-in.svelte.d.ts → SignedIn.svelte.d.ts} +1 -4
  18. package/dist/components/SignedOut.svelte +32 -0
  19. package/dist/components/{firekit/signed-out.svelte.d.ts → SignedOut.svelte.d.ts} +3 -5
  20. package/dist/components/UploadTask.svelte +75 -0
  21. package/dist/components/UploadTask.svelte.d.ts +33 -0
  22. package/dist/config.d.ts +29 -6
  23. package/dist/config.js +37 -74
  24. package/dist/context.d.ts +46 -0
  25. package/dist/context.js +56 -0
  26. package/dist/firebase.d.ts +25 -84
  27. package/dist/firebase.js +75 -125
  28. package/dist/index.d.ts +32 -20
  29. package/dist/index.js +49 -30
  30. package/dist/services/ai.svelte.d.ts +152 -0
  31. package/dist/services/ai.svelte.js +302 -0
  32. package/dist/services/analytics.d.ts +39 -231
  33. package/dist/services/analytics.js +89 -421
  34. package/dist/services/app-check.svelte.d.ts +82 -0
  35. package/dist/services/app-check.svelte.js +159 -0
  36. package/dist/services/auth.d.ts +63 -352
  37. package/dist/services/auth.js +353 -718
  38. package/dist/services/bundles.d.ts +42 -0
  39. package/dist/services/bundles.js +57 -0
  40. package/dist/services/callable.d.ts +57 -0
  41. package/dist/services/callable.js +115 -0
  42. package/dist/services/collection.svelte.d.ts +154 -221
  43. package/dist/services/collection.svelte.js +357 -663
  44. package/dist/services/document.svelte.d.ts +73 -254
  45. package/dist/services/document.svelte.js +196 -497
  46. package/dist/services/in-app-messaging.d.ts +46 -0
  47. package/dist/services/in-app-messaging.js +88 -0
  48. package/dist/services/messaging.svelte.d.ts +75 -0
  49. package/dist/services/messaging.svelte.js +190 -0
  50. package/dist/services/mutations.d.ts +59 -282
  51. package/dist/services/mutations.js +202 -951
  52. package/dist/services/performance.d.ts +60 -0
  53. package/dist/services/performance.js +118 -0
  54. package/dist/services/presence.svelte.d.ts +21 -89
  55. package/dist/services/presence.svelte.js +232 -469
  56. package/dist/services/realtime.svelte.d.ts +54 -125
  57. package/dist/services/realtime.svelte.js +111 -175
  58. package/dist/services/remote-config.svelte.d.ts +73 -0
  59. package/dist/services/remote-config.svelte.js +204 -0
  60. package/dist/services/storage.svelte.d.ts +81 -208
  61. package/dist/services/storage.svelte.js +190 -305
  62. package/dist/services/user.svelte.d.ts +23 -244
  63. package/dist/services/user.svelte.js +129 -439
  64. package/dist/types/analytics.d.ts +2 -36
  65. package/dist/types/analytics.js +0 -5
  66. package/dist/types/auth.d.ts +15 -85
  67. package/dist/types/auth.js +0 -17
  68. package/dist/types/collection.d.ts +31 -225
  69. package/dist/types/collection.js +5 -51
  70. package/dist/types/document.d.ts +11 -236
  71. package/dist/types/document.js +2 -47
  72. package/dist/types/firebase.d.ts +10 -13
  73. package/dist/types/firebase.js +3 -9
  74. package/dist/types/index.d.ts +5 -5
  75. package/dist/types/index.js +5 -4
  76. package/dist/types/mutations.d.ts +11 -225
  77. package/dist/types/mutations.js +6 -51
  78. package/dist/types/presence.d.ts +5 -158
  79. package/dist/types/presence.js +0 -20
  80. package/dist/utils/errors.d.ts +10 -14
  81. package/dist/utils/errors.js +11 -16
  82. package/dist/utils/firestore.d.ts +3 -4
  83. package/dist/utils/firestore.js +7 -10
  84. package/dist/utils/index.d.ts +4 -4
  85. package/dist/utils/index.js +4 -8
  86. package/dist/utils/providers.d.ts +4 -13
  87. package/dist/utils/providers.js +14 -13
  88. package/dist/utils/user.d.ts +1 -3
  89. package/dist/utils/user.js +1 -3
  90. package/package.json +41 -55
  91. package/dist/components/docs/doc-content.svelte +0 -19
  92. package/dist/components/docs/doc-content.svelte.d.ts +0 -6
  93. package/dist/components/docs/doc-header.svelte +0 -24
  94. package/dist/components/docs/doc-header.svelte.d.ts +0 -13
  95. package/dist/components/docs/doc-renderer.svelte +0 -27
  96. package/dist/components/docs/doc-renderer.svelte.d.ts +0 -8
  97. package/dist/components/docs/mobile-table-of-contents.svelte +0 -42
  98. package/dist/components/docs/mobile-table-of-contents.svelte.d.ts +0 -3
  99. package/dist/components/docs/table-of-contents.svelte +0 -33
  100. package/dist/components/docs/table-of-contents.svelte.d.ts +0 -4
  101. package/dist/components/docs/toc.svelte.d.ts +0 -16
  102. package/dist/components/docs/toc.svelte.js +0 -59
  103. package/dist/components/firekit/Collection.svelte +0 -122
  104. package/dist/components/firekit/Collection.svelte.d.ts +0 -27
  105. package/dist/components/firekit/Doc.svelte +0 -140
  106. package/dist/components/firekit/Doc.svelte.d.ts +0 -28
  107. package/dist/components/firekit/Node.svelte +0 -97
  108. package/dist/components/firekit/Node.svelte.d.ts +0 -23
  109. package/dist/components/firekit/auth-guard.svelte +0 -120
  110. package/dist/components/firekit/auth-guard.svelte.d.ts +0 -26
  111. package/dist/components/firekit/custom-guard.svelte +0 -163
  112. package/dist/components/firekit/custom-guard.svelte.d.ts +0 -31
  113. package/dist/components/firekit/download-url.svelte +0 -92
  114. package/dist/components/firekit/download-url.svelte.d.ts +0 -19
  115. package/dist/components/firekit/firebase-app.svelte +0 -33
  116. package/dist/components/firekit/firebase-app.svelte.d.ts +0 -7
  117. package/dist/components/firekit/node-list.svelte +0 -102
  118. package/dist/components/firekit/node-list.svelte.d.ts +0 -27
  119. package/dist/components/firekit/signed-in.svelte +0 -42
  120. package/dist/components/firekit/signed-out.svelte +0 -42
  121. package/dist/components/firekit/storage-list.svelte +0 -97
  122. package/dist/components/firekit/storage-list.svelte.d.ts +0 -26
  123. package/dist/components/firekit/upload-task.svelte +0 -108
  124. package/dist/components/firekit/upload-task.svelte.d.ts +0 -24
  125. package/dist/components/nav/app-sidebar.svelte +0 -175
  126. package/dist/components/nav/app-sidebar.svelte.d.ts +0 -9
  127. package/dist/components/nav/auto-breadcrumb.svelte +0 -41
  128. package/dist/components/nav/auto-breadcrumb.svelte.d.ts +0 -3
  129. package/dist/components/nav/dark-mode-toggle.svelte +0 -17
  130. package/dist/components/nav/dark-mode-toggle.svelte.d.ts +0 -18
  131. package/dist/components/nav/nav-components.svelte +0 -24
  132. package/dist/components/nav/nav-components.svelte.d.ts +0 -11
  133. package/dist/components/nav/nav-main.svelte +0 -45
  134. package/dist/components/nav/nav-main.svelte.d.ts +0 -11
  135. package/dist/components/nav/nav-secondary.svelte +0 -32
  136. package/dist/components/nav/nav-secondary.svelte.d.ts +0 -14
  137. package/dist/components/nav/site-header.svelte +0 -32
  138. package/dist/components/nav/site-header.svelte.d.ts +0 -18
  139. package/dist/components/ui/avatar/avatar-fallback.svelte +0 -17
  140. package/dist/components/ui/avatar/avatar-fallback.svelte.d.ts +0 -4
  141. package/dist/components/ui/avatar/avatar-image.svelte +0 -17
  142. package/dist/components/ui/avatar/avatar-image.svelte.d.ts +0 -4
  143. package/dist/components/ui/avatar/avatar.svelte +0 -19
  144. package/dist/components/ui/avatar/avatar.svelte.d.ts +0 -4
  145. package/dist/components/ui/avatar/index.d.ts +0 -4
  146. package/dist/components/ui/avatar/index.js +0 -6
  147. package/dist/components/ui/badge/badge.svelte +0 -50
  148. package/dist/components/ui/badge/badge.svelte.d.ts +0 -32
  149. package/dist/components/ui/badge/index.d.ts +0 -2
  150. package/dist/components/ui/badge/index.js +0 -2
  151. package/dist/components/ui/breadcrumb/breadcrumb-ellipsis.svelte +0 -23
  152. package/dist/components/ui/breadcrumb/breadcrumb-ellipsis.svelte.d.ts +0 -5
  153. package/dist/components/ui/breadcrumb/breadcrumb-item.svelte +0 -20
  154. package/dist/components/ui/breadcrumb/breadcrumb-item.svelte.d.ts +0 -5
  155. package/dist/components/ui/breadcrumb/breadcrumb-link.svelte +0 -31
  156. package/dist/components/ui/breadcrumb/breadcrumb-link.svelte.d.ts +0 -11
  157. package/dist/components/ui/breadcrumb/breadcrumb-list.svelte +0 -23
  158. package/dist/components/ui/breadcrumb/breadcrumb-list.svelte.d.ts +0 -5
  159. package/dist/components/ui/breadcrumb/breadcrumb-page.svelte +0 -23
  160. package/dist/components/ui/breadcrumb/breadcrumb-page.svelte.d.ts +0 -5
  161. package/dist/components/ui/breadcrumb/breadcrumb-separator.svelte +0 -27
  162. package/dist/components/ui/breadcrumb/breadcrumb-separator.svelte.d.ts +0 -5
  163. package/dist/components/ui/breadcrumb/breadcrumb.svelte +0 -21
  164. package/dist/components/ui/breadcrumb/breadcrumb.svelte.d.ts +0 -5
  165. package/dist/components/ui/breadcrumb/index.d.ts +0 -8
  166. package/dist/components/ui/breadcrumb/index.js +0 -10
  167. package/dist/components/ui/button/button.svelte +0 -80
  168. package/dist/components/ui/button/button.svelte.d.ts +0 -58
  169. package/dist/components/ui/button/index.d.ts +0 -2
  170. package/dist/components/ui/button/index.js +0 -4
  171. package/dist/components/ui/card/card-action.svelte +0 -20
  172. package/dist/components/ui/card/card-action.svelte.d.ts +0 -5
  173. package/dist/components/ui/card/card-content.svelte +0 -15
  174. package/dist/components/ui/card/card-content.svelte.d.ts +0 -5
  175. package/dist/components/ui/card/card-description.svelte +0 -20
  176. package/dist/components/ui/card/card-description.svelte.d.ts +0 -5
  177. package/dist/components/ui/card/card-footer.svelte +0 -20
  178. package/dist/components/ui/card/card-footer.svelte.d.ts +0 -5
  179. package/dist/components/ui/card/card-header.svelte +0 -23
  180. package/dist/components/ui/card/card-header.svelte.d.ts +0 -5
  181. package/dist/components/ui/card/card-title.svelte +0 -20
  182. package/dist/components/ui/card/card-title.svelte.d.ts +0 -5
  183. package/dist/components/ui/card/card.svelte +0 -23
  184. package/dist/components/ui/card/card.svelte.d.ts +0 -5
  185. package/dist/components/ui/card/index.d.ts +0 -8
  186. package/dist/components/ui/card/index.js +0 -10
  187. package/dist/components/ui/chart/chart-container.svelte +0 -80
  188. package/dist/components/ui/chart/chart-container.svelte.d.ts +0 -9
  189. package/dist/components/ui/chart/chart-style.svelte +0 -36
  190. package/dist/components/ui/chart/chart-style.svelte.d.ts +0 -8
  191. package/dist/components/ui/chart/chart-tooltip.svelte +0 -159
  192. package/dist/components/ui/chart/chart-tooltip.svelte.d.ts +0 -27
  193. package/dist/components/ui/chart/chart-utils.d.ts +0 -36
  194. package/dist/components/ui/chart/chart-utils.js +0 -33
  195. package/dist/components/ui/chart/index.d.ts +0 -4
  196. package/dist/components/ui/chart/index.js +0 -4
  197. package/dist/components/ui/checkbox/checkbox.svelte +0 -36
  198. package/dist/components/ui/checkbox/checkbox.svelte.d.ts +0 -4
  199. package/dist/components/ui/checkbox/index.d.ts +0 -2
  200. package/dist/components/ui/checkbox/index.js +0 -4
  201. package/dist/components/ui/data-table/data-table.svelte.d.ts +0 -40
  202. package/dist/components/ui/data-table/data-table.svelte.js +0 -110
  203. package/dist/components/ui/data-table/flex-render.svelte +0 -36
  204. package/dist/components/ui/data-table/flex-render.svelte.d.ts +0 -30
  205. package/dist/components/ui/data-table/index.d.ts +0 -3
  206. package/dist/components/ui/data-table/index.js +0 -3
  207. package/dist/components/ui/data-table/render-helpers.d.ts +0 -90
  208. package/dist/components/ui/data-table/render-helpers.js +0 -99
  209. package/dist/components/ui/dialog/dialog-close.svelte +0 -7
  210. package/dist/components/ui/dialog/dialog-close.svelte.d.ts +0 -4
  211. package/dist/components/ui/dialog/dialog-content.svelte +0 -43
  212. package/dist/components/ui/dialog/dialog-content.svelte.d.ts +0 -11
  213. package/dist/components/ui/dialog/dialog-description.svelte +0 -17
  214. package/dist/components/ui/dialog/dialog-description.svelte.d.ts +0 -4
  215. package/dist/components/ui/dialog/dialog-footer.svelte +0 -20
  216. package/dist/components/ui/dialog/dialog-footer.svelte.d.ts +0 -5
  217. package/dist/components/ui/dialog/dialog-header.svelte +0 -20
  218. package/dist/components/ui/dialog/dialog-header.svelte.d.ts +0 -5
  219. package/dist/components/ui/dialog/dialog-overlay.svelte +0 -20
  220. package/dist/components/ui/dialog/dialog-overlay.svelte.d.ts +0 -4
  221. package/dist/components/ui/dialog/dialog-title.svelte +0 -17
  222. package/dist/components/ui/dialog/dialog-title.svelte.d.ts +0 -4
  223. package/dist/components/ui/dialog/dialog-trigger.svelte +0 -7
  224. package/dist/components/ui/dialog/dialog-trigger.svelte.d.ts +0 -4
  225. package/dist/components/ui/dialog/index.d.ts +0 -11
  226. package/dist/components/ui/dialog/index.js +0 -14
  227. package/dist/components/ui/drawer/drawer-close.svelte +0 -7
  228. package/dist/components/ui/drawer/drawer-close.svelte.d.ts +0 -4
  229. package/dist/components/ui/drawer/drawer-content.svelte +0 -37
  230. package/dist/components/ui/drawer/drawer-content.svelte.d.ts +0 -7
  231. package/dist/components/ui/drawer/drawer-description.svelte +0 -17
  232. package/dist/components/ui/drawer/drawer-description.svelte.d.ts +0 -4
  233. package/dist/components/ui/drawer/drawer-footer.svelte +0 -20
  234. package/dist/components/ui/drawer/drawer-footer.svelte.d.ts +0 -5
  235. package/dist/components/ui/drawer/drawer-header.svelte +0 -20
  236. package/dist/components/ui/drawer/drawer-header.svelte.d.ts +0 -5
  237. package/dist/components/ui/drawer/drawer-nested.svelte +0 -12
  238. package/dist/components/ui/drawer/drawer-nested.svelte.d.ts +0 -3
  239. package/dist/components/ui/drawer/drawer-overlay.svelte +0 -20
  240. package/dist/components/ui/drawer/drawer-overlay.svelte.d.ts +0 -4
  241. package/dist/components/ui/drawer/drawer-title.svelte +0 -17
  242. package/dist/components/ui/drawer/drawer-title.svelte.d.ts +0 -4
  243. package/dist/components/ui/drawer/drawer-trigger.svelte +0 -7
  244. package/dist/components/ui/drawer/drawer-trigger.svelte.d.ts +0 -4
  245. package/dist/components/ui/drawer/drawer.svelte +0 -12
  246. package/dist/components/ui/drawer/drawer.svelte.d.ts +0 -3
  247. package/dist/components/ui/drawer/index.d.ts +0 -13
  248. package/dist/components/ui/drawer/index.js +0 -15
  249. package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte +0 -41
  250. package/dist/components/ui/dropdown-menu/dropdown-menu-checkbox-item.svelte.d.ts +0 -9
  251. package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte +0 -27
  252. package/dist/components/ui/dropdown-menu/dropdown-menu-content.svelte.d.ts +0 -7
  253. package/dist/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte +0 -22
  254. package/dist/components/ui/dropdown-menu/dropdown-menu-group-heading.svelte.d.ts +0 -8
  255. package/dist/components/ui/dropdown-menu/dropdown-menu-group.svelte +0 -7
  256. package/dist/components/ui/dropdown-menu/dropdown-menu-group.svelte.d.ts +0 -4
  257. package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte +0 -27
  258. package/dist/components/ui/dropdown-menu/dropdown-menu-item.svelte.d.ts +0 -8
  259. package/dist/components/ui/dropdown-menu/dropdown-menu-label.svelte +0 -24
  260. package/dist/components/ui/dropdown-menu/dropdown-menu-label.svelte.d.ts +0 -8
  261. package/dist/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte +0 -16
  262. package/dist/components/ui/dropdown-menu/dropdown-menu-radio-group.svelte.d.ts +0 -4
  263. package/dist/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte +0 -31
  264. package/dist/components/ui/dropdown-menu/dropdown-menu-radio-item.svelte.d.ts +0 -4
  265. package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte +0 -17
  266. package/dist/components/ui/dropdown-menu/dropdown-menu-separator.svelte.d.ts +0 -4
  267. package/dist/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte +0 -20
  268. package/dist/components/ui/dropdown-menu/dropdown-menu-shortcut.svelte.d.ts +0 -5
  269. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte +0 -20
  270. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-content.svelte.d.ts +0 -4
  271. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte +0 -29
  272. package/dist/components/ui/dropdown-menu/dropdown-menu-sub-trigger.svelte.d.ts +0 -7
  273. package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte +0 -7
  274. package/dist/components/ui/dropdown-menu/dropdown-menu-trigger.svelte.d.ts +0 -4
  275. package/dist/components/ui/dropdown-menu/index.d.ts +0 -25
  276. package/dist/components/ui/dropdown-menu/index.js +0 -17
  277. package/dist/components/ui/input/index.d.ts +0 -2
  278. package/dist/components/ui/input/index.js +0 -4
  279. package/dist/components/ui/input/input.svelte +0 -51
  280. package/dist/components/ui/input/input.svelte.d.ts +0 -13
  281. package/dist/components/ui/label/index.d.ts +0 -2
  282. package/dist/components/ui/label/index.js +0 -4
  283. package/dist/components/ui/label/label.svelte +0 -20
  284. package/dist/components/ui/label/label.svelte.d.ts +0 -4
  285. package/dist/components/ui/scroll-area/index.d.ts +0 -3
  286. package/dist/components/ui/scroll-area/index.js +0 -5
  287. package/dist/components/ui/scroll-area/scroll-area-scrollbar.svelte +0 -31
  288. package/dist/components/ui/scroll-area/scroll-area-scrollbar.svelte.d.ts +0 -4
  289. package/dist/components/ui/scroll-area/scroll-area.svelte +0 -40
  290. package/dist/components/ui/scroll-area/scroll-area.svelte.d.ts +0 -10
  291. package/dist/components/ui/select/index.d.ts +0 -11
  292. package/dist/components/ui/select/index.js +0 -14
  293. package/dist/components/ui/select/select-content.svelte +0 -40
  294. package/dist/components/ui/select/select-content.svelte.d.ts +0 -8
  295. package/dist/components/ui/select/select-group-heading.svelte +0 -21
  296. package/dist/components/ui/select/select-group-heading.svelte.d.ts +0 -10
  297. package/dist/components/ui/select/select-group.svelte +0 -7
  298. package/dist/components/ui/select/select-group.svelte.d.ts +0 -4
  299. package/dist/components/ui/select/select-item.svelte +0 -38
  300. package/dist/components/ui/select/select-item.svelte.d.ts +0 -4
  301. package/dist/components/ui/select/select-label.svelte +0 -20
  302. package/dist/components/ui/select/select-label.svelte.d.ts +0 -6
  303. package/dist/components/ui/select/select-scroll-down-button.svelte +0 -20
  304. package/dist/components/ui/select/select-scroll-down-button.svelte.d.ts +0 -4
  305. package/dist/components/ui/select/select-scroll-up-button.svelte +0 -20
  306. package/dist/components/ui/select/select-scroll-up-button.svelte.d.ts +0 -4
  307. package/dist/components/ui/select/select-separator.svelte +0 -18
  308. package/dist/components/ui/select/select-separator.svelte.d.ts +0 -4
  309. package/dist/components/ui/select/select-trigger.svelte +0 -29
  310. package/dist/components/ui/select/select-trigger.svelte.d.ts +0 -8
  311. package/dist/components/ui/separator/index.d.ts +0 -2
  312. package/dist/components/ui/separator/index.js +0 -4
  313. package/dist/components/ui/separator/separator.svelte +0 -20
  314. package/dist/components/ui/separator/separator.svelte.d.ts +0 -4
  315. package/dist/components/ui/sheet/index.d.ts +0 -11
  316. package/dist/components/ui/sheet/index.js +0 -14
  317. package/dist/components/ui/sheet/sheet-close.svelte +0 -7
  318. package/dist/components/ui/sheet/sheet-close.svelte.d.ts +0 -4
  319. package/dist/components/ui/sheet/sheet-content.svelte +0 -58
  320. package/dist/components/ui/sheet/sheet-content.svelte.d.ts +0 -35
  321. package/dist/components/ui/sheet/sheet-description.svelte +0 -17
  322. package/dist/components/ui/sheet/sheet-description.svelte.d.ts +0 -4
  323. package/dist/components/ui/sheet/sheet-footer.svelte +0 -20
  324. package/dist/components/ui/sheet/sheet-footer.svelte.d.ts +0 -5
  325. package/dist/components/ui/sheet/sheet-header.svelte +0 -20
  326. package/dist/components/ui/sheet/sheet-header.svelte.d.ts +0 -5
  327. package/dist/components/ui/sheet/sheet-overlay.svelte +0 -20
  328. package/dist/components/ui/sheet/sheet-overlay.svelte.d.ts +0 -4
  329. package/dist/components/ui/sheet/sheet-title.svelte +0 -17
  330. package/dist/components/ui/sheet/sheet-title.svelte.d.ts +0 -4
  331. package/dist/components/ui/sheet/sheet-trigger.svelte +0 -7
  332. package/dist/components/ui/sheet/sheet-trigger.svelte.d.ts +0 -4
  333. package/dist/components/ui/sidebar/constants.d.ts +0 -6
  334. package/dist/components/ui/sidebar/constants.js +0 -6
  335. package/dist/components/ui/sidebar/context.svelte.d.ts +0 -42
  336. package/dist/components/ui/sidebar/context.svelte.js +0 -54
  337. package/dist/components/ui/sidebar/index.d.ts +0 -25
  338. package/dist/components/ui/sidebar/index.js +0 -27
  339. package/dist/components/ui/sidebar/sidebar-content.svelte +0 -24
  340. package/dist/components/ui/sidebar/sidebar-content.svelte.d.ts +0 -5
  341. package/dist/components/ui/sidebar/sidebar-footer.svelte +0 -21
  342. package/dist/components/ui/sidebar/sidebar-footer.svelte.d.ts +0 -5
  343. package/dist/components/ui/sidebar/sidebar-group-action.svelte +0 -36
  344. package/dist/components/ui/sidebar/sidebar-group-action.svelte.d.ts +0 -11
  345. package/dist/components/ui/sidebar/sidebar-group-content.svelte +0 -21
  346. package/dist/components/ui/sidebar/sidebar-group-content.svelte.d.ts +0 -5
  347. package/dist/components/ui/sidebar/sidebar-group-label.svelte +0 -34
  348. package/dist/components/ui/sidebar/sidebar-group-label.svelte.d.ts +0 -11
  349. package/dist/components/ui/sidebar/sidebar-group.svelte +0 -21
  350. package/dist/components/ui/sidebar/sidebar-group.svelte.d.ts +0 -5
  351. package/dist/components/ui/sidebar/sidebar-header.svelte +0 -21
  352. package/dist/components/ui/sidebar/sidebar-header.svelte.d.ts +0 -5
  353. package/dist/components/ui/sidebar/sidebar-input.svelte +0 -21
  354. package/dist/components/ui/sidebar/sidebar-input.svelte.d.ts +0 -11
  355. package/dist/components/ui/sidebar/sidebar-inset.svelte +0 -24
  356. package/dist/components/ui/sidebar/sidebar-inset.svelte.d.ts +0 -5
  357. package/dist/components/ui/sidebar/sidebar-menu-action.svelte +0 -43
  358. package/dist/components/ui/sidebar/sidebar-menu-action.svelte.d.ts +0 -12
  359. package/dist/components/ui/sidebar/sidebar-menu-badge.svelte +0 -29
  360. package/dist/components/ui/sidebar/sidebar-menu-badge.svelte.d.ts +0 -5
  361. package/dist/components/ui/sidebar/sidebar-menu-button.svelte +0 -103
  362. package/dist/components/ui/sidebar/sidebar-menu-button.svelte.d.ts +0 -51
  363. package/dist/components/ui/sidebar/sidebar-menu-item.svelte +0 -21
  364. package/dist/components/ui/sidebar/sidebar-menu-item.svelte.d.ts +0 -5
  365. package/dist/components/ui/sidebar/sidebar-menu-skeleton.svelte +0 -36
  366. package/dist/components/ui/sidebar/sidebar-menu-skeleton.svelte.d.ts +0 -8
  367. package/dist/components/ui/sidebar/sidebar-menu-sub-button.svelte +0 -43
  368. package/dist/components/ui/sidebar/sidebar-menu-sub-button.svelte.d.ts +0 -13
  369. package/dist/components/ui/sidebar/sidebar-menu-sub-item.svelte +0 -21
  370. package/dist/components/ui/sidebar/sidebar-menu-sub-item.svelte.d.ts +0 -5
  371. package/dist/components/ui/sidebar/sidebar-menu-sub.svelte +0 -25
  372. package/dist/components/ui/sidebar/sidebar-menu-sub.svelte.d.ts +0 -5
  373. package/dist/components/ui/sidebar/sidebar-menu.svelte +0 -21
  374. package/dist/components/ui/sidebar/sidebar-menu.svelte.d.ts +0 -5
  375. package/dist/components/ui/sidebar/sidebar-provider.svelte +0 -53
  376. package/dist/components/ui/sidebar/sidebar-provider.svelte.d.ts +0 -9
  377. package/dist/components/ui/sidebar/sidebar-rail.svelte +0 -36
  378. package/dist/components/ui/sidebar/sidebar-rail.svelte.d.ts +0 -5
  379. package/dist/components/ui/sidebar/sidebar-separator.svelte +0 -19
  380. package/dist/components/ui/sidebar/sidebar-separator.svelte.d.ts +0 -13
  381. package/dist/components/ui/sidebar/sidebar-trigger.svelte +0 -35
  382. package/dist/components/ui/sidebar/sidebar-trigger.svelte.d.ts +0 -8
  383. package/dist/components/ui/sidebar/sidebar.svelte +0 -104
  384. package/dist/components/ui/sidebar/sidebar.svelte.d.ts +0 -10
  385. package/dist/components/ui/skeleton/index.d.ts +0 -2
  386. package/dist/components/ui/skeleton/index.js +0 -4
  387. package/dist/components/ui/skeleton/skeleton.svelte +0 -17
  388. package/dist/components/ui/skeleton/skeleton.svelte.d.ts +0 -5
  389. package/dist/components/ui/table/index.d.ts +0 -9
  390. package/dist/components/ui/table/index.js +0 -11
  391. package/dist/components/ui/table/table-body.svelte +0 -20
  392. package/dist/components/ui/table/table-body.svelte.d.ts +0 -5
  393. package/dist/components/ui/table/table-caption.svelte +0 -20
  394. package/dist/components/ui/table/table-caption.svelte.d.ts +0 -5
  395. package/dist/components/ui/table/table-cell.svelte +0 -20
  396. package/dist/components/ui/table/table-cell.svelte.d.ts +0 -5
  397. package/dist/components/ui/table/table-footer.svelte +0 -20
  398. package/dist/components/ui/table/table-footer.svelte.d.ts +0 -5
  399. package/dist/components/ui/table/table-head.svelte +0 -23
  400. package/dist/components/ui/table/table-head.svelte.d.ts +0 -5
  401. package/dist/components/ui/table/table-header.svelte +0 -20
  402. package/dist/components/ui/table/table-header.svelte.d.ts +0 -5
  403. package/dist/components/ui/table/table-row.svelte +0 -23
  404. package/dist/components/ui/table/table-row.svelte.d.ts +0 -5
  405. package/dist/components/ui/table/table.svelte +0 -22
  406. package/dist/components/ui/table/table.svelte.d.ts +0 -5
  407. package/dist/components/ui/tabs/index.d.ts +0 -5
  408. package/dist/components/ui/tabs/index.js +0 -7
  409. package/dist/components/ui/tabs/tabs-content.svelte +0 -17
  410. package/dist/components/ui/tabs/tabs-content.svelte.d.ts +0 -4
  411. package/dist/components/ui/tabs/tabs-list.svelte +0 -20
  412. package/dist/components/ui/tabs/tabs-list.svelte.d.ts +0 -4
  413. package/dist/components/ui/tabs/tabs-trigger.svelte +0 -20
  414. package/dist/components/ui/tabs/tabs-trigger.svelte.d.ts +0 -4
  415. package/dist/components/ui/tabs/tabs.svelte +0 -19
  416. package/dist/components/ui/tabs/tabs.svelte.d.ts +0 -4
  417. package/dist/components/ui/toggle/index.d.ts +0 -3
  418. package/dist/components/ui/toggle/index.js +0 -5
  419. package/dist/components/ui/toggle/toggle.svelte +0 -52
  420. package/dist/components/ui/toggle/toggle.svelte.d.ts +0 -43
  421. package/dist/components/ui/toggle-group/index.d.ts +0 -3
  422. package/dist/components/ui/toggle-group/index.js +0 -5
  423. package/dist/components/ui/toggle-group/toggle-group-item.svelte +0 -34
  424. package/dist/components/ui/toggle-group/toggle-group-item.svelte.d.ts +0 -6
  425. package/dist/components/ui/toggle-group/toggle-group.svelte +0 -47
  426. package/dist/components/ui/toggle-group/toggle-group.svelte.d.ts +0 -8
  427. package/dist/components/ui/tooltip/index.d.ts +0 -7
  428. package/dist/components/ui/tooltip/index.js +0 -9
  429. package/dist/components/ui/tooltip/tooltip-content.svelte +0 -47
  430. package/dist/components/ui/tooltip/tooltip-content.svelte.d.ts +0 -7
  431. package/dist/components/ui/tooltip/tooltip-trigger.svelte +0 -7
  432. package/dist/components/ui/tooltip/tooltip-trigger.svelte.d.ts +0 -4
  433. package/dist/hooks/is-mobile.svelte.d.ts +0 -4
  434. package/dist/hooks/is-mobile.svelte.js +0 -7
  435. package/dist/services/index.d.ts +0 -9
  436. package/dist/services/index.js +0 -10
  437. package/dist/types/docs.d.ts +0 -67
  438. package/dist/types/docs.js +0 -1
  439. package/dist/utils.d.ts +0 -15
  440. package/dist/utils.js +0 -44
@@ -1,16 +1,46 @@
1
- /**
2
- * @fileoverview FirekitCollection - Optimized collection management for Svelte applications
3
- * @module FirekitCollection
4
- * @version 1.0.0
5
- */
6
- import { collection, collectionGroup, query, onSnapshot, getDocs, where, orderBy, limit, startAt, startAfter, endAt, endBefore } from 'firebase/firestore';
1
+ import { collection, collectionGroup, query, getDocs, getDocsFromServer, onSnapshot, orderBy, limit, limitToLast, where, startAt, startAfter, endAt, endBefore, getCountFromServer } from 'firebase/firestore';
7
2
  import { firebaseService } from '../firebase.js';
8
- import { browser } from '$app/environment';
9
- import { CollectionErrorCode, CollectionError } from '../types/collection.js';
3
+ import { CollectionError, CollectionErrorCode } from '../types/collection.js';
4
+ function getDb() {
5
+ const db = firebaseService.getDbInstance();
6
+ if (!db)
7
+ throw new Error('Firestore is not initialized.');
8
+ return db;
9
+ }
10
+ function mapFirestoreError(err, path) {
11
+ const codeMap = {
12
+ 'permission-denied': CollectionErrorCode.PERMISSION_DENIED,
13
+ 'unauthenticated': CollectionErrorCode.UNAUTHENTICATED,
14
+ 'not-found': CollectionErrorCode.NOT_FOUND,
15
+ 'already-exists': CollectionErrorCode.ALREADY_EXISTS,
16
+ 'unavailable': CollectionErrorCode.UNAVAILABLE,
17
+ 'deadline-exceeded': CollectionErrorCode.DEADLINE_EXCEEDED,
18
+ 'cancelled': CollectionErrorCode.CANCELLED,
19
+ 'internal': CollectionErrorCode.INTERNAL_ERROR,
20
+ 'data-loss': CollectionErrorCode.DATA_LOSS,
21
+ 'failed-precondition': CollectionErrorCode.FAILED_PRECONDITION,
22
+ 'aborted': CollectionErrorCode.ABORTED,
23
+ 'out-of-range': CollectionErrorCode.OUT_OF_RANGE,
24
+ 'unimplemented': CollectionErrorCode.UNIMPLEMENTED,
25
+ 'resource-exhausted': CollectionErrorCode.RESOURCE_EXHAUSTED
26
+ };
27
+ const code = codeMap[err.code] ?? CollectionErrorCode.UNKNOWN;
28
+ return new CollectionError(code, err.message, path, undefined, err);
29
+ }
30
+ // ── Query builder ─────────────────────────────────────────────────────────────
10
31
  /**
11
- * Query builder implementation for type-safe query construction
32
+ * Fluent query builder wraps Firestore QueryConstraints.
33
+ *
34
+ * @example
35
+ * ```ts
36
+ * const constraints = new FirekitQueryBuilder<Post>()
37
+ * .where('published', '==', true)
38
+ * .orderBy('createdAt', 'desc')
39
+ * .limit(20)
40
+ * .build();
41
+ * ```
12
42
  */
13
- class FirekitQueryBuilder {
43
+ export class FirekitQueryBuilder {
14
44
  constraints = [];
15
45
  where(field, operator, value) {
16
46
  this.constraints.push(where(field, operator, value));
@@ -24,6 +54,10 @@ class FirekitQueryBuilder {
24
54
  this.constraints.push(limit(count));
25
55
  return this;
26
56
  }
57
+ limitToLast(count) {
58
+ this.constraints.push(limitToLast(count));
59
+ return this;
60
+ }
27
61
  startAt(...values) {
28
62
  this.constraints.push(startAt(...values));
29
63
  return this;
@@ -43,754 +77,414 @@ class FirekitQueryBuilder {
43
77
  build() {
44
78
  return [...this.constraints];
45
79
  }
80
+ /** Convenience — returns the constructed Firestore Query for a given collection ref. */
81
+ buildQuery(ref) {
82
+ return query(ref, ...this.constraints);
83
+ }
46
84
  }
85
+ // ── Main class ────────────────────────────────────────────────────────────────
47
86
  /**
48
- * Comprehensive Firestore collection management with real-time updates and advanced features.
49
- * Uses Svelte 5 runes for optimal reactivity and performance.
87
+ * Reactive Firestore collection subscription.
50
88
  *
51
- * @class FirekitCollection
52
- * @template T Document data type
89
+ * Manages a Firestore collection query with reactive state via Svelte 5 runes.
53
90
  *
54
91
  * @example
55
- * ```typescript
56
- * interface User {
57
- * id: string;
58
- * name: string;
59
- * email: string;
60
- * active: boolean;
61
- * }
62
- *
63
- * // Simple collection subscription
64
- * const users = firekitCollection<User>('users');
65
- *
66
- * // With query constraints
67
- * const activeUsers = firekitCollection<User>('users',
68
- * where('active', '==', true),
69
- * orderBy('name'),
70
- * limit(10)
71
- * );
72
- *
73
- * // With advanced options
74
- * const paginatedUsers = firekitCollection<User>('users', {
75
- * pagination: { enabled: true, pageSize: 20 },
76
- * cache: { enabled: true, ttl: 300000 },
77
- * transform: (doc) => ({ ...doc, displayName: doc.name.toUpperCase() })
78
- * });
79
- *
80
- * // Access reactive state
81
- * $: if (users.loading) {
82
- * console.log('Loading...');
83
- * } else if (users.error) {
84
- * console.error('Error:', users.error);
85
- * } else {
86
- * console.log('Users:', users.data);
87
- * }
92
+ * ```svelte
93
+ * <script lang="ts">
94
+ * import { firekitCollection } from 'svelte-firekit';
95
+ * const posts = firekitCollection<Post>('posts', [where('published', '==', true)]);
96
+ * </script>
97
+ * {#each posts.data as post}...{/each}
88
98
  * ```
89
99
  */
90
- class FirekitCollection {
91
- // Reactive state using Svelte 5 runes
100
+ export class FirekitCollection {
101
+ // ── Reactive state ────────────────────────────────────────────────────────
92
102
  _data = $state([]);
93
103
  _loading = $state(true);
94
- _initialized = $state(false);
95
104
  _error = $state(null);
96
- _lastUpdated = $state(null);
97
- // Internal state
98
- collectionRef = null;
99
- queryRef = null;
100
- unsubscribe = null;
101
- options;
102
- stats = this.initializeStats();
103
- cache = new Map();
104
- collectionPath;
105
- /**
106
- * Creates a collection subscription
107
- *
108
- * @param path Collection path
109
- * @param constraintsOrOptions Query constraints or collection options
110
- * @param additionalConstraints Additional constraints if options were provided
111
- */
112
- constructor(path, constraintsOrOptions, ...additionalConstraints) {
113
- this.collectionPath = path;
114
- // Parse constructor arguments
115
- if (Array.isArray(constraintsOrOptions)) {
116
- // Old style: path, ...constraints
117
- this.options = {};
118
- this.initializeCollection([...constraintsOrOptions, ...additionalConstraints]);
119
- }
120
- else {
121
- // New style: path, options, ...constraints
122
- this.options = constraintsOrOptions || {};
123
- // Only use additionalConstraints since options object doesn't contain constraints
124
- this.initializeCollection(additionalConstraints);
125
- }
126
- }
127
- /**
128
- * Initialize statistics object
129
- */
130
- initializeStats() {
131
- return {
132
- totalDocuments: 0,
133
- readCount: 0,
134
- writeCount: 0,
135
- cacheHitRate: 0,
136
- averageQueryTime: 0,
137
- lastActivity: new Date(),
138
- memoryUsage: 0
105
+ _size = $state(0);
106
+ _fromCache = $state(false);
107
+ _hasPendingWrites = $state(false);
108
+ // ── Derived ───────────────────────────────────────────────────────────────
109
+ isEmpty = $derived(!this._loading && this._size === 0);
110
+ hasData = $derived(this._size > 0);
111
+ isReady = $derived(!this._loading && this._error === null);
112
+ // ── Pagination state ──────────────────────────────────────────────────────
113
+ _pageSize = $state(0); // 0 = pagination disabled
114
+ _currentPage = $state(1);
115
+ _hasMore = $state(false);
116
+ // Cursors are not reactive — they are internal implementation detail
117
+ _lastVisible = null;
118
+ _cursorStack = [];
119
+ // ── Internal ──────────────────────────────────────────────────────────────
120
+ _unsubscribe = null;
121
+ _path;
122
+ _constraints;
123
+ _options;
124
+ _isGroup;
125
+ constructor(path, constraints = [], options = {}, isGroup = false) {
126
+ this._path = path;
127
+ this._constraints = constraints;
128
+ this._isGroup = isGroup;
129
+ this._options = {
130
+ realtime: true,
131
+ includeMetadata: false,
132
+ transform: (doc) => doc,
133
+ filter: () => true,
134
+ ...options
139
135
  };
140
- }
141
- /**
142
- * Initialize collection subscription
143
- */
144
- async initializeCollection(constraints) {
145
- if (!browser)
136
+ this._init();
137
+ }
138
+ // ── Public getters ────────────────────────────────────────────────────────
139
+ get data() { return this._data; }
140
+ get loading() { return this._loading; }
141
+ get error() { return this._error; }
142
+ get size() { return this._size; }
143
+ get path() { return this._path; }
144
+ get fromCache() { return this._fromCache; }
145
+ get hasPendingWrites() { return this._hasPendingWrites; }
146
+ get pageSize() { return this._pageSize; }
147
+ get currentPage() { return this._currentPage; }
148
+ get hasMore() { return this._hasMore; }
149
+ // ── Initialization ────────────────────────────────────────────────────────
150
+ _buildQuery() {
151
+ const db = getDb();
152
+ const ref = this._isGroup
153
+ ? collectionGroup(db, this._path)
154
+ : collection(db, this._path);
155
+ return query(ref, ...this._constraints);
156
+ }
157
+ _init() {
158
+ if (typeof window === 'undefined') {
159
+ this._loading = false;
146
160
  return;
161
+ }
147
162
  try {
148
- const firestore = firebaseService.getDbInstance();
149
- if (!firestore) {
150
- throw new CollectionError(CollectionErrorCode.COLLECTION_UNAVAILABLE, 'Firestore instance not available', this.collectionPath);
151
- }
152
- // Check cache first
153
- const cacheKey = this.getCacheKey(constraints);
154
- if (this.options.cache?.enabled && this.isCacheValid(cacheKey)) {
155
- const cached = this.cache.get(cacheKey);
156
- this._data = cached.data;
157
- this._loading = false;
158
- this._initialized = true;
159
- this._lastUpdated = cached.timestamp;
160
- this.stats.cacheHitRate = (this.stats.cacheHitRate + 1) / 2;
161
- }
162
- // Create collection reference
163
- this.collectionRef = collection(firestore, this.collectionPath);
164
- // Create query with constraints
165
- this.queryRef =
166
- constraints.length > 0 ? query(this.collectionRef, ...constraints) : this.collectionRef;
167
- // Set up real-time listener or one-time fetch
168
- if (this.options.realtime !== false) {
169
- this.setupRealtimeListener();
163
+ if (this._options.realtime) {
164
+ this._subscribe();
170
165
  }
171
166
  else {
172
- await this.fetchOnce();
167
+ this._fetchOnce();
173
168
  }
174
169
  }
175
- catch (error) {
176
- this.handleError(error);
170
+ catch (err) {
171
+ this._error = new CollectionError(CollectionErrorCode.REFERENCE_UNAVAILABLE, err instanceof Error ? err.message : String(err), this._path);
172
+ this._loading = false;
177
173
  }
178
174
  }
179
- /**
180
- * Set up real-time document listener
181
- */
182
- setupRealtimeListener() {
183
- if (!this.queryRef)
184
- return;
185
- const options = {
186
- includeMetadataChanges: this.options.includeMetadata || false
187
- };
188
- this.unsubscribe = onSnapshot(this.queryRef, options, (snapshot) => {
189
- this.processSnapshot(snapshot);
190
- }, (error) => {
191
- this.handleError(error);
175
+ _subscribe() {
176
+ const q = this._buildQuery();
177
+ this._unsubscribe = onSnapshot(q, { includeMetadataChanges: this._options.includeMetadata }, (snap) => this._handleSnapshot(snap), (err) => {
178
+ this._error = mapFirestoreError(err, this._path);
179
+ this._loading = false;
192
180
  });
193
181
  }
194
- /**
195
- * Fetch collection data once (no real-time updates)
196
- */
197
- async fetchOnce() {
198
- if (!this.queryRef)
199
- return;
182
+ async _fetchOnce() {
200
183
  try {
201
- this._loading = true;
202
- const startTime = Date.now();
203
- const snapshot = await getDocs(this.queryRef);
204
- const queryTime = Date.now() - startTime;
205
- this.stats.averageQueryTime = (this.stats.averageQueryTime + queryTime) / 2;
206
- this.processSnapshot(snapshot);
184
+ const snap = await getDocs(this._buildQuery());
185
+ this._handleSnapshot(snap);
207
186
  }
208
- catch (error) {
209
- this.handleError(error);
210
- }
211
- }
212
- /**
213
- * Process query snapshot and update state
214
- */
215
- processSnapshot(snapshot) {
216
- try {
217
- const startTime = Date.now();
218
- // Extract documents with ID
219
- let documents = snapshot.docs.map((doc) => {
220
- const data = doc.data();
221
- return { id: doc.id, ...data };
222
- });
223
- // Apply transform function if provided
224
- if (this.options.transform) {
225
- documents = documents.map(this.options.transform);
226
- }
227
- // Apply filter function if provided
228
- if (this.options.filter) {
229
- documents = documents.filter(this.options.filter);
230
- }
231
- // Apply sort function if provided
232
- if (this.options.sort) {
233
- documents = documents.sort(this.options.sort);
234
- }
235
- // Track document changes for events
236
- const changes = this.calculateChanges(this._data, documents);
237
- // Update reactive state
238
- this._data = documents;
187
+ catch (err) {
188
+ this._error = mapFirestoreError(err, this._path);
239
189
  this._loading = false;
240
- this._initialized = true;
241
- this._error = null;
242
- this._lastUpdated = new Date();
243
- // Update statistics
244
- this.stats.totalDocuments = documents.length;
245
- this.stats.readCount++;
246
- this.stats.lastActivity = new Date();
247
- this.stats.memoryUsage = this.calculateMemoryUsage(documents);
248
- // Update cache if enabled
249
- if (this.options.cache?.enabled) {
250
- const cacheKey = this.getCacheKey([]);
251
- this.cache.set(cacheKey, {
252
- data: documents,
253
- timestamp: new Date()
254
- });
255
- this.cleanupCache();
256
- }
257
- }
258
- catch (error) {
259
- this.handleError(error);
260
190
  }
261
191
  }
262
- /**
263
- * Calculate changes between old and new document arrays
264
- */
265
- calculateChanges(oldDocs, newDocs) {
266
- const changes = [];
267
- const oldMap = new Map(oldDocs.map((doc, index) => [doc.id, { doc, index }]));
268
- const newMap = new Map(newDocs.map((doc, index) => [doc.id, { doc, index }]));
269
- // Find added and modified documents
270
- newDocs.forEach((newDoc, newIndex) => {
271
- const id = newDoc.id;
272
- const oldEntry = oldMap.get(id);
273
- if (!oldEntry) {
274
- // Document was added
275
- changes.push({
276
- type: 'added',
277
- doc: newDoc,
278
- oldIndex: -1,
279
- newIndex,
280
- timestamp: new Date()
281
- });
282
- }
283
- else if (JSON.stringify(oldEntry.doc) !== JSON.stringify(newDoc)) {
284
- // Document was modified
285
- changes.push({
286
- type: 'modified',
287
- doc: newDoc,
288
- oldIndex: oldEntry.index,
289
- newIndex,
290
- timestamp: new Date()
291
- });
292
- }
192
+ _handleSnapshot(snap) {
193
+ const docs = snap.docs.map((d) => {
194
+ const raw = { id: d.id, ...d.data() };
195
+ return this._options.transform(raw);
293
196
  });
294
- // Find removed documents
295
- oldDocs.forEach((oldDoc, oldIndex) => {
296
- const id = oldDoc.id;
297
- if (!newMap.has(id)) {
298
- changes.push({
299
- type: 'removed',
300
- doc: oldDoc,
301
- oldIndex,
302
- newIndex: -1,
303
- timestamp: new Date()
304
- });
305
- }
306
- });
307
- return changes;
308
- }
309
- /**
310
- * Handle and process errors
311
- */
312
- handleError(error) {
313
- let collectionError;
314
- if (error instanceof CollectionError) {
315
- collectionError = error;
316
- }
317
- else {
318
- // Map Firestore errors to CollectionError
319
- const code = this.mapFirestoreErrorCode(error.code);
320
- collectionError = new CollectionError(code, error.message || 'An unknown error occurred', this.collectionPath, [], error);
321
- }
322
- this._error = collectionError;
197
+ this._data = this._options.filter ? docs.filter(this._options.filter) : docs;
198
+ this._size = this._data.length;
199
+ this._fromCache = snap.metadata.fromCache;
200
+ this._hasPendingWrites = snap.metadata.hasPendingWrites;
201
+ this._error = null;
323
202
  this._loading = false;
324
- console.error('FirekitCollection error:', collectionError);
325
- }
326
- /**
327
- * Map Firestore error codes to CollectionErrorCode
328
- */
329
- mapFirestoreErrorCode(firestoreCode) {
330
- switch (firestoreCode) {
331
- case 'permission-denied':
332
- return CollectionErrorCode.PERMISSION_DENIED;
333
- case 'not-found':
334
- return CollectionErrorCode.NOT_FOUND;
335
- case 'unavailable':
336
- return CollectionErrorCode.UNAVAILABLE;
337
- case 'deadline-exceeded':
338
- return CollectionErrorCode.DEADLINE_EXCEEDED;
339
- case 'unauthenticated':
340
- return CollectionErrorCode.UNAUTHENTICATED;
341
- case 'resource-exhausted':
342
- return CollectionErrorCode.RESOURCE_EXHAUSTED;
343
- case 'failed-precondition':
344
- return CollectionErrorCode.FAILED_PRECONDITION;
345
- case 'aborted':
346
- return CollectionErrorCode.ABORTED;
347
- case 'out-of-range':
348
- return CollectionErrorCode.OUT_OF_RANGE;
349
- case 'unimplemented':
350
- return CollectionErrorCode.UNIMPLEMENTED;
351
- case 'internal':
352
- return CollectionErrorCode.INTERNAL_ERROR;
353
- case 'data-loss':
354
- return CollectionErrorCode.DATA_LOSS;
355
- case 'cancelled':
356
- return CollectionErrorCode.CANCELLED;
357
- default:
358
- return CollectionErrorCode.UNKNOWN;
359
- }
360
- }
361
- /**
362
- * Generate cache key for query
363
- */
364
- getCacheKey(constraints) {
365
- if (this.options.cache?.customKey) {
366
- return this.options.cache.customKey(this.collectionPath, constraints);
367
- }
368
- // More reliable constraint serialization
369
- const constraintString = constraints
370
- .map((c) => {
371
- try {
372
- return JSON.stringify(c);
373
- }
374
- catch {
375
- return c.toString();
376
- }
377
- })
378
- .join('|');
379
- return `${this.collectionPath}:${constraintString}`;
380
- }
381
- /**
382
- * Check if cache entry is still valid
383
- */
384
- isCacheValid(cacheKey) {
385
- const cached = this.cache.get(cacheKey);
386
- if (!cached)
387
- return false;
388
- const ttl = this.options.cache?.ttl || 300000; // 5 minutes default
389
- return Date.now() - cached.timestamp.getTime() < ttl;
390
- }
391
- /**
392
- * Clean up expired cache entries
393
- */
394
- cleanupCache() {
395
- const maxSize = this.options.cache?.maxSize || 100;
396
- const ttl = this.options.cache?.ttl || 300000;
397
- const now = Date.now();
398
- // Remove expired entries
399
- for (const [key, entry] of this.cache.entries()) {
400
- if (now - entry.timestamp.getTime() > ttl) {
401
- this.cache.delete(key);
402
- }
403
- }
404
- // Remove oldest entries if cache is too large
405
- if (this.cache.size > maxSize) {
406
- const entries = Array.from(this.cache.entries()).sort((a, b) => a[1].timestamp.getTime() - b[1].timestamp.getTime());
407
- const toRemove = entries.slice(0, this.cache.size - maxSize);
408
- toRemove.forEach(([key]) => this.cache.delete(key));
203
+ // Track cursors for pagination
204
+ if (snap.docs.length > 0) {
205
+ this._lastVisible = snap.docs[snap.docs.length - 1];
409
206
  }
410
207
  }
208
+ // ── Paginated fetch ───────────────────────────────────────────────────────
411
209
  /**
412
- * Calculate memory usage of documents
210
+ * Fetches a single page. Fetches `pageSize + 1` docs to detect `hasMore`,
211
+ * then trims the result to `pageSize` for display.
212
+ * @param cursor Start after this document. Pass null for the first page.
213
+ * @param append If true, appends to existing data instead of replacing it (for loadMore).
413
214
  */
414
- calculateMemoryUsage(documents) {
215
+ async _fetchPage(cursor, append = false) {
216
+ this._loading = true;
415
217
  try {
416
- return JSON.stringify(documents).length * 2; // Rough estimate
218
+ const base = this._buildQuery();
219
+ const paginatedQuery = cursor
220
+ ? query(base, startAfter(cursor), limit(this._pageSize + 1))
221
+ : query(base, limit(this._pageSize + 1));
222
+ const snap = await getDocs(paginatedQuery);
223
+ const allDocs = snap.docs;
224
+ this._hasMore = allDocs.length > this._pageSize;
225
+ const pageDocs = allDocs.slice(0, this._pageSize);
226
+ if (pageDocs.length > 0) {
227
+ this._lastVisible = pageDocs[pageDocs.length - 1];
228
+ }
229
+ const mapped = pageDocs.map((d) => {
230
+ const raw = { id: d.id, ...d.data() };
231
+ return this._options.transform(raw);
232
+ });
233
+ const filtered = this._options.filter ? mapped.filter(this._options.filter) : mapped;
234
+ this._data = append ? [...this._data, ...filtered] : filtered;
235
+ this._size = this._data.length;
236
+ this._fromCache = snap.metadata.fromCache;
237
+ this._hasPendingWrites = snap.metadata.hasPendingWrites;
238
+ this._error = null;
417
239
  }
418
- catch {
419
- return 0;
240
+ catch (err) {
241
+ this._error = mapFirestoreError(err, this._path);
420
242
  }
421
- }
422
- // ========================================
423
- // REACTIVE GETTERS (Public API)
424
- // ========================================
425
- /**
426
- * Get current collection data
427
- */
428
- get data() {
429
- return this._data;
430
- }
431
- /**
432
- * Get loading state
433
- */
434
- get loading() {
435
- return this._loading;
436
- }
437
- /**
438
- * Get initialization state
439
- */
440
- get initialized() {
441
- return this._initialized;
442
- }
443
- /**
444
- * Get error state
445
- */
446
- get error() {
447
- return this._error;
448
- }
449
- /**
450
- * Check if collection is empty
451
- */
452
- get empty() {
453
- return this._data.length === 0;
454
- }
455
- /**
456
- * Get number of documents
457
- */
458
- get size() {
459
- return this._data.length;
460
- }
461
- /**
462
- * Get last update timestamp
463
- */
464
- get lastUpdated() {
465
- return this._lastUpdated;
466
- }
467
- /**
468
- * Get collection reference
469
- */
470
- get ref() {
471
- if (!this.collectionRef) {
472
- throw new CollectionError(CollectionErrorCode.REFERENCE_UNAVAILABLE, 'Collection reference not available', this.collectionPath);
473
- }
474
- return this.collectionRef;
475
- }
476
- /**
477
- * Get query reference
478
- */
479
- get queryReference() {
480
- if (!this.queryRef) {
481
- throw new CollectionError(CollectionErrorCode.REFERENCE_UNAVAILABLE, 'Query reference not available', this.collectionPath);
243
+ finally {
244
+ this._loading = false;
482
245
  }
483
- return this.queryRef;
484
246
  }
485
- /**
486
- * Get collection path
487
- */
488
- get path() {
489
- return this.collectionPath;
490
- }
491
- /**
492
- * Get collection state summary
493
- */
494
- get state() {
495
- return {
496
- data: this._data,
497
- loading: this._loading,
498
- initialized: this._initialized,
499
- error: this._error,
500
- empty: this.empty,
501
- size: this.size,
502
- lastUpdated: this._lastUpdated
503
- };
504
- }
505
- // ========================================
506
- // PUBLIC METHODS
507
- // ========================================
508
- /**
509
- * Manually refresh collection data
510
- */
247
+ // ── Public methods ────────────────────────────────────────────────────────
248
+ /** Re-fetches from cache or server. */
511
249
  async refresh() {
512
- if (!this.queryRef) {
513
- throw new CollectionError(CollectionErrorCode.REFERENCE_UNAVAILABLE, 'Cannot refresh: query reference not available', this.collectionPath);
514
- }
250
+ this._loading = true;
515
251
  try {
516
- this._loading = true;
517
- const snapshot = await getDocs(this.queryRef);
518
- this.processSnapshot(snapshot);
252
+ const snap = await getDocs(this._buildQuery());
253
+ this._handleSnapshot(snap);
519
254
  }
520
- catch (error) {
521
- this.handleError(error);
522
- throw error;
255
+ catch (err) {
256
+ this._error = mapFirestoreError(err, this._path);
257
+ this._loading = false;
523
258
  }
524
259
  }
525
- /**
526
- * Get fresh data from server (bypassing cache)
527
- */
260
+ /** Forces a fetch directly from the Firestore server (bypasses cache). */
528
261
  async getFromServer() {
529
- if (!this.queryRef) {
530
- throw new CollectionError(CollectionErrorCode.REFERENCE_UNAVAILABLE, 'Cannot fetch: query reference not available', this.collectionPath);
531
- }
262
+ this._loading = true;
532
263
  try {
533
- const snapshot = await getDocs(this.queryRef);
534
- return snapshot.docs.map((doc) => {
535
- const data = doc.data();
536
- return { id: doc.id, ...data };
537
- });
264
+ const snap = await getDocsFromServer(this._buildQuery());
265
+ this._handleSnapshot(snap);
538
266
  }
539
- catch (error) {
540
- this.handleError(error);
541
- throw error;
267
+ catch (err) {
268
+ this._error = mapFirestoreError(err, this._path);
269
+ this._loading = false;
542
270
  }
543
271
  }
544
272
  /**
545
- * Add query constraints to existing query
273
+ * Returns the server-side document count (uses Firestore aggregation query).
274
+ * Does not download the documents.
546
275
  */
547
- addConstraints(...constraints) {
548
- if (!this.collectionRef) {
549
- throw new CollectionError(CollectionErrorCode.REFERENCE_UNAVAILABLE, 'Cannot add constraints: collection reference not available', this.collectionPath);
550
- }
551
- const newQuery = query(this.queryRef || this.collectionRef, ...constraints);
552
- const newCollection = new FirekitCollection(this.collectionPath, this.options);
553
- newCollection.queryRef = newQuery;
554
- newCollection.initializeCollection([]);
555
- return newCollection;
276
+ async countFromServer() {
277
+ const snap = await getCountFromServer(this._buildQuery());
278
+ return snap.data().count;
556
279
  }
557
280
  /**
558
- * Create a new query builder for this collection
281
+ * Replaces the current query constraints and re-fetches.
559
282
  */
560
- createQuery() {
561
- return new FirekitQueryBuilder();
283
+ async setConstraints(constraints) {
284
+ this._unsubscribe?.();
285
+ this._unsubscribe = null;
286
+ this._constraints = constraints;
287
+ this._loading = true;
288
+ if (this._options.realtime) {
289
+ this._subscribe();
290
+ }
291
+ else {
292
+ await this._fetchOnce();
293
+ }
562
294
  }
563
295
  /**
564
- * Apply new query constraints
296
+ * Appends additional constraints (e.g. pagination cursor) and re-fetches.
565
297
  */
566
- withQuery(builder) {
567
- return this.addConstraints(...builder.build());
298
+ async addConstraints(constraints) {
299
+ return this.setConstraints([...this._constraints, ...constraints]);
568
300
  }
569
- /**
570
- * Filter documents by predicate
571
- */
301
+ /** Switches between real-time and one-time mode. */
302
+ setRealtimeMode(enabled) {
303
+ if (enabled === this._options.realtime)
304
+ return;
305
+ this._options.realtime = enabled;
306
+ if (!enabled) {
307
+ this._unsubscribe?.();
308
+ this._unsubscribe = null;
309
+ }
310
+ else {
311
+ this._subscribe();
312
+ }
313
+ }
314
+ // ── Client-side convenience ───────────────────────────────────────────────
315
+ /** Client-side filter (does NOT modify the Firestore query). */
572
316
  filter(predicate) {
573
317
  return this._data.filter(predicate);
574
318
  }
575
- /**
576
- * Find first document matching predicate
577
- */
319
+ /** Finds the first document matching a predicate. */
578
320
  find(predicate) {
579
321
  return this._data.find(predicate);
580
322
  }
581
- /**
582
- * Find document by ID
583
- */
323
+ /** Finds a document by its Firestore document ID. */
584
324
  findById(id) {
585
- return this._data.find((doc) => doc.id === id);
325
+ return this._data.find((d) => d.id === id);
586
326
  }
587
- /**
588
- * Sort documents by field or custom function
589
- */
327
+ /** Client-side sort (returns a new array, does NOT modify stored data). */
590
328
  sort(compareFn) {
591
329
  return [...this._data].sort(compareFn);
592
330
  }
331
+ // ── Pagination ────────────────────────────────────────────────────────────
593
332
  /**
594
- * Get paginated subset of documents
595
- */
596
- paginate(page, pageSize) {
597
- const startIndex = (page - 1) * pageSize;
598
- const endIndex = startIndex + pageSize;
599
- return this._data.slice(startIndex, endIndex);
600
- }
601
- /**
602
- * Group documents by field value
603
- */
604
- groupBy(field) {
605
- const groups = new Map();
606
- this._data.forEach((doc) => {
607
- const key = doc[field];
608
- if (!groups.has(key)) {
609
- groups.set(key, []);
610
- }
611
- groups.get(key).push(doc);
612
- });
613
- return groups;
614
- }
615
- /**
616
- * Get unique values for a field
617
- */
618
- unique(field) {
619
- const values = this._data.map((doc) => doc[field]);
620
- return Array.from(new Set(values));
621
- }
622
- /**
623
- * Count documents matching predicate
624
- */
625
- count(predicate) {
626
- return predicate ? this._data.filter(predicate).length : this._data.length;
627
- }
628
- /**
629
- * Check if any document matches predicate
630
- */
631
- some(predicate) {
632
- return this._data.some(predicate);
633
- }
634
- /**
635
- * Check if all documents match predicate
636
- */
637
- every(predicate) {
638
- return this._data.every(predicate);
333
+ * Enables cursor-based pagination and loads the first page.
334
+ *
335
+ * Disables the real-time listener — paginated queries use one-time fetches.
336
+ *
337
+ * @example
338
+ * ```ts
339
+ * const posts = firekitCollection<Post>('posts', [orderBy('createdAt', 'desc')]);
340
+ * await posts.setPagination(10); // 10 per page
341
+ * ```
342
+ */
343
+ async setPagination(pageSize) {
344
+ this._unsubscribe?.();
345
+ this._unsubscribe = null;
346
+ this._options.realtime = false;
347
+ this._pageSize = pageSize;
348
+ this._currentPage = 1;
349
+ this._lastVisible = null;
350
+ this._cursorStack = [];
351
+ await this._fetchPage(null);
352
+ }
353
+ /**
354
+ * Loads the next page, replacing the current data.
355
+ * Call `setPagination()` first.
356
+ */
357
+ async nextPage() {
358
+ if (this._pageSize === 0 || !this._hasMore || !this._lastVisible)
359
+ return;
360
+ this._cursorStack.push(this._lastVisible);
361
+ await this._fetchPage(this._lastVisible);
362
+ this._currentPage++;
639
363
  }
640
364
  /**
641
- * Switch between realtime and one-time fetch modes
365
+ * Loads the previous page, replacing the current data.
642
366
  */
643
- setRealtimeMode(realtime) {
644
- if (this.options.realtime === realtime)
367
+ async prevPage() {
368
+ if (this._pageSize === 0 || this._currentPage <= 1)
645
369
  return;
646
- this.options.realtime = realtime;
647
- // Clean up existing listener
648
- if (this.unsubscribe) {
649
- this.unsubscribe();
650
- this.unsubscribe = null;
651
- }
652
- // Set up new mode
653
- if (realtime) {
654
- this.setupRealtimeListener();
655
- }
370
+ this._cursorStack.pop(); // remove current-page cursor
371
+ const prevCursor = this._cursorStack[this._cursorStack.length - 1] ?? null;
372
+ await this._fetchPage(prevCursor);
373
+ this._currentPage--;
374
+ // Always has more going backwards (we came from a later page)
375
+ this._hasMore = true;
656
376
  }
657
377
  /**
658
- * Clear cache for this collection
378
+ * Appends the next page to existing data (infinite scroll).
379
+ * Call `setPagination()` first.
659
380
  */
660
- clearCache() {
661
- const cacheKey = this.getCacheKey([]);
662
- this.cache.delete(cacheKey);
381
+ async loadMore() {
382
+ if (this._pageSize === 0 || !this._hasMore || !this._lastVisible)
383
+ return;
384
+ this._cursorStack.push(this._lastVisible);
385
+ await this._fetchPage(this._lastVisible, true);
386
+ this._currentPage++;
663
387
  }
664
388
  /**
665
- * Get collection statistics
389
+ * Resets pagination back to the first page.
666
390
  */
667
- getStats() {
668
- return { ...this.stats };
391
+ async resetPagination() {
392
+ if (this._pageSize === 0)
393
+ return;
394
+ this._currentPage = 1;
395
+ this._lastVisible = null;
396
+ this._cursorStack = [];
397
+ await this._fetchPage(null);
669
398
  }
399
+ // ── Reactive path ─────────────────────────────────────────────────────────
670
400
  /**
671
- * Reset statistics
672
- */
673
- resetStats() {
674
- this.stats = this.initializeStats();
401
+ * Changes the collection path and re-fetches.
402
+ * Tears down any existing real-time listener before switching.
403
+ *
404
+ * @example
405
+ * ```ts
406
+ * const messages = firekitCollection<Message>('rooms/general/messages');
407
+ * // User switches room:
408
+ * messages.setPath('rooms/random/messages');
409
+ * ```
410
+ */
411
+ setPath(newPath) {
412
+ this._unsubscribe?.();
413
+ this._unsubscribe = null;
414
+ this._path = newPath;
415
+ this._loading = true;
416
+ this._data = [];
417
+ this._error = null;
418
+ this._lastVisible = null;
419
+ this._cursorStack = [];
420
+ this._currentPage = 1;
421
+ this._init();
675
422
  }
676
423
  /**
677
- * Wait for collection to initialize
424
+ * Resolves when the collection has finished its initial load.
678
425
  */
679
- async waitForInitialization() {
426
+ waitForReady() {
427
+ if (!this._loading)
428
+ return Promise.resolve(this._data);
429
+ // $effect.root creates a reactive scope outside of component initialization,
430
+ // so this works safely whether called inside or outside a Svelte component.
680
431
  return new Promise((resolve) => {
681
- if (this._initialized) {
682
- resolve(this._data);
683
- return;
684
- }
685
- // Poll for initialization since we removed events
686
- const checkInterval = setInterval(() => {
687
- if (this._initialized) {
688
- clearInterval(checkInterval);
689
- resolve(this._data);
690
- }
691
- }, 100);
692
- // Timeout after 10 seconds
693
- setTimeout(() => {
694
- clearInterval(checkInterval);
695
- resolve(this._data);
696
- }, 10000);
432
+ const stop = $effect.root(() => {
433
+ $effect(() => {
434
+ if (!this._loading) {
435
+ stop();
436
+ resolve(this._data);
437
+ }
438
+ });
439
+ });
697
440
  });
698
441
  }
699
- // ========================================
700
- // CLEANUP
701
- // ========================================
702
- /**
703
- * Dispose of all resources and cleanup
704
- */
442
+ /** Stops the real-time listener and frees resources. */
705
443
  dispose() {
706
- // Unsubscribe from real-time updates
707
- if (this.unsubscribe) {
708
- this.unsubscribe();
709
- this.unsubscribe = null;
710
- }
711
- // Clear cache
712
- this.cache.clear();
713
- // Reset state
714
- this._data = [];
715
- this._loading = false;
716
- this._initialized = false;
717
- this._error = null;
718
- this._lastUpdated = null;
444
+ this._unsubscribe?.();
445
+ this._unsubscribe = null;
719
446
  }
720
447
  }
448
+ // ── Collection group ──────────────────────────────────────────────────────────
721
449
  /**
722
- * Collection Group implementation for querying across multiple collections
450
+ * Reactive Firestore collection group query.
451
+ * Queries across all collections sharing the same name (collectionGroup).
452
+ *
453
+ * @example
454
+ * ```svelte
455
+ * <script lang="ts">
456
+ * import { firekitCollectionGroup } from 'svelte-firekit';
457
+ * // Query 'comments' across all parent documents
458
+ * const allComments = firekitCollectionGroup<Comment>('comments');
459
+ * </script>
460
+ * ```
723
461
  */
724
- class FirekitCollectionGroup extends FirekitCollection {
725
- constructor(collectionId, constraintsOrOptions, ...additionalConstraints) {
726
- // Initialize with empty options to avoid parent constructor issues
727
- super(`__collection_group__${collectionId}`, {});
728
- // Parse constructor arguments properly
729
- if (Array.isArray(constraintsOrOptions)) {
730
- this.options = {};
731
- this.initializeCollectionGroup(collectionId, [
732
- ...constraintsOrOptions,
733
- ...additionalConstraints
734
- ]);
735
- }
736
- else {
737
- this.options = constraintsOrOptions || {};
738
- this.initializeCollectionGroup(collectionId, additionalConstraints);
739
- }
740
- }
741
- /**
742
- * Initialize collection group subscription
743
- */
744
- async initializeCollectionGroup(collectionId, constraints) {
745
- if (!browser)
746
- return;
747
- try {
748
- const firestore = firebaseService.getDbInstance();
749
- if (!firestore) {
750
- throw new CollectionError(CollectionErrorCode.COLLECTION_UNAVAILABLE, 'Firestore instance not available', collectionId);
751
- }
752
- // Create collection group reference
753
- const groupRef = collectionGroup(firestore, collectionId);
754
- // Create query with constraints
755
- this.queryRef =
756
- constraints.length > 0
757
- ? query(groupRef, ...constraints)
758
- : groupRef;
759
- // Set up real-time listener or one-time fetch
760
- if (this.options.realtime !== false) {
761
- this.setupRealtimeListener();
762
- }
763
- else {
764
- await this.fetchOnce();
765
- }
766
- }
767
- catch (error) {
768
- this.handleError(error);
769
- }
462
+ export class FirekitCollectionGroup extends FirekitCollection {
463
+ constructor(collectionId, constraints = [], options = {}) {
464
+ super(collectionId, constraints, options, true);
770
465
  }
771
466
  }
772
- export function firekitCollection(path, constraintsOrOptions, ...additionalConstraints) {
773
- if (Array.isArray(constraintsOrOptions)) {
774
- return new FirekitCollection(path, [...constraintsOrOptions, ...additionalConstraints]);
775
- }
776
- else {
777
- return new FirekitCollection(path, constraintsOrOptions, ...additionalConstraints);
778
- }
467
+ // ── Factory functions ─────────────────────────────────────────────────────────
468
+ /**
469
+ * Creates a reactive Firestore collection with real-time updates.
470
+ *
471
+ * @example
472
+ * ```ts
473
+ * const posts = firekitCollection<Post>('posts', [where('published', '==', true)]);
474
+ * ```
475
+ */
476
+ export function firekitCollection(path, constraints = [], options) {
477
+ return new FirekitCollection(path, constraints, { ...options, realtime: true });
779
478
  }
780
479
  /**
781
- * Creates a one-time collection fetch (no real-time updates)
480
+ * Creates a one-time Firestore collection fetch (no real-time listener).
782
481
  */
783
- export function firekitCollectionOnce(path, ...constraints) {
784
- return new FirekitCollection(path, { realtime: false }, ...constraints);
482
+ export function firekitCollectionOnce(path, constraints = [], options) {
483
+ return new FirekitCollection(path, constraints, { ...options, realtime: false });
785
484
  }
786
- export function firekitCollectionGroup(collectionId, constraintsOrOptions, ...additionalConstraints) {
787
- if (Array.isArray(constraintsOrOptions)) {
788
- return new FirekitCollectionGroup(collectionId, [
789
- ...constraintsOrOptions,
790
- ...additionalConstraints
791
- ]);
792
- }
793
- else {
794
- return new FirekitCollectionGroup(collectionId, constraintsOrOptions, ...additionalConstraints);
795
- }
485
+ /**
486
+ * Creates a reactive Firestore collection group query with real-time updates.
487
+ */
488
+ export function firekitCollectionGroup(collectionId, constraints = [], options) {
489
+ return new FirekitCollectionGroup(collectionId, constraints, { ...options, realtime: true });
796
490
  }