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,137 +1,86 @@
1
- /**
2
- * @fileoverview FirekitPresence - Clean presence tracking for Svelte applications
3
- * @module FirekitPresence
4
- * @version 1.0.0
5
- */
6
1
  import { ref, onValue, onDisconnect, set, get, serverTimestamp } from 'firebase/database';
7
2
  import { firebaseService } from '../firebase.js';
8
- import { browser } from '$app/environment';
9
3
  import { PresenceErrorCode, PresenceError } from '../types/presence.js';
10
- /**
11
- * Handles geolocation tracking
12
- */
4
+ // ── Geolocation helper ────────────────────────────────────────────────────────
13
5
  class GeolocationService {
14
- config;
15
- watchId = null;
6
+ _config;
7
+ _watchId = null;
16
8
  _hasConsent = $state(false);
17
9
  _location = $state(null);
18
- _error = $state(null);
19
10
  constructor(config) {
20
- this.config = config;
21
- }
22
- get hasConsent() {
23
- return this._hasConsent;
24
- }
25
- get location() {
26
- return this._location;
11
+ this._config = config;
27
12
  }
28
- get error() {
29
- return this._error;
30
- }
31
- /**
32
- * Request user consent for location tracking
33
- */
13
+ get hasConsent() { return this._hasConsent; }
14
+ get location() { return this._location; }
34
15
  async requestConsent() {
35
- if (!this.config.enabled || !browser)
16
+ if (!this._config.enabled || typeof window === 'undefined')
36
17
  return false;
37
- try {
38
- if (this.config.type === 'browser') {
39
- const success = await new Promise((resolve) => {
40
- navigator.geolocation.getCurrentPosition(() => resolve(true), () => resolve(false), {
41
- timeout: this.config.timeout || 10000,
42
- enableHighAccuracy: this.config.enableHighAccuracy || false
43
- });
44
- });
45
- this._hasConsent = success;
46
- return success;
47
- }
18
+ if (this._config.type !== 'browser') {
48
19
  this._hasConsent = true;
49
20
  return true;
50
21
  }
51
- catch (error) {
52
- this._error = error;
53
- return false;
54
- }
22
+ return new Promise((resolve) => {
23
+ navigator.geolocation.getCurrentPosition(() => { this._hasConsent = true; resolve(true); }, () => resolve(false), { timeout: this._config.timeout ?? 10_000, enableHighAccuracy: this._config.enableHighAccuracy ?? false });
24
+ });
55
25
  }
56
- /**
57
- * Get current location
58
- */
59
26
  async getCurrentLocation() {
60
- if (!this.config.enabled || (this.config.requireConsent && !this._hasConsent)) {
27
+ if (!this._config.enabled)
61
28
  return null;
62
- }
63
- try {
64
- switch (this.config.type) {
65
- case 'browser':
66
- return this.getBrowserLocation();
67
- case 'ip':
68
- return this.getIPLocation();
69
- case 'custom':
70
- return this.getCustomLocation();
71
- default:
72
- return null;
73
- }
74
- }
75
- catch (error) {
76
- this._error = error;
29
+ if (this._config.requireConsent && !this._hasConsent)
77
30
  return null;
31
+ switch (this._config.type) {
32
+ case 'browser': return this._getBrowserLocation();
33
+ case 'ip': return this._getIPLocation();
34
+ case 'custom': return this._getCustomLocation();
35
+ default: return null;
78
36
  }
79
37
  }
80
- /**
81
- * Start watching location changes
82
- */
83
- startWatching(updateInterval) {
84
- if (!this.config.enabled || this.watchId)
38
+ startWatching(intervalMs) {
39
+ if (!this._config.enabled || this._watchId)
85
40
  return;
86
- const watchLocation = async () => {
87
- const location = await this.getCurrentLocation();
88
- if (location) {
89
- this._location = location;
90
- }
41
+ const tick = async () => {
42
+ const loc = await this.getCurrentLocation();
43
+ if (loc)
44
+ this._location = loc;
91
45
  };
92
- watchLocation();
93
- this.watchId = window.setInterval(watchLocation, updateInterval);
46
+ tick();
47
+ this._watchId = window.setInterval(tick, intervalMs);
94
48
  }
95
- /**
96
- * Stop watching location changes
97
- */
98
49
  stopWatching() {
99
- if (this.watchId) {
100
- clearInterval(this.watchId);
101
- this.watchId = null;
50
+ if (this._watchId !== null) {
51
+ clearInterval(this._watchId);
52
+ this._watchId = null;
102
53
  }
103
54
  }
104
- async getBrowserLocation() {
55
+ _getBrowserLocation() {
105
56
  return new Promise((resolve) => {
106
- navigator.geolocation.getCurrentPosition((position) => {
107
- resolve({
108
- latitude: position.coords.latitude,
109
- longitude: position.coords.longitude,
110
- accuracy: position.coords.accuracy,
111
- altitude: position.coords.altitude || undefined,
112
- altitudeAccuracy: position.coords.altitudeAccuracy || undefined,
113
- heading: position.coords.heading || undefined,
114
- speed: position.coords.speed || undefined,
115
- lastUpdated: new Date().toISOString(),
116
- source: 'browser'
117
- });
118
- }, () => resolve(null), {
119
- timeout: this.config.timeout || 10000,
120
- enableHighAccuracy: this.config.enableHighAccuracy || false,
121
- maximumAge: this.config.maximumAge || 300000
57
+ navigator.geolocation.getCurrentPosition((pos) => resolve({
58
+ latitude: pos.coords.latitude,
59
+ longitude: pos.coords.longitude,
60
+ accuracy: pos.coords.accuracy,
61
+ altitude: pos.coords.altitude ?? undefined,
62
+ altitudeAccuracy: pos.coords.altitudeAccuracy ?? undefined,
63
+ heading: pos.coords.heading ?? undefined,
64
+ speed: pos.coords.speed ?? undefined,
65
+ lastUpdated: new Date().toISOString(),
66
+ source: 'browser'
67
+ }), () => resolve(null), {
68
+ timeout: this._config.timeout ?? 10_000,
69
+ enableHighAccuracy: this._config.enableHighAccuracy ?? false,
70
+ maximumAge: this._config.maximumAge ?? 300_000
122
71
  });
123
72
  });
124
73
  }
125
- async getIPLocation() {
126
- if (!this.config.ipServiceUrl)
74
+ async _getIPLocation() {
75
+ if (!this._config.ipServiceUrl)
127
76
  return null;
128
77
  try {
129
- const response = await fetch(this.config.ipServiceUrl);
130
- const data = await response.json();
78
+ const res = await fetch(this._config.ipServiceUrl);
79
+ const data = await res.json();
131
80
  return {
132
81
  latitude: data.latitude,
133
82
  longitude: data.longitude,
134
- accuracy: data.accuracy || undefined,
83
+ accuracy: data.accuracy,
135
84
  lastUpdated: new Date().toISOString(),
136
85
  source: 'ip'
137
86
  };
@@ -140,16 +89,12 @@ class GeolocationService {
140
89
  return null;
141
90
  }
142
91
  }
143
- async getCustomLocation() {
144
- if (!this.config.customGeolocationFn)
92
+ async _getCustomLocation() {
93
+ if (!this._config.customGeolocationFn)
145
94
  return null;
146
95
  try {
147
- const result = await this.config.customGeolocationFn();
148
- return {
149
- ...result,
150
- lastUpdated: new Date().toISOString(),
151
- source: 'custom'
152
- };
96
+ const result = await this._config.customGeolocationFn();
97
+ return { ...result, lastUpdated: new Date().toISOString(), source: 'custom' };
153
98
  }
154
99
  catch {
155
100
  return null;
@@ -159,469 +104,287 @@ class GeolocationService {
159
104
  this.stopWatching();
160
105
  this._hasConsent = false;
161
106
  this._location = null;
162
- this._error = null;
163
107
  }
164
108
  }
165
- /**
166
- * Handles device information detection
167
- */
168
- class DeviceInfoService {
169
- static getDeviceInfo() {
170
- const userAgent = navigator.userAgent;
171
- const platform = navigator.platform;
172
- // Detect device type
173
- const isMobile = /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(userAgent);
174
- const isTablet = /iPad|Android(?=.*Tablet)|Windows NT.*Touch/i.test(userAgent);
175
- let deviceType = 'unknown';
176
- if (isTablet)
177
- deviceType = 'tablet';
178
- else if (isMobile)
179
- deviceType = 'mobile';
180
- else
181
- deviceType = 'desktop';
182
- // Detect browser and version
183
- const browserMatch = userAgent.match(/(firefox|chrome|safari|opera|edge|msie|trident(?=\/))\/?\s*(\d+)/i);
184
- const browser = browserMatch ? browserMatch[1] : 'Unknown';
185
- const browserVersion = browserMatch ? browserMatch[2] : '';
186
- // Detect OS and version
187
- let os = 'Unknown';
188
- let osVersion = '';
189
- if (userAgent.includes('Windows NT')) {
190
- os = 'Windows';
191
- const winMatch = userAgent.match(/Windows NT ([\d.]+)/);
192
- osVersion = winMatch ? winMatch[1] : '';
193
- }
194
- else if (userAgent.includes('Mac OS X')) {
195
- os = 'macOS';
196
- const macMatch = userAgent.match(/Mac OS X ([\d_]+)/);
197
- osVersion = macMatch ? macMatch[1].replace(/_/g, '.') : '';
198
- }
199
- else if (userAgent.includes('Linux')) {
200
- os = 'Linux';
201
- }
202
- else if (userAgent.includes('Android')) {
203
- os = 'Android';
204
- const androidMatch = userAgent.match(/Android ([\d.]+)/);
205
- osVersion = androidMatch ? androidMatch[1] : '';
206
- }
207
- else if (userAgent.includes('iOS')) {
208
- os = 'iOS';
209
- const iosMatch = userAgent.match(/OS ([\d_]+)/);
210
- osVersion = iosMatch ? iosMatch[1].replace(/_/g, '.') : '';
211
- }
212
- // Generate device ID
213
- const deviceId = `${browser}-${os}-${platform}`.replace(/[^a-zA-Z0-9-]/g, '');
214
- // Get screen resolution and timezone
215
- const screenResolution = `${screen.width}x${screen.height}`;
216
- const timezone = Intl.DateTimeFormat().resolvedOptions().timeZone;
217
- return {
218
- id: deviceId,
219
- type: deviceType,
220
- browser,
221
- browserVersion,
222
- os,
223
- osVersion,
224
- userAgent,
225
- screenResolution,
226
- timezone
227
- };
228
- }
109
+ // ── Device info helper ────────────────────────────────────────────────────────
110
+ function getDeviceInfo() {
111
+ const ua = navigator.userAgent;
112
+ const isMobile = /Android|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(ua);
113
+ const isTablet = /iPad|Android(?=.*Tablet)|Windows NT.*Touch/i.test(ua);
114
+ const type = isTablet ? 'tablet' : isMobile ? 'mobile' : 'desktop';
115
+ const browserMatch = ua.match(/(firefox|chrome|safari|opera|edge|msie|trident(?=\/))\/?\s*(\d+)/i);
116
+ const browser = browserMatch ? browserMatch[1] : 'Unknown';
117
+ const browserVersion = browserMatch ? browserMatch[2] : '';
118
+ let os = 'Unknown', osVersion = '';
119
+ if (ua.includes('Windows NT')) {
120
+ os = 'Windows';
121
+ osVersion = ua.match(/Windows NT ([\d.]+)/)?.[1] ?? '';
122
+ }
123
+ else if (ua.includes('Mac OS X')) {
124
+ os = 'macOS';
125
+ osVersion = (ua.match(/Mac OS X ([\d_]+)/)?.[1] ?? '').replace(/_/g, '.');
126
+ }
127
+ else if (ua.includes('Android')) {
128
+ os = 'Android';
129
+ osVersion = ua.match(/Android ([\d.]+)/)?.[1] ?? '';
130
+ }
131
+ else if (ua.includes('Linux')) {
132
+ os = 'Linux';
133
+ }
134
+ else if (ua.includes('iOS')) {
135
+ os = 'iOS';
136
+ osVersion = (ua.match(/OS ([\d_]+)/)?.[1] ?? '').replace(/_/g, '.');
137
+ }
138
+ return {
139
+ id: `${browser}-${os}`.replace(/[^a-zA-Z0-9-]/g, ''),
140
+ type,
141
+ browser,
142
+ browserVersion,
143
+ os,
144
+ osVersion,
145
+ userAgent: ua,
146
+ screenResolution: `${screen.width}x${screen.height}`,
147
+ timezone: Intl.DateTimeFormat().resolvedOptions().timeZone
148
+ };
229
149
  }
150
+ // ── Main presence service ─────────────────────────────────────────────────────
230
151
  /**
231
- * Main presence tracking service
152
+ * Reactive user presence tracking via Firebase Realtime Database.
153
+ *
154
+ * Monitors RTDB `.info/connected`, writes session data on connect,
155
+ * registers `onDisconnect` cleanup, and tracks page visibility changes.
232
156
  *
233
- * @class FirekitPresence
234
157
  * @example
235
- * ```typescript
158
+ * ```ts
236
159
  * import { firekitPresence } from 'svelte-firekit';
237
- *
238
- * // Initialize
239
- * await firekitPresence.initialize(user, {
240
- * geolocation: { enabled: true, type: 'browser' },
241
- * sessionTTL: 30 * 60 * 1000
242
- * });
243
- *
244
- * // Access reactive state
245
- * $: console.log('Status:', firekitPresence.status);
160
+ * await firekitPresence.initialize(user, { sessionTTL: 30 * 60 * 1000 });
246
161
  * ```
247
162
  */
248
163
  class FirekitPresence {
249
164
  static instance;
250
- config = {
251
- sessionTTL: 30 * 60 * 1000,
252
- updateInterval: 60 * 1000,
253
- trackDeviceInfo: true
254
- };
255
- geolocationService = null;
256
- connectedListener = null;
257
- currentUser = null;
258
- // Reactive state using Svelte 5 runes
165
+ // ── Reactive state ──────────────────────────────────────────────────────
259
166
  _initialized = $state(false);
260
167
  _status = $state('offline');
261
168
  _loading = $state(false);
262
169
  _error = $state(null);
263
170
  _currentSession = $state(null);
264
171
  _sessions = $state([]);
172
+ // ── Internal ────────────────────────────────────────────────────────────
173
+ _config = { sessionTTL: 30 * 60_000, updateInterval: 60_000, trackDeviceInfo: true };
174
+ _geo = null;
175
+ _connectedUnsub = null;
176
+ _currentUser = null;
265
177
  constructor() {
266
- if (browser) {
267
- this.setupVisibilityListener();
178
+ if (typeof window !== 'undefined') {
179
+ document.addEventListener('visibilitychange', this._onVisibilityChange);
268
180
  }
269
181
  }
270
- /**
271
- * Gets singleton instance of FirekitPresence
272
- */
273
182
  static getInstance() {
274
- if (!FirekitPresence.instance) {
183
+ if (!FirekitPresence.instance)
275
184
  FirekitPresence.instance = new FirekitPresence();
276
- }
277
185
  return FirekitPresence.instance;
278
186
  }
279
- // ========================================
280
- // REACTIVE GETTERS
281
- // ========================================
282
- get initialized() {
283
- return this._initialized;
284
- }
285
- get status() {
286
- return this._status;
287
- }
288
- get loading() {
289
- return this._loading;
290
- }
291
- get error() {
292
- return this._error;
293
- }
294
- get currentSession() {
295
- return this._currentSession;
296
- }
297
- get sessions() {
298
- return this._sessions;
299
- }
300
- get location() {
301
- return this.geolocationService?.location || null;
302
- }
303
- get hasLocationConsent() {
304
- return this.geolocationService?.hasConsent || false;
305
- }
306
- // ========================================
307
- // INITIALIZATION
308
- // ========================================
309
- /**
310
- * Initialize presence tracking
311
- * @param user Current authenticated user
312
- * @param config Presence configuration options
313
- */
187
+ // ── Getters ─────────────────────────────────────────────────────────────
188
+ get initialized() { return this._initialized; }
189
+ get status() { return this._status; }
190
+ get loading() { return this._loading; }
191
+ get error() { return this._error; }
192
+ get currentSession() { return this._currentSession; }
193
+ get sessions() { return this._sessions; }
194
+ get location() { return this._geo?.location ?? null; }
195
+ get hasLocationConsent() { return this._geo?.hasConsent ?? false; }
196
+ // ── Initialization ───────────────────────────────────────────────────────
314
197
  async initialize(user, config) {
198
+ if (typeof window === 'undefined') {
199
+ throw new PresenceError(PresenceErrorCode.INITIALIZATION_FAILED, 'Presence can only be initialized in a browser environment.');
200
+ }
201
+ if (this._initialized)
202
+ return;
203
+ this._loading = true;
204
+ this._currentUser = user;
205
+ if (config)
206
+ this._config = { ...this._config, ...config };
315
207
  try {
316
- if (!browser) {
317
- throw new PresenceError(PresenceErrorCode.INITIALIZATION_FAILED, 'Presence service can only be initialized in browser environment');
318
- }
319
- if (this._initialized) {
320
- console.warn('Presence service is already initialized');
321
- return;
322
- }
323
- this._loading = true;
324
- this.currentUser = user;
325
- this.config = { ...this.config, ...config };
326
- // Initialize geolocation service if enabled
327
- if (this.config.geolocation?.enabled) {
328
- this.geolocationService = new GeolocationService(this.config.geolocation);
329
- if (this.config.geolocation.requireConsent) {
330
- const hasConsent = await this.geolocationService.requestConsent();
208
+ if (this._config.geolocation?.enabled) {
209
+ this._geo = new GeolocationService(this._config.geolocation);
210
+ if (this._config.geolocation.requireConsent) {
211
+ await this._geo.requestConsent();
331
212
  }
332
- // Start location tracking if consent granted
333
- if (!this.config.geolocation.requireConsent || this.geolocationService.hasConsent) {
334
- this.geolocationService.startWatching(this.config.updateInterval);
213
+ if (!this._config.geolocation.requireConsent || this._geo.hasConsent) {
214
+ this._geo.startWatching(this._config.updateInterval);
335
215
  }
336
216
  }
337
- // Set up Firebase connection monitoring
338
- await this.setupConnectionMonitoring();
217
+ await this._setupConnectionMonitoring();
339
218
  this._initialized = true;
340
219
  }
341
- catch (error) {
342
- this._error =
343
- error instanceof PresenceError
344
- ? error
345
- : new PresenceError(PresenceErrorCode.INITIALIZATION_FAILED, `Failed to initialize presence service: ${error.message}`, error);
220
+ catch (err) {
221
+ // Clean up geolocation if it started before the error
222
+ this._geo?.dispose();
223
+ this._geo = null;
224
+ this._error = err instanceof PresenceError
225
+ ? err
226
+ : new PresenceError(PresenceErrorCode.INITIALIZATION_FAILED, err.message, err);
346
227
  throw this._error;
347
228
  }
348
229
  finally {
349
230
  this._loading = false;
350
231
  }
351
232
  }
352
- /**
353
- * Set up Firebase connection monitoring
354
- */
355
- async setupConnectionMonitoring() {
233
+ // ── Connection monitoring ────────────────────────────────────────────────
234
+ async _setupConnectionMonitoring() {
356
235
  const db = firebaseService.getDatabaseInstance();
357
- if (!db) {
358
- throw new PresenceError(PresenceErrorCode.DATABASE_ERROR, 'Firebase Database instance not available');
359
- }
236
+ if (!db)
237
+ throw new PresenceError(PresenceErrorCode.DATABASE_ERROR, 'Realtime Database is not initialized.');
360
238
  const connectedRef = ref(db, '.info/connected');
361
- this.connectedListener = onValue(connectedRef, async (snapshot) => {
362
- if (snapshot.val() === true) {
239
+ this._connectedUnsub = onValue(connectedRef, async (snap) => {
240
+ if (snap.val() === true) {
363
241
  await this.setPresence('online');
364
- await this.setupDisconnectHandler();
242
+ await this._setupDisconnectHandler();
365
243
  }
366
244
  else {
367
- await this.setPresence('offline');
245
+ this._status = 'offline';
368
246
  }
369
247
  });
370
248
  }
371
- /**
372
- * Set up disconnect handler for graceful offline transitions
373
- */
374
- async setupDisconnectHandler() {
375
- if (!this.currentUser || !this._currentSession)
249
+ async _setupDisconnectHandler() {
250
+ if (!this._currentUser || !this._currentSession)
376
251
  return;
377
252
  const db = firebaseService.getDatabaseInstance();
378
253
  if (!db)
379
254
  return;
380
- const sessionPath = this.config.sessionPath || 'presence';
381
- const sessionRef = ref(db, `${sessionPath}/${this.currentUser.uid}/sessions/${this._currentSession.id}`);
382
- await onDisconnect(sessionRef).update({
255
+ const path = `${this._config.sessionPath ?? 'presence'}/${this._currentUser.uid}/sessions/${this._currentSession.id}`;
256
+ await onDisconnect(ref(db, path)).update({
383
257
  status: 'offline',
384
258
  lastSeen: serverTimestamp()
385
259
  });
386
260
  }
387
- /**
388
- * Set up page visibility listener
389
- */
390
- setupVisibilityListener() {
391
- if (!browser)
261
+ _onVisibilityChange = async () => {
262
+ if (!this._initialized)
392
263
  return;
393
- document.addEventListener('visibilitychange', async () => {
394
- if (!this._initialized)
395
- return;
396
- if (document.visibilityState === 'hidden') {
397
- await this.setPresence('away');
398
- }
399
- else {
400
- await this.setPresence('online');
401
- }
402
- });
403
- }
404
- // ========================================
405
- // PRESENCE MANAGEMENT
406
- // ========================================
407
- /**
408
- * Set presence status
409
- */
264
+ await this.setPresence(document.visibilityState === 'hidden' ? 'away' : 'online');
265
+ };
266
+ // ── Presence management ──────────────────────────────────────────────────
410
267
  async setPresence(status) {
268
+ if (!this._currentUser) {
269
+ throw new PresenceError(PresenceErrorCode.USER_NOT_AUTHENTICATED, 'No authenticated user.');
270
+ }
271
+ const db = firebaseService.getDatabaseInstance();
272
+ if (!db)
273
+ throw new PresenceError(PresenceErrorCode.DATABASE_ERROR, 'Realtime Database is not initialized.');
411
274
  try {
412
- if (!this.currentUser) {
413
- throw new PresenceError(PresenceErrorCode.USER_NOT_AUTHENTICATED, 'No authenticated user found');
414
- }
415
- const db = firebaseService.getDatabaseInstance();
416
- if (!db) {
417
- throw new PresenceError(PresenceErrorCode.DATABASE_ERROR, 'Firebase Database instance not available');
418
- }
419
- // Get current location if available
420
- const location = await this.geolocationService?.getCurrentLocation();
421
- // Get device info if enabled
422
- const device = this.config.trackDeviceInfo ? DeviceInfoService.getDeviceInfo() : undefined;
423
- let session;
424
- if (!this._currentSession) {
425
- // Create new session
426
- session = {
427
- id: `${this.currentUser.uid}_${device?.id || Date.now()}`,
428
- userId: this.currentUser.uid,
275
+ const location = await this._geo?.getCurrentLocation() ?? undefined;
276
+ const device = this._config.trackDeviceInfo ? getDeviceInfo() : undefined;
277
+ const now = new Date().toISOString();
278
+ const session = this._currentSession
279
+ ? { ...this._currentSession, status, lastSeen: now, lastActivity: now, ...(location && { location }) }
280
+ : {
281
+ id: `${this._currentUser.uid}_${device?.id ?? Date.now()}`,
282
+ userId: this._currentUser.uid,
429
283
  status,
430
- createdAt: new Date().toISOString(),
431
- lastSeen: new Date().toISOString(),
432
- lastActivity: new Date().toISOString(),
284
+ createdAt: now,
285
+ lastSeen: now,
286
+ lastActivity: now,
433
287
  ...(location && { location }),
434
288
  ...(device && { device }),
435
- ...(this.config.customMetadata && { metadata: this.config.customMetadata })
289
+ ...(this._config.customMetadata && { metadata: this._config.customMetadata })
436
290
  };
437
- }
438
- else {
439
- // Update existing session
440
- session = {
441
- ...this._currentSession,
442
- status,
443
- lastSeen: new Date().toISOString(),
444
- lastActivity: new Date().toISOString(),
445
- ...(location && { location })
446
- };
447
- }
448
- // Save session to Firebase
449
- const sessionPath = this.config.sessionPath || 'presence';
450
- const sessionRef = ref(db, `${sessionPath}/${this.currentUser.uid}/sessions/${session.id}`);
291
+ const sessionRef = ref(db, `${this._config.sessionPath ?? 'presence'}/${this._currentUser.uid}/sessions/${session.id}`);
451
292
  await set(sessionRef, session);
452
- // Update local state
453
293
  this._currentSession = session;
454
294
  this._status = status;
455
- // Load and update all sessions
456
- await this.loadSessions();
295
+ await this._loadSessions();
457
296
  }
458
- catch (error) {
459
- this._error =
460
- error instanceof PresenceError
461
- ? error
462
- : new PresenceError(PresenceErrorCode.DATABASE_ERROR, `Failed to set presence: ${error.message}`, error);
297
+ catch (err) {
298
+ this._error = err instanceof PresenceError
299
+ ? err
300
+ : new PresenceError(PresenceErrorCode.DATABASE_ERROR, err.message, err);
463
301
  throw this._error;
464
302
  }
465
303
  }
466
- /**
467
- * Load all sessions for current user
468
- */
469
- async loadSessions() {
470
- if (!this.currentUser)
304
+ async _loadSessions() {
305
+ if (!this._currentUser)
306
+ return;
307
+ const db = firebaseService.getDatabaseInstance();
308
+ if (!db)
309
+ return;
310
+ const basePath = `${this._config.sessionPath ?? 'presence'}/${this._currentUser.uid}/sessions`;
311
+ const snap = await get(ref(db, basePath));
312
+ if (!snap.exists()) {
313
+ this._sessions = [];
471
314
  return;
472
- try {
473
- const db = firebaseService.getDatabaseInstance();
474
- if (!db)
475
- return;
476
- const sessionPath = this.config.sessionPath || 'presence';
477
- const sessionsRef = ref(db, `${sessionPath}/${this.currentUser.uid}/sessions`);
478
- const snapshot = await get(sessionsRef);
479
- if (snapshot.exists()) {
480
- const sessionsData = snapshot.val();
481
- let sessions = Object.values(sessionsData);
482
- // Clean up stale sessions
483
- if (this.config.sessionTTL) {
484
- const cutoffTime = new Date(Date.now() - this.config.sessionTTL).toISOString();
485
- const expiredSessions = sessions.filter((session) => session.lastSeen < cutoffTime);
486
- sessions = sessions.filter((session) => session.lastSeen >= cutoffTime);
487
- // Remove stale sessions from database
488
- for (const expiredSession of expiredSessions) {
489
- const staleSessionRef = ref(db, `${sessionPath}/${this.currentUser.uid}/sessions/${expiredSession.id}`);
490
- await set(staleSessionRef, null);
491
- }
492
- }
493
- this._sessions = sessions;
494
- }
495
- else {
496
- this._sessions = [];
497
- }
498
315
  }
499
- catch (error) {
500
- console.error('Failed to load sessions:', error);
316
+ let sessions = Object.values(snap.val());
317
+ if (this._config.sessionTTL) {
318
+ const cutoff = new Date(Date.now() - this._config.sessionTTL).toISOString();
319
+ const expired = sessions.filter((s) => s.lastSeen < cutoff);
320
+ sessions = sessions.filter((s) => s.lastSeen >= cutoff);
321
+ await Promise.all(expired.map((s) => set(ref(db, `${basePath}/${s.id}`), null)));
501
322
  }
323
+ this._sessions = sessions;
502
324
  }
503
- // ========================================
504
- // UTILITY METHODS
505
- // ========================================
506
- /**
507
- * Get presence statistics
508
- */
509
- getPresenceStats() {
325
+ // ── Helpers ──────────────────────────────────────────────────────────────
326
+ getStats() {
510
327
  const sessions = this._sessions;
511
- let totalSessionTime = 0;
512
- const deviceSet = new Set();
513
- let lastActivityTime = 0;
514
- sessions.forEach((session) => {
515
- if (session.device?.id) {
516
- deviceSet.add(session.device.id);
517
- }
518
- const sessionStart = new Date(session.createdAt).getTime();
519
- const sessionEnd = new Date(session.lastSeen).getTime();
520
- totalSessionTime += sessionEnd - sessionStart;
521
- if (session.lastActivity) {
522
- const activityTime = new Date(session.lastActivity).getTime();
523
- lastActivityTime = Math.max(lastActivityTime, activityTime);
524
- }
525
- });
526
- const averageSessionDuration = sessions.length > 0 ? totalSessionTime / sessions.length : 0;
328
+ let totalMs = 0;
329
+ const devices = new Set();
330
+ let lastActivity = 0;
331
+ for (const s of sessions) {
332
+ if (s.device?.id)
333
+ devices.add(s.device.id);
334
+ totalMs += new Date(s.lastSeen).getTime() - new Date(s.createdAt).getTime();
335
+ if (s.lastActivity)
336
+ lastActivity = Math.max(lastActivity, new Date(s.lastActivity).getTime());
337
+ }
527
338
  return {
528
339
  totalSessions: sessions.length,
529
340
  onlineSessions: sessions.filter((s) => s.status === 'online').length,
530
341
  awaySessions: sessions.filter((s) => s.status === 'away').length,
531
342
  offlineSessions: sessions.filter((s) => s.status === 'offline').length,
532
- uniqueDevices: deviceSet.size,
533
- averageSessionDuration,
534
- lastActivity: lastActivityTime > 0 ? new Date(lastActivityTime).toISOString() : ''
343
+ uniqueDevices: devices.size,
344
+ averageSessionDuration: sessions.length > 0 ? totalMs / sessions.length : 0,
345
+ lastActivity: lastActivity > 0 ? new Date(lastActivity).toISOString() : ''
535
346
  };
536
347
  }
537
- /**
538
- * Request location consent manually
539
- */
540
- async requestLocationConsent() {
541
- if (!this.geolocationService) {
542
- throw new PresenceError(PresenceErrorCode.GEOLOCATION_UNAVAILABLE, 'Geolocation service not available');
543
- }
544
- return await this.geolocationService.requestConsent();
545
- }
546
- /**
547
- * Get current user's online sessions count
548
- */
549
- getOnlineSessionsCount() {
550
- return this._sessions.filter((session) => session.status === 'online').length;
551
- }
552
- /**
553
- * Check if user is online on any device
554
- */
555
- isUserOnline() {
556
- return this._sessions.some((session) => session.status === 'online');
557
- }
558
- /**
559
- * Get sessions by status
560
- */
348
+ isOnline() { return this._sessions.some((s) => s.status === 'online'); }
561
349
  getSessionsByStatus(status) {
562
- return this._sessions.filter((session) => session.status === status);
350
+ return this._sessions.filter((s) => s.status === status);
351
+ }
352
+ async requestLocationConsent() {
353
+ if (!this._geo)
354
+ throw new PresenceError(PresenceErrorCode.GEOLOCATION_UNAVAILABLE, 'Geolocation not configured.');
355
+ return this._geo.requestConsent();
563
356
  }
564
- /**
565
- * Force refresh presence data
566
- */
567
357
  async refresh() {
568
358
  if (!this._initialized)
569
359
  return;
570
360
  this._loading = true;
571
361
  try {
572
- await this.loadSessions();
573
- if (this._currentSession) {
362
+ await this._loadSessions();
363
+ if (this._currentSession)
574
364
  await this.setPresence(this._status);
575
- }
576
365
  }
577
366
  finally {
578
367
  this._loading = false;
579
368
  }
580
369
  }
581
- // ========================================
582
- // CLEANUP
583
- // ========================================
584
- /**
585
- * Dispose of all resources and cleanup
586
- */
587
370
  async dispose() {
588
- try {
589
- // Set status to offline before cleanup
590
- if (this._currentSession) {
371
+ if (this._currentSession) {
372
+ try {
591
373
  await this.setPresence('offline');
592
374
  }
375
+ catch { /* best-effort */ }
593
376
  }
594
- catch (error) {
595
- console.error('Error setting offline status during disposal:', error);
596
- }
597
- // Stop location tracking
598
- this.geolocationService?.dispose();
599
- // Remove connection listener
600
- if (this.connectedListener) {
601
- this.connectedListener();
602
- this.connectedListener = null;
377
+ this._geo?.dispose();
378
+ this._connectedUnsub?.();
379
+ this._connectedUnsub = null;
380
+ if (typeof document !== 'undefined') {
381
+ document.removeEventListener('visibilitychange', this._onVisibilityChange);
603
382
  }
604
- // Reset state
605
383
  this._initialized = false;
606
384
  this._status = 'offline';
607
- this._loading = false;
608
385
  this._error = null;
609
386
  this._currentSession = null;
610
387
  this._sessions = [];
611
388
  }
612
389
  }
613
- /**
614
- * Pre-initialized singleton instance of FirekitPresence.
615
- *
616
- * @example
617
- * ```typescript
618
- * import { firekitPresence } from 'svelte-firekit';
619
- *
620
- * // Initialize presence tracking
621
- * await firekitPresence.initialize(user, {
622
- * geolocation: { enabled: true, type: 'browser' },
623
- * sessionTTL: 30 * 60 * 1000
624
- * });
625
- * ```
626
- */
627
390
  export const firekitPresence = FirekitPresence.getInstance();