@lenne.tech/ng-base 18.1.2 → 22.0.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 (416) hide show
  1. package/CLAUDE.md +55 -0
  2. package/LICENSE +2 -2
  3. package/README.md +237 -44
  4. package/fesm2022/lenne.tech-ng-base-ai.mjs +767 -0
  5. package/fesm2022/lenne.tech-ng-base-ai.mjs.map +1 -0
  6. package/fesm2022/lenne.tech-ng-base-auth-provide.mjs +939 -0
  7. package/fesm2022/lenne.tech-ng-base-auth-provide.mjs.map +1 -0
  8. package/fesm2022/lenne.tech-ng-base-auth.mjs +454 -0
  9. package/fesm2022/lenne.tech-ng-base-auth.mjs.map +1 -0
  10. package/fesm2022/lenne.tech-ng-base-bug-bug-report-dialog-BRzVmKJr.mjs +825 -0
  11. package/fesm2022/lenne.tech-ng-base-bug-bug-report-dialog-BRzVmKJr.mjs.map +1 -0
  12. package/fesm2022/lenne.tech-ng-base-bug-bug-report-service-DWoTb_iw.mjs +351 -0
  13. package/fesm2022/lenne.tech-ng-base-bug-bug-report-service-DWoTb_iw.mjs.map +1 -0
  14. package/fesm2022/lenne.tech-ng-base-bug-capture-engine-TkjMDdqj.mjs +1046 -0
  15. package/fesm2022/lenne.tech-ng-base-bug-capture-engine-TkjMDdqj.mjs.map +1 -0
  16. package/fesm2022/lenne.tech-ng-base-bug-constants-Brm2KGHi.mjs +4 -0
  17. package/fesm2022/lenne.tech-ng-base-bug-constants-Brm2KGHi.mjs.map +1 -0
  18. package/fesm2022/lenne.tech-ng-base-bug-messages-BsP4fRQU.mjs +179 -0
  19. package/fesm2022/lenne.tech-ng-base-bug-messages-BsP4fRQU.mjs.map +1 -0
  20. package/fesm2022/lenne.tech-ng-base-bug-provide.mjs +26 -0
  21. package/fesm2022/lenne.tech-ng-base-bug-provide.mjs.map +1 -0
  22. package/fesm2022/lenne.tech-ng-base-bug-report-Tzlhe1Cm.mjs +62 -0
  23. package/fesm2022/lenne.tech-ng-base-bug-report-Tzlhe1Cm.mjs.map +1 -0
  24. package/fesm2022/lenne.tech-ng-base-bug-server.mjs +818 -0
  25. package/fesm2022/lenne.tech-ng-base-bug-server.mjs.map +1 -0
  26. package/fesm2022/lenne.tech-ng-base-bug.mjs +196 -0
  27. package/fesm2022/lenne.tech-ng-base-bug.mjs.map +1 -0
  28. package/fesm2022/lenne.tech-ng-base-files-ui.mjs +445 -0
  29. package/fesm2022/lenne.tech-ng-base-files-ui.mjs.map +1 -0
  30. package/fesm2022/lenne.tech-ng-base-files.mjs +474 -0
  31. package/fesm2022/lenne.tech-ng-base-files.mjs.map +1 -0
  32. package/fesm2022/lenne.tech-ng-base-server.mjs +408 -0
  33. package/fesm2022/lenne.tech-ng-base-server.mjs.map +1 -0
  34. package/fesm2022/lenne.tech-ng-base-share.mjs +76 -0
  35. package/fesm2022/lenne.tech-ng-base-share.mjs.map +1 -0
  36. package/fesm2022/lenne.tech-ng-base-sync.mjs +1096 -0
  37. package/fesm2022/lenne.tech-ng-base-sync.mjs.map +1 -0
  38. package/fesm2022/lenne.tech-ng-base-testing.mjs +171 -0
  39. package/fesm2022/lenne.tech-ng-base-testing.mjs.map +1 -0
  40. package/fesm2022/lenne.tech-ng-base-ui-provide.mjs +124 -0
  41. package/fesm2022/lenne.tech-ng-base-ui-provide.mjs.map +1 -0
  42. package/fesm2022/lenne.tech-ng-base-ui.mjs +34611 -0
  43. package/fesm2022/lenne.tech-ng-base-ui.mjs.map +1 -0
  44. package/fesm2022/lenne.tech-ng-base-utils.mjs +287 -0
  45. package/fesm2022/lenne.tech-ng-base-utils.mjs.map +1 -0
  46. package/fesm2022/lenne.tech-ng-base.mjs +615 -902
  47. package/fesm2022/lenne.tech-ng-base.mjs.map +1 -1
  48. package/i18n/auth/de.json +17 -0
  49. package/i18n/auth/en.json +17 -0
  50. package/i18n/bug/de.json +85 -0
  51. package/i18n/bug/en.json +85 -0
  52. package/i18n/de.json +8 -0
  53. package/i18n/en.json +8 -0
  54. package/i18n/files/de.json +27 -0
  55. package/i18n/files/en.json +27 -0
  56. package/i18n/share/de.json +8 -0
  57. package/i18n/share/en.json +8 -0
  58. package/i18n/ui/de.json +38 -0
  59. package/i18n/ui/en.json +38 -0
  60. package/package.json +127 -58
  61. package/types/lenne.tech-ng-base-ai.d.ts +830 -0
  62. package/types/lenne.tech-ng-base-auth-provide.d.ts +603 -0
  63. package/types/lenne.tech-ng-base-auth.d.ts +320 -0
  64. package/types/lenne.tech-ng-base-bug-provide.d.ts +272 -0
  65. package/types/lenne.tech-ng-base-bug-rolldown-runtime-C25Le4-w.d.ts +1 -0
  66. package/types/lenne.tech-ng-base-bug-server.d.ts +316 -0
  67. package/types/lenne.tech-ng-base-bug.d.ts +202 -0
  68. package/types/lenne.tech-ng-base-files-ui.d.ts +116 -0
  69. package/types/lenne.tech-ng-base-files.d.ts +288 -0
  70. package/types/lenne.tech-ng-base-server.d.ts +262 -0
  71. package/types/lenne.tech-ng-base-share.d.ts +21 -0
  72. package/types/lenne.tech-ng-base-sync.d.ts +380 -0
  73. package/types/lenne.tech-ng-base-testing.d.ts +327 -0
  74. package/types/lenne.tech-ng-base-ui-provide.d.ts +65 -0
  75. package/types/lenne.tech-ng-base-ui.d.ts +7732 -0
  76. package/types/lenne.tech-ng-base-utils.d.ts +150 -0
  77. package/types/lenne.tech-ng-base.d.ts +503 -0
  78. package/ui/styles/components/accordion.css +3 -0
  79. package/ui/styles/components/alert-dialog.css +4 -0
  80. package/ui/styles/components/alert.css +3 -0
  81. package/ui/styles/components/aspect-ratio.css +3 -0
  82. package/ui/styles/components/attachment.css +4 -0
  83. package/ui/styles/components/autocomplete.css +4 -0
  84. package/ui/styles/components/avatar.css +3 -0
  85. package/ui/styles/components/badge.css +3 -0
  86. package/ui/styles/components/breadcrumb.css +3 -0
  87. package/ui/styles/components/bubble.css +3 -0
  88. package/ui/styles/components/button-group.css +3 -0
  89. package/ui/styles/components/button.css +3 -0
  90. package/ui/styles/components/calendar.css +5 -0
  91. package/ui/styles/components/card.css +3 -0
  92. package/ui/styles/components/checkbox.css +3 -0
  93. package/ui/styles/components/code-block.css +4 -0
  94. package/ui/styles/components/collapsible.css +3 -0
  95. package/ui/styles/components/combobox.css +5 -0
  96. package/ui/styles/components/command.css +5 -0
  97. package/ui/styles/components/context-menu.css +3 -0
  98. package/ui/styles/components/date-picker.css +7 -0
  99. package/ui/styles/components/dialog.css +4 -0
  100. package/ui/styles/components/drawer.css +3 -0
  101. package/ui/styles/components/dropdown-menu.css +3 -0
  102. package/ui/styles/components/empty.css +3 -0
  103. package/ui/styles/components/field.css +5 -0
  104. package/ui/styles/components/hover-card.css +3 -0
  105. package/ui/styles/components/index.css +91 -0
  106. package/ui/styles/components/input-group.css +6 -0
  107. package/ui/styles/components/input-otp.css +3 -0
  108. package/ui/styles/components/input.css +3 -0
  109. package/ui/styles/components/item.css +4 -0
  110. package/ui/styles/components/kbd.css +3 -0
  111. package/ui/styles/components/label.css +3 -0
  112. package/ui/styles/components/lt-breadcrumb.css +3 -0
  113. package/ui/styles/components/lt-bug-attachments.css +5 -0
  114. package/ui/styles/components/lt-bug-journey-timeline.css +5 -0
  115. package/ui/styles/components/lt-bug-report-dialog.css +15 -0
  116. package/ui/styles/components/lt-bug-report.css +4 -0
  117. package/ui/styles/components/lt-color-mode-button.css +3 -0
  118. package/ui/styles/components/lt-confirm-dialog.css +4 -0
  119. package/ui/styles/components/lt-data-view.css +5 -0
  120. package/ui/styles/components/lt-date-picker.css +3 -0
  121. package/ui/styles/components/lt-date-time-picker.css +5 -0
  122. package/ui/styles/components/lt-enter-action.css +2 -0
  123. package/ui/styles/components/lt-footer.css +3 -0
  124. package/ui/styles/components/lt-form-field.css +4 -0
  125. package/ui/styles/components/lt-header.css +5 -0
  126. package/ui/styles/components/lt-imports.css +21 -0
  127. package/ui/styles/components/lt-navigation-menu.css +3 -0
  128. package/ui/styles/components/lt-notice.css +3 -0
  129. package/ui/styles/components/lt-overlay-defaults.css +3 -0
  130. package/ui/styles/components/lt-page-card.css +3 -0
  131. package/ui/styles/components/lt-page-title.css +2 -0
  132. package/ui/styles/components/lt-password-input.css +4 -0
  133. package/ui/styles/components/lt-readonly-field.css +2 -0
  134. package/ui/styles/components/lt-select.css +4 -0
  135. package/ui/styles/components/lt-text-field.css +5 -0
  136. package/ui/styles/components/lt-toolbar-item.css +2 -0
  137. package/ui/styles/components/lt-toolbar.css +3 -0
  138. package/ui/styles/components/lt-tus-upload-component.css +5 -0
  139. package/ui/styles/components/marker.css +3 -0
  140. package/ui/styles/components/menubar.css +3 -0
  141. package/ui/styles/components/message-scroller.css +4 -0
  142. package/ui/styles/components/message.css +3 -0
  143. package/ui/styles/components/native-select.css +3 -0
  144. package/ui/styles/components/navigation-menu.css +3 -0
  145. package/ui/styles/components/pagination.css +4 -0
  146. package/ui/styles/components/popover.css +3 -0
  147. package/ui/styles/components/progress.css +3 -0
  148. package/ui/styles/components/questionnaire.css +4 -0
  149. package/ui/styles/components/radio-group.css +3 -0
  150. package/ui/styles/components/resizable.css +3 -0
  151. package/ui/styles/components/select.css +3 -0
  152. package/ui/styles/components/separator.css +3 -0
  153. package/ui/styles/components/sheet.css +4 -0
  154. package/ui/styles/components/sidebar.css +9 -0
  155. package/ui/styles/components/skeleton.css +3 -0
  156. package/ui/styles/components/slider.css +3 -0
  157. package/ui/styles/components/sonner.css +4 -0
  158. package/ui/styles/components/spinner.css +3 -0
  159. package/ui/styles/components/switch.css +3 -0
  160. package/ui/styles/components/table.css +3 -0
  161. package/ui/styles/components/tabs.css +4 -0
  162. package/ui/styles/components/textarea.css +3 -0
  163. package/ui/styles/components/toggle-group.css +4 -0
  164. package/ui/styles/components/toggle.css +3 -0
  165. package/ui/styles/components/tooltip.css +3 -0
  166. package/ui/styles/components/trace.css +3 -0
  167. package/ui/styles/components/typography.css +3 -0
  168. package/ui/styles/components/utils.css +2 -0
  169. package/ui/styles/core.css +137 -0
  170. package/ui/styles/palette.css +94 -0
  171. package/ui/styles/theme.css +14 -0
  172. package/ui/styles/transitions.css +131 -0
  173. package/base-cms/index.d.ts +0 -5
  174. package/base-cms/interfaces/base-cms-module-config.interface.d.ts +0 -16
  175. package/base-cms/pages/base-cms/base-cms.component.d.ts +0 -92
  176. package/base-cms/public-api.d.ts +0 -5
  177. package/base-components/components/breadcrumb/breadcrumb.component.d.ts +0 -10
  178. package/base-components/components/change-password/change-password.component.d.ts +0 -24
  179. package/base-components/components/checkbox/checkbox.component.d.ts +0 -12
  180. package/base-components/components/delete-account/delete-account.component.d.ts +0 -15
  181. package/base-components/components/fab-button/fab-button.component.d.ts +0 -16
  182. package/base-components/components/input/input.component.d.ts +0 -27
  183. package/base-components/components/loading-bar/loading-bar.component.d.ts +0 -17
  184. package/base-components/components/model-form/model-form-base.component.d.ts +0 -64
  185. package/base-components/components/model-form/model-form.component.d.ts +0 -139
  186. package/base-components/components/model-form-sub/model-form-sub.component.d.ts +0 -56
  187. package/base-components/components/model-table/model-table.component.d.ts +0 -115
  188. package/base-components/components/refence-input/refence-input.component.d.ts +0 -84
  189. package/base-components/components/select/select.component.d.ts +0 -25
  190. package/base-components/components/skeleton-loader/skeleton-loader.component.d.ts +0 -10
  191. package/base-components/components/tags/tags.component.d.ts +0 -60
  192. package/base-components/components/textarea/textarea.component.d.ts +0 -21
  193. package/base-components/components/toast/toast.component.d.ts +0 -19
  194. package/base-components/components/upload-image/upload-image.component.d.ts +0 -111
  195. package/base-components/directives/back-button.directive.d.ts +0 -9
  196. package/base-components/directives/context-menu.directive.d.ts +0 -22
  197. package/base-components/directives/sort.directive.d.ts +0 -15
  198. package/base-components/directives/stop-propagation.directive.d.ts +0 -10
  199. package/base-components/index.d.ts +0 -5
  200. package/base-components/pipes/ellipses.pipe.d.ts +0 -10
  201. package/base-components/public-api.d.ts +0 -26
  202. package/base-prototype/index.d.ts +0 -5
  203. package/base-prototype/pages/email-verification/email-verification.component.d.ts +0 -18
  204. package/base-prototype/pages/forgot-password/forgot-password.component.d.ts +0 -26
  205. package/base-prototype/pages/login/login.component.d.ts +0 -33
  206. package/base-prototype/pages/profile/profile.component.d.ts +0 -24
  207. package/base-prototype/pages/register/register.component.d.ts +0 -31
  208. package/base-prototype/pages/set-password/set-password.component.d.ts +0 -29
  209. package/base-prototype/public-api.d.ts +0 -9
  210. package/esm2022/base-cms/interfaces/base-cms-module-config.interface.mjs +0 -3
  211. package/esm2022/base-cms/lenne.tech-ng-base-base-cms.mjs +0 -5
  212. package/esm2022/base-cms/pages/base-cms/base-cms.component.mjs +0 -238
  213. package/esm2022/base-cms/public-api.mjs +0 -8
  214. package/esm2022/base-components/components/breadcrumb/breadcrumb.component.mjs +0 -23
  215. package/esm2022/base-components/components/change-password/change-password.component.mjs +0 -97
  216. package/esm2022/base-components/components/checkbox/checkbox.component.mjs +0 -38
  217. package/esm2022/base-components/components/delete-account/delete-account.component.mjs +0 -59
  218. package/esm2022/base-components/components/fab-button/fab-button.component.mjs +0 -24
  219. package/esm2022/base-components/components/input/input.component.mjs +0 -75
  220. package/esm2022/base-components/components/loading-bar/loading-bar.component.mjs +0 -37
  221. package/esm2022/base-components/components/model-form/model-form-base.component.mjs +0 -145
  222. package/esm2022/base-components/components/model-form/model-form.component.mjs +0 -591
  223. package/esm2022/base-components/components/model-form-sub/model-form-sub.component.mjs +0 -117
  224. package/esm2022/base-components/components/model-table/model-table.component.mjs +0 -478
  225. package/esm2022/base-components/components/refence-input/refence-input.component.mjs +0 -278
  226. package/esm2022/base-components/components/select/select.component.mjs +0 -62
  227. package/esm2022/base-components/components/skeleton-loader/skeleton-loader.component.mjs +0 -33
  228. package/esm2022/base-components/components/tags/tags.component.mjs +0 -227
  229. package/esm2022/base-components/components/textarea/textarea.component.mjs +0 -79
  230. package/esm2022/base-components/components/toast/toast.component.mjs +0 -69
  231. package/esm2022/base-components/components/upload-image/upload-image.component.mjs +0 -346
  232. package/esm2022/base-components/directives/back-button.directive.mjs +0 -25
  233. package/esm2022/base-components/directives/context-menu.directive.mjs +0 -112
  234. package/esm2022/base-components/directives/sort.directive.mjs +0 -61
  235. package/esm2022/base-components/directives/stop-propagation.directive.mjs +0 -24
  236. package/esm2022/base-components/lenne.tech-ng-base-base-components.mjs +0 -5
  237. package/esm2022/base-components/pipes/ellipses.pipe.mjs +0 -23
  238. package/esm2022/base-components/public-api.mjs +0 -30
  239. package/esm2022/base-prototype/lenne.tech-ng-base-base-prototype.mjs +0 -5
  240. package/esm2022/base-prototype/pages/email-verification/email-verification.component.mjs +0 -60
  241. package/esm2022/base-prototype/pages/forgot-password/forgot-password.component.mjs +0 -78
  242. package/esm2022/base-prototype/pages/login/login.component.mjs +0 -114
  243. package/esm2022/base-prototype/pages/profile/profile.component.mjs +0 -87
  244. package/esm2022/base-prototype/pages/register/register.component.mjs +0 -100
  245. package/esm2022/base-prototype/pages/set-password/set-password.component.mjs +0 -91
  246. package/esm2022/base-prototype/public-api.mjs +0 -11
  247. package/esm2022/lenne.tech-ng-base.mjs +0 -5
  248. package/esm2022/public-api.mjs +0 -25
  249. package/esm2022/shared/classes/auth.class.mjs +0 -14
  250. package/esm2022/shared/classes/basic-user.class.mjs +0 -49
  251. package/esm2022/shared/classes/graphql-enum.class.mjs +0 -10
  252. package/esm2022/shared/classes/graphql-meta.class.mjs +0 -345
  253. package/esm2022/shared/classes/graphql-type.class.mjs +0 -14
  254. package/esm2022/shared/classes/helper.class.mjs +0 -307
  255. package/esm2022/shared/classes/sort.class.mjs +0 -38
  256. package/esm2022/shared/classes/standard.class.mjs +0 -40
  257. package/esm2022/shared/decorators/debounce.decorator.mjs +0 -12
  258. package/esm2022/shared/enums/comparison-operator.enum.mjs +0 -16
  259. package/esm2022/shared/enums/graphql-request-type.enum.mjs +0 -10
  260. package/esm2022/shared/enums/logical-operator.enum.mjs +0 -10
  261. package/esm2022/shared/enums/skeleton-type.enum.mjs +0 -7
  262. package/esm2022/shared/enums/sort-order.enum.mjs +0 -6
  263. package/esm2022/shared/enums/toast-type.enum.mjs +0 -8
  264. package/esm2022/shared/functions/ws-client.function.mjs +0 -39
  265. package/esm2022/shared/interfaces/base-module-config.interface.mjs +0 -3
  266. package/esm2022/shared/interfaces/breadcrumb.interface.mjs +0 -2
  267. package/esm2022/shared/interfaces/can-component-deactivate.interface.mjs +0 -2
  268. package/esm2022/shared/interfaces/cms-enum-values.interface.mjs +0 -2
  269. package/esm2022/shared/interfaces/cms-field-config.interface.mjs +0 -2
  270. package/esm2022/shared/interfaces/cms-model-config.interface.mjs +0 -2
  271. package/esm2022/shared/interfaces/cms-table-field.interface.mjs +0 -2
  272. package/esm2022/shared/interfaces/combined-filter-input.interface.mjs +0 -2
  273. package/esm2022/shared/interfaces/compress-options.interface.mjs +0 -2
  274. package/esm2022/shared/interfaces/cropping-options.interface.mjs +0 -2
  275. package/esm2022/shared/interfaces/field-object.interface.mjs +0 -2
  276. package/esm2022/shared/interfaces/field.interface.mjs +0 -2
  277. package/esm2022/shared/interfaces/filter-input.interface.mjs +0 -2
  278. package/esm2022/shared/interfaces/find-args.interface.mjs +0 -2
  279. package/esm2022/shared/interfaces/graphql-crud-type.interface.mjs +0 -2
  280. package/esm2022/shared/interfaces/graphql-fields-object.interface.mjs +0 -2
  281. package/esm2022/shared/interfaces/graphql-options.interface.mjs +0 -2
  282. package/esm2022/shared/interfaces/graphql-plus-options.interfacen.mjs +0 -2
  283. package/esm2022/shared/interfaces/graphql-type-collection.interface.mjs +0 -2
  284. package/esm2022/shared/interfaces/login-config.interface.mjs +0 -2
  285. package/esm2022/shared/interfaces/register-config.interface.mjs +0 -2
  286. package/esm2022/shared/interfaces/single-filter-input.interface.mjs +0 -2
  287. package/esm2022/shared/interfaces/sort-input.interface.mjs +0 -2
  288. package/esm2022/shared/interfaces/time-components.interface.mjs +0 -2
  289. package/esm2022/shared/interfaces/toast.interface.mjs +0 -2
  290. package/esm2022/shared/lenne.tech-ng-base-shared.mjs +0 -5
  291. package/esm2022/shared/public-api.mjs +0 -74
  292. package/esm2022/shared/services/auth.service.mjs +0 -152
  293. package/esm2022/shared/services/breadcrumb.service.mjs +0 -69
  294. package/esm2022/shared/services/cms.service.mjs +0 -82
  295. package/esm2022/shared/services/file.service.mjs +0 -86
  296. package/esm2022/shared/services/forms.service.mjs +0 -61
  297. package/esm2022/shared/services/graphql-meta.service.mjs +0 -132
  298. package/esm2022/shared/services/graphql-plus.service.mjs +0 -93
  299. package/esm2022/shared/services/graphql.service.mjs +0 -510
  300. package/esm2022/shared/services/image.service.mjs +0 -102
  301. package/esm2022/shared/services/loader.service.mjs +0 -78
  302. package/esm2022/shared/services/navigation.service.mjs +0 -38
  303. package/esm2022/shared/services/scroll.service.mjs +0 -207
  304. package/esm2022/shared/services/storage.service.mjs +0 -149
  305. package/esm2022/shared/services/toast.service.mjs +0 -39
  306. package/esm2022/shared/services/user.service.mjs +0 -160
  307. package/esm2022/shared/services/ws.service.mjs +0 -17
  308. package/esm2022/shared/types/graphql-fields.type.mjs +0 -2
  309. package/esm2022/shared/types/storage.type.mjs +0 -2
  310. package/esm2022/shared/validators/email.validator.mjs +0 -7
  311. package/esm2022/shared/validators/match.validator.mjs +0 -22
  312. package/esm2022/shared/validators/secure-password.validator.mjs +0 -7
  313. package/esm2022/src/base.module.mjs +0 -64
  314. package/esm2022/src/decorators/auto-unsubscribe.decorator.mjs +0 -23
  315. package/esm2022/src/directives/lazy-load.directive.mjs +0 -48
  316. package/esm2022/src/directives/match-height.directive.mjs +0 -92
  317. package/esm2022/src/directives/resizable.directive.mjs +0 -92
  318. package/esm2022/src/factories/apollo-options.factory.mjs +0 -108
  319. package/esm2022/src/functions/extract-files.function.mjs +0 -87
  320. package/esm2022/src/guards/auth.guard.mjs +0 -91
  321. package/esm2022/src/guards/can-deactivate.guard.mjs +0 -16
  322. package/esm2022/src/guards/logout.guard.mjs +0 -34
  323. package/esm2022/src/pipes/date-ago.pipe.mjs +0 -64
  324. package/esm2022/src/pipes/safe-html.pipe.mjs +0 -22
  325. package/esm2022/src/services/fullscreen.service.mjs +0 -51
  326. package/esm2022/src/services/seo.service.mjs +0 -109
  327. package/esm2022/src/services/theme.service.mjs +0 -44
  328. package/fesm2022/lenne.tech-ng-base-base-cms.mjs +0 -251
  329. package/fesm2022/lenne.tech-ng-base-base-cms.mjs.map +0 -1
  330. package/fesm2022/lenne.tech-ng-base-base-components.mjs +0 -2917
  331. package/fesm2022/lenne.tech-ng-base-base-components.mjs.map +0 -1
  332. package/fesm2022/lenne.tech-ng-base-base-prototype.mjs +0 -505
  333. package/fesm2022/lenne.tech-ng-base-base-prototype.mjs.map +0 -1
  334. package/fesm2022/lenne.tech-ng-base-shared.mjs +0 -2863
  335. package/fesm2022/lenne.tech-ng-base-shared.mjs.map +0 -1
  336. package/index.d.ts +0 -5
  337. package/public-api.d.ts +0 -17
  338. package/shared/classes/auth.class.d.ts +0 -10
  339. package/shared/classes/basic-user.class.d.ts +0 -27
  340. package/shared/classes/graphql-enum.class.d.ts +0 -7
  341. package/shared/classes/graphql-meta.class.d.ts +0 -66
  342. package/shared/classes/graphql-type.class.d.ts +0 -13
  343. package/shared/classes/helper.class.d.ts +0 -99
  344. package/shared/classes/sort.class.d.ts +0 -12
  345. package/shared/classes/standard.class.d.ts +0 -32
  346. package/shared/decorators/debounce.decorator.d.ts +0 -1
  347. package/shared/enums/comparison-operator.enum.d.ts +0 -14
  348. package/shared/enums/graphql-request-type.enum.d.ts +0 -8
  349. package/shared/enums/logical-operator.enum.d.ts +0 -8
  350. package/shared/enums/skeleton-type.enum.d.ts +0 -5
  351. package/shared/enums/sort-order.enum.d.ts +0 -4
  352. package/shared/enums/toast-type.enum.d.ts +0 -6
  353. package/shared/functions/ws-client.function.d.ts +0 -5
  354. package/shared/index.d.ts +0 -5
  355. package/shared/interfaces/base-module-config.interface.d.ts +0 -61
  356. package/shared/interfaces/breadcrumb.interface.d.ts +0 -4
  357. package/shared/interfaces/can-component-deactivate.interface.d.ts +0 -7
  358. package/shared/interfaces/cms-enum-values.interface.d.ts +0 -4
  359. package/shared/interfaces/cms-field-config.interface.d.ts +0 -45
  360. package/shared/interfaces/cms-model-config.interface.d.ts +0 -14
  361. package/shared/interfaces/cms-table-field.interface.d.ts +0 -10
  362. package/shared/interfaces/combined-filter-input.interface.d.ts +0 -9
  363. package/shared/interfaces/compress-options.interface.d.ts +0 -15
  364. package/shared/interfaces/cropping-options.interface.d.ts +0 -12
  365. package/shared/interfaces/field-object.interface.d.ts +0 -6
  366. package/shared/interfaces/field.interface.d.ts +0 -5
  367. package/shared/interfaces/filter-input.interface.d.ts +0 -9
  368. package/shared/interfaces/find-args.interface.d.ts +0 -11
  369. package/shared/interfaces/graphql-crud-type.interface.d.ts +0 -7
  370. package/shared/interfaces/graphql-fields-object.interface.d.ts +0 -6
  371. package/shared/interfaces/graphql-options.interface.d.ts +0 -11
  372. package/shared/interfaces/graphql-plus-options.interfacen.d.ts +0 -9
  373. package/shared/interfaces/graphql-type-collection.interface.d.ts +0 -7
  374. package/shared/interfaces/login-config.interface.d.ts +0 -6
  375. package/shared/interfaces/register-config.interface.d.ts +0 -4
  376. package/shared/interfaces/single-filter-input.interface.d.ts +0 -11
  377. package/shared/interfaces/sort-input.interface.d.ts +0 -5
  378. package/shared/interfaces/time-components.interface.d.ts +0 -6
  379. package/shared/interfaces/toast.interface.d.ts +0 -8
  380. package/shared/public-api.d.ts +0 -65
  381. package/shared/services/auth.service.d.ts +0 -44
  382. package/shared/services/breadcrumb.service.d.ts +0 -32
  383. package/shared/services/cms.service.d.ts +0 -27
  384. package/shared/services/file.service.d.ts +0 -22
  385. package/shared/services/forms.service.d.ts +0 -14
  386. package/shared/services/graphql-meta.service.d.ts +0 -45
  387. package/shared/services/graphql-plus.service.d.ts +0 -27
  388. package/shared/services/graphql.service.d.ts +0 -71
  389. package/shared/services/image.service.d.ts +0 -27
  390. package/shared/services/loader.service.d.ts +0 -32
  391. package/shared/services/navigation.service.d.ts +0 -15
  392. package/shared/services/scroll.service.d.ts +0 -85
  393. package/shared/services/storage.service.d.ts +0 -49
  394. package/shared/services/toast.service.d.ts +0 -15
  395. package/shared/services/user.service.d.ts +0 -77
  396. package/shared/services/ws.service.d.ts +0 -8
  397. package/shared/types/graphql-fields.type.d.ts +0 -5
  398. package/shared/types/storage.type.d.ts +0 -4
  399. package/shared/validators/email.validator.d.ts +0 -1
  400. package/shared/validators/match.validator.d.ts +0 -4
  401. package/shared/validators/secure-password.validator.d.ts +0 -1
  402. package/src/base.module.d.ts +0 -16
  403. package/src/decorators/auto-unsubscribe.decorator.d.ts +0 -5
  404. package/src/directives/lazy-load.directive.d.ts +0 -17
  405. package/src/directives/match-height.directive.d.ts +0 -20
  406. package/src/directives/resizable.directive.d.ts +0 -26
  407. package/src/factories/apollo-options.factory.d.ts +0 -16
  408. package/src/functions/extract-files.function.d.ts +0 -15
  409. package/src/guards/auth.guard.d.ts +0 -27
  410. package/src/guards/can-deactivate.guard.d.ts +0 -10
  411. package/src/guards/logout.guard.d.ts +0 -16
  412. package/src/pipes/date-ago.pipe.d.ts +0 -34
  413. package/src/pipes/safe-html.pipe.d.ts +0 -13
  414. package/src/services/fullscreen.service.d.ts +0 -18
  415. package/src/services/seo.service.d.ts +0 -50
  416. package/src/services/theme.service.d.ts +0 -17
