@signality/core 0.0.1-alpha.2 → 0.0.1-alpha.3

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 (219) hide show
  1. package/browser/battery/index.d.ts +27 -2
  2. package/browser/bluetooth/index.d.ts +40 -13
  3. package/browser/breakpoints/index.d.ts +22 -9
  4. package/browser/broadcast-channel/index.d.ts +1 -1
  5. package/browser/browser-language/index.d.ts +1 -1
  6. package/browser/clipboard/index.d.ts +22 -6
  7. package/browser/device-posture/index.d.ts +23 -2
  8. package/browser/display-media/index.d.ts +34 -22
  9. package/browser/eye-dropper/index.d.ts +22 -6
  10. package/browser/favicon/index.d.ts +29 -2
  11. package/browser/file-dialog/index.d.ts +97 -0
  12. package/browser/fps/index.d.ts +1 -1
  13. package/browser/fullscreen/index.d.ts +78 -0
  14. package/browser/gamepad/index.d.ts +39 -9
  15. package/browser/geolocation/index.d.ts +44 -13
  16. package/browser/index.d.ts +8 -1
  17. package/browser/input-modality/index.d.ts +1 -1
  18. package/browser/listener/index.d.ts +1 -1
  19. package/browser/media-query/index.d.ts +1 -1
  20. package/browser/network/index.d.ts +37 -9
  21. package/browser/online/index.d.ts +1 -1
  22. package/browser/page-visibility/index.d.ts +1 -1
  23. package/browser/permission-state/index.d.ts +23 -0
  24. package/browser/picture-in-picture/index.d.ts +24 -6
  25. package/browser/screen-orientation/index.d.ts +1 -1
  26. package/browser/speech-recognition/index.d.ts +51 -13
  27. package/browser/speech-synthesis/index.d.ts +82 -42
  28. package/browser/storage/index.d.ts +1 -1
  29. package/browser/text-direction/index.d.ts +2 -5
  30. package/{elements → browser}/text-selection/index.d.ts +1 -1
  31. package/browser/vibration/index.d.ts +38 -9
  32. package/browser/wake-lock/index.d.ts +51 -12
  33. package/browser/web-notification/index.d.ts +35 -9
  34. package/browser/web-share/index.d.ts +19 -5
  35. package/browser/web-worker/index.d.ts +35 -11
  36. package/browser/window-focus/index.d.ts +27 -0
  37. package/{elements → browser}/window-size/index.d.ts +6 -7
  38. package/elements/active-element/index.d.ts +1 -1
  39. package/elements/dropzone/index.d.ts +60 -10
  40. package/elements/element-focus/index.d.ts +1 -1
  41. package/elements/element-focus-within/index.d.ts +1 -1
  42. package/elements/element-hover/index.d.ts +1 -1
  43. package/elements/element-size/index.d.ts +8 -5
  44. package/elements/element-visibility/index.d.ts +25 -7
  45. package/elements/index.d.ts +0 -2
  46. package/elements/mouse-position/index.d.ts +27 -7
  47. package/elements/on-click-outside/index.d.ts +1 -1
  48. package/elements/on-disconnect/index.d.ts +1 -1
  49. package/elements/on-long-press/index.d.ts +1 -1
  50. package/elements/pointer-swipe/index.d.ts +1 -1
  51. package/elements/scroll-position/index.d.ts +2 -2
  52. package/elements/swipe/index.d.ts +1 -1
  53. package/fesm2022/signality-core-browser-battery.mjs +1 -1
  54. package/fesm2022/signality-core-browser-battery.mjs.map +1 -1
  55. package/fesm2022/signality-core-browser-bluetooth.mjs +28 -27
  56. package/fesm2022/signality-core-browser-bluetooth.mjs.map +1 -1
  57. package/fesm2022/signality-core-browser-breakpoints.mjs +19 -10
  58. package/fesm2022/signality-core-browser-breakpoints.mjs.map +1 -1
  59. package/fesm2022/signality-core-browser-broadcast-channel.mjs +1 -1
  60. package/fesm2022/signality-core-browser-broadcast-channel.mjs.map +1 -1
  61. package/fesm2022/signality-core-browser-browser-language.mjs +1 -1
  62. package/fesm2022/signality-core-browser-browser-language.mjs.map +1 -1
  63. package/fesm2022/signality-core-browser-clipboard.mjs +1 -1
  64. package/fesm2022/signality-core-browser-clipboard.mjs.map +1 -1
  65. package/fesm2022/signality-core-browser-device-posture.mjs +13 -0
  66. package/fesm2022/signality-core-browser-device-posture.mjs.map +1 -1
  67. package/fesm2022/signality-core-browser-display-media.mjs +4 -17
  68. package/fesm2022/signality-core-browser-display-media.mjs.map +1 -1
  69. package/fesm2022/signality-core-browser-eye-dropper.mjs +1 -1
  70. package/fesm2022/signality-core-browser-eye-dropper.mjs.map +1 -1
  71. package/fesm2022/signality-core-browser-favicon.mjs +2 -2
  72. package/fesm2022/signality-core-browser-favicon.mjs.map +1 -1
  73. package/fesm2022/signality-core-browser-file-dialog.mjs +109 -0
  74. package/fesm2022/signality-core-browser-file-dialog.mjs.map +1 -0
  75. package/fesm2022/signality-core-browser-fps.mjs +1 -1
  76. package/fesm2022/signality-core-browser-fps.mjs.map +1 -1
  77. package/fesm2022/signality-core-browser-fullscreen.mjs +113 -0
  78. package/fesm2022/signality-core-browser-fullscreen.mjs.map +1 -0
  79. package/fesm2022/signality-core-browser-gamepad.mjs +14 -4
  80. package/fesm2022/signality-core-browser-gamepad.mjs.map +1 -1
  81. package/fesm2022/signality-core-browser-geolocation.mjs +8 -19
  82. package/fesm2022/signality-core-browser-geolocation.mjs.map +1 -1
  83. package/fesm2022/signality-core-browser-input-modality.mjs +1 -1
  84. package/fesm2022/signality-core-browser-input-modality.mjs.map +1 -1
  85. package/fesm2022/signality-core-browser-listener.mjs +18 -6
  86. package/fesm2022/signality-core-browser-listener.mjs.map +1 -1
  87. package/fesm2022/signality-core-browser-media-query.mjs +1 -1
  88. package/fesm2022/signality-core-browser-media-query.mjs.map +1 -1
  89. package/fesm2022/signality-core-browser-network.mjs +2 -2
  90. package/fesm2022/signality-core-browser-network.mjs.map +1 -1
  91. package/fesm2022/signality-core-browser-online.mjs +1 -1
  92. package/fesm2022/signality-core-browser-online.mjs.map +1 -1
  93. package/fesm2022/signality-core-browser-page-visibility.mjs +1 -1
  94. package/fesm2022/signality-core-browser-page-visibility.mjs.map +1 -1
  95. package/fesm2022/signality-core-browser-permission-state.mjs +57 -0
  96. package/fesm2022/signality-core-browser-permission-state.mjs.map +1 -0
  97. package/fesm2022/signality-core-browser-picture-in-picture.mjs +30 -13
  98. package/fesm2022/signality-core-browser-picture-in-picture.mjs.map +1 -1
  99. package/fesm2022/signality-core-browser-screen-orientation.mjs +1 -1
  100. package/fesm2022/signality-core-browser-screen-orientation.mjs.map +1 -1
  101. package/fesm2022/signality-core-browser-speech-recognition.mjs +7 -19
  102. package/fesm2022/signality-core-browser-speech-recognition.mjs.map +1 -1
  103. package/fesm2022/signality-core-browser-speech-synthesis.mjs +14 -16
  104. package/fesm2022/signality-core-browser-speech-synthesis.mjs.map +1 -1
  105. package/fesm2022/signality-core-browser-storage.mjs +1 -1
  106. package/fesm2022/signality-core-browser-storage.mjs.map +1 -1
  107. package/fesm2022/signality-core-browser-text-direction.mjs +1 -4
  108. package/fesm2022/signality-core-browser-text-direction.mjs.map +1 -1
  109. package/fesm2022/{signality-core-elements-text-selection.mjs → signality-core-browser-text-selection.mjs} +2 -2
  110. package/fesm2022/signality-core-browser-text-selection.mjs.map +1 -0
  111. package/fesm2022/signality-core-browser-vibration.mjs +14 -5
  112. package/fesm2022/signality-core-browser-vibration.mjs.map +1 -1
  113. package/fesm2022/signality-core-browser-wake-lock.mjs +33 -16
  114. package/fesm2022/signality-core-browser-wake-lock.mjs.map +1 -1
  115. package/fesm2022/signality-core-browser-web-notification.mjs +5 -7
  116. package/fesm2022/signality-core-browser-web-notification.mjs.map +1 -1
  117. package/fesm2022/signality-core-browser-web-share.mjs +3 -5
  118. package/fesm2022/signality-core-browser-web-share.mjs.map +1 -1
  119. package/fesm2022/signality-core-browser-web-worker.mjs +6 -3
  120. package/fesm2022/signality-core-browser-web-worker.mjs.map +1 -1
  121. package/fesm2022/signality-core-browser-window-focus.mjs +48 -0
  122. package/fesm2022/signality-core-browser-window-focus.mjs.map +1 -0
  123. package/fesm2022/{signality-core-elements-window-size.mjs → signality-core-browser-window-size.mjs} +4 -24
  124. package/fesm2022/signality-core-browser-window-size.mjs.map +1 -0
  125. package/fesm2022/signality-core-browser.mjs +8 -1
  126. package/fesm2022/signality-core-browser.mjs.map +1 -1
  127. package/fesm2022/signality-core-elements-active-element.mjs +1 -1
  128. package/fesm2022/signality-core-elements-active-element.mjs.map +1 -1
  129. package/fesm2022/signality-core-elements-dropzone.mjs +28 -29
  130. package/fesm2022/signality-core-elements-dropzone.mjs.map +1 -1
  131. package/fesm2022/signality-core-elements-element-focus-within.mjs +1 -1
  132. package/fesm2022/signality-core-elements-element-focus-within.mjs.map +1 -1
  133. package/fesm2022/signality-core-elements-element-focus.mjs +1 -1
  134. package/fesm2022/signality-core-elements-element-focus.mjs.map +1 -1
  135. package/fesm2022/signality-core-elements-element-hover.mjs +1 -1
  136. package/fesm2022/signality-core-elements-element-hover.mjs.map +1 -1
  137. package/fesm2022/signality-core-elements-element-size.mjs +19 -24
  138. package/fesm2022/signality-core-elements-element-size.mjs.map +1 -1
  139. package/fesm2022/signality-core-elements-element-visibility.mjs +2 -2
  140. package/fesm2022/signality-core-elements-element-visibility.mjs.map +1 -1
  141. package/fesm2022/signality-core-elements-mouse-position.mjs +3 -3
  142. package/fesm2022/signality-core-elements-mouse-position.mjs.map +1 -1
  143. package/fesm2022/signality-core-elements-on-click-outside.mjs +1 -1
  144. package/fesm2022/signality-core-elements-on-click-outside.mjs.map +1 -1
  145. package/fesm2022/signality-core-elements-on-disconnect.mjs +1 -1
  146. package/fesm2022/signality-core-elements-on-disconnect.mjs.map +1 -1
  147. package/fesm2022/signality-core-elements-on-long-press.mjs +1 -1
  148. package/fesm2022/signality-core-elements-on-long-press.mjs.map +1 -1
  149. package/fesm2022/signality-core-elements-pointer-swipe.mjs +1 -1
  150. package/fesm2022/signality-core-elements-pointer-swipe.mjs.map +1 -1
  151. package/fesm2022/signality-core-elements-scroll-position.mjs +2 -2
  152. package/fesm2022/signality-core-elements-scroll-position.mjs.map +1 -1
  153. package/fesm2022/signality-core-elements-swipe.mjs +1 -1
  154. package/fesm2022/signality-core-elements-swipe.mjs.map +1 -1
  155. package/fesm2022/signality-core-elements.mjs +0 -2
  156. package/fesm2022/signality-core-elements.mjs.map +1 -1
  157. package/fesm2022/signality-core-internal.mjs +54 -7
  158. package/fesm2022/signality-core-internal.mjs.map +1 -1
  159. package/fesm2022/signality-core-observers-intersection-observer.mjs +3 -2
  160. package/fesm2022/signality-core-observers-intersection-observer.mjs.map +1 -1
  161. package/fesm2022/signality-core-observers-mutation-observer.mjs +3 -2
  162. package/fesm2022/signality-core-observers-mutation-observer.mjs.map +1 -1
  163. package/fesm2022/signality-core-observers-resize-observer.mjs +3 -2
  164. package/fesm2022/signality-core-observers-resize-observer.mjs.map +1 -1
  165. package/fesm2022/signality-core-observers.mjs +0 -1
  166. package/fesm2022/signality-core-observers.mjs.map +1 -1
  167. package/fesm2022/signality-core-reactivity-debounced.mjs.map +1 -1
  168. package/fesm2022/signality-core-reactivity-throttled.mjs.map +1 -1
  169. package/fesm2022/signality-core-reactivity-watcher.mjs.map +1 -1
  170. package/fesm2022/signality-core-router-fragment.mjs +1 -1
  171. package/fesm2022/signality-core-router-fragment.mjs.map +1 -1
  172. package/fesm2022/signality-core-router-params.mjs +1 -1
  173. package/fesm2022/signality-core-router-params.mjs.map +1 -1
  174. package/fesm2022/signality-core-router-query-params.mjs.map +1 -1
  175. package/fesm2022/signality-core-router-route-data.mjs +1 -1
  176. package/fesm2022/signality-core-router-route-data.mjs.map +1 -1
  177. package/fesm2022/signality-core-router-router-listener.mjs.map +1 -1
  178. package/fesm2022/signality-core-router-title.mjs +1 -1
  179. package/fesm2022/signality-core-router-title.mjs.map +1 -1
  180. package/fesm2022/signality-core-router-url.mjs +1 -1
  181. package/fesm2022/signality-core-router-url.mjs.map +1 -1
  182. package/fesm2022/signality-core-scheduling-debounce-callback.mjs +1 -1
  183. package/fesm2022/signality-core-scheduling-debounce-callback.mjs.map +1 -1
  184. package/fesm2022/signality-core-scheduling-interval.mjs +27 -72
  185. package/fesm2022/signality-core-scheduling-interval.mjs.map +1 -1
  186. package/internal/utils/assert.d.ts +2 -0
  187. package/internal/utils/dom/index.d.ts +1 -0
  188. package/internal/utils/dom/is-element.d.ts +1 -1
  189. package/internal/utils/dom/is-event-target.d.ts +1 -0
  190. package/internal/utils/files/index.d.ts +1 -0
  191. package/internal/utils/files/is-accepted-file.d.ts +11 -0
  192. package/internal/utils/index.d.ts +3 -0
  193. package/internal/utils/to-element.d.ts +1 -1
  194. package/internal/utils/unref-element.d.ts +2 -0
  195. package/observers/index.d.ts +0 -1
  196. package/observers/intersection-observer/index.d.ts +22 -1
  197. package/observers/mutation-observer/index.d.ts +43 -1
  198. package/observers/resize-observer/index.d.ts +13 -1
  199. package/package.json +25 -17
  200. package/reactivity/debounced/index.d.ts +2 -2
  201. package/reactivity/throttled/index.d.ts +2 -2
  202. package/reactivity/watcher/index.d.ts +2 -2
  203. package/router/fragment/index.d.ts +1 -1
  204. package/router/params/index.d.ts +1 -1
  205. package/router/query-params/index.d.ts +5 -3
  206. package/router/route-data/index.d.ts +1 -1
  207. package/router/router-listener/index.d.ts +1 -1
  208. package/router/title/index.d.ts +1 -1
  209. package/router/url/index.d.ts +1 -1
  210. package/scheduling/debounce-callback/index.d.ts +1 -1
  211. package/scheduling/interval/index.d.ts +19 -27
  212. package/browser/pointer-lock-element/index.d.ts +0 -22
  213. package/fesm2022/signality-core-browser-pointer-lock-element.mjs +0 -43
  214. package/fesm2022/signality-core-browser-pointer-lock-element.mjs.map +0 -1
  215. package/fesm2022/signality-core-elements-text-selection.mjs.map +0 -1
  216. package/fesm2022/signality-core-elements-window-size.mjs.map +0 -1
  217. package/fesm2022/signality-core-observers-performance-observer.mjs +0 -84
  218. package/fesm2022/signality-core-observers-performance-observer.mjs.map +0 -1
  219. package/observers/performance-observer/index.d.ts +0 -58
@@ -1 +1 @@
1
- {"version":3,"file":"signality-core-router-router-listener.mjs","sources":["../../../projects/core/router/router-listener/index.ts","../../../projects/core/router/router-listener/signality-core-router-router-listener.ts"],"sourcesContent":["import { inject } from '@angular/core';\nimport {\n ActivationEnd,\n ActivationStart,\n ChildActivationEnd,\n ChildActivationStart,\n type Event as RouterEvent,\n GuardsCheckEnd,\n GuardsCheckStart,\n NavigationCancel,\n NavigationEnd,\n NavigationError,\n NavigationSkipped,\n NavigationStart,\n ResolveEnd,\n ResolveStart,\n RouteConfigLoadEnd,\n RouteConfigLoadStart,\n Router,\n RoutesRecognized,\n Scroll,\n} from '@angular/router';\nimport { filter } from 'rxjs';\nimport { setupContext } from '@signality/core/internal';\nimport type { WithInjector } from '@signality/core/types';\n\nexport interface RouterListenerOptions extends WithInjector {\n /** If true, automatically unsubscribe after the first event */\n readonly once?: boolean;\n}\n\nexport interface RouterListenerRef {\n /** Manually unsubscribe from router events */\n readonly destroy: () => void;\n}\n\nexport type RouterEventType =\n | 'navigationstart'\n | 'navigationend'\n | 'navigationcancel'\n | 'navigationerror'\n | 'navigationskipped'\n | 'routesrecognized'\n | 'guardscheckstart'\n | 'guardscheckend'\n | 'resolvestart'\n | 'resolveend'\n | 'routeconfigloadstart'\n | 'routeconfigloadend'\n | 'childactivationstart'\n | 'childactivationend'\n | 'activationstart'\n | 'activationend'\n | 'scroll';\n\n/**\n * Event-driven listener for [Angular Router](https://angular.dev/guide/routing) events.\n *\n * @param event - Router event name in lowercase (e.g., 'navigationstart') or array of event names\n * @param handler - Type-safe handler function for the specific event(s)\n * @param options - Optional configuration\n * @returns RouterListenerRef with destroy method for manual unsubscribe\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * @if (isLoading()) {\n * <p>Navigation in progress...</p>\n * }\n * `\n * })\n * class NavigationComponent {\n * readonly isLoading = signal(false);\n *\n * constructor() {\n * routerListener('navigationstart', event => {\n * this.isLoading.set(true);\n * });\n *\n * routerListener('navigationend', event => {\n * this.isLoading.set(false);\n * });\n * }\n * }\n * ```\n */\nexport function routerListener(\n event: 'navigationstart',\n handler: (event: NavigationStart) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'navigationend',\n handler: (event: NavigationEnd) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'navigationcancel',\n handler: (event: NavigationCancel) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'navigationerror',\n handler: (event: NavigationError) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'navigationskipped',\n handler: (event: NavigationSkipped) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'routesrecognized',\n handler: (event: RoutesRecognized) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'guardscheckstart',\n handler: (event: GuardsCheckStart) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'guardscheckend',\n handler: (event: GuardsCheckEnd) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'resolvestart',\n handler: (event: ResolveStart) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'resolveend',\n handler: (event: ResolveEnd) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'routeconfigloadstart',\n handler: (event: RouteConfigLoadStart) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'routeconfigloadend',\n handler: (event: RouteConfigLoadEnd) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'childactivationstart',\n handler: (event: ChildActivationStart) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'childactivationend',\n handler: (event: ChildActivationEnd) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'activationstart',\n handler: (event: ActivationStart) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'activationend',\n handler: (event: ActivationEnd) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'scroll',\n handler: (event: Scroll) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener<T extends readonly [RouterEventType, ...RouterEventType[]]>(\n events: T,\n handler: (event: RouterEventTypeArrayToUnion<T>) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: RouterEventType | readonly RouterEventType[],\n handler: (event: any) => void,\n options?: RouterListenerOptions\n): RouterListenerRef {\n const { runInContext } = setupContext(options?.injector, routerListener);\n\n return runInContext(({ onCleanup }) => {\n const router = inject(Router);\n const events = Array.isArray(event) ? event : [event];\n const EventClasses = events.map(\n (e): new (...args: any[]) => RouterEvent => EVENT_CLASSES[e as RouterEventType]\n );\n\n const subscription = router.events\n .pipe(\n filter((routerEvent: RouterEvent): routerEvent is RouterEvent =>\n EventClasses.some(EventClass => routerEvent instanceof EventClass)\n )\n )\n .subscribe(e => {\n handler(e);\n\n if (options?.once) {\n subscription.unsubscribe();\n }\n });\n\n const destroy = subscription.unsubscribe.bind(subscription);\n\n onCleanup(destroy);\n\n return { destroy };\n });\n}\n\nconst EVENT_CLASSES: Record<RouterEventType, new (...args: any[]) => RouterEvent> = {\n navigationstart: NavigationStart,\n navigationend: NavigationEnd,\n navigationcancel: NavigationCancel,\n navigationerror: NavigationError,\n navigationskipped: NavigationSkipped,\n routesrecognized: RoutesRecognized,\n guardscheckstart: GuardsCheckStart,\n guardscheckend: GuardsCheckEnd,\n resolvestart: ResolveStart,\n resolveend: ResolveEnd,\n routeconfigloadstart: RouteConfigLoadStart,\n routeconfigloadend: RouteConfigLoadEnd,\n childactivationstart: ChildActivationStart,\n childactivationend: ChildActivationEnd,\n activationstart: ActivationStart,\n activationend: ActivationEnd,\n scroll: Scroll,\n};\n\ntype RouterEventTypeMap = {\n navigationstart: NavigationStart;\n navigationend: NavigationEnd;\n navigationcancel: NavigationCancel;\n navigationerror: NavigationError;\n navigationskipped: NavigationSkipped;\n routesrecognized: RoutesRecognized;\n guardscheckstart: GuardsCheckStart;\n guardscheckend: GuardsCheckEnd;\n resolvestart: ResolveStart;\n resolveend: ResolveEnd;\n routeconfigloadstart: RouteConfigLoadStart;\n routeconfigloadend: RouteConfigLoadEnd;\n childactivationstart: ChildActivationStart;\n childactivationend: ChildActivationEnd;\n activationstart: ActivationStart;\n activationend: ActivationEnd;\n scroll: Scroll;\n};\n\ntype RouterEventTypeToEventType<T extends RouterEventType> = RouterEventTypeMap[T];\n\ntype RouterEventTypeArrayToUnion<T extends readonly RouterEventType[]> = T[number] extends infer U\n ? U extends RouterEventType\n ? RouterEventTypeToEventType<U>\n : never\n : never;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;SAiLgB,cAAc,CAC5B,KAAmD,EACnD,OAA6B,EAC7B,OAA+B,EAAA;AAE/B,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,cAAc,CAAC;AAExE,IAAA,OAAO,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,KAAI;AACpC,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AAC7B,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC;AACrD,QAAA,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAC7B,CAAC,CAAC,KAA0C,aAAa,CAAC,CAAoB,CAAC,CAChF;AAED,QAAA,MAAM,YAAY,GAAG,MAAM,CAAC;aACzB,IAAI,CACH,MAAM,CAAC,CAAC,WAAwB,KAC9B,YAAY,CAAC,IAAI,CAAC,UAAU,IAAI,WAAW,YAAY,UAAU,CAAC,CACnE;aAEF,SAAS,CAAC,CAAC,IAAG;YACb,OAAO,CAAC,CAAC,CAAC;AAEV,YAAA,IAAI,OAAO,EAAE,IAAI,EAAE;gBACjB,YAAY,CAAC,WAAW,EAAE;YAC5B;AACF,QAAA,CAAC,CAAC;QAEJ,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC;QAE3D,SAAS,CAAC,OAAO,CAAC;QAElB,OAAO,EAAE,OAAO,EAAE;AACpB,IAAA,CAAC,CAAC;AACJ;AAEA,MAAM,aAAa,GAAiE;AAClF,IAAA,eAAe,EAAE,eAAe;AAChC,IAAA,aAAa,EAAE,aAAa;AAC5B,IAAA,gBAAgB,EAAE,gBAAgB;AAClC,IAAA,eAAe,EAAE,eAAe;AAChC,IAAA,iBAAiB,EAAE,iBAAiB;AACpC,IAAA,gBAAgB,EAAE,gBAAgB;AAClC,IAAA,gBAAgB,EAAE,gBAAgB;AAClC,IAAA,cAAc,EAAE,cAAc;AAC9B,IAAA,YAAY,EAAE,YAAY;AAC1B,IAAA,UAAU,EAAE,UAAU;AACtB,IAAA,oBAAoB,EAAE,oBAAoB;AAC1C,IAAA,kBAAkB,EAAE,kBAAkB;AACtC,IAAA,oBAAoB,EAAE,oBAAoB;AAC1C,IAAA,kBAAkB,EAAE,kBAAkB;AACtC,IAAA,eAAe,EAAE,eAAe;AAChC,IAAA,aAAa,EAAE,aAAa;AAC5B,IAAA,MAAM,EAAE,MAAM;CACf;;ACvOD;;AAEG;;;;"}
1
+ {"version":3,"file":"signality-core-router-router-listener.mjs","sources":["../../../projects/core/router/router-listener/index.ts","../../../projects/core/router/router-listener/signality-core-router-router-listener.ts"],"sourcesContent":["import { inject } from '@angular/core';\nimport {\n ActivationEnd,\n ActivationStart,\n ChildActivationEnd,\n ChildActivationStart,\n type Event as RouterEvent,\n GuardsCheckEnd,\n GuardsCheckStart,\n NavigationCancel,\n NavigationEnd,\n NavigationError,\n NavigationSkipped,\n NavigationStart,\n ResolveEnd,\n ResolveStart,\n RouteConfigLoadEnd,\n RouteConfigLoadStart,\n Router,\n RoutesRecognized,\n Scroll,\n} from '@angular/router';\nimport { filter } from 'rxjs';\nimport { setupContext } from '@signality/core/internal';\nimport type { WithInjector } from '@signality/core/types';\n\nexport interface RouterListenerOptions extends WithInjector {\n /** If true, automatically unsubscribe after the first event */\n readonly once?: boolean;\n}\n\nexport interface RouterListenerRef {\n /** Manually unsubscribe from router events */\n readonly destroy: () => void;\n}\n\nexport type RouterEventType =\n | 'navigationstart'\n | 'navigationend'\n | 'navigationcancel'\n | 'navigationerror'\n | 'navigationskipped'\n | 'routesrecognized'\n | 'guardscheckstart'\n | 'guardscheckend'\n | 'resolvestart'\n | 'resolveend'\n | 'routeconfigloadstart'\n | 'routeconfigloadend'\n | 'childactivationstart'\n | 'childactivationend'\n | 'activationstart'\n | 'activationend'\n | 'scroll';\n\n/**\n * Event-driven listener for [Angular Router](https://angular.dev/guide/routing) events.\n *\n * @param event - Router event name in lowercase (e.g., 'navigationstart') or array of event names\n * @param handler - Type-safe handler function for the specific event(s)\n * @param options - Optional configuration\n * @returns RouterListenerRef with destroy method for manual unsubscribe\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * @if (isLoading()) {\n * <p>Navigation in progress...</p>\n * }\n * `\n * })\n * export class NavigationDemo {\n * readonly isLoading = signal(false);\n *\n * constructor() {\n * routerListener('navigationstart', event => {\n * this.isLoading.set(true);\n * });\n *\n * routerListener('navigationend', event => {\n * this.isLoading.set(false);\n * });\n * }\n * }\n * ```\n */\nexport function routerListener(\n event: 'navigationstart',\n handler: (event: NavigationStart) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'navigationend',\n handler: (event: NavigationEnd) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'navigationcancel',\n handler: (event: NavigationCancel) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'navigationerror',\n handler: (event: NavigationError) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'navigationskipped',\n handler: (event: NavigationSkipped) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'routesrecognized',\n handler: (event: RoutesRecognized) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'guardscheckstart',\n handler: (event: GuardsCheckStart) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'guardscheckend',\n handler: (event: GuardsCheckEnd) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'resolvestart',\n handler: (event: ResolveStart) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'resolveend',\n handler: (event: ResolveEnd) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'routeconfigloadstart',\n handler: (event: RouteConfigLoadStart) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'routeconfigloadend',\n handler: (event: RouteConfigLoadEnd) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'childactivationstart',\n handler: (event: ChildActivationStart) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'childactivationend',\n handler: (event: ChildActivationEnd) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'activationstart',\n handler: (event: ActivationStart) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'activationend',\n handler: (event: ActivationEnd) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: 'scroll',\n handler: (event: Scroll) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener<T extends readonly [RouterEventType, ...RouterEventType[]]>(\n events: T,\n handler: (event: RouterEventTypeArrayToUnion<T>) => void,\n options?: RouterListenerOptions\n): RouterListenerRef;\nexport function routerListener(\n event: RouterEventType | readonly RouterEventType[],\n handler: (event: any) => void,\n options?: RouterListenerOptions\n): RouterListenerRef {\n const { runInContext } = setupContext(options?.injector, routerListener);\n\n return runInContext(({ onCleanup }) => {\n const router = inject(Router);\n const events = Array.isArray(event) ? event : [event];\n const EventClasses = events.map(\n (e): new (...args: any[]) => RouterEvent => EVENT_CLASSES[e as RouterEventType]\n );\n\n const subscription = router.events\n .pipe(\n filter((routerEvent: RouterEvent): routerEvent is RouterEvent =>\n EventClasses.some(EventClass => routerEvent instanceof EventClass)\n )\n )\n .subscribe(e => {\n handler(e);\n\n if (options?.once) {\n subscription.unsubscribe();\n }\n });\n\n const destroy = subscription.unsubscribe.bind(subscription);\n\n onCleanup(destroy);\n\n return { destroy };\n });\n}\n\nconst EVENT_CLASSES: Record<RouterEventType, new (...args: any[]) => RouterEvent> = {\n navigationstart: NavigationStart,\n navigationend: NavigationEnd,\n navigationcancel: NavigationCancel,\n navigationerror: NavigationError,\n navigationskipped: NavigationSkipped,\n routesrecognized: RoutesRecognized,\n guardscheckstart: GuardsCheckStart,\n guardscheckend: GuardsCheckEnd,\n resolvestart: ResolveStart,\n resolveend: ResolveEnd,\n routeconfigloadstart: RouteConfigLoadStart,\n routeconfigloadend: RouteConfigLoadEnd,\n childactivationstart: ChildActivationStart,\n childactivationend: ChildActivationEnd,\n activationstart: ActivationStart,\n activationend: ActivationEnd,\n scroll: Scroll,\n};\n\ntype RouterEventTypeMap = {\n navigationstart: NavigationStart;\n navigationend: NavigationEnd;\n navigationcancel: NavigationCancel;\n navigationerror: NavigationError;\n navigationskipped: NavigationSkipped;\n routesrecognized: RoutesRecognized;\n guardscheckstart: GuardsCheckStart;\n guardscheckend: GuardsCheckEnd;\n resolvestart: ResolveStart;\n resolveend: ResolveEnd;\n routeconfigloadstart: RouteConfigLoadStart;\n routeconfigloadend: RouteConfigLoadEnd;\n childactivationstart: ChildActivationStart;\n childactivationend: ChildActivationEnd;\n activationstart: ActivationStart;\n activationend: ActivationEnd;\n scroll: Scroll;\n};\n\ntype RouterEventTypeToEventType<T extends RouterEventType> = RouterEventTypeMap[T];\n\ntype RouterEventTypeArrayToUnion<T extends readonly RouterEventType[]> = T[number] extends infer U\n ? U extends RouterEventType\n ? RouterEventTypeToEventType<U>\n : never\n : never;\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;SAiLgB,cAAc,CAC5B,KAAmD,EACnD,OAA6B,EAC7B,OAA+B,EAAA;AAE/B,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,cAAc,CAAC;AAExE,IAAA,OAAO,YAAY,CAAC,CAAC,EAAE,SAAS,EAAE,KAAI;AACpC,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;AAC7B,QAAA,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,KAAK,CAAC,GAAG,KAAK,GAAG,CAAC,KAAK,CAAC;AACrD,QAAA,MAAM,YAAY,GAAG,MAAM,CAAC,GAAG,CAC7B,CAAC,CAAC,KAA0C,aAAa,CAAC,CAAoB,CAAC,CAChF;AAED,QAAA,MAAM,YAAY,GAAG,MAAM,CAAC;aACzB,IAAI,CACH,MAAM,CAAC,CAAC,WAAwB,KAC9B,YAAY,CAAC,IAAI,CAAC,UAAU,IAAI,WAAW,YAAY,UAAU,CAAC,CACnE;aAEF,SAAS,CAAC,CAAC,IAAG;YACb,OAAO,CAAC,CAAC,CAAC;AAEV,YAAA,IAAI,OAAO,EAAE,IAAI,EAAE;gBACjB,YAAY,CAAC,WAAW,EAAE;YAC5B;AACF,QAAA,CAAC,CAAC;QAEJ,MAAM,OAAO,GAAG,YAAY,CAAC,WAAW,CAAC,IAAI,CAAC,YAAY,CAAC;QAE3D,SAAS,CAAC,OAAO,CAAC;QAElB,OAAO,EAAE,OAAO,EAAE;AACpB,IAAA,CAAC,CAAC;AACJ;AAEA,MAAM,aAAa,GAAiE;AAClF,IAAA,eAAe,EAAE,eAAe;AAChC,IAAA,aAAa,EAAE,aAAa;AAC5B,IAAA,gBAAgB,EAAE,gBAAgB;AAClC,IAAA,eAAe,EAAE,eAAe;AAChC,IAAA,iBAAiB,EAAE,iBAAiB;AACpC,IAAA,gBAAgB,EAAE,gBAAgB;AAClC,IAAA,gBAAgB,EAAE,gBAAgB;AAClC,IAAA,cAAc,EAAE,cAAc;AAC9B,IAAA,YAAY,EAAE,YAAY;AAC1B,IAAA,UAAU,EAAE,UAAU;AACtB,IAAA,oBAAoB,EAAE,oBAAoB;AAC1C,IAAA,kBAAkB,EAAE,kBAAkB;AACtC,IAAA,oBAAoB,EAAE,oBAAoB;AAC1C,IAAA,kBAAkB,EAAE,kBAAkB;AACtC,IAAA,eAAe,EAAE,eAAe;AAChC,IAAA,aAAa,EAAE,aAAa;AAC5B,IAAA,MAAM,EAAE,MAAM;CACf;;ACvOD;;AAEG;;;;"}
@@ -21,7 +21,7 @@ import { setupContext, proxySignal } from '@signality/core/internal';
21
21
  * </div>
22
22
  * `
23
23
  * })
24
- * class PageComponent {
24
+ * export class Page {
25
25
  * readonly pageTitle = title();
26
26
  *
27
27
  * updateTitle() {
@@ -1 +1 @@
1
- {"version":3,"file":"signality-core-router-title.mjs","sources":["../../../projects/core/router/title/index.ts","../../../projects/core/router/title/signality-core-router-title.ts"],"sourcesContent":["import { type CreateSignalOptions, inject, linkedSignal, type WritableSignal } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { Title } from '@angular/platform-browser';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { filter } from 'rxjs';\nimport { proxySignal, setupContext } from '@signality/core/internal';\nimport type { WithInjector } from '@signality/core/types';\n\nexport type TitleOptions = CreateSignalOptions<string> & WithInjector;\n\n/**\n * Reactive wrapper around the [Angular Router](https://angular.dev/guide/routing) route title.\n *\n * @param options - Optional configuration\n * @returns A writable signal containing the current route title (string)\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <div>\n * <h1>{{ pageTitle() }}</h1>\n * <button (click)=\"updateTitle()\">Update Title</button>\n * </div>\n * `\n * })\n * class PageComponent {\n * readonly pageTitle = title();\n *\n * updateTitle() {\n * this.pageTitle.set('New Page Title');\n * }\n * }\n * ```\n */\nexport function title(options?: TitleOptions): WritableSignal<string> {\n const { runInContext } = setupContext(options?.injector, title);\n\n return runInContext(() => {\n const route = inject(ActivatedRoute);\n const html = inject(Title);\n\n return proxySignal(\n linkedSignal(\n toSignal<string, string>(route.title.pipe(filter(Boolean)), {\n initialValue: route.snapshot.title || html.getTitle(),\n }),\n { ...options }\n ),\n {\n set: (value, source) => {\n html.setTitle(value);\n source.set(value);\n },\n }\n );\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;AAUA;;;;;;;;;;;;;;;;;;;;;;;;AAwBG;AACG,SAAU,KAAK,CAAC,OAAsB,EAAA;AAC1C,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC;IAE/D,OAAO,YAAY,CAAC,MAAK;AACvB,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC;AACpC,QAAA,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC;AAE1B,QAAA,OAAO,WAAW,CAChB,YAAY,CACV,QAAQ,CAAiB,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE;YAC1D,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE;AACtD,SAAA,CAAC,EACF,EAAE,GAAG,OAAO,EAAE,CACf,EACD;AACE,YAAA,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,KAAI;AACrB,gBAAA,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;AACpB,gBAAA,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;YACnB,CAAC;AACF,SAAA,CACF;AACH,IAAA,CAAC,CAAC;AACJ;;ACzDA;;AAEG;;;;"}
1
+ {"version":3,"file":"signality-core-router-title.mjs","sources":["../../../projects/core/router/title/index.ts","../../../projects/core/router/title/signality-core-router-title.ts"],"sourcesContent":["import { type CreateSignalOptions, inject, linkedSignal, type WritableSignal } from '@angular/core';\nimport { ActivatedRoute } from '@angular/router';\nimport { Title } from '@angular/platform-browser';\nimport { toSignal } from '@angular/core/rxjs-interop';\nimport { filter } from 'rxjs';\nimport { proxySignal, setupContext } from '@signality/core/internal';\nimport type { WithInjector } from '@signality/core/types';\n\nexport type TitleOptions = CreateSignalOptions<string> & WithInjector;\n\n/**\n * Reactive wrapper around the [Angular Router](https://angular.dev/guide/routing) route title.\n *\n * @param options - Optional configuration\n * @returns A writable signal containing the current route title (string)\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <div>\n * <h1>{{ pageTitle() }}</h1>\n * <button (click)=\"updateTitle()\">Update Title</button>\n * </div>\n * `\n * })\n * export class Page {\n * readonly pageTitle = title();\n *\n * updateTitle() {\n * this.pageTitle.set('New Page Title');\n * }\n * }\n * ```\n */\nexport function title(options?: TitleOptions): WritableSignal<string> {\n const { runInContext } = setupContext(options?.injector, title);\n\n return runInContext(() => {\n const route = inject(ActivatedRoute);\n const html = inject(Title);\n\n return proxySignal(\n linkedSignal(\n toSignal<string, string>(route.title.pipe(filter(Boolean)), {\n initialValue: route.snapshot.title || html.getTitle(),\n }),\n { ...options }\n ),\n {\n set: (value, source) => {\n html.setTitle(value);\n source.set(value);\n },\n }\n );\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;;;AAUA;;;;;;;;;;;;;;;;;;;;;;;;AAwBG;AACG,SAAU,KAAK,CAAC,OAAsB,EAAA;AAC1C,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,KAAK,CAAC;IAE/D,OAAO,YAAY,CAAC,MAAK;AACvB,QAAA,MAAM,KAAK,GAAG,MAAM,CAAC,cAAc,CAAC;AACpC,QAAA,MAAM,IAAI,GAAG,MAAM,CAAC,KAAK,CAAC;AAE1B,QAAA,OAAO,WAAW,CAChB,YAAY,CACV,QAAQ,CAAiB,KAAK,CAAC,KAAK,CAAC,IAAI,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,EAAE;YAC1D,YAAY,EAAE,KAAK,CAAC,QAAQ,CAAC,KAAK,IAAI,IAAI,CAAC,QAAQ,EAAE;AACtD,SAAA,CAAC,EACF,EAAE,GAAG,OAAO,EAAE,CACf,EACD;AACE,YAAA,GAAG,EAAE,CAAC,KAAK,EAAE,MAAM,KAAI;AACrB,gBAAA,IAAI,CAAC,QAAQ,CAAC,KAAK,CAAC;AACpB,gBAAA,MAAM,CAAC,GAAG,CAAC,KAAK,CAAC;YACnB,CAAC;AACF,SAAA,CACF;AACH,IAAA,CAAC,CAAC;AACJ;;ACzDA;;AAEG;;;;"}
@@ -19,7 +19,7 @@ import { routerListener } from '@signality/core/router/router-listener';
19
19
  * </div>
20
20
  * `
21
21
  * })
22
- * class UrlComponent {
22
+ * export class UrlDemo {
23
23
  * readonly currentUrl = url();
24
24
  * readonly absoluteUrl = url({ absolute: true });
25
25
  * }
@@ -1 +1 @@
1
- {"version":3,"file":"signality-core-router-url.mjs","sources":["../../../projects/core/router/url/index.ts","../../../projects/core/router/url/signality-core-router-url.ts"],"sourcesContent":["import { type CreateSignalOptions, inject, signal, type Signal } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { constSignal, setupContext } from '@signality/core/internal';\nimport type { WithInjector } from '@signality/core/types';\nimport { routerListener } from '@signality/core/router/router-listener';\n\nexport interface UrlOptions extends CreateSignalOptions<string>, WithInjector {\n /**\n * Include origin (protocol + host) for absolute URL.\n * @default false\n */\n readonly absolute?: boolean;\n}\n\n/**\n * Reactive wrapper around the [Angular Router](https://angular.dev/guide/routing) current URL.\n *\n * @param options - Optional configuration\n * @returns A signal containing the current URL\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <div>\n * <p>Current URL: {{ currentUrl() }}</p>\n * <p>Absolute URL: {{ absoluteUrl() }}</p>\n * </div>\n * `\n * })\n * class UrlComponent {\n * readonly currentUrl = url();\n * readonly absoluteUrl = url({ absolute: true });\n * }\n * ```\n */\nexport function url(options?: UrlOptions): Signal<string> {\n const { runInContext } = setupContext(options?.injector, url);\n\n return runInContext(({ isServer }) => {\n const router = inject(Router);\n\n if (isServer) {\n return constSignal(router.url);\n }\n\n const getUrl = () => {\n const relativeUrl = router.url;\n\n if (options?.absolute) {\n return location.origin + relativeUrl;\n }\n\n return relativeUrl;\n };\n\n const result = signal(getUrl(), options);\n\n routerListener('navigationend', () => result.set(getUrl()));\n\n return result.asReadonly();\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAcA;;;;;;;;;;;;;;;;;;;;;AAqBG;AACG,SAAU,GAAG,CAAC,OAAoB,EAAA;AACtC,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC;AAE7D,IAAA,OAAO,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAI;AACnC,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAE7B,IAAI,QAAQ,EAAE;AACZ,YAAA,OAAO,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC;QAChC;QAEA,MAAM,MAAM,GAAG,MAAK;AAClB,YAAA,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG;AAE9B,YAAA,IAAI,OAAO,EAAE,QAAQ,EAAE;AACrB,gBAAA,OAAO,QAAQ,CAAC,MAAM,GAAG,WAAW;YACtC;AAEA,YAAA,OAAO,WAAW;AACpB,QAAA,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,EAAE,OAAO,CAAC;AAExC,QAAA,cAAc,CAAC,eAAe,EAAE,MAAM,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;AAE3D,QAAA,OAAO,MAAM,CAAC,UAAU,EAAE;AAC5B,IAAA,CAAC,CAAC;AACJ;;AC9DA;;AAEG;;;;"}
1
+ {"version":3,"file":"signality-core-router-url.mjs","sources":["../../../projects/core/router/url/index.ts","../../../projects/core/router/url/signality-core-router-url.ts"],"sourcesContent":["import { type CreateSignalOptions, inject, signal, type Signal } from '@angular/core';\nimport { Router } from '@angular/router';\nimport { constSignal, setupContext } from '@signality/core/internal';\nimport type { WithInjector } from '@signality/core/types';\nimport { routerListener } from '@signality/core/router/router-listener';\n\nexport interface UrlOptions extends CreateSignalOptions<string>, WithInjector {\n /**\n * Include origin (protocol + host) for absolute URL.\n * @default false\n */\n readonly absolute?: boolean;\n}\n\n/**\n * Reactive wrapper around the [Angular Router](https://angular.dev/guide/routing) current URL.\n *\n * @param options - Optional configuration\n * @returns A signal containing the current URL\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <div>\n * <p>Current URL: {{ currentUrl() }}</p>\n * <p>Absolute URL: {{ absoluteUrl() }}</p>\n * </div>\n * `\n * })\n * export class UrlDemo {\n * readonly currentUrl = url();\n * readonly absoluteUrl = url({ absolute: true });\n * }\n * ```\n */\nexport function url(options?: UrlOptions): Signal<string> {\n const { runInContext } = setupContext(options?.injector, url);\n\n return runInContext(({ isServer }) => {\n const router = inject(Router);\n\n if (isServer) {\n return constSignal(router.url);\n }\n\n const getUrl = () => {\n const relativeUrl = router.url;\n\n if (options?.absolute) {\n return location.origin + relativeUrl;\n }\n\n return relativeUrl;\n };\n\n const result = signal(getUrl(), options);\n\n routerListener('navigationend', () => result.set(getUrl()));\n\n return result.asReadonly();\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;;AAcA;;;;;;;;;;;;;;;;;;;;;AAqBG;AACG,SAAU,GAAG,CAAC,OAAoB,EAAA;AACtC,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,GAAG,CAAC;AAE7D,IAAA,OAAO,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,KAAI;AACnC,QAAA,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,CAAC;QAE7B,IAAI,QAAQ,EAAE;AACZ,YAAA,OAAO,WAAW,CAAC,MAAM,CAAC,GAAG,CAAC;QAChC;QAEA,MAAM,MAAM,GAAG,MAAK;AAClB,YAAA,MAAM,WAAW,GAAG,MAAM,CAAC,GAAG;AAE9B,YAAA,IAAI,OAAO,EAAE,QAAQ,EAAE;AACrB,gBAAA,OAAO,QAAQ,CAAC,MAAM,GAAG,WAAW;YACtC;AAEA,YAAA,OAAO,WAAW;AACpB,QAAA,CAAC;QAED,MAAM,MAAM,GAAG,MAAM,CAAC,MAAM,EAAE,EAAE,OAAO,CAAC;AAExC,QAAA,cAAc,CAAC,eAAe,EAAE,MAAM,MAAM,CAAC,GAAG,CAAC,MAAM,EAAE,CAAC,CAAC;AAE3D,QAAA,OAAO,MAAM,CAAC,UAAU,EAAE;AAC5B,IAAA,CAAC,CAAC;AACJ;;AC9DA;;AAEG;;;;"}
@@ -16,7 +16,7 @@ import { setupContext, toValue } from '@signality/core/internal';
16
16
  * <input (input)="handleInput($event.target.value)" />
17
17
  * `,
18
18
  * })
19
- * export class SearchComponent {
19
+ * export class SearchInput {
20
20
  * readonly debounceTime = input(300);
21
21
  * readonly searchChange = output<string>();
22
22
  *
@@ -1 +1 @@
1
- {"version":3,"file":"signality-core-scheduling-debounce-callback.mjs","sources":["../../../projects/core/scheduling/debounce-callback/index.ts","../../../projects/core/scheduling/debounce-callback/signality-core-scheduling-debounce-callback.ts"],"sourcesContent":["import type { MaybeSignal, WithInjector } from '@signality/core/types';\nimport { setupContext, type Timer, toValue } from '@signality/core/internal';\n\n/**\n * Creates a debounced version of a callback function.\n * The callback will only be executed after the specified wait time has elapsed since the last invocation.\n *\n * @param callback - The function to debounce\n * @param wait - Debounce delay in milliseconds (can be a reactive signal)\n * @param options - Optional configuration including injector\n * @returns A debounced version of the callback function\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <input (input)=\"handleInput($event.target.value)\" />\n * `,\n * })\n * export class SearchComponent {\n * readonly debounceTime = input(300);\n * readonly searchChange = output<string>();\n *\n * readonly handleInput = debounceCallback(value => {\n * this.searchChange.emit(value);\n * }, this.debounceTime);\n * }\n * ```\n */\nexport function debounceCallback<T extends (...args: any[]) => any>(\n callback: T,\n wait: MaybeSignal<number>,\n options?: WithInjector\n): T {\n const { runInContext } = setupContext(options?.injector, debounceCallback);\n\n return runInContext(({ isServer, onCleanup }) => {\n if (isServer) {\n return callback;\n }\n\n let timer: Timer;\n\n onCleanup(() => {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n });\n\n return new Proxy(callback, {\n apply(target, thisArg, args) {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n timer = setTimeout(() => {\n target.apply(thisArg, args);\n }, toValue.untracked(wait));\n },\n });\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;AAyBG;SACa,gBAAgB,CAC9B,QAAW,EACX,IAAyB,EACzB,OAAsB,EAAA;AAEtB,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,gBAAgB,CAAC;IAE1E,OAAO,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAI;QAC9C,IAAI,QAAQ,EAAE;AACZ,YAAA,OAAO,QAAQ;QACjB;AAEA,QAAA,IAAI,KAAY;QAEhB,SAAS,CAAC,MAAK;AACb,YAAA,IAAI,KAAK,KAAK,SAAS,EAAE;gBACvB,YAAY,CAAC,KAAK,CAAC;YACrB;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE;AACzB,YAAA,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAA;AACzB,gBAAA,IAAI,KAAK,KAAK,SAAS,EAAE;oBACvB,YAAY,CAAC,KAAK,CAAC;gBACrB;AACA,gBAAA,KAAK,GAAG,UAAU,CAAC,MAAK;AACtB,oBAAA,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC;gBAC7B,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;AACF,SAAA,CAAC;AACJ,IAAA,CAAC,CAAC;AACJ;;AC5DA;;AAEG;;;;"}
1
+ {"version":3,"file":"signality-core-scheduling-debounce-callback.mjs","sources":["../../../projects/core/scheduling/debounce-callback/index.ts","../../../projects/core/scheduling/debounce-callback/signality-core-scheduling-debounce-callback.ts"],"sourcesContent":["import type { MaybeSignal, WithInjector } from '@signality/core/types';\nimport { setupContext, type Timer, toValue } from '@signality/core/internal';\n\n/**\n * Creates a debounced version of a callback function.\n * The callback will only be executed after the specified wait time has elapsed since the last invocation.\n *\n * @param callback - The function to debounce\n * @param wait - Debounce delay in milliseconds (can be a reactive signal)\n * @param options - Optional configuration including injector\n * @returns A debounced version of the callback function\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <input (input)=\"handleInput($event.target.value)\" />\n * `,\n * })\n * export class SearchInput {\n * readonly debounceTime = input(300);\n * readonly searchChange = output<string>();\n *\n * readonly handleInput = debounceCallback(value => {\n * this.searchChange.emit(value);\n * }, this.debounceTime);\n * }\n * ```\n */\nexport function debounceCallback<T extends (...args: any[]) => any>(\n callback: T,\n wait: MaybeSignal<number>,\n options?: WithInjector\n): T {\n const { runInContext } = setupContext(options?.injector, debounceCallback);\n\n return runInContext(({ isServer, onCleanup }) => {\n if (isServer) {\n return callback;\n }\n\n let timer: Timer;\n\n onCleanup(() => {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n });\n\n return new Proxy(callback, {\n apply(target, thisArg, args) {\n if (timer !== undefined) {\n clearTimeout(timer);\n }\n timer = setTimeout(() => {\n target.apply(thisArg, args);\n }, toValue.untracked(wait));\n },\n });\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;AAGA;;;;;;;;;;;;;;;;;;;;;;;;;AAyBG;SACa,gBAAgB,CAC9B,QAAW,EACX,IAAyB,EACzB,OAAsB,EAAA;AAEtB,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,gBAAgB,CAAC;IAE1E,OAAO,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAI;QAC9C,IAAI,QAAQ,EAAE;AACZ,YAAA,OAAO,QAAQ;QACjB;AAEA,QAAA,IAAI,KAAY;QAEhB,SAAS,CAAC,MAAK;AACb,YAAA,IAAI,KAAK,KAAK,SAAS,EAAE;gBACvB,YAAY,CAAC,KAAK,CAAC;YACrB;AACF,QAAA,CAAC,CAAC;AAEF,QAAA,OAAO,IAAI,KAAK,CAAC,QAAQ,EAAE;AACzB,YAAA,KAAK,CAAC,MAAM,EAAE,OAAO,EAAE,IAAI,EAAA;AACzB,gBAAA,IAAI,KAAK,KAAK,SAAS,EAAE;oBACvB,YAAY,CAAC,KAAK,CAAC;gBACrB;AACA,gBAAA,KAAK,GAAG,UAAU,CAAC,MAAK;AACtB,oBAAA,MAAM,CAAC,KAAK,CAAC,OAAO,EAAE,IAAI,CAAC;gBAC7B,CAAC,EAAE,OAAO,CAAC,SAAS,CAAC,IAAI,CAAC,CAAC;YAC7B,CAAC;AACF,SAAA,CAAC;AACJ,IAAA,CAAC,CAAC;AACJ;;AC5DA;;AAEG;;;;"}
@@ -1,33 +1,31 @@
1
- import { signal, untracked, isSignal } from '@angular/core';
2
- import { setupContext, NOOP_FN, constSignal, toValue } from '@signality/core/internal';
1
+ import { isSignal } from '@angular/core';
2
+ import { setupContext, NOOP_EFFECT_REF, toValue } from '@signality/core/internal';
3
3
  import { watcher } from '@signality/core/reactivity/watcher';
4
4
 
5
5
  /**
6
- * Creates a reactive interval that executes a callback function at specified intervals.
7
- * Automatically handles cleanup and supports reactive interval duration.
6
+ * Signal-based wrapper around [`setInterval`](https://developer.mozilla.org/en-US/docs/Web/API/Window/setInterval).
7
+ * Creates a reactive interval that executes a callback at specified intervals.
8
+ * The interval starts immediately upon creation and can be stopped with `destroy()`.
8
9
  *
9
- * @param callback - Function to execute on each interval tick, receives current counter value
10
+ * @param callback - Function to execute on each interval tick
10
11
  * @param intervalMs - Interval duration in milliseconds (can be a reactive signal)
11
- * @param options - Optional configuration including immediate start and injector
12
- * @returns An IntervalRef with control methods and state signals
12
+ * @param options - Optional configuration
13
+ * @returns An IntervalRef with a `destroy` method to stop the interval
13
14
  *
14
15
  * @example
15
16
  * ```typescript
16
17
  * @Component({
17
18
  * template: `
18
- * <p>Status: {{ polling.isActive() ? 'Polling' : 'Stopped' }}</p>
19
- * <button (click)="polling.pause()">Stop</button>
20
- * <button (click)="polling.resume()">Start</button>
19
+ * <p>Ticks: {{ ticks() }}</p>
20
+ * <button (click)="polling.destroy()">Stop</button>
21
21
  * `,
22
22
  * })
23
23
  * export class PeriodicTask {
24
- * readonly polling = interval(async () => {
25
- * await this.checkStatus();
26
- * }, 5000);
24
+ * readonly ticks = signal(0);
27
25
  *
28
- * async checkStatus() {
29
- * // async operation
30
- * }
26
+ * readonly polling = interval(() => {
27
+ * this.ticks.update(n => n + 1);
28
+ * }, 5000);
31
29
  * }
32
30
  * ```
33
31
  */
@@ -35,70 +33,27 @@ function interval(callback, intervalMs, options) {
35
33
  const { runInContext } = setupContext(options?.injector, interval);
36
34
  return runInContext(({ isServer, onCleanup }) => {
37
35
  if (isServer) {
38
- return {
39
- isActive: constSignal(false),
40
- counter: constSignal(0),
41
- pause: NOOP_FN,
42
- resume: NOOP_FN,
43
- reset: NOOP_FN,
44
- };
36
+ return NOOP_EFFECT_REF;
45
37
  }
46
- const isActive = signal(false, ...(ngDevMode ? [{ debugName: "isActive" }] : []));
47
- const counter = signal(0, ...(ngDevMode ? [{ debugName: "counter" }] : []));
48
38
  let intervalId;
49
39
  const start = () => {
50
- untracked(() => {
51
- if (intervalId !== undefined || !isActive()) {
52
- return;
53
- }
54
- const ms = toValue(intervalMs);
55
- intervalId = setInterval(() => {
56
- const currentCounter = counter() + 1;
57
- counter.set(currentCounter);
58
- callback(currentCounter);
59
- }, ms);
60
- });
61
- };
62
- const pause = () => {
63
- cleanup();
64
- isActive.set(false);
65
- };
66
- const cleanup = () => {
67
- if (intervalId !== undefined) {
68
- clearInterval(intervalId);
69
- intervalId = undefined;
70
- }
71
- };
72
- const resume = () => {
73
- if (intervalId !== undefined) {
74
- return;
75
- }
76
- isActive.set(true);
77
- start();
78
- };
79
- const reset = () => {
80
- counter.set(0);
40
+ clearInterval(intervalId);
41
+ const ms = toValue.untracked(intervalMs);
42
+ intervalId = ms > 0 ? setInterval(callback, ms) : undefined;
81
43
  };
82
44
  if (isSignal(intervalMs)) {
83
- watcher(intervalMs, newMs => {
84
- if (isActive() && newMs !== undefined) {
85
- cleanup();
86
- start();
87
- }
88
- });
45
+ watcher(intervalMs, start);
89
46
  }
90
- onCleanup(cleanup);
47
+ const destroy = () => {
48
+ clearInterval(intervalId);
49
+ intervalId = undefined;
50
+ };
51
+ onCleanup(destroy);
91
52
  if (options?.immediate) {
92
- isActive.set(true);
93
- start();
53
+ callback();
94
54
  }
95
- return {
96
- isActive: isActive.asReadonly(),
97
- counter: counter.asReadonly(),
98
- pause,
99
- resume,
100
- reset,
101
- };
55
+ start();
56
+ return { destroy };
102
57
  });
103
58
  }
104
59
 
@@ -1 +1 @@
1
- {"version":3,"file":"signality-core-scheduling-interval.mjs","sources":["../../../projects/core/scheduling/interval/index.ts","../../../projects/core/scheduling/interval/signality-core-scheduling-interval.ts"],"sourcesContent":["import { isSignal, signal, type Signal, untracked } from '@angular/core';\nimport { constSignal, NOOP_FN, setupContext, type Timer, toValue } from '@signality/core/internal';\nimport type { MaybeSignal, WithInjector } from '@signality/core/types';\nimport { watcher } from '@signality/core/reactivity/watcher';\n\nexport interface IntervalOptions extends WithInjector {\n /**\n * Whether to start the interval immediately.\n * @default false\n */\n readonly immediate?: boolean;\n}\n\nexport interface IntervalRef {\n /** Whether the interval is currently active */\n readonly isActive: Signal<boolean>;\n\n /** Number of times the callback has been executed */\n readonly counter: Signal<number>;\n\n /** Pause the interval */\n readonly pause: () => void;\n\n /** Resume the interval */\n readonly resume: () => void;\n\n /** Reset the counter to 0 */\n readonly reset: () => void;\n}\n\n/**\n * Creates a reactive interval that executes a callback function at specified intervals.\n * Automatically handles cleanup and supports reactive interval duration.\n *\n * @param callback - Function to execute on each interval tick, receives current counter value\n * @param intervalMs - Interval duration in milliseconds (can be a reactive signal)\n * @param options - Optional configuration including immediate start and injector\n * @returns An IntervalRef with control methods and state signals\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <p>Status: {{ polling.isActive() ? 'Polling' : 'Stopped' }}</p>\n * <button (click)=\"polling.pause()\">Stop</button>\n * <button (click)=\"polling.resume()\">Start</button>\n * `,\n * })\n * export class PeriodicTask {\n * readonly polling = interval(async () => {\n * await this.checkStatus();\n * }, 5000);\n *\n * async checkStatus() {\n * // async operation\n * }\n * }\n * ```\n */\nexport function interval(\n callback: (counter: number) => void,\n intervalMs: MaybeSignal<number>,\n options?: IntervalOptions\n): IntervalRef {\n const { runInContext } = setupContext(options?.injector, interval);\n\n return runInContext(({ isServer, onCleanup }) => {\n if (isServer) {\n return {\n isActive: constSignal(false),\n counter: constSignal(0),\n pause: NOOP_FN,\n resume: NOOP_FN,\n reset: NOOP_FN,\n };\n }\n\n const isActive = signal(false);\n const counter = signal(0);\n\n let intervalId: Timer;\n\n const start = () => {\n untracked(() => {\n if (intervalId !== undefined || !isActive()) {\n return;\n }\n\n const ms = toValue(intervalMs);\n\n intervalId = setInterval(() => {\n const currentCounter = counter() + 1;\n counter.set(currentCounter);\n callback(currentCounter);\n }, ms);\n });\n };\n\n const pause = () => {\n cleanup();\n isActive.set(false);\n };\n\n const cleanup = () => {\n if (intervalId !== undefined) {\n clearInterval(intervalId);\n intervalId = undefined;\n }\n };\n\n const resume = () => {\n if (intervalId !== undefined) {\n return;\n }\n\n isActive.set(true);\n start();\n };\n\n const reset = () => {\n counter.set(0);\n };\n\n if (isSignal(intervalMs)) {\n watcher(intervalMs, newMs => {\n if (isActive() && newMs !== undefined) {\n cleanup();\n start();\n }\n });\n }\n\n onCleanup(cleanup);\n\n if (options?.immediate) {\n isActive.set(true);\n start();\n }\n\n return {\n isActive: isActive.asReadonly(),\n counter: counter.asReadonly(),\n pause,\n resume,\n reset,\n };\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AA8BA;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BG;SACa,QAAQ,CACtB,QAAmC,EACnC,UAA+B,EAC/B,OAAyB,EAAA;AAEzB,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC;IAElE,OAAO,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAI;QAC9C,IAAI,QAAQ,EAAE;YACZ,OAAO;AACL,gBAAA,QAAQ,EAAE,WAAW,CAAC,KAAK,CAAC;AAC5B,gBAAA,OAAO,EAAE,WAAW,CAAC,CAAC,CAAC;AACvB,gBAAA,KAAK,EAAE,OAAO;AACd,gBAAA,MAAM,EAAE,OAAO;AACf,gBAAA,KAAK,EAAE,OAAO;aACf;QACH;AAEA,QAAA,MAAM,QAAQ,GAAG,MAAM,CAAC,KAAK,oDAAC;AAC9B,QAAA,MAAM,OAAO,GAAG,MAAM,CAAC,CAAC,mDAAC;AAEzB,QAAA,IAAI,UAAiB;QAErB,MAAM,KAAK,GAAG,MAAK;YACjB,SAAS,CAAC,MAAK;gBACb,IAAI,UAAU,KAAK,SAAS,IAAI,CAAC,QAAQ,EAAE,EAAE;oBAC3C;gBACF;AAEA,gBAAA,MAAM,EAAE,GAAG,OAAO,CAAC,UAAU,CAAC;AAE9B,gBAAA,UAAU,GAAG,WAAW,CAAC,MAAK;AAC5B,oBAAA,MAAM,cAAc,GAAG,OAAO,EAAE,GAAG,CAAC;AACpC,oBAAA,OAAO,CAAC,GAAG,CAAC,cAAc,CAAC;oBAC3B,QAAQ,CAAC,cAAc,CAAC;gBAC1B,CAAC,EAAE,EAAE,CAAC;AACR,YAAA,CAAC,CAAC;AACJ,QAAA,CAAC;QAED,MAAM,KAAK,GAAG,MAAK;AACjB,YAAA,OAAO,EAAE;AACT,YAAA,QAAQ,CAAC,GAAG,CAAC,KAAK,CAAC;AACrB,QAAA,CAAC;QAED,MAAM,OAAO,GAAG,MAAK;AACnB,YAAA,IAAI,UAAU,KAAK,SAAS,EAAE;gBAC5B,aAAa,CAAC,UAAU,CAAC;gBACzB,UAAU,GAAG,SAAS;YACxB;AACF,QAAA,CAAC;QAED,MAAM,MAAM,GAAG,MAAK;AAClB,YAAA,IAAI,UAAU,KAAK,SAAS,EAAE;gBAC5B;YACF;AAEA,YAAA,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;AAClB,YAAA,KAAK,EAAE;AACT,QAAA,CAAC;QAED,MAAM,KAAK,GAAG,MAAK;AACjB,YAAA,OAAO,CAAC,GAAG,CAAC,CAAC,CAAC;AAChB,QAAA,CAAC;AAED,QAAA,IAAI,QAAQ,CAAC,UAAU,CAAC,EAAE;AACxB,YAAA,OAAO,CAAC,UAAU,EAAE,KAAK,IAAG;AAC1B,gBAAA,IAAI,QAAQ,EAAE,IAAI,KAAK,KAAK,SAAS,EAAE;AACrC,oBAAA,OAAO,EAAE;AACT,oBAAA,KAAK,EAAE;gBACT;AACF,YAAA,CAAC,CAAC;QACJ;QAEA,SAAS,CAAC,OAAO,CAAC;AAElB,QAAA,IAAI,OAAO,EAAE,SAAS,EAAE;AACtB,YAAA,QAAQ,CAAC,GAAG,CAAC,IAAI,CAAC;AAClB,YAAA,KAAK,EAAE;QACT;QAEA,OAAO;AACL,YAAA,QAAQ,EAAE,QAAQ,CAAC,UAAU,EAAE;AAC/B,YAAA,OAAO,EAAE,OAAO,CAAC,UAAU,EAAE;YAC7B,KAAK;YACL,MAAM;YACN,KAAK;SACN;AACH,IAAA,CAAC,CAAC;AACJ;;ACnJA;;AAEG;;;;"}
1
+ {"version":3,"file":"signality-core-scheduling-interval.mjs","sources":["../../../projects/core/scheduling/interval/index.ts","../../../projects/core/scheduling/interval/signality-core-scheduling-interval.ts"],"sourcesContent":["import { isSignal } from '@angular/core';\nimport { NOOP_EFFECT_REF, setupContext, type Timer, toValue } from '@signality/core/internal';\nimport type { MaybeSignal, WithInjector } from '@signality/core/types';\nimport { watcher } from '@signality/core/reactivity/watcher';\n\nexport interface IntervalOptions extends WithInjector {\n /**\n * Call the callback immediately, without waiting for the first tick.\n *\n * @default false\n */\n readonly immediate?: boolean;\n}\n\nexport interface IntervalRef {\n /**\n * Stop the interval permanently.\n */\n readonly destroy: () => void;\n}\n\n/**\n * Signal-based wrapper around [`setInterval`](https://developer.mozilla.org/en-US/docs/Web/API/Window/setInterval).\n * Creates a reactive interval that executes a callback at specified intervals.\n * The interval starts immediately upon creation and can be stopped with `destroy()`.\n *\n * @param callback - Function to execute on each interval tick\n * @param intervalMs - Interval duration in milliseconds (can be a reactive signal)\n * @param options - Optional configuration\n * @returns An IntervalRef with a `destroy` method to stop the interval\n *\n * @example\n * ```typescript\n * @Component({\n * template: `\n * <p>Ticks: {{ ticks() }}</p>\n * <button (click)=\"polling.destroy()\">Stop</button>\n * `,\n * })\n * export class PeriodicTask {\n * readonly ticks = signal(0);\n *\n * readonly polling = interval(() => {\n * this.ticks.update(n => n + 1);\n * }, 5000);\n * }\n * ```\n */\nexport function interval(\n callback: () => void,\n intervalMs: MaybeSignal<number>,\n options?: IntervalOptions\n): IntervalRef {\n const { runInContext } = setupContext(options?.injector, interval);\n\n return runInContext(({ isServer, onCleanup }) => {\n if (isServer) {\n return NOOP_EFFECT_REF;\n }\n\n let intervalId: Timer;\n\n const start = () => {\n clearInterval(intervalId);\n\n const ms = toValue.untracked(intervalMs);\n intervalId = ms > 0 ? setInterval(callback, ms) : undefined;\n };\n\n if (isSignal(intervalMs)) {\n watcher(intervalMs, start);\n }\n\n const destroy = () => {\n clearInterval(intervalId);\n intervalId = undefined;\n };\n\n onCleanup(destroy);\n\n if (options?.immediate) {\n callback();\n }\n\n start();\n\n return { destroy };\n });\n}\n","/**\n * Generated bundle index. Do not edit.\n */\n\nexport * from './index';\n"],"names":[],"mappings":";;;;AAqBA;;;;;;;;;;;;;;;;;;;;;;;;;;AA0BG;SACa,QAAQ,CACtB,QAAoB,EACpB,UAA+B,EAC/B,OAAyB,EAAA;AAEzB,IAAA,MAAM,EAAE,YAAY,EAAE,GAAG,YAAY,CAAC,OAAO,EAAE,QAAQ,EAAE,QAAQ,CAAC;IAElE,OAAO,YAAY,CAAC,CAAC,EAAE,QAAQ,EAAE,SAAS,EAAE,KAAI;QAC9C,IAAI,QAAQ,EAAE;AACZ,YAAA,OAAO,eAAe;QACxB;AAEA,QAAA,IAAI,UAAiB;QAErB,MAAM,KAAK,GAAG,MAAK;YACjB,aAAa,CAAC,UAAU,CAAC;YAEzB,MAAM,EAAE,GAAG,OAAO,CAAC,SAAS,CAAC,UAAU,CAAC;AACxC,YAAA,UAAU,GAAG,EAAE,GAAG,CAAC,GAAG,WAAW,CAAC,QAAQ,EAAE,EAAE,CAAC,GAAG,SAAS;AAC7D,QAAA,CAAC;AAED,QAAA,IAAI,QAAQ,CAAC,UAAU,CAAC,EAAE;AACxB,YAAA,OAAO,CAAC,UAAU,EAAE,KAAK,CAAC;QAC5B;QAEA,MAAM,OAAO,GAAG,MAAK;YACnB,aAAa,CAAC,UAAU,CAAC;YACzB,UAAU,GAAG,SAAS;AACxB,QAAA,CAAC;QAED,SAAS,CAAC,OAAO,CAAC;AAElB,QAAA,IAAI,OAAO,EAAE,SAAS,EAAE;AACtB,YAAA,QAAQ,EAAE;QACZ;AAEA,QAAA,KAAK,EAAE;QAEP,OAAO,EAAE,OAAO,EAAE;AACpB,IAAA,CAAC,CAAC;AACJ;;ACxFA;;AAEG;;;;"}
@@ -0,0 +1,2 @@
1
+ export declare function assertElement(value: unknown, source: string): asserts value is Element;
2
+ export declare function assertEventTarget(value: unknown, source: string): asserts value is EventTarget;
@@ -3,4 +3,5 @@ export * from './get-event-target';
3
3
  export * from './get-pip-element';
4
4
  export * from './get-shadow-root';
5
5
  export * from './is-element';
6
+ export * from './is-event-target';
6
7
  export * from './is-node-within';
@@ -1 +1 @@
1
- export declare function isElement(obj: Element | EventTarget | Node | object | null): obj is Element;
1
+ export declare function isElement(value: unknown): value is Element;
@@ -0,0 +1 @@
1
+ export declare function isEventTarget(value: unknown): value is EventTarget;
@@ -0,0 +1 @@
1
+ export * from './is-accepted-file';
@@ -0,0 +1,11 @@
1
+ /**
2
+ * Checks whether a file matches the given accept patterns.
3
+ * Follows the native HTML
4
+ * [`accept`](https://developer.mozilla.org/en-US/docs/Web/HTML/Reference/Attributes/accept) attribute format:
5
+ * MIME types (`'image/png'`), wildcards (`'image/*'`), and file extensions (`'.pdf'`).
6
+ *
7
+ * @param file - File to check
8
+ * @param accept - Comma-separated string of accepted patterns (e.g. `'image/*, .pdf'`)
9
+ * @internal
10
+ */
11
+ export declare function isAcceptedFile(file: File, accept: string): boolean;
@@ -1,5 +1,6 @@
1
1
  export * from './bom';
2
2
  export * from './dom';
3
+ export * from './assert';
3
4
  export * from './context';
4
5
  export * from './create-token';
5
6
  export * from './is-query-signal';
@@ -8,3 +9,5 @@ export * from './const-signal';
8
9
  export * from './proxy-signal';
9
10
  export * from './to-element';
10
11
  export * from './to-value';
12
+ export * from './unref-element';
13
+ export * from './files/index';
@@ -1,4 +1,4 @@
1
- import { ElementRef, type Signal } from '@angular/core';
1
+ import { type ElementRef, type Signal } from '@angular/core';
2
2
  export interface ToElementFn extends ToElementBase {
3
3
  untracked: ToElementBase;
4
4
  }
@@ -0,0 +1,2 @@
1
+ import { ElementRef } from '@angular/core';
2
+ export declare function unrefElement<T>(value: T | ElementRef<T>): T;
@@ -1,4 +1,3 @@
1
1
  export * from '@signality/core/observers/intersection-observer';
2
2
  export * from '@signality/core/observers/mutation-observer';
3
- export * from '@signality/core/observers/performance-observer';
4
3
  export * from '@signality/core/observers/resize-observer';
@@ -1,11 +1,32 @@
1
1
  import { type CreateEffectOptions } from '@angular/core';
2
2
  import type { MaybeElementSignal, MaybeSignal } from '@signality/core/types';
3
3
  export interface IntersectionObserverInitOptions extends Omit<CreateEffectOptions, 'allowSignalWrites'> {
4
+ /**
5
+ * Scrollable ancestor used as the intersection viewport.
6
+ * `null` or `undefined` defaults to the browser viewport.
7
+ *
8
+ * @see [IntersectionObserver: root on MDN](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/root)
9
+ */
4
10
  readonly root?: MaybeElementSignal<Element> | Document | null;
11
+ /**
12
+ * CSS margin applied around the root before computing intersections.
13
+ * Accepts values in the same format as the CSS `margin` property (e.g. `'10px 0px'`).
14
+ *
15
+ * @see [IntersectionObserver: rootMargin on MDN](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/rootMargin)
16
+ */
5
17
  readonly rootMargin?: MaybeSignal<string>;
18
+ /**
19
+ * Fraction(s) of the target element that must be visible to trigger the callback.
20
+ * A single number or an array of thresholds, each between `0` and `1`.
21
+ *
22
+ * @see [IntersectionObserver: thresholds on MDN](https://developer.mozilla.org/en-US/docs/Web/API/IntersectionObserver/thresholds)
23
+ */
6
24
  readonly threshold?: MaybeSignal<number | number[]>;
7
25
  }
8
26
  export interface IntersectionObserverRef {
27
+ /**
28
+ * Stop observing all targets and disconnect the underlying `IntersectionObserver`.
29
+ */
9
30
  readonly destroy: () => void;
10
31
  }
11
32
  /**
@@ -27,7 +48,7 @@ export interface IntersectionObserverRef {
27
48
  * }
28
49
  * `
29
50
  * })
30
- * class IntersectionComponent {
51
+ * export class IntersectionDemo {
31
52
  * readonly section = viewChild<ElementRef>('section');
32
53
  * readonly isVisible = signal(false);
33
54
  *
@@ -1,15 +1,57 @@
1
1
  import { type CreateEffectOptions } from '@angular/core';
2
2
  import type { MaybeElementSignal, MaybeSignal } from '@signality/core/types';
3
3
  export interface MutationObserverInitOptions extends Omit<CreateEffectOptions, 'allowSignalWrites'> {
4
+ /**
5
+ * Whether to observe additions and removals of child nodes.
6
+ *
7
+ * @see [MutationObserver.observe(): childList on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe#childlist)
8
+ */
4
9
  readonly childList?: MaybeSignal<boolean>;
10
+ /**
11
+ * Whether to observe attribute changes on the target element.
12
+ * Use `attributeFilter` to limit which attributes are observed.
13
+ *
14
+ * @see [MutationObserver.observe(): attributes on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe#attributes)
15
+ */
5
16
  readonly attributes?: MaybeSignal<boolean>;
17
+ /**
18
+ * Whether to observe changes to the text content (`CharacterData`) of the target.
19
+ *
20
+ * @see [MutationObserver.observe(): characterData on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe#characterdata)
21
+ */
6
22
  readonly characterData?: MaybeSignal<boolean>;
23
+ /**
24
+ * Whether to extend observation to the entire subtree of the target element.
25
+ *
26
+ * @see [MutationObserver.observe(): subtree on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe#subtree)
27
+ */
7
28
  readonly subtree?: MaybeSignal<boolean>;
29
+ /**
30
+ * Whether to record the previous attribute value in each `MutationRecord`.
31
+ * Implicitly sets `attributes` to `true` if not already set.
32
+ *
33
+ * @see [MutationObserver.observe(): attributeOldValue on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe#attributeoldvalue)
34
+ */
8
35
  readonly attributeOldValue?: MaybeSignal<boolean>;
36
+ /**
37
+ * Whether to record the previous character data value in each `MutationRecord`.
38
+ * Implicitly sets `characterData` to `true` if not already set.
39
+ *
40
+ * @see [MutationObserver.observe(): characterDataOldValue on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe#characterdataoldvalue)
41
+ */
9
42
  readonly characterDataOldValue?: MaybeSignal<boolean>;
43
+ /**
44
+ * Array of attribute local names to observe. Only mutations to listed attributes are reported.
45
+ * Implicitly sets `attributes` to `true` if not already set.
46
+ *
47
+ * @see [MutationObserver.observe(): attributeFilter on MDN](https://developer.mozilla.org/en-US/docs/Web/API/MutationObserver/observe#attributefilter)
48
+ */
10
49
  readonly attributeFilter?: MaybeSignal<string[]>;
11
50
  }
12
51
  export interface MutationObserverRef {
52
+ /**
53
+ * Stop observing all targets and disconnect the underlying `MutationObserver`.
54
+ */
13
55
  readonly destroy: () => void;
14
56
  }
15
57
  /**
@@ -30,7 +72,7 @@ export interface MutationObserverRef {
30
72
  * </div>
31
73
  * `
32
74
  * })
33
- * class MutationComponent {
75
+ * export class MutationComponent {
34
76
  * readonly container = viewChild<ElementRef>('container');
35
77
  * readonly childCount = signal(0);
36
78
  *
@@ -1,9 +1,21 @@
1
1
  import { type CreateEffectOptions } from '@angular/core';
2
2
  import type { MaybeElementSignal, MaybeSignal } from '@signality/core/types';
3
3
  export interface ResizeObserverInitOptions extends Omit<CreateEffectOptions, 'allowSignalWrites'> {
4
+ /**
5
+ * Box model to measure when reporting size changes.
6
+ *
7
+ * - `'content-box'` — size of the content area, excluding padding and border (default).
8
+ * - `'border-box'` — size including padding and border.
9
+ * - `'device-pixel-content-box'` — content-box size in physical device pixels.
10
+ *
11
+ * @see [ResizeObserver.observe(): box on MDN](https://developer.mozilla.org/en-US/docs/Web/API/ResizeObserver/observe#box)
12
+ */
4
13
  readonly box?: MaybeSignal<ResizeObserverBoxOptions>;
5
14
  }
6
15
  export interface ResizeObserverRef {
16
+ /**
17
+ * Stop observing all targets and disconnect the underlying `ResizeObserver`.
18
+ */
7
19
  readonly destroy: () => void;
8
20
  }
9
21
  /**
@@ -24,7 +36,7 @@ export interface ResizeObserverRef {
24
36
  * </div>
25
37
  * `
26
38
  * })
27
- * class ResizeComponent {
39
+ * export class ResizeComponent {
28
40
  * readonly resizable = viewChild<ElementRef>('resizable');
29
41
  * readonly size = signal({ width: 0, height: 0 });
30
42
  *
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@signality/core",
3
- "version": "0.0.1-alpha.2",
3
+ "version": "0.0.1-alpha.3",
4
4
  "license": "MIT",
5
5
  "author": "Vyacheslav Borodin <https://github.com/vs-borodin>",
6
6
  "description": "A foundational toolkit for Angular Signals",
@@ -116,10 +116,18 @@
116
116
  "types": "./browser/favicon/index.d.ts",
117
117
  "default": "./fesm2022/signality-core-browser-favicon.mjs"
118
118
  },
119
+ "./browser/file-dialog": {
120
+ "types": "./browser/file-dialog/index.d.ts",
121
+ "default": "./fesm2022/signality-core-browser-file-dialog.mjs"
122
+ },
119
123
  "./browser/fps": {
120
124
  "types": "./browser/fps/index.d.ts",
121
125
  "default": "./fesm2022/signality-core-browser-fps.mjs"
122
126
  },
127
+ "./browser/fullscreen": {
128
+ "types": "./browser/fullscreen/index.d.ts",
129
+ "default": "./fesm2022/signality-core-browser-fullscreen.mjs"
130
+ },
123
131
  "./browser/gamepad": {
124
132
  "types": "./browser/gamepad/index.d.ts",
125
133
  "default": "./fesm2022/signality-core-browser-gamepad.mjs"
@@ -152,14 +160,14 @@
152
160
  "types": "./browser/page-visibility/index.d.ts",
153
161
  "default": "./fesm2022/signality-core-browser-page-visibility.mjs"
154
162
  },
163
+ "./browser/permission-state": {
164
+ "types": "./browser/permission-state/index.d.ts",
165
+ "default": "./fesm2022/signality-core-browser-permission-state.mjs"
166
+ },
155
167
  "./browser/picture-in-picture": {
156
168
  "types": "./browser/picture-in-picture/index.d.ts",
157
169
  "default": "./fesm2022/signality-core-browser-picture-in-picture.mjs"
158
170
  },
159
- "./browser/pointer-lock-element": {
160
- "types": "./browser/pointer-lock-element/index.d.ts",
161
- "default": "./fesm2022/signality-core-browser-pointer-lock-element.mjs"
162
- },
163
171
  "./browser/screen-orientation": {
164
172
  "types": "./browser/screen-orientation/index.d.ts",
165
173
  "default": "./fesm2022/signality-core-browser-screen-orientation.mjs"
@@ -180,6 +188,10 @@
180
188
  "types": "./browser/text-direction/index.d.ts",
181
189
  "default": "./fesm2022/signality-core-browser-text-direction.mjs"
182
190
  },
191
+ "./browser/text-selection": {
192
+ "types": "./browser/text-selection/index.d.ts",
193
+ "default": "./fesm2022/signality-core-browser-text-selection.mjs"
194
+ },
183
195
  "./browser/vibration": {
184
196
  "types": "./browser/vibration/index.d.ts",
185
197
  "default": "./fesm2022/signality-core-browser-vibration.mjs"
@@ -200,6 +212,14 @@
200
212
  "types": "./browser/web-worker/index.d.ts",
201
213
  "default": "./fesm2022/signality-core-browser-web-worker.mjs"
202
214
  },
215
+ "./browser/window-focus": {
216
+ "types": "./browser/window-focus/index.d.ts",
217
+ "default": "./fesm2022/signality-core-browser-window-focus.mjs"
218
+ },
219
+ "./browser/window-size": {
220
+ "types": "./browser/window-size/index.d.ts",
221
+ "default": "./fesm2022/signality-core-browser-window-size.mjs"
222
+ },
203
223
  "./elements/active-element": {
204
224
  "types": "./elements/active-element/index.d.ts",
205
225
  "default": "./fesm2022/signality-core-elements-active-element.mjs"
@@ -256,14 +276,6 @@
256
276
  "types": "./elements/swipe/index.d.ts",
257
277
  "default": "./fesm2022/signality-core-elements-swipe.mjs"
258
278
  },
259
- "./elements/text-selection": {
260
- "types": "./elements/text-selection/index.d.ts",
261
- "default": "./fesm2022/signality-core-elements-text-selection.mjs"
262
- },
263
- "./elements/window-size": {
264
- "types": "./elements/window-size/index.d.ts",
265
- "default": "./fesm2022/signality-core-elements-window-size.mjs"
266
- },
267
279
  "./forms/cva": {
268
280
  "types": "./forms/cva/index.d.ts",
269
281
  "default": "./fesm2022/signality-core-forms-cva.mjs"
@@ -276,10 +288,6 @@
276
288
  "types": "./observers/mutation-observer/index.d.ts",
277
289
  "default": "./fesm2022/signality-core-observers-mutation-observer.mjs"
278
290
  },
279
- "./observers/performance-observer": {
280
- "types": "./observers/performance-observer/index.d.ts",
281
- "default": "./fesm2022/signality-core-observers-performance-observer.mjs"
282
- },
283
291
  "./observers/resize-observer": {
284
292
  "types": "./observers/resize-observer/index.d.ts",
285
293
  "default": "./fesm2022/signality-core-observers-resize-observer.mjs"
@@ -18,7 +18,7 @@ export type DebouncedOptions<T> = CreateSignalOptions<T> & WithInjector;
18
18
  * <p>Debounced value: {{ debouncedQuery() }}</p>
19
19
  * `
20
20
  * })
21
- * class SearchInput {
21
+ * export class SearchInput {
22
22
  * readonly query = signal('');
23
23
  * readonly debouncedQuery = debounced(this.query, 300);
24
24
  * }
@@ -42,7 +42,7 @@ export declare function debounced<S extends Signal<any>>(source: S, timeMs: Mayb
42
42
  * <p>Search results for: {{ query() }}</p>
43
43
  * `
44
44
  * })
45
- * class SearchInput {
45
+ * export class SearchInput {
46
46
  * readonly query = debounced('', 300);
47
47
  * }
48
48
  * ```