@@ -0,0 +1,1096 @@
1
+ import { DOCUMENT, isPlatformBrowser } from "@angular/common";
2
+ import { DestroyRef, InjectionToken, PLATFORM_ID, assertInInjectionContext, effect, inject, makeEnvironmentProviders, provideAppInitializer, signal, untracked } from "@angular/core";
3
+ import { LT_AUTH_SIGN_OUT_HOOKS, LtAuthStore } from "@lenne.tech/ng-base/auth/provide";
4
+ import { LT_FETCH, LT_RUNTIME_CONFIG, LtApiUrlService, mergeLtFeatureOptions } from "@lenne.tech/ng-base";
5
+ const LT_SYNC_DB_NAME = "lt-offline-sync";
6
+ const LT_SYNC_CHANNEL_NAME = "lt-offline-sync";
7
+ const STORES = [
8
+ "meta",
9
+ "outbox",
10
+ "records"
11
+ ];
12
+ const done = (request) => new Promise((resolve, reject) => {
13
+ request.addEventListener("success", () => resolve(request.result));
14
+ request.addEventListener("error", () => reject(request.error));
15
+ });
16
+ let connection;
17
+ let opening;
18
+ function openDatabase() {
19
+ if (connection) return Promise.resolve(connection);
20
+ opening ??= (async () => {
21
+ const request = indexedDB.open(LT_SYNC_DB_NAME, 1);
22
+ request.addEventListener("upgradeneeded", () => {
23
+ const db = request.result;
24
+ db.createObjectStore("records", { keyPath: ["model", "id"] }).createIndex("model", "model");
25
+ const outbox = db.createObjectStore("outbox", {
26
+ autoIncrement: true,
27
+ keyPath: "seq"
28
+ });
29
+ outbox.createIndex("mutationId", "mutationId", { unique: true });
30
+ outbox.createIndex("model", "model");
31
+ db.createObjectStore("meta", { keyPath: "key" });
32
+ });
33
+ try {
34
+ const db = await done(request);
35
+ db.addEventListener("versionchange", () => {
36
+ db.close();
37
+ if (connection === db) connection = void 0;
38
+ });
39
+ connection = db;
40
+ return db;
41
+ } finally {
42
+ opening = void 0;
43
+ }
44
+ })();
45
+ return opening;
46
+ }
47
+ var LtSyncOwnerChangedError = class extends Error {
48
+ constructor() {
49
+ super("the local sync data changed owner");
50
+ this.name = "LtSyncOwnerChangedError";
51
+ }
52
+ };
53
+ async function runLtSyncTx(model, fn, options = {}) {
54
+ const transaction = (await openDatabase()).transaction(STORES, "readwrite");
55
+ const finished = new Promise((resolve, reject) => {
56
+ transaction.addEventListener("complete", () => resolve());
57
+ transaction.addEventListener("abort", () => reject(transaction.error ?? /* @__PURE__ */ new Error("transaction aborted")));
58
+ transaction.addEventListener("error", () => reject(transaction.error));
59
+ });
60
+ const store = (name) => transaction.objectStore(name);
61
+ const strip = (stored) => {
62
+ if (!stored) return void 0;
63
+ const { model: _model, ...record } = stored;
64
+ return record;
65
+ };
66
+ const tx = {
67
+ addOutbox: (item) => {
68
+ const { seq: _seq, ...rest } = item;
69
+ return done(store("outbox").add({
70
+ ...rest,
71
+ model
72
+ }));
73
+ },
74
+ clearRecords: async (keepIds) => {
75
+ const keys = await done(store("records").index("model").getAllKeys(model));
76
+ for (const key of keys) if (!keepIds.has(key[1])) await done(store("records").delete(key));
77
+ },
78
+ deleteMeta: (key) => done(store("meta").delete(key)),
79
+ deleteRecord: (id) => done(store("records").delete([model, id])),
80
+ getMeta: async (key) => (await done(store("meta").get(key)))?.value,
81
+ getRecord: async (id) => strip(await done(store("records").get([model, id]))),
82
+ listOutbox: async () => {
83
+ return (await done(store("outbox").index("model").getAll(model))).map(({ model: _model, ...item }) => item);
84
+ },
85
+ listRecords: async () => (await done(store("records").index("model").getAll(model))).map((record) => strip(record)),
86
+ putOutbox: (item) => done(store("outbox").put({
87
+ ...item,
88
+ model
89
+ })),
90
+ putRecord: (record) => done(store("records").put({
91
+ ...record,
92
+ model
93
+ })),
94
+ removeOutbox: async (mutationId) => {
95
+ const key = await done(store("outbox").index("mutationId").getKey(mutationId));
96
+ if (key !== void 0) await done(store("outbox").delete(key));
97
+ },
98
+ setMeta: (key, value) => done(store("meta").put({
99
+ key,
100
+ value
101
+ }))
102
+ };
103
+ let result;
104
+ try {
105
+ if (options.owner !== void 0 && await tx.getMeta("owner") !== options.owner) throw new LtSyncOwnerChangedError();
106
+ result = await fn(tx);
107
+ } catch (error) {
108
+ transaction.abort();
109
+ await finished.catch(() => void 0);
110
+ throw error;
111
+ }
112
+ await finished;
113
+ return result;
114
+ }
115
+ async function listLtSyncPendingModels() {
116
+ const transaction = (await openDatabase()).transaction(["outbox"], "readonly");
117
+ const items = await done(transaction.objectStore("outbox").getAll());
118
+ return [...new Set(items.map((item) => item.model))];
119
+ }
120
+ function getLtSyncOwner() {
121
+ return runLtSyncTx("", (tx) => tx.getMeta("owner"));
122
+ }
123
+ async function claimLtSyncOwner(userId) {
124
+ const transaction = (await openDatabase()).transaction(STORES, "readwrite");
125
+ const finished = new Promise((resolve, reject) => {
126
+ transaction.addEventListener("complete", () => resolve());
127
+ transaction.addEventListener("abort", () => reject(transaction.error ?? /* @__PURE__ */ new Error("transaction aborted")));
128
+ transaction.addEventListener("error", () => reject(transaction.error));
129
+ });
130
+ const meta = transaction.objectStore("meta");
131
+ const owner = (await done(meta.get("owner")))?.value;
132
+ let wiped = false;
133
+ if (owner !== userId) {
134
+ if (await done(transaction.objectStore("records").count()) + await done(transaction.objectStore("outbox").count()) + await done(meta.count()) > 0) {
135
+ for (const name of STORES) await done(transaction.objectStore(name).clear());
136
+ wiped = true;
137
+ }
138
+ await done(meta.put({
139
+ key: "owner",
140
+ value: userId
141
+ }));
142
+ }
143
+ await finished;
144
+ if (wiped) postLtSyncMessage({ type: "cleared" });
145
+ return wiped;
146
+ }
147
+ async function deleteLtSyncDatabase() {
148
+ if (typeof indexedDB === "undefined") return;
149
+ await opening?.catch(() => void 0);
150
+ connection?.close();
151
+ connection = void 0;
152
+ await new Promise((resolve, reject) => {
153
+ const request = indexedDB.deleteDatabase(LT_SYNC_DB_NAME);
154
+ request.addEventListener("success", () => resolve());
155
+ request.addEventListener("error", () => reject(request.error));
156
+ request.addEventListener("blocked", () => void 0);
157
+ });
158
+ postLtSyncMessage({ type: "cleared" });
159
+ }
160
+ function postLtSyncMessage(message) {
161
+ if (typeof BroadcastChannel === "undefined") return;
162
+ const channel = new BroadcastChannel(LT_SYNC_CHANNEL_NAME);
163
+ try {
164
+ channel.postMessage(message);
165
+ } finally {
166
+ channel.close();
167
+ }
168
+ }
169
+ const PUSH_CHUNK = 100;
170
+ const MAX_PUSH_ROUNDS = 50;
171
+ var LtSyncOfflineError = class extends Error {
172
+ constructor(cause) {
173
+ super(`offline: ${cause instanceof Error ? cause.message : String(cause)}`);
174
+ this.name = "LtSyncOfflineError";
175
+ }
176
+ };
177
+ var LtSyncUnauthorizedError = class extends Error {
178
+ constructor() {
179
+ super("unauthorized");
180
+ this.name = "LtSyncUnauthorizedError";
181
+ }
182
+ };
183
+ var LtSyncBackoffError = class extends Error {
184
+ status;
185
+ retryAfterMs;
186
+ constructor(status, retryAfterMs) {
187
+ super(`server answered ${status}`);
188
+ this.status = status;
189
+ this.retryAfterMs = retryAfterMs;
190
+ this.name = "LtSyncBackoffError";
191
+ }
192
+ };
193
+ const hex = (bytes) => Array.from(bytes, (byte) => byte.toString(16).padStart(2, "0")).join("");
194
+ function ltSyncObjectId() {
195
+ const random = /* @__PURE__ */ new Uint8Array(8);
196
+ globalThis.crypto.getRandomValues(random);
197
+ return Math.floor(Date.now() / 1e3).toString(16).padStart(8, "0") + hex(random);
198
+ }
199
+ function ltSyncUuidV7() {
200
+ const bytes = /* @__PURE__ */ new Uint8Array(16);
201
+ globalThis.crypto.getRandomValues(bytes);
202
+ let time = Date.now();
203
+ for (let index = 5; index >= 0; index--) {
204
+ bytes[index] = time % 256;
205
+ time = Math.floor(time / 256);
206
+ }
207
+ bytes[6] = 112 | bytes[6] & 15;
208
+ bytes[8] = 128 | bytes[8] & 63;
209
+ const value = hex(bytes);
210
+ return `${value.slice(0, 8)}-${value.slice(8, 12)}-${value.slice(12, 16)}-${value.slice(16, 20)}-${value.slice(20)}`;
211
+ }
212
+ let environment = {
213
+ basePath: "/sync",
214
+ buildApiUrl: (path) => path,
215
+ fetch: (input, init) => fetch(input, {
216
+ credentials: "include",
217
+ ...init
218
+ })
219
+ };
220
+ function configureLtSync(env) {
221
+ environment = {
222
+ ...environment,
223
+ ...env
224
+ };
225
+ }
226
+ function getLtSyncBasePath() {
227
+ return environment.basePath || "/sync";
228
+ }
229
+ function buildLtSyncUrl(path) {
230
+ return environment.buildApiUrl(`${getLtSyncBasePath()}${path}`);
231
+ }
232
+ function ltSyncFetch(input, init) {
233
+ return environment.fetch(input, init);
234
+ }
235
+ function retryAfterMs(value) {
236
+ if (!value) return void 0;
237
+ const seconds = Number(value);
238
+ if (Number.isFinite(seconds)) return Math.max(0, seconds * 1e3);
239
+ const date = Date.parse(value);
240
+ return Number.isNaN(date) ? void 0 : Math.max(0, date - Date.now());
241
+ }
242
+ const engines = /* @__PURE__ */ new Map();
243
+ function ltSyncScope(model, tenantId) {
244
+ return tenantId ? `${model}#${tenantId}` : model;
245
+ }
246
+ function parseLtSyncScope(scope) {
247
+ const at = scope.indexOf("#");
248
+ return at === -1 ? { model: scope } : {
249
+ model: scope.slice(0, at),
250
+ tenantId: scope.slice(at + 1)
251
+ };
252
+ }
253
+ function localOf(item) {
254
+ return {
255
+ data: item.deletedAt ? void 0 : item.data,
256
+ deletedAt: item.deletedAt ?? null,
257
+ id: item.id,
258
+ updatedAt: item.updatedAt ?? null,
259
+ version: item.version
260
+ };
261
+ }
262
+ function lastPending(outbox, id) {
263
+ return outbox.filter((item) => item.id === id).at(-1);
264
+ }
265
+ function nextBase(record, pending) {
266
+ return pending ? (pending.baseVersion ?? 0) + 1 : record.version;
267
+ }
268
+ function pushItem(item) {
269
+ const { baseVersion, data, id, mutationId, op } = item;
270
+ return {
271
+ ...baseVersion === void 0 ? {} : { baseVersion },
272
+ ...data === void 0 ? {} : { data },
273
+ id,
274
+ mutationId,
275
+ op
276
+ };
277
+ }
278
+ function emptyResult$1() {
279
+ return {
280
+ applied: 0,
281
+ conflicts: [],
282
+ forbidden: false,
283
+ needsLogin: false,
284
+ offline: false,
285
+ rejected: [],
286
+ resynced: false,
287
+ retried: 0
288
+ };
289
+ }
290
+ function createLtSyncEngine(options) {
291
+ const { idFormat = "objectId", model, onConflict, pageLimit = 200, tenantId } = options;
292
+ const fetchImpl = options.fetch ?? ltSyncFetch;
293
+ const scope = ltSyncScope(model, tenantId);
294
+ const cursorKey = `cursor:${scope}`;
295
+ const run = (fn) => runLtSyncTx(scope, fn);
296
+ const runAs = (owner, fn) => runLtSyncTx(scope, fn, owner === void 0 ? {} : { owner });
297
+ const newId = () => idFormat === "uuidv7" ? ltSyncUuidV7() : ltSyncObjectId();
298
+ async function request(method, path, payload) {
299
+ const headers = { accept: "application/json" };
300
+ if (payload !== void 0) headers["content-type"] = "application/json";
301
+ if (tenantId) headers["x-tenant-id"] = tenantId;
302
+ let response;
303
+ try {
304
+ response = await fetchImpl(buildLtSyncUrl(path), {
305
+ body: payload === void 0 ? void 0 : JSON.stringify(payload),
306
+ headers,
307
+ method
308
+ });
309
+ } catch (error) {
310
+ throw new LtSyncOfflineError(error);
311
+ }
312
+ if (response.status === 401) throw new LtSyncUnauthorizedError();
313
+ if (response.status === 429 || response.status === 503) throw new LtSyncBackoffError(response.status, retryAfterMs(response.headers.get("retry-after")));
314
+ const text = await response.text();
315
+ let body;
316
+ try {
317
+ body = text ? JSON.parse(text) : void 0;
318
+ } catch {
319
+ body = void 0;
320
+ }
321
+ if (response.status === 410 || response.status === 403 && method === "GET") return {
322
+ body,
323
+ status: response.status
324
+ };
325
+ if (!response.ok) {
326
+ const error = /* @__PURE__ */ new Error(`${method} ${getLtSyncBasePath()}${path} answered ${response.status}: ${text.slice(0, 300)}`);
327
+ error.status = response.status;
328
+ throw error;
329
+ }
330
+ return {
331
+ body,
332
+ status: response.status
333
+ };
334
+ }
335
+ async function settle(tx, item, outcome, result, resolution) {
336
+ const status = outcome?.status;
337
+ if (status === "retry" || !status) {
338
+ result.retried++;
339
+ return;
340
+ }
341
+ await tx.removeOutbox(item.mutationId);
342
+ const record = await tx.getRecord(item.id);
343
+ if (status === "applied") {
344
+ result.applied++;
345
+ if (item.op === "delete") await tx.deleteRecord(item.id);
346
+ else if (record && (record.version ?? 0) < (outcome.version ?? 0)) await tx.putRecord({
347
+ ...record,
348
+ version: outcome.version
349
+ });
350
+ return;
351
+ }
352
+ const later = (await tx.listOutbox()).filter((entry) => entry.id === item.id);
353
+ if (status === "merged" && outcome.record) {
354
+ result.applied++;
355
+ const pendingData = later.filter((entry) => entry.op === "upsert").reduce((data, entry) => ({
356
+ ...data,
357
+ ...entry.data
358
+ }), {});
359
+ const merged = localOf(outcome.record);
360
+ await tx.putRecord(merged.deletedAt ? merged : {
361
+ ...merged,
362
+ data: {
363
+ ...merged.data,
364
+ ...pendingData
365
+ }
366
+ });
367
+ return;
368
+ }
369
+ if (status === "conflict") {
370
+ result.conflicts.push(outcome);
371
+ for (const entry of later) await tx.removeOutbox(entry.mutationId);
372
+ if (!outcome.record || outcome.record.deletedAt) {
373
+ await tx.deleteRecord(item.id);
374
+ return;
375
+ }
376
+ const server = localOf(outcome.record);
377
+ if (resolution === "server") {
378
+ await tx.putRecord(server);
379
+ return;
380
+ }
381
+ await tx.putRecord({
382
+ ...server,
383
+ data: {
384
+ ...server.data,
385
+ ...resolution.data
386
+ }
387
+ });
388
+ await tx.addOutbox({
389
+ baseVersion: server.version,
390
+ data: resolution.data,
391
+ id: item.id,
392
+ mutationId: ltSyncUuidV7(),
393
+ op: "upsert"
394
+ });
395
+ return;
396
+ }
397
+ for (const entry of later) await tx.removeOutbox(entry.mutationId);
398
+ if (status === "not_found") {
399
+ await tx.deleteRecord(item.id);
400
+ return;
401
+ }
402
+ result.rejected.push(outcome);
403
+ if (record && !record.version) await tx.deleteRecord(item.id);
404
+ else if (record) await tx.deleteMeta(cursorKey);
405
+ }
406
+ async function resolveConflict(item, outcome) {
407
+ if (outcome?.status !== "conflict" || !onConflict || !outcome.record || outcome.record.deletedAt) return "server";
408
+ const local = await run((tx) => tx.getRecord(item.id));
409
+ const answer = await onConflict({
410
+ change: {
411
+ data: item.data,
412
+ op: item.op
413
+ },
414
+ local,
415
+ server: localOf(outcome.record)
416
+ });
417
+ return answer === "server" || !answer?.data ? "server" : answer;
418
+ }
419
+ async function push(result, owner) {
420
+ const carried = /* @__PURE__ */ new Set();
421
+ for (let round = 0; round < MAX_PUSH_ROUNDS; round++) {
422
+ const chunk = await runAs(owner, async (tx) => {
423
+ const records = /* @__PURE__ */ new Set();
424
+ const items = [];
425
+ for (const item of await tx.listOutbox()) {
426
+ if (items.length === PUSH_CHUNK) break;
427
+ if (records.has(item.id)) continue;
428
+ records.add(item.id);
429
+ if (!carried.has(item.mutationId)) items.push(item);
430
+ }
431
+ for (const item of items) await tx.putOutbox({
432
+ ...item,
433
+ attempted: true
434
+ });
435
+ return items;
436
+ });
437
+ if (!chunk.length) return;
438
+ for (const item of chunk) carried.add(item.mutationId);
439
+ const results = (await request("POST", `/${encodeURIComponent(model)}`, { items: chunk.map(pushItem) })).body?.results ?? [];
440
+ for (let index = 0; index < chunk.length; index++) {
441
+ const item = chunk[index];
442
+ const resolution = await resolveConflict(item, results[index]);
443
+ await runAs(owner, (tx) => settle(tx, item, results[index], result, resolution));
444
+ }
445
+ }
446
+ }
447
+ async function pull(result, owner) {
448
+ let cursor = await run((tx) => tx.getMeta(cursorKey));
449
+ for (let page = 0; page < 1e4; page++) {
450
+ const query = new URLSearchParams({ limit: String(pageLimit) });
451
+ if (cursor) query.set("cursor", cursor);
452
+ const response = await request("GET", `/${encodeURIComponent(model)}?${query}`);
453
+ if (response.status === 403) {
454
+ result.forbidden = true;
455
+ await runAs(owner, async (tx) => {
456
+ await tx.clearRecords(new Set((await tx.listOutbox()).map((item) => item.id)));
457
+ await tx.deleteMeta(cursorKey);
458
+ });
459
+ return false;
460
+ }
461
+ if (response.status === 410) {
462
+ if (result.resynced) throw new Error(`resync loop: ${JSON.stringify(response.body)}`);
463
+ result.resynced = true;
464
+ await runAs(owner, async (tx) => {
465
+ await tx.clearRecords(new Set((await tx.listOutbox()).map((item) => item.id)));
466
+ await tx.deleteMeta(cursorKey);
467
+ });
468
+ cursor = void 0;
469
+ continue;
470
+ }
471
+ const body = response.body;
472
+ await runAs(owner, async (tx) => {
473
+ const pending = new Set((await tx.listOutbox()).map((item) => item.id));
474
+ for (const item of body.items ?? []) {
475
+ if (pending.has(item.id)) continue;
476
+ const local = await tx.getRecord(item.id);
477
+ if (local && local.version > item.version) continue;
478
+ if (item.deletedAt) await tx.deleteRecord(item.id);
479
+ else await tx.putRecord(localOf(item));
480
+ }
481
+ await tx.setMeta(cursorKey, body.cursor);
482
+ });
483
+ cursor = body.cursor;
484
+ if (!body.hasMore) return result.resynced;
485
+ }
486
+ throw new Error("pull did not end");
487
+ }
488
+ async function syncOnce() {
489
+ const result = emptyResult$1();
490
+ try {
491
+ const owner = await getLtSyncOwner();
492
+ await push(result, owner);
493
+ if (await pull(result, owner)) await push(result, owner);
494
+ } catch (error) {
495
+ if (error instanceof LtSyncOwnerChangedError) return result;
496
+ if (error instanceof LtSyncUnauthorizedError) result.needsLogin = true;
497
+ else if (error instanceof LtSyncOfflineError) result.offline = true;
498
+ else if (error instanceof LtSyncBackoffError) result.retryAfterMs = error.retryAfterMs ?? 0;
499
+ else throw error;
500
+ }
501
+ return result;
502
+ }
503
+ async function syncLocked() {
504
+ const locks = typeof navigator === "undefined" ? void 0 : navigator.locks;
505
+ if (!locks) return syncOnce();
506
+ return await locks.request(`lt-offline-sync:${scope}`, syncOnce);
507
+ }
508
+ let current = null;
509
+ let next = null;
510
+ function sync() {
511
+ if (!current) {
512
+ current = syncLocked().finally(() => {
513
+ current = null;
514
+ });
515
+ return current;
516
+ }
517
+ next ??= current.catch(() => void 0).then(() => {
518
+ next = null;
519
+ return sync();
520
+ });
521
+ return next;
522
+ }
523
+ const engine = {
524
+ async create(data) {
525
+ const record = {
526
+ data,
527
+ deletedAt: null,
528
+ id: newId(),
529
+ updatedAt: null,
530
+ version: 0
531
+ };
532
+ await run(async (tx) => {
533
+ await tx.putRecord(record);
534
+ await tx.addOutbox({
535
+ data,
536
+ id: record.id,
537
+ mutationId: ltSyncUuidV7(),
538
+ op: "upsert"
539
+ });
540
+ });
541
+ return record;
542
+ },
543
+ get: (id) => run((tx) => tx.getRecord(id)),
544
+ async list() {
545
+ return (await run((tx) => tx.listRecords())).filter((record) => !record.deletedAt).sort((a, b) => a.id < b.id ? -1 : 1);
546
+ },
547
+ model,
548
+ pendingCount: () => run(async (tx) => (await tx.listOutbox()).length),
549
+ async pushPending() {
550
+ try {
551
+ await push(emptyResult$1(), await getLtSyncOwner());
552
+ } catch {}
553
+ },
554
+ scope,
555
+ async remove(id) {
556
+ await run(async (tx) => {
557
+ const record = await tx.getRecord(id);
558
+ if (!record || record.deletedAt) return;
559
+ const pending = lastPending(await tx.listOutbox(), id);
560
+ if (pending && !pending.attempted) {
561
+ await tx.removeOutbox(pending.mutationId);
562
+ if (pending.baseVersion === void 0) {
563
+ await tx.deleteRecord(id);
564
+ return;
565
+ }
566
+ }
567
+ const baseVersion = pending && !pending.attempted ? pending.baseVersion : nextBase(record, pending);
568
+ await tx.addOutbox({
569
+ baseVersion,
570
+ id,
571
+ mutationId: ltSyncUuidV7(),
572
+ op: "delete"
573
+ });
574
+ await tx.putRecord({
575
+ ...record,
576
+ data: void 0,
577
+ deletedAt: (/* @__PURE__ */ new Date()).toISOString()
578
+ });
579
+ });
580
+ },
581
+ sync,
582
+ async update(id, data) {
583
+ return run(async (tx) => {
584
+ const record = await tx.getRecord(id);
585
+ if (!record || record.deletedAt) throw new Error(`no live local record ${id}`);
586
+ const pending = lastPending(await tx.listOutbox(), id);
587
+ if (pending && pending.op === "upsert" && !pending.attempted) await tx.putOutbox({
588
+ ...pending,
589
+ data: {
590
+ ...pending.data,
591
+ ...data
592
+ }
593
+ });
594
+ else await tx.addOutbox({
595
+ baseVersion: nextBase(record, pending),
596
+ data,
597
+ id,
598
+ mutationId: ltSyncUuidV7(),
599
+ op: "upsert"
600
+ });
601
+ const changed = {
602
+ ...record,
603
+ data: {
604
+ ...record.data,
605
+ ...data
606
+ }
607
+ };
608
+ await tx.putRecord(changed);
609
+ return changed;
610
+ });
611
+ }
612
+ };
613
+ engines.set(scope, engine);
614
+ return engine;
615
+ }
616
+ async function flushLtSyncBeforeSignOut(userId, timeoutMs = 5e3) {
617
+ if (typeof indexedDB === "undefined" || !userId) return;
618
+ let timer;
619
+ const timeout = new Promise((resolve) => {
620
+ timer = setTimeout(resolve, timeoutMs);
621
+ });
622
+ const flush = (async () => {
623
+ if (await getLtSyncOwner().catch(() => void 0) !== userId) return;
624
+ const scopes = await listLtSyncPendingModels().catch(() => []);
625
+ await Promise.all(scopes.map((scope) => (engines.get(scope) ?? createLtSyncEngine(parseLtSyncScope(scope))).pushPending()));
626
+ })();
627
+ try {
628
+ await Promise.race([flush, timeout]);
629
+ } finally {
630
+ clearTimeout(timer);
631
+ }
632
+ }
633
+ function resetLtSyncEngines() {
634
+ engines.clear();
635
+ }
636
+ const LINE_LIMIT = 1048576;
637
+ const DEFAULT_RETRY_MS = 3e3;
638
+ const MAX_BACKOFF_MS = 6e4;
639
+ async function readEvents(body, onEvent, signal) {
640
+ const reader = body.getReader();
641
+ const decoder = new TextDecoder();
642
+ let buffer = "";
643
+ let event = {
644
+ data: "",
645
+ event: "message"
646
+ };
647
+ const dispatchLine = (line) => {
648
+ if (line === "") {
649
+ if (event.data || event.retry !== void 0) onEvent(event);
650
+ event = {
651
+ data: "",
652
+ event: "message"
653
+ };
654
+ return;
655
+ }
656
+ if (line.startsWith(":")) return;
657
+ const colon = line.indexOf(":");
658
+ const field = colon === -1 ? line : line.slice(0, colon);
659
+ const value = colon === -1 ? "" : line.slice(colon + 1).replace(/^ /, "");
660
+ if (field === "event") event.event = value;
661
+ else if (field === "data") event.data = event.data ? `${event.data}\n${value}` : value;
662
+ else if (field === "retry" && /^\d+$/.test(value)) event.retry = Number(value);
663
+ };
664
+ const onAbort = () => void reader.cancel().catch(() => void 0);
665
+ signal.addEventListener("abort", onAbort);
666
+ try {
667
+ for (;;) {
668
+ const { done, value } = await reader.read();
669
+ if (done) return;
670
+ buffer += decoder.decode(value, { stream: true });
671
+ let newline = buffer.search(/\r?\n|\r/);
672
+ while (newline !== -1) {
673
+ const line = buffer.slice(0, newline);
674
+ const skip = buffer[newline] === "\r" && buffer[newline + 1] === "\n" ? 2 : 1;
675
+ buffer = buffer.slice(newline + skip);
676
+ dispatchLine(line);
677
+ newline = buffer.search(/\r?\n|\r/);
678
+ }
679
+ if (buffer.length > LINE_LIMIT) throw new Error("sync hint stream: line exceeds 1 MiB");
680
+ }
681
+ } finally {
682
+ signal.removeEventListener("abort", onAbort);
683
+ reader.releaseLock();
684
+ }
685
+ }
686
+ const hubs = /* @__PURE__ */ new Map();
687
+ function subscribeLtSyncHints(subscriber) {
688
+ const key = subscriber.tenantId ?? "";
689
+ let hub = hubs.get(key);
690
+ if (!hub) {
691
+ hub = {
692
+ models: "",
693
+ subscribers: /* @__PURE__ */ new Set()
694
+ };
695
+ hubs.set(key, hub);
696
+ }
697
+ const joined = hub;
698
+ joined.subscribers.add(subscriber);
699
+ connectHub(key, joined);
700
+ return () => {
701
+ if (!joined.subscribers.delete(subscriber)) return;
702
+ if (joined.subscribers.size === 0) {
703
+ joined.close?.();
704
+ if (hubs.get(key) === joined) hubs.delete(key);
705
+ return;
706
+ }
707
+ connectHub(key, joined);
708
+ };
709
+ }
710
+ function connectHub(key, hub) {
711
+ const models = [...new Set([...hub.subscribers].map((subscriber) => subscriber.model))].sort().join(",");
712
+ if (hub.close && hub.models === models) return;
713
+ hub.close?.();
714
+ hub.models = models;
715
+ hub.close = openLtSyncHints({
716
+ models: models.split(","),
717
+ onConnect: () => {
718
+ for (const subscriber of Array.from(hub.subscribers)) subscriber.onConnect();
719
+ },
720
+ onHint: (model) => {
721
+ for (const subscriber of Array.from(hub.subscribers)) if (subscriber.model === model) subscriber.onHint();
722
+ },
723
+ onStop: (reason) => {
724
+ hub.close = void 0;
725
+ hub.models = "";
726
+ for (const subscriber of Array.from(hub.subscribers)) subscriber.onStop?.(reason);
727
+ },
728
+ tenantId: key || void 0
729
+ });
730
+ }
731
+ function openLtSyncHints(options) {
732
+ const { models, onConnect, onHint, onStop, tenantId } = options;
733
+ const fetchImpl = options.fetch ?? ltSyncFetch;
734
+ let closed = false;
735
+ let controller;
736
+ let timer;
737
+ let wake;
738
+ let retryMs = DEFAULT_RETRY_MS;
739
+ let failures = 0;
740
+ const wait = (ms) => new Promise((resolve) => {
741
+ wake = resolve;
742
+ timer = setTimeout(resolve, ms);
743
+ });
744
+ const loop = async () => {
745
+ while (!closed) {
746
+ controller = new AbortController();
747
+ try {
748
+ const query = new URLSearchParams({ models: models.join(",") });
749
+ const headers = { accept: "text/event-stream" };
750
+ if (tenantId) headers["x-tenant-id"] = tenantId;
751
+ const response = await fetchImpl(buildLtSyncUrl(`/hints?${query}`), {
752
+ headers,
753
+ method: "GET",
754
+ signal: controller.signal
755
+ });
756
+ if (response.status === 404 || response.status === 401) {
757
+ await response.body?.cancel().catch(() => void 0);
758
+ if (!closed) onStop?.(response.status === 404 ? "disabled" : "unauthorized");
759
+ return;
760
+ }
761
+ if (!response.ok || !response.body) throw new Error(`sync hint stream answered ${response.status}`);
762
+ failures = 0;
763
+ onConnect();
764
+ await readEvents(response.body, (event) => {
765
+ if (event.retry !== void 0) retryMs = event.retry;
766
+ if (event.event !== "change") return;
767
+ try {
768
+ const model = JSON.parse(event.data).model;
769
+ if (typeof model === "string") onHint(model);
770
+ } catch {}
771
+ }, controller.signal);
772
+ if (!closed) await wait(retryMs);
773
+ } catch {
774
+ if (closed) return;
775
+ failures++;
776
+ await wait(Math.min(retryMs * 2 ** Math.min(failures - 1, 5), MAX_BACKOFF_MS));
777
+ }
778
+ }
779
+ };
780
+ loop();
781
+ return () => {
782
+ closed = true;
783
+ controller?.abort();
784
+ clearTimeout(timer);
785
+ wake?.();
786
+ };
787
+ }
788
+ const BACKOFF_START_MS = 1e3;
789
+ const BACKOFF_MAX_MS = 6e4;
790
+ const LOCAL_CHANGE_DELAY_MS = 300;
791
+ const emptyResult = (overrides = {}) => ({
792
+ applied: 0,
793
+ conflicts: [],
794
+ forbidden: false,
795
+ needsLogin: false,
796
+ offline: false,
797
+ rejected: [],
798
+ resynced: false,
799
+ retried: 0,
800
+ ...overrides
801
+ });
802
+ function injectLtOfflineSync(model, options = {}) {
803
+ assertInInjectionContext(injectLtOfflineSync);
804
+ const records = signal([], ...ngDevMode ? [{ debugName: "records" }] : /* istanbul ignore next */ []);
805
+ const pendingCount = signal(0, ...ngDevMode ? [{ debugName: "pendingCount" }] : /* istanbul ignore next */ []);
806
+ const offline = signal(false, ...ngDevMode ? [{ debugName: "offline" }] : /* istanbul ignore next */ []);
807
+ const syncing = signal(false, ...ngDevMode ? [{ debugName: "syncing" }] : /* istanbul ignore next */ []);
808
+ const needsLogin = signal(false, ...ngDevMode ? [{ debugName: "needsLogin" }] : /* istanbul ignore next */ []);
809
+ const forbidden = signal(false, ...ngDevMode ? [{ debugName: "forbidden" }] : /* istanbul ignore next */ []);
810
+ const conflicts = signal([], ...ngDevMode ? [{ debugName: "conflicts" }] : /* istanbul ignore next */ []);
811
+ const rejected = signal([], ...ngDevMode ? [{ debugName: "rejected" }] : /* istanbul ignore next */ []);
812
+ const error = signal(null, ...ngDevMode ? [{ debugName: "error" }] : /* istanbul ignore next */ []);
813
+ const lastSyncedAt = signal(null, ...ngDevMode ? [{ debugName: "lastSyncedAt" }] : /* istanbul ignore next */ []);
814
+ const state = {
815
+ conflicts: conflicts.asReadonly(),
816
+ error: error.asReadonly(),
817
+ forbidden: forbidden.asReadonly(),
818
+ lastSyncedAt: lastSyncedAt.asReadonly(),
819
+ needsLogin: needsLogin.asReadonly(),
820
+ offline: offline.asReadonly(),
821
+ pendingCount: pendingCount.asReadonly(),
822
+ records: records.asReadonly(),
823
+ rejected: rejected.asReadonly(),
824
+ syncing: syncing.asReadonly()
825
+ };
826
+ if (!isPlatformBrowser(inject(PLATFORM_ID)) || typeof indexedDB === "undefined") {
827
+ const browserOnly = () => Promise.reject(/* @__PURE__ */ new Error("injectLtOfflineSync: offline sync runs in the browser only"));
828
+ return {
829
+ ...state,
830
+ create: browserOnly,
831
+ get: async () => void 0,
832
+ remove: browserOnly,
833
+ sync: async () => emptyResult(),
834
+ update: browserOnly
835
+ };
836
+ }
837
+ const auth = inject(LtAuthStore);
838
+ const destroyRef = inject(DestroyRef);
839
+ const doc = inject(DOCUMENT);
840
+ const win = doc.defaultView;
841
+ const auto = options.auto !== false;
842
+ const engine = createLtSyncEngine({
843
+ idFormat: options.idFormat,
844
+ model,
845
+ onConflict: options.onConflict,
846
+ pageLimit: options.pageLimit,
847
+ tenantId: options.tenantId
848
+ });
849
+ const channel = typeof BroadcastChannel === "undefined" ? void 0 : new BroadcastChannel(LT_SYNC_CHANNEL_NAME);
850
+ let ownerId = null;
851
+ let claiming = null;
852
+ const currentUserId = () => {
853
+ const id = auth.user()?.id;
854
+ return id ? String(id) : null;
855
+ };
856
+ async function ensureOwner() {
857
+ const id = currentUserId();
858
+ if (!id) {
859
+ ownerId = null;
860
+ return false;
861
+ }
862
+ if (id === ownerId) return true;
863
+ if (claiming?.id !== id) {
864
+ const pending = {
865
+ done: claimLtSyncOwner(id),
866
+ id
867
+ };
868
+ claiming = pending;
869
+ pending.done.finally(() => {
870
+ if (claiming === pending) claiming = null;
871
+ });
872
+ }
873
+ await claiming.done;
874
+ if (currentUserId() !== id) return ensureOwner();
875
+ ownerId = id;
876
+ return true;
877
+ }
878
+ async function refresh() {
879
+ if (!await ensureOwner()) {
880
+ records.set([]);
881
+ pendingCount.set(0);
882
+ return;
883
+ }
884
+ const [list, pending] = await Promise.all([engine.list(), engine.pendingCount()]);
885
+ records.set(list);
886
+ pendingCount.set(pending);
887
+ }
888
+ async function owned(fn) {
889
+ if (!await ensureOwner()) throw new Error("injectLtOfflineSync: no signed-in user owns the local data");
890
+ return fn();
891
+ }
892
+ let timer;
893
+ let backoffMs = 0;
894
+ let disposed = false;
895
+ let closeHints;
896
+ let hintsStopped = null;
897
+ function announce() {
898
+ const message = {
899
+ scope: engine.scope,
900
+ type: "changed"
901
+ };
902
+ if (!disposed) {
903
+ channel?.postMessage(message);
904
+ return;
905
+ }
906
+ if (typeof BroadcastChannel === "undefined") return;
907
+ const once = new BroadcastChannel(LT_SYNC_CHANNEL_NAME);
908
+ try {
909
+ once.postMessage(message);
910
+ } finally {
911
+ once.close();
912
+ }
913
+ }
914
+ function schedule(ms) {
915
+ if (disposed) return;
916
+ clearTimeout(timer);
917
+ timer = setTimeout(() => void sync().catch(() => void 0), ms);
918
+ }
919
+ function backOff(retryAfterMs = 0) {
920
+ backoffMs = Math.min(backoffMs ? backoffMs * 2 : BACKOFF_START_MS, BACKOFF_MAX_MS);
921
+ if (auto && win?.navigator.onLine !== false) schedule(Math.max(retryAfterMs, backoffMs));
922
+ }
923
+ async function sync() {
924
+ if (!await ensureOwner()) {
925
+ needsLogin.set(true);
926
+ return emptyResult({ needsLogin: true });
927
+ }
928
+ syncing.set(true);
929
+ try {
930
+ const result = await engine.sync();
931
+ error.set(null);
932
+ offline.set(result.offline);
933
+ needsLogin.set(result.needsLogin);
934
+ forbidden.set(result.forbidden);
935
+ conflicts.set(result.conflicts);
936
+ rejected.set(result.rejected);
937
+ if (result.offline || result.retryAfterMs !== void 0 || result.retried) backOff(result.retryAfterMs);
938
+ else if (!result.needsLogin) {
939
+ backoffMs = 0;
940
+ lastSyncedAt.set(/* @__PURE__ */ new Date());
941
+ if (hintsStopped === "unauthorized") {
942
+ hintsStopped = null;
943
+ startHints();
944
+ }
945
+ }
946
+ return result;
947
+ } catch (caught) {
948
+ error.set(caught instanceof Error ? caught : new Error(String(caught)));
949
+ throw caught;
950
+ } finally {
951
+ syncing.set(false);
952
+ await refresh();
953
+ announce();
954
+ }
955
+ }
956
+ const autoSync = () => {
957
+ if (auto) sync().catch(() => void 0);
958
+ };
959
+ async function afterLocalChange() {
960
+ announce();
961
+ await refresh();
962
+ if (auto) schedule(LOCAL_CHANGE_DELAY_MS);
963
+ }
964
+ function startHints() {
965
+ if (!auto || options.hints === false || closeHints || hintsStopped || disposed) return;
966
+ if (doc.visibilityState === "hidden" || !auth.user()?.id) return;
967
+ closeHints = subscribeLtSyncHints({
968
+ model,
969
+ onConnect: autoSync,
970
+ onHint: autoSync,
971
+ onStop: (reason) => {
972
+ stopHints();
973
+ hintsStopped = reason;
974
+ },
975
+ tenantId: options.tenantId
976
+ });
977
+ }
978
+ function stopHints() {
979
+ closeHints?.();
980
+ closeHints = void 0;
981
+ }
982
+ const onOnline = () => {
983
+ offline.set(false);
984
+ backoffMs = 0;
985
+ autoSync();
986
+ };
987
+ const onOffline = () => {
988
+ offline.set(true);
989
+ };
990
+ const onVisibility = () => {
991
+ if (doc.visibilityState === "hidden") {
992
+ stopHints();
993
+ return;
994
+ }
995
+ startHints();
996
+ autoSync();
997
+ };
998
+ const onMessage = (event) => {
999
+ if (event.data?.type === "cleared") {
1000
+ ownerId = null;
1001
+ refresh();
1002
+ } else if (event.data?.type === "changed" && event.data.scope === engine.scope) refresh();
1003
+ };
1004
+ win?.addEventListener("online", onOnline);
1005
+ win?.addEventListener("offline", onOffline);
1006
+ win?.addEventListener("focus", autoSync);
1007
+ doc.addEventListener("visibilitychange", onVisibility);
1008
+ if (win?.navigator.onLine === false) offline.set(true);
1009
+ channel?.addEventListener("message", onMessage);
1010
+ let watchedUserId = auth.user()?.id ?? null;
1011
+ const userWatch = effect(() => {
1012
+ const id = auth.user()?.id ?? null;
1013
+ untracked(() => {
1014
+ if (id === watchedUserId) return;
1015
+ watchedUserId = id;
1016
+ stopHints();
1017
+ hintsStopped = hintsStopped === "disabled" ? "disabled" : null;
1018
+ refresh().then(() => {
1019
+ if (!id) return;
1020
+ startHints();
1021
+ autoSync();
1022
+ });
1023
+ });
1024
+ }, ...ngDevMode ? [{ debugName: "userWatch" }] : /* istanbul ignore next */ []);
1025
+ destroyRef.onDestroy(() => {
1026
+ disposed = true;
1027
+ clearTimeout(timer);
1028
+ stopHints();
1029
+ userWatch.destroy();
1030
+ channel?.removeEventListener("message", onMessage);
1031
+ channel?.close();
1032
+ win?.removeEventListener("online", onOnline);
1033
+ win?.removeEventListener("offline", onOffline);
1034
+ win?.removeEventListener("focus", autoSync);
1035
+ doc.removeEventListener("visibilitychange", onVisibility);
1036
+ });
1037
+ refresh().then(() => {
1038
+ startHints();
1039
+ autoSync();
1040
+ });
1041
+ return {
1042
+ ...state,
1043
+ async create(data) {
1044
+ const record = await owned(() => engine.create(data));
1045
+ await afterLocalChange();
1046
+ return record;
1047
+ },
1048
+ async get(id) {
1049
+ return await ensureOwner() ? engine.get(id) : void 0;
1050
+ },
1051
+ async remove(id) {
1052
+ await owned(() => engine.remove(id));
1053
+ await afterLocalChange();
1054
+ },
1055
+ sync,
1056
+ async update(id, data) {
1057
+ const record = await owned(() => engine.update(id, data));
1058
+ await afterLocalChange();
1059
+ return record;
1060
+ }
1061
+ };
1062
+ }
1063
+ const LT_SYNC_INPUT_OPTIONS = new InjectionToken("LT_SYNC_INPUT_OPTIONS", { factory: () => ({}) });
1064
+ const LT_SYNC_OPTIONS = new InjectionToken("LT_SYNC_OPTIONS", { factory: () => mergeLtFeatureOptions({ basePath: "/sync" }, inject(LT_SYNC_INPUT_OPTIONS), inject(LT_RUNTIME_CONFIG, { optional: true })?.lt.sync) });
1065
+ function provideLtSync(options = {}) {
1066
+ return makeEnvironmentProviders([
1067
+ {
1068
+ provide: LT_SYNC_INPUT_OPTIONS,
1069
+ useValue: options
1070
+ },
1071
+ provideAppInitializer(() => {
1072
+ if (!isPlatformBrowser(inject(PLATFORM_ID))) return;
1073
+ const api = inject(LtApiUrlService);
1074
+ const fetch = inject(LT_FETCH);
1075
+ configureLtSync({
1076
+ basePath: inject(LT_SYNC_OPTIONS).basePath,
1077
+ buildApiUrl: (path) => api.buildUrl(path),
1078
+ fetch: (input, init) => fetch(input, init)
1079
+ });
1080
+ }),
1081
+ {
1082
+ multi: true,
1083
+ provide: LT_AUTH_SIGN_OUT_HOOKS,
1084
+ useFactory: () => {
1085
+ const isBrowser = isPlatformBrowser(inject(PLATFORM_ID));
1086
+ return {
1087
+ afterSignOut: () => isBrowser ? deleteLtSyncDatabase() : void 0,
1088
+ beforeSignOut: (userId) => isBrowser ? flushLtSyncBeforeSignOut(userId ?? void 0, 5e3) : void 0
1089
+ };
1090
+ }
1091
+ }
1092
+ ]);
1093
+ }
1094
+ export { LT_SYNC_CHANNEL_NAME, LT_SYNC_DB_NAME, LT_SYNC_OPTIONS, LtSyncBackoffError, LtSyncOfflineError, LtSyncOwnerChangedError, LtSyncUnauthorizedError, buildLtSyncUrl, claimLtSyncOwner, configureLtSync, createLtSyncEngine, deleteLtSyncDatabase, flushLtSyncBeforeSignOut, getLtSyncBasePath, getLtSyncOwner, injectLtOfflineSync, listLtSyncPendingModels, ltSyncFetch, ltSyncObjectId, ltSyncScope, ltSyncUuidV7, openLtSyncHints, provideLtSync, resetLtSyncEngines, runLtSyncTx, subscribeLtSyncHints };
1095
+
1096
+ //# sourceMappingURL=lenne.tech-ng-base-sync.mjs.